* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt mode
2020-04-27 16:29 3% ` Jerin Jacob
@ 2020-04-27 16:49 3% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2020-04-27 16:49 UTC (permalink / raw)
To: Jerin Jacob
Cc: Dumitrescu, Cristian, Nithin Dabilpuram, Singh, Jasvinder,
Thomas Monjalon, Andrew Rybchenko, dev, jerinj, kkanas,
Nithin Dabilpuram, Kinsella, Ray, Neil Horman, Luca Boccassi,
Kevin Traynor, David Marchand, Bruce Richardson
On 4/27/2020 5:29 PM, Jerin Jacob wrote:
> On Mon, Apr 27, 2020 at 9:42 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>
>> On 4/27/2020 10:19 AM, Dumitrescu, Cristian wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Yigit, Ferruh <ferruh.yigit@intel.com>
>>>> Sent: Saturday, April 25, 2020 9:09 PM
>>>> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Nithin Dabilpuram
>>>> <nithind1988@gmail.com>; Singh, Jasvinder <jasvinder.singh@intel.com>;
>>>> Thomas Monjalon <thomas@monjalon.net>; Andrew Rybchenko
>>>> <arybchenko@solarflare.com>
>>>> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
>>>> Dabilpuram <ndabilpuram@marvell.com>
>>>> Subject: Re: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
>>>> mode
>>>>
>>>> On 4/24/2020 11:28 AM, Dumitrescu, Cristian wrote:
>>>>>
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Nithin Dabilpuram <nithind1988@gmail.com>
>>>>>> Sent: Wednesday, April 22, 2020 6:21 PM
>>>>>> To: Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
>>>>>> <cristian.dumitrescu@intel.com>; Thomas Monjalon
>>>>>> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Andrew
>>>>>> Rybchenko <arybchenko@solarflare.com>
>>>>>> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
>>>>>> Dabilpuram <ndabilpuram@marvell.com>
>>>>>> Subject: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
>>>>>> mode
>>>>>>
>>>>>> From: Nithin Dabilpuram <ndabilpuram@marvell.com>
>>>>>>
>>>>>> Some NIC hardware support shaper to work in packet mode i.e
>>>>>> shaping or ratelimiting traffic is in packets per second (PPS) as
>>>>>> opposed to default bytes per second (BPS). Hence this patch
>>>>>> adds support to configure shared or private shaper in packet mode,
>>>>>> provide rate in PPS and add related tm capabilities in port/level/node
>>>>>> capability structures.
>>>>>>
>>>>>> This patch also updates tm port/level/node capability structures with
>>>>>> exiting features of scheduler wfq packet mode, scheduler wfq byte mode
>>>>>> and private/shared shaper byte mode.
>>>>>>
>>>>>> SoftNIC PMD is also updated with new capabilities.
>>>>>>
>>>>>> Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
>>>>>> ---
>>>>>> v3..v4:
>>>>>> - Update text under packet_mode as per Cristian.
>>>>>> - Update rte_eth_softnic_tm.c based on Jasvinder's comments.
>>>>>> - Add error enum
>>>> RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PACKET_MODE
>>>>>> - Fix shaper_profile_check() with packet mode check
>>>>>> - Fix typo's
>>>>>>
>>>>>
>>>>> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>>>>>
>>>>
>>>> Hi Nithin,
>>>>
>>>> It looks like patch is causing ABI break, I am getting following warning [1],
>>>> can you please check?
>>>>
>>>> [1]
>>>> https://pastebin.com/XYNFg14u
>>>
>>>
>>> Hi Ferruh,
>>>
>>> The RTE_TM API is marked as experimental, but it looks that this was not correctly marked when __rte_experimental ABI checker was introduced.
>>>
>>> It is marked as experimental at the top of the rte_tm.h, similarly to other APIs introduced around same time, but it was not correctly picked up by the ABI check procedure when later introduced, so __rte_experimental was not added to every function.
>>>
>>
>> :(
>>
>> Is it time to mature them?
>>
>> As you said they are not marked as experimental both in header file (function
>> declarations) and .map file.
>>
>> The problem is, they are not marked as experimental in DPDK_20.0 ABI (v19.11),
>> so marking them as experimental now will break the ABI. Not sure what to do,
>> cc'ed a few ABI related names for comment.
>>
>> For me, we need to proceed as the experimental tag removed and APIs become
>> mature starting from v19.11, since this is what happened in practice, and remove
>> a few existing being experimental references in the doxygen comments.
>
> I think, accidentally we can not make a library as NON-experimental.
> TM never went through experimental to mature transition(see git log
> lib/librte_ethdev/rte_tm.h)
> It was a bug to not mark as experimental in each function in the ABI process.
> Some of the features like packet marking are not even implemented by any HW.
> I think, we can make API stable only all the features are implemented
> by one or two HW.
Fair enough, specially if the API is not ready yet.
But they were part of stable ABI, and marking them as experimental now will
break the old applications using these APIs.
>
>>
>> Ray, Neil, David, Luca, Kevin, what do you think?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt mode
2020-04-27 16:12 4% ` Ferruh Yigit
2020-04-27 16:28 3% ` Dumitrescu, Cristian
@ 2020-04-27 16:29 3% ` Jerin Jacob
2020-04-27 16:49 3% ` Ferruh Yigit
1 sibling, 1 reply; 200+ results
From: Jerin Jacob @ 2020-04-27 16:29 UTC (permalink / raw)
To: Ferruh Yigit
Cc: Dumitrescu, Cristian, Nithin Dabilpuram, Singh, Jasvinder,
Thomas Monjalon, Andrew Rybchenko, dev, jerinj, kkanas,
Nithin Dabilpuram, Kinsella, Ray, Neil Horman, Luca Boccassi,
Kevin Traynor, David Marchand, Bruce Richardson
On Mon, Apr 27, 2020 at 9:42 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>
> On 4/27/2020 10:19 AM, Dumitrescu, Cristian wrote:
> >
> >
> >> -----Original Message-----
> >> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> >> Sent: Saturday, April 25, 2020 9:09 PM
> >> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Nithin Dabilpuram
> >> <nithind1988@gmail.com>; Singh, Jasvinder <jasvinder.singh@intel.com>;
> >> Thomas Monjalon <thomas@monjalon.net>; Andrew Rybchenko
> >> <arybchenko@solarflare.com>
> >> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
> >> Dabilpuram <ndabilpuram@marvell.com>
> >> Subject: Re: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
> >> mode
> >>
> >> On 4/24/2020 11:28 AM, Dumitrescu, Cristian wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Nithin Dabilpuram <nithind1988@gmail.com>
> >>>> Sent: Wednesday, April 22, 2020 6:21 PM
> >>>> To: Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
> >>>> <cristian.dumitrescu@intel.com>; Thomas Monjalon
> >>>> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Andrew
> >>>> Rybchenko <arybchenko@solarflare.com>
> >>>> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
> >>>> Dabilpuram <ndabilpuram@marvell.com>
> >>>> Subject: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
> >>>> mode
> >>>>
> >>>> From: Nithin Dabilpuram <ndabilpuram@marvell.com>
> >>>>
> >>>> Some NIC hardware support shaper to work in packet mode i.e
> >>>> shaping or ratelimiting traffic is in packets per second (PPS) as
> >>>> opposed to default bytes per second (BPS). Hence this patch
> >>>> adds support to configure shared or private shaper in packet mode,
> >>>> provide rate in PPS and add related tm capabilities in port/level/node
> >>>> capability structures.
> >>>>
> >>>> This patch also updates tm port/level/node capability structures with
> >>>> exiting features of scheduler wfq packet mode, scheduler wfq byte mode
> >>>> and private/shared shaper byte mode.
> >>>>
> >>>> SoftNIC PMD is also updated with new capabilities.
> >>>>
> >>>> Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
> >>>> ---
> >>>> v3..v4:
> >>>> - Update text under packet_mode as per Cristian.
> >>>> - Update rte_eth_softnic_tm.c based on Jasvinder's comments.
> >>>> - Add error enum
> >> RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PACKET_MODE
> >>>> - Fix shaper_profile_check() with packet mode check
> >>>> - Fix typo's
> >>>>
> >>>
> >>> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> >>>
> >>
> >> Hi Nithin,
> >>
> >> It looks like patch is causing ABI break, I am getting following warning [1],
> >> can you please check?
> >>
> >> [1]
> >> https://pastebin.com/XYNFg14u
> >
> >
> > Hi Ferruh,
> >
> > The RTE_TM API is marked as experimental, but it looks that this was not correctly marked when __rte_experimental ABI checker was introduced.
> >
> > It is marked as experimental at the top of the rte_tm.h, similarly to other APIs introduced around same time, but it was not correctly picked up by the ABI check procedure when later introduced, so __rte_experimental was not added to every function.
> >
>
> :(
>
> Is it time to mature them?
>
> As you said they are not marked as experimental both in header file (function
> declarations) and .map file.
>
> The problem is, they are not marked as experimental in DPDK_20.0 ABI (v19.11),
> so marking them as experimental now will break the ABI. Not sure what to do,
> cc'ed a few ABI related names for comment.
>
> For me, we need to proceed as the experimental tag removed and APIs become
> mature starting from v19.11, since this is what happened in practice, and remove
> a few existing being experimental references in the doxygen comments.
I think, accidentally we can not make a library as NON-experimental.
TM never went through experimental to mature transition(see git log
lib/librte_ethdev/rte_tm.h)
It was a bug to not mark as experimental in each function in the ABI process.
Some of the features like packet marking are not even implemented by any HW.
I think, we can make API stable only all the features are implemented
by one or two HW.
>
> Ray, Neil, David, Luca, Kevin, what do you think?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt mode
2020-04-27 16:12 4% ` Ferruh Yigit
@ 2020-04-27 16:28 3% ` Dumitrescu, Cristian
2020-04-27 16:29 3% ` Jerin Jacob
1 sibling, 0 replies; 200+ results
From: Dumitrescu, Cristian @ 2020-04-27 16:28 UTC (permalink / raw)
To: Yigit, Ferruh, Nithin Dabilpuram, Singh, Jasvinder,
Thomas Monjalon, Andrew Rybchenko
Cc: dev, jerinj, kkanas, Nithin Dabilpuram, Kinsella, Ray,
Neil Horman, Luca Boccassi, Kevin Traynor, David Marchand,
Richardson, Bruce
> -----Original Message-----
> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> Sent: Monday, April 27, 2020 5:13 PM
> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Nithin Dabilpuram
> <nithind1988@gmail.com>; Singh, Jasvinder <jasvinder.singh@intel.com>;
> Thomas Monjalon <thomas@monjalon.net>; Andrew Rybchenko
> <arybchenko@solarflare.com>
> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
> Dabilpuram <ndabilpuram@marvell.com>; Kinsella, Ray
> <ray.kinsella@intel.com>; Neil Horman <nhorman@tuxdriver.com>; Luca
> Boccassi <bluca@debian.org>; Kevin Traynor <ktraynor@redhat.com>; David
> Marchand <david.marchand@redhat.com>; Richardson, Bruce
> <bruce.richardson@intel.com>
> Subject: Re: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
> mode
>
> On 4/27/2020 10:19 AM, Dumitrescu, Cristian wrote:
> >
> >
> >> -----Original Message-----
> >> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> >> Sent: Saturday, April 25, 2020 9:09 PM
> >> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Nithin
> Dabilpuram
> >> <nithind1988@gmail.com>; Singh, Jasvinder <jasvinder.singh@intel.com>;
> >> Thomas Monjalon <thomas@monjalon.net>; Andrew Rybchenko
> >> <arybchenko@solarflare.com>
> >> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
> >> Dabilpuram <ndabilpuram@marvell.com>
> >> Subject: Re: [PATCH v4 1/4] ethdev: add tm support for shaper config in
> pkt
> >> mode
> >>
> >> On 4/24/2020 11:28 AM, Dumitrescu, Cristian wrote:
> >>>
> >>>
> >>>> -----Original Message-----
> >>>> From: Nithin Dabilpuram <nithind1988@gmail.com>
> >>>> Sent: Wednesday, April 22, 2020 6:21 PM
> >>>> To: Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
> >>>> <cristian.dumitrescu@intel.com>; Thomas Monjalon
> >>>> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> Andrew
> >>>> Rybchenko <arybchenko@solarflare.com>
> >>>> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
> >>>> Dabilpuram <ndabilpuram@marvell.com>
> >>>> Subject: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
> >>>> mode
> >>>>
> >>>> From: Nithin Dabilpuram <ndabilpuram@marvell.com>
> >>>>
> >>>> Some NIC hardware support shaper to work in packet mode i.e
> >>>> shaping or ratelimiting traffic is in packets per second (PPS) as
> >>>> opposed to default bytes per second (BPS). Hence this patch
> >>>> adds support to configure shared or private shaper in packet mode,
> >>>> provide rate in PPS and add related tm capabilities in port/level/node
> >>>> capability structures.
> >>>>
> >>>> This patch also updates tm port/level/node capability structures with
> >>>> exiting features of scheduler wfq packet mode, scheduler wfq byte
> mode
> >>>> and private/shared shaper byte mode.
> >>>>
> >>>> SoftNIC PMD is also updated with new capabilities.
> >>>>
> >>>> Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
> >>>> ---
> >>>> v3..v4:
> >>>> - Update text under packet_mode as per Cristian.
> >>>> - Update rte_eth_softnic_tm.c based on Jasvinder's comments.
> >>>> - Add error enum
> >> RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PACKET_MODE
> >>>> - Fix shaper_profile_check() with packet mode check
> >>>> - Fix typo's
> >>>>
> >>>
> >>> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> >>>
> >>
> >> Hi Nithin,
> >>
> >> It looks like patch is causing ABI break, I am getting following warning [1],
> >> can you please check?
> >>
> >> [1]
> >> https://pastebin.com/XYNFg14u
> >
> >
> > Hi Ferruh,
> >
> > The RTE_TM API is marked as experimental, but it looks that this was not
> correctly marked when __rte_experimental ABI checker was introduced.
> >
> > It is marked as experimental at the top of the rte_tm.h, similarly to other
> APIs introduced around same time, but it was not correctly picked up by the
> ABI check procedure when later introduced, so __rte_experimental was not
> added to every function.
> >
>
> :(
>
> Is it time to mature them?
>
> As you said they are not marked as experimental both in header file
> (function
> declarations) and .map file.
>
> The problem is, they are not marked as experimental in DPDK_20.0 ABI
> (v19.11),
> so marking them as experimental now will break the ABI. Not sure what to
> do,
> cc'ed a few ABI related names for comment.
>
> For me, we need to proceed as the experimental tag removed and APIs
> become
> mature starting from v19.11, since this is what happened in practice, and
> remove
> a few existing being experimental references in the doxygen comments.
>
> Ray, Neil, David, Luca, Kevin, what do you think?
Hi Ferruh,
IMO your proposed approach is fixing the wrong problem and is probably not the right way of doing things.
This API is correctly marked as experimental in the header file rte_tm.h and in the MAINTAINERS file, therefore it should remain experimental, as more changes are expected from the people like Nithin and others currently upstreaming drivers for it.
For some reason, the __rte_experimental tags were not added to this file when the ABI checker was introduced, and this is the real problem that should be fixed.
Regards,
Cristian
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt mode
2020-04-27 9:19 4% ` Dumitrescu, Cristian
@ 2020-04-27 16:12 4% ` Ferruh Yigit
2020-04-27 16:28 3% ` Dumitrescu, Cristian
2020-04-27 16:29 3% ` Jerin Jacob
0 siblings, 2 replies; 200+ results
From: Ferruh Yigit @ 2020-04-27 16:12 UTC (permalink / raw)
To: Dumitrescu, Cristian, Nithin Dabilpuram, Singh, Jasvinder,
Thomas Monjalon, Andrew Rybchenko
Cc: dev, jerinj, kkanas, Nithin Dabilpuram, Kinsella, Ray,
Neil Horman, Luca Boccassi, Kevin Traynor, David Marchand,
Bruce Richardson
On 4/27/2020 10:19 AM, Dumitrescu, Cristian wrote:
>
>
>> -----Original Message-----
>> From: Yigit, Ferruh <ferruh.yigit@intel.com>
>> Sent: Saturday, April 25, 2020 9:09 PM
>> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Nithin Dabilpuram
>> <nithind1988@gmail.com>; Singh, Jasvinder <jasvinder.singh@intel.com>;
>> Thomas Monjalon <thomas@monjalon.net>; Andrew Rybchenko
>> <arybchenko@solarflare.com>
>> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
>> Dabilpuram <ndabilpuram@marvell.com>
>> Subject: Re: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
>> mode
>>
>> On 4/24/2020 11:28 AM, Dumitrescu, Cristian wrote:
>>>
>>>
>>>> -----Original Message-----
>>>> From: Nithin Dabilpuram <nithind1988@gmail.com>
>>>> Sent: Wednesday, April 22, 2020 6:21 PM
>>>> To: Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
>>>> <cristian.dumitrescu@intel.com>; Thomas Monjalon
>>>> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Andrew
>>>> Rybchenko <arybchenko@solarflare.com>
>>>> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
>>>> Dabilpuram <ndabilpuram@marvell.com>
>>>> Subject: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
>>>> mode
>>>>
>>>> From: Nithin Dabilpuram <ndabilpuram@marvell.com>
>>>>
>>>> Some NIC hardware support shaper to work in packet mode i.e
>>>> shaping or ratelimiting traffic is in packets per second (PPS) as
>>>> opposed to default bytes per second (BPS). Hence this patch
>>>> adds support to configure shared or private shaper in packet mode,
>>>> provide rate in PPS and add related tm capabilities in port/level/node
>>>> capability structures.
>>>>
>>>> This patch also updates tm port/level/node capability structures with
>>>> exiting features of scheduler wfq packet mode, scheduler wfq byte mode
>>>> and private/shared shaper byte mode.
>>>>
>>>> SoftNIC PMD is also updated with new capabilities.
>>>>
>>>> Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
>>>> ---
>>>> v3..v4:
>>>> - Update text under packet_mode as per Cristian.
>>>> - Update rte_eth_softnic_tm.c based on Jasvinder's comments.
>>>> - Add error enum
>> RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PACKET_MODE
>>>> - Fix shaper_profile_check() with packet mode check
>>>> - Fix typo's
>>>>
>>>
>>> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>>>
>>
>> Hi Nithin,
>>
>> It looks like patch is causing ABI break, I am getting following warning [1],
>> can you please check?
>>
>> [1]
>> https://pastebin.com/XYNFg14u
>
>
> Hi Ferruh,
>
> The RTE_TM API is marked as experimental, but it looks that this was not correctly marked when __rte_experimental ABI checker was introduced.
>
> It is marked as experimental at the top of the rte_tm.h, similarly to other APIs introduced around same time, but it was not correctly picked up by the ABI check procedure when later introduced, so __rte_experimental was not added to every function.
>
:(
Is it time to mature them?
As you said they are not marked as experimental both in header file (function
declarations) and .map file.
The problem is, they are not marked as experimental in DPDK_20.0 ABI (v19.11),
so marking them as experimental now will break the ABI. Not sure what to do,
cc'ed a few ABI related names for comment.
For me, we need to proceed as the experimental tag removed and APIs become
mature starting from v19.11, since this is what happened in practice, and remove
a few existing being experimental references in the doxygen comments.
Ray, Neil, David, Luca, Kevin, what do you think?
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v4] eal/cpuflags: add x86 based cpu flags
2020-04-27 12:31 3% ` Thomas Monjalon
@ 2020-04-27 13:58 0% ` Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-27 13:58 UTC (permalink / raw)
To: Thomas Monjalon, ray.kinsella, nhorman, Kevin Laatz
Cc: dev, bruce.richardson, harry.van.haaren, david.marchand,
Haiyue Wang, ktraynor
On 27/04/2020 13:31, Thomas Monjalon wrote:
> 27/04/2020 11:27, Ray Kinsella:
>> On 25/04/2020 17:04, Thomas Monjalon wrote:
>>> PS: Who is REALLY maintaining the ABI?
>>> We really miss someone who carefully check all these things,
>>> and take care of the doc and tooling.
>>
>> I would say that I am missing these changes to libabigail.ignore, which would be useful.
>> Should we consolidate the ABI Policy and ABI Versioning sections of the MAINTAINERS file?
>
> Yes, I think it does not make sense spliting ABI topic in 2 sections
> in MAINTAINERS file.
> We need to have a clear ownership covering policy, libs, tooling and doc.
> Let's agree to merge all in one section please.
>
I would suggest merging and listing myself and Neil as maintainers?
Unless you are aware of another potential owner?
Ray K
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4] abi: change references to abi 20.0.1 to abi v21
2020-04-27 13:45 10% ` [dpdk-dev] [PATCH v4] " Ray Kinsella
@ 2020-04-27 13:45 21% ` Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-27 13:45 UTC (permalink / raw)
To: dev
Cc: aostruszka, stephen, david.marchand, Ray Kinsella,
Thomas Monjalon, Neil Horman, Jingjing Wu, Wenzhuo Lu,
Matan Azrad, Shahaf Shuler, Viacheslav Ovsiienko, Jerin Jacob,
Nithin Dabilpuram, Alfredo Cardigliano, Mahipal Challa,
Cristian Dumitrescu
Change references to abi 20.0.1 to use abi v21, see
https://doc.dpdk.org/guides/contributing/abi_policy.html#general-guidelines.
"Major ABI versions are declared no more frequently than yearly.
Compatibility with the major ABI version is mandatory in subsequent
releases until a new major ABI version is declared."
Add myself as the map file maintainer to more closely monitor future abi
changes.
Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
MAINTAINERS | 2 ++
devtools/libabigail.abignore | 5 +++++
drivers/common/iavf/rte_common_iavf_version.map | 2 +-
drivers/common/mlx5/rte_common_mlx5_version.map | 2 +-
drivers/common/octeontx2/rte_common_octeontx2_version.map | 2 +-
drivers/net/ionic/rte_pmd_ionic_version.map | 2 +-
drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map | 2 +-
drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map | 2 +-
lib/librte_meter/rte_meter_version.map | 2 +-
9 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index d31a809..7d521f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -86,6 +86,8 @@ F: doc/
ABI Policy
M: Ray Kinsella <mdr@ashroe.eu>
F: doc/guides/contributing/abi_*.rst
+F: drivers/*/*/*.map
+F: lib/*/*.map
Developers and Maintainers Tools
M: Thomas Monjalon <thomas@monjalon.net>
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 986a527..b0147fd 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -29,3 +29,8 @@
type_kind = enum
name = rte_eth_event_type
changed_enumerators = RTE_ETH_EVENT_MAX
+; Explicit ignore ABI 20.0.1
+[suppress_function]
+ symbol_version = DPDK_20.0.1
+[suppress_variable]
+ symbol_version = DPDK_20.0.1
diff --git a/drivers/common/iavf/rte_common_iavf_version.map b/drivers/common/iavf/rte_common_iavf_version.map
index 2f11d67..92ceac1 100644
--- a/drivers/common/iavf/rte_common_iavf_version.map
+++ b/drivers/common/iavf/rte_common_iavf_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
global:
iavf_init_adminq;
diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map
index b58a378..564a9a7 100644
--- a/drivers/common/mlx5/rte_common_mlx5_version.map
+++ b/drivers/common/mlx5/rte_common_mlx5_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
global:
mlx5_class_get;
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 8f2404b..01279c3 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -34,7 +34,7 @@ DPDK_20.0 {
local: *;
};
-DPDK_20.0.1 {
+DPDK_21 {
global:
otx2_eth_dev_is_sec_capable;
diff --git a/drivers/net/ionic/rte_pmd_ionic_version.map b/drivers/net/ionic/rte_pmd_ionic_version.map
index bc8fd6d..acdaf58 100644
--- a/drivers/net/ionic/rte_pmd_ionic_version.map
+++ b/drivers/net/ionic/rte_pmd_ionic_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
local: *;
};
diff --git a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
index bc8fd6d..acdaf58 100644
--- a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
+++ b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
local: *;
};
diff --git a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
index 179f7f1..4a76d1d 100644
--- a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
+++ b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
@@ -1,3 +1,3 @@
-DPDK_20.0.1 {
+DPDK_21 {
local: *;
};
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index fc12cc0..2c7dadb 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -13,7 +13,7 @@ DPDK_20.0 {
local: *;
};
-DPDK_20.0.1 {
+DPDK_21 {
global:
rte_meter_trtcm_rfc4115_color_aware_check;
--
2.7.4
^ permalink raw reply [relevance 21%]
* [dpdk-dev] [PATCH v4] abi: change references to abi 20.0.1 to abi v21
2020-04-20 9:34 15% [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21 Ray Kinsella
` (2 preceding siblings ...)
2020-04-27 9:06 11% ` [dpdk-dev] [PATCH v3] " Ray Kinsella
@ 2020-04-27 13:45 10% ` Ray Kinsella
2020-04-27 13:45 21% ` Ray Kinsella
3 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-27 13:45 UTC (permalink / raw)
To: dev
Cc: aostruszka, stephen, david.marchand, Ray Kinsella,
Thomas Monjalon, Neil Horman, Jingjing Wu, Wenzhuo Lu,
Matan Azrad, Shahaf Shuler, Viacheslav Ovsiienko, Jerin Jacob,
Nithin Dabilpuram, Alfredo Cardigliano, Mahipal Challa,
Cristian Dumitrescu
v4:
* restored suppressions for v20.0.1 incorrectly removed in v3.
Ray Kinsella (1):
abi: change references to abi 20.0.1 to abi v21
MAINTAINERS | 2 ++
devtools/libabigail.abignore | 5 +++++
drivers/common/iavf/rte_common_iavf_version.map | 2 +-
drivers/common/mlx5/rte_common_mlx5_version.map | 2 +-
drivers/common/octeontx2/rte_common_octeontx2_version.map | 2 +-
drivers/net/ionic/rte_pmd_ionic_version.map | 2 +-
drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map | 2 +-
drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map | 2 +-
lib/librte_meter/rte_meter_version.map | 2 +-
9 files changed, 14 insertions(+), 7 deletions(-)
--
2.7.4
^ permalink raw reply [relevance 10%]
* Re: [dpdk-dev] [PATCH v4] eal/cpuflags: add x86 based cpu flags
2020-04-27 9:27 4% ` Ray Kinsella
2020-04-27 9:31 0% ` Laatz, Kevin
@ 2020-04-27 12:31 3% ` Thomas Monjalon
2020-04-27 13:58 0% ` Ray Kinsella
1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-27 12:31 UTC (permalink / raw)
To: ray.kinsella, nhorman, Kevin Laatz, Ray Kinsella
Cc: dev, bruce.richardson, harry.van.haaren, david.marchand,
Haiyue Wang, ktraynor
27/04/2020 11:27, Ray Kinsella:
> On 25/04/2020 17:04, Thomas Monjalon wrote:
> > PS: Who is REALLY maintaining the ABI?
> > We really miss someone who carefully check all these things,
> > and take care of the doc and tooling.
>
> I would say that I am missing these changes to libabigail.ignore, which would be useful.
> Should we consolidate the ABI Policy and ABI Versioning sections of the MAINTAINERS file?
Yes, I think it does not make sense spliting ABI topic in 2 sections
in MAINTAINERS file.
We need to have a clear ownership covering policy, libs, tooling and doc.
Let's agree to merge all in one section please.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3] mempool: return 0 if area is too small on populate
2020-04-25 22:23 12% ` [dpdk-dev] [PATCH v3] " Thomas Monjalon
2020-04-26 16:52 12% ` [dpdk-dev] [PATCH v4] " Thomas Monjalon
@ 2020-04-27 11:44 0% ` Ray Kinsella
1 sibling, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-27 11:44 UTC (permalink / raw)
To: Thomas Monjalon, dev
Cc: david.marchand, Olivier Matz, Neil Horman, John McNamara,
Marko Kovacevic, Xiaoyun Li, Jingjing Wu, Andrew Rybchenko
On 25/04/2020 23:23, Thomas Monjalon wrote:
> From: Olivier Matz <olivier.matz@6wind.com>
>
> Change rte_mempool_populate_iova() and rte_mempool_populate_iova() to
> return 0 instead of -EINVAL when there is not enough room to store one
> object, as it can be helpful for applications to distinguish this
> specific case.
>
> As this is an ABI change, use symbol versioning to preserve old
> behavior for binary applications.
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
>
> changes in v3:
> - rebase
> - remove deprecation notice
> - notify API change in release notes
> - fix ABI version from 20.0.1 to 20.0.2 (should be 21 maybe)
yes, should be v21.
>
> This v3 cannot be merged because of a false positive ABI check:
>
> 2 Removed functions:
> 'function int rte_mempool_populate_iova(rte_mempool*, char*, rte_iova_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)' {rte_mempool_populate_iova@@DPDK_20.0}
> 'function int rte_mempool_populate_virt(rte_mempool*, char*, size_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)' {rte_mempool_populate_virt@@DPDK_20.0}
Well it's not really a false positive, as the v20 symbols are now missing.
See notes on VERSION_SYMBOL.
>
> ---
> doc/guides/rel_notes/deprecation.rst | 5 --
> doc/guides/rel_notes/release_20_05.rst | 4 ++
> examples/ntb/ntb_fwd.c | 2 +-
> lib/librte_mempool/meson.build | 2 +
> lib/librte_mempool/rte_mempool.c | 77 ++++++++++++++++++----
> lib/librte_mempool/rte_mempool.h | 14 ++--
> lib/librte_mempool/rte_mempool_version.map | 7 ++
> 7 files changed, 90 insertions(+), 21 deletions(-)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 1339f54f5f..20aa745b77 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -65,11 +65,6 @@ Deprecation Notices
> structure would be made internal (or removed if all dependencies are cleared)
> in future releases.
>
> -* mempool: starting from v20.05, the API of rte_mempool_populate_iova()
> - and rte_mempool_populate_virt() will change to return 0 instead
> - of -EINVAL when there is not enough room to store one object. The ABI
> - will be preserved until 20.11.
> -
> * ethdev: the legacy filter API, including
> ``rte_eth_dev_filter_supported()``, ``rte_eth_dev_filter_ctrl()`` as well
> as filter types MACVLAN, ETHERTYPE, FLEXIBLE, SYN, NTUPLE, TUNNEL, FDIR,
> diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
> index b124c3f287..ab20a7d021 100644
> --- a/doc/guides/rel_notes/release_20_05.rst
> +++ b/doc/guides/rel_notes/release_20_05.rst
> @@ -241,6 +241,10 @@ API Changes
> Also, make sure to start the actual text at the margin.
> =========================================================
>
> +* mempool: The API of ``rte_mempool_populate_iova()`` and
> + ``rte_mempool_populate_virt()`` changed to return 0 instead of -EINVAL
> + when there is not enough room to store one object.
> +
>
> ABI Changes
> -----------
> diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
> index d49189e175..eba8ebf9fa 100644
> --- a/examples/ntb/ntb_fwd.c
> +++ b/examples/ntb/ntb_fwd.c
> @@ -1319,7 +1319,7 @@ ntb_mbuf_pool_create(uint16_t mbuf_seg_size, uint32_t nb_mbuf,
> mz->len - ntb_info.ntb_hdr_size,
> ntb_mempool_mz_free,
> (void *)(uintptr_t)mz);
> - if (ret < 0) {
> + if (ret <= 0) {
> rte_memzone_free(mz);
> rte_mempool_free(mp);
> return NULL;
> diff --git a/lib/librte_mempool/meson.build b/lib/librte_mempool/meson.build
> index a6e861cbfc..7dbe6b9bea 100644
> --- a/lib/librte_mempool/meson.build
> +++ b/lib/librte_mempool/meson.build
> @@ -9,6 +9,8 @@ foreach flag: extra_flags
> endif
> endforeach
>
> +use_function_versioning = true
> +
> sources = files('rte_mempool.c', 'rte_mempool_ops.c',
> 'rte_mempool_ops_default.c', 'mempool_trace_points.c')
> headers = files('rte_mempool.h', 'rte_mempool_trace.h',
> diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
> index 0be8f9f59d..edbdafaafb 100644
> --- a/lib/librte_mempool/rte_mempool.c
> +++ b/lib/librte_mempool/rte_mempool.c
> @@ -31,6 +31,7 @@
> #include <rte_string_fns.h>
> #include <rte_spinlock.h>
> #include <rte_tailq.h>
> +#include <rte_function_versioning.h>
>
> #include "rte_mempool.h"
> #include "rte_mempool_trace.h"
> @@ -303,12 +304,17 @@ mempool_ops_alloc_once(struct rte_mempool *mp)
> return 0;
> }
>
> +__vsym int
> +rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
> + rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
> + void *opaque);
> +
> /* Add objects in the pool, using a physically contiguous memory
> * zone. Return the number of objects added, or a negative value
> * on error.
> */
> -static int
> -__rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> +__vsym int
> +rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
> rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
> void *opaque)
> {
> @@ -366,14 +372,27 @@ __rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> return ret;
> }
>
> -int
> -rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> +BIND_DEFAULT_SYMBOL(rte_mempool_populate_iova, _v20_0_2, 20.0.2);
as discussed v21.
> +MAP_STATIC_SYMBOL(
> + int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> + rte_iova_t iova, size_t len,
> + rte_mempool_memchunk_free_cb_t *free_cb,
> + void *opaque),
> + rte_mempool_populate_iova_v20_0_2);
> +
> +__vsym int
> +rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
> + rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
> + void *opaque);
> +
> +__vsym int
> +rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
> rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
> void *opaque)
> {
> int ret;
>
> - ret = __rte_mempool_populate_iova(mp, vaddr, iova, len, free_cb,
> + ret = rte_mempool_populate_iova_v20_0_2(mp, vaddr, iova, len, free_cb,
> opaque);
> if (ret == 0)
> ret = -EINVAL;
> @@ -381,6 +400,7 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> rte_mempool_trace_populate_iova(mp, vaddr, iova, len, free_cb, opaque);
> return ret;
> }
> +VERSION_SYMBOL(rte_mempool_populate_iova, _v20_0, 20.0);
this should be
VERSION_SYMBOL(rte_mempool_populate_iova, _v20, 20.0);
>
> static rte_iova_t
> get_iova(void *addr)
> @@ -395,11 +415,16 @@ get_iova(void *addr)
> return ms->iova + RTE_PTR_DIFF(addr, ms->addr);
> }
>
> +__vsym int
> +rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
> + size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
> + void *opaque);
> +
> /* Populate the mempool with a virtual area. Return the number of
> * objects added, or a negative value on error.
> */
> -int
> -rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
> +__vsym int
> +rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
> size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
> void *opaque)
> {
> @@ -432,7 +457,7 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
> break;
> }
>
> - ret = __rte_mempool_populate_iova(mp, addr + off, iova,
> + ret = rte_mempool_populate_iova_v20_0_2(mp, addr + off, iova,
> phys_len, free_cb, opaque);
> if (ret == 0)
> continue;
> @@ -443,9 +468,6 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
> cnt += ret;
> }
>
> - if (cnt == 0)
> - return -EINVAL;
> -
> rte_mempool_trace_populate_virt(mp, addr, len, pg_sz, free_cb, opaque);
> return cnt;
>
> @@ -453,6 +475,35 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
> rte_mempool_free_memchunks(mp);
> return ret;
> }
> +BIND_DEFAULT_SYMBOL(rte_mempool_populate_virt, _v20_0_2, 20.0.2);
as discussed v21.
> +MAP_STATIC_SYMBOL(
> + int rte_mempool_populate_virt(struct rte_mempool *mp,
> + char *addr, size_t len, size_t pg_sz,
> + rte_mempool_memchunk_free_cb_t *free_cb,
> + void *opaque),
> + rte_mempool_populate_virt_v20_0_2);
> +
> +__vsym int
> +rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
> + size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
> + void *opaque);
> +
> +__vsym int
> +rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
> + size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
> + void *opaque)
> +{
> + int ret;
> +
> + ret = rte_mempool_populate_virt_v20_0_2(mp, addr, len, pg_sz,
> + free_cb, opaque);
> +
> + if (ret == 0)
> + ret = -EINVAL;
> +
> + return ret;
> +}
> +VERSION_SYMBOL(rte_mempool_populate_virt, _v20_0, 20.0);
this should be
VERSION_SYMBOL(rte_mempool_populate_virt, _v20, 20.0);
>
> /* Get the minimal page size used in a mempool before populating it. */
> int
> @@ -609,6 +660,8 @@ rte_mempool_populate_default(struct rte_mempool *mp)
> mz->len, pg_sz,
> rte_mempool_memchunk_mz_free,
> (void *)(uintptr_t)mz);
> + if (ret == 0) /* should not happen */
> + ret = -ENOBUFS;
> if (ret < 0) {
> rte_memzone_free(mz);
> goto fail;
> @@ -701,6 +754,8 @@ rte_mempool_populate_anon(struct rte_mempool *mp)
>
> ret = rte_mempool_populate_virt(mp, addr, size, getpagesize(),
> rte_mempool_memchunk_anon_free, addr);
> + if (ret == 0) /* should not happen */
> + ret = -ENOBUFS;
> if (ret < 0) {
> rte_errno = -ret;
> goto fail;
> diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
> index 6e0573ea42..652d19f9f1 100644
> --- a/lib/librte_mempool/rte_mempool.h
> +++ b/lib/librte_mempool/rte_mempool.h
> @@ -1112,9 +1112,12 @@ rte_mempool_free(struct rte_mempool *mp);
> * @param opaque
> * An opaque argument passed to free_cb.
> * @return
> - * The number of objects added on success.
> + * The number of objects added on success (strictly positive).
> * On error, the chunk is not added in the memory list of the
> - * mempool and a negative errno is returned.
> + * mempool the following code is returned:
> + * (0): not enough room in chunk for one object.
> + * (-ENOSPC): mempool is already populated.
> + * (-ENOMEM): allocation failure.
> */
> int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
> @@ -1139,9 +1142,12 @@ int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
> * @param opaque
> * An opaque argument passed to free_cb.
> * @return
> - * The number of objects added on success.
> + * The number of objects added on success (strictly positive).
> * On error, the chunk is not added in the memory list of the
> - * mempool and a negative errno is returned.
> + * mempool the following code is returned:
> + * (0): not enough room in chunk for one object.
> + * (-ENOSPC): mempool is already populated.
> + * (-ENOMEM): allocation failure.
> */
> int
> rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
> diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
> index 695dd6e04f..9e58093665 100644
> --- a/lib/librte_mempool/rte_mempool_version.map
> +++ b/lib/librte_mempool/rte_mempool_version.map
> @@ -31,6 +31,13 @@ DPDK_20.0 {
> local: *;
> };
>
> +DPDK_20.0.2 {
as discussed DPDK_21
> + global:
> +
> + rte_mempool_populate_iova;
> + rte_mempool_populate_virt;
> +} DPDK_20.0;
> +
> EXPERIMENTAL {
> global:
>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4] eal/cpuflags: add x86 based cpu flags
2020-04-27 9:35 0% ` Ray Kinsella
@ 2020-04-27 10:08 0% ` Laatz, Kevin
0 siblings, 0 replies; 200+ results
From: Laatz, Kevin @ 2020-04-27 10:08 UTC (permalink / raw)
To: Ray Kinsella, Thomas Monjalon, Kinsella, Ray, nhorman
Cc: dev, Richardson, Bruce, Van Haaren, Harry, david.marchand
> On 27/04/2020 10:31, Laatz, Kevin wrote:
> >
> >> (replying this time to the list)
> >>
> >> On 25/04/2020 17:04, Thomas Monjalon wrote:
> >>> 16/04/2020 13:00, Kevin Laatz:
> >>>> This patch adds CPU flags which will enable the detection of ISA
> >>>> features available on more recent x86 based CPUs.
> >>> [...]
> >>>> --- a/devtools/libabigail.abignore
> >>>> +++ b/devtools/libabigail.abignore
> >>>> +; Ignore this enum update as it should not be allocated by the
> >>>> +application [suppress_type]
> >>>> + type_kind = enum
> >>>> + name = rte_cpu_flag_t
> >>>> + changed_enumerators = RTE_CPUFLAG_NUMFLAGS
> >>>
> >>> The justification is not correct.
> >>> The application is allowed to use RTE_CPUFLAG_NUMFLAGS in array
> >> allocation.
> >>> But no API is returning a CPU flag, so the new flags will remain
> >>> unknown to the application.
> >>>
> >>> However, there is a behaviour change:
> >>> The functions rte_cpu_get_flag_name() and
> rte_cpu_get_flag_enabled()
> >>> will now accept new values, which were previously considered as an
> error.
> >>> Is it an ABI breakage? I would say no.
> >>
> >> We saw something similar with the Cryptodev's
> >> rte_crypto_sym_xform_type also.
> >> Libabigail appears to be particularly sensitive to changes to enumerations.
> >> Leaving it to the user to decide if there is a problem.
> >>
> >> I am seeing a bit of weirdness though between versions of libabigail.
> >> 1.7.1 seems to fine with the change, however 1.2 is reporting an issue.
> >>
> >> Kevin - what version are you using?
> >
> > I'm using version 1.6.0
>
> right you are either on Fedora 31 or some Ubuntu v19.xx, right?
At the time of making the patch: Ubuntu 18.04 with a manually upgraded libabigail
Currently Ubuntu 20.04 (beta).
>
> >
> >>
> >>>
> >>> PS: Who is REALLY maintaining the ABI?
> >>> We really miss someone who carefully check all these things, and
> >>> take care of the doc and tooling.
> >>>
> >>>
> >>
> >> I would say that I am missing these changes to libabigail.ignore,
> >> which would be useful.
> >> Should we consolidate the ABI Policy and ABI Versioning sections of
> >> the MAINTAINERS file?
> >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4] eal/cpuflags: add x86 based cpu flags
2020-04-27 9:31 0% ` Laatz, Kevin
@ 2020-04-27 9:35 0% ` Ray Kinsella
2020-04-27 10:08 0% ` Laatz, Kevin
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-27 9:35 UTC (permalink / raw)
To: Laatz, Kevin, Thomas Monjalon, Kinsella, Ray, nhorman
Cc: dev, Richardson, Bruce, Van Haaren, Harry, david.marchand
On 27/04/2020 10:31, Laatz, Kevin wrote:
>
>> (replying this time to the list)
>>
>> On 25/04/2020 17:04, Thomas Monjalon wrote:
>>> 16/04/2020 13:00, Kevin Laatz:
>>>> This patch adds CPU flags which will enable the detection of ISA
>>>> features available on more recent x86 based CPUs.
>>> [...]
>>>> --- a/devtools/libabigail.abignore
>>>> +++ b/devtools/libabigail.abignore
>>>> +; Ignore this enum update as it should not be allocated by the
>>>> +application [suppress_type]
>>>> + type_kind = enum
>>>> + name = rte_cpu_flag_t
>>>> + changed_enumerators = RTE_CPUFLAG_NUMFLAGS
>>>
>>> The justification is not correct.
>>> The application is allowed to use RTE_CPUFLAG_NUMFLAGS in array
>> allocation.
>>> But no API is returning a CPU flag, so the new flags will remain
>>> unknown to the application.
>>>
>>> However, there is a behaviour change:
>>> The functions rte_cpu_get_flag_name() and rte_cpu_get_flag_enabled()
>>> will now accept new values, which were previously considered as an error.
>>> Is it an ABI breakage? I would say no.
>>
>> We saw something similar with the Cryptodev's rte_crypto_sym_xform_type
>> also.
>> Libabigail appears to be particularly sensitive to changes to enumerations.
>> Leaving it to the user to decide if there is a problem.
>>
>> I am seeing a bit of weirdness though between versions of libabigail.
>> 1.7.1 seems to fine with the change, however 1.2 is reporting an issue.
>>
>> Kevin - what version are you using?
>
> I'm using version 1.6.0
right you are either on Fedora 31 or some Ubuntu v19.xx, right?
>
>>
>>>
>>> PS: Who is REALLY maintaining the ABI?
>>> We really miss someone who carefully check all these things, and take
>>> care of the doc and tooling.
>>>
>>>
>>
>> I would say that I am missing these changes to libabigail.ignore, which would
>> be useful.
>> Should we consolidate the ABI Policy and ABI Versioning sections of the
>> MAINTAINERS file?
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4] eal/cpuflags: add x86 based cpu flags
2020-04-27 9:27 4% ` Ray Kinsella
@ 2020-04-27 9:31 0% ` Laatz, Kevin
2020-04-27 9:35 0% ` Ray Kinsella
2020-04-27 12:31 3% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Laatz, Kevin @ 2020-04-27 9:31 UTC (permalink / raw)
To: Ray Kinsella, Thomas Monjalon, Kinsella, Ray, nhorman
Cc: dev, Richardson, Bruce, Van Haaren, Harry, david.marchand
> (replying this time to the list)
>
> On 25/04/2020 17:04, Thomas Monjalon wrote:
> > 16/04/2020 13:00, Kevin Laatz:
> >> This patch adds CPU flags which will enable the detection of ISA
> >> features available on more recent x86 based CPUs.
> > [...]
> >> --- a/devtools/libabigail.abignore
> >> +++ b/devtools/libabigail.abignore
> >> +; Ignore this enum update as it should not be allocated by the
> >> +application [suppress_type]
> >> + type_kind = enum
> >> + name = rte_cpu_flag_t
> >> + changed_enumerators = RTE_CPUFLAG_NUMFLAGS
> >
> > The justification is not correct.
> > The application is allowed to use RTE_CPUFLAG_NUMFLAGS in array
> allocation.
> > But no API is returning a CPU flag, so the new flags will remain
> > unknown to the application.
> >
> > However, there is a behaviour change:
> > The functions rte_cpu_get_flag_name() and rte_cpu_get_flag_enabled()
> > will now accept new values, which were previously considered as an error.
> > Is it an ABI breakage? I would say no.
>
> We saw something similar with the Cryptodev's rte_crypto_sym_xform_type
> also.
> Libabigail appears to be particularly sensitive to changes to enumerations.
> Leaving it to the user to decide if there is a problem.
>
> I am seeing a bit of weirdness though between versions of libabigail.
> 1.7.1 seems to fine with the change, however 1.2 is reporting an issue.
>
> Kevin - what version are you using?
I'm using version 1.6.0
>
> >
> > PS: Who is REALLY maintaining the ABI?
> > We really miss someone who carefully check all these things, and take
> > care of the doc and tooling.
> >
> >
>
> I would say that I am missing these changes to libabigail.ignore, which would
> be useful.
> Should we consolidate the ABI Policy and ABI Versioning sections of the
> MAINTAINERS file?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4] eal/cpuflags: add x86 based cpu flags
2020-04-25 16:04 4% ` Thomas Monjalon
@ 2020-04-27 9:27 4% ` Ray Kinsella
2020-04-27 9:31 0% ` Laatz, Kevin
2020-04-27 12:31 3% ` Thomas Monjalon
0 siblings, 2 replies; 200+ results
From: Ray Kinsella @ 2020-04-27 9:27 UTC (permalink / raw)
To: Thomas Monjalon, ray.kinsella, nhorman, Kevin Laatz
Cc: dev, bruce.richardson, harry.van.haaren, david.marchand
(replying this time to the list)
On 25/04/2020 17:04, Thomas Monjalon wrote:
> 16/04/2020 13:00, Kevin Laatz:
>> This patch adds CPU flags which will enable the detection of ISA
>> features available on more recent x86 based CPUs.
> [...]
>> --- a/devtools/libabigail.abignore
>> +++ b/devtools/libabigail.abignore
>> +; Ignore this enum update as it should not be allocated by the application
>> +[suppress_type]
>> + type_kind = enum
>> + name = rte_cpu_flag_t
>> + changed_enumerators = RTE_CPUFLAG_NUMFLAGS
>
> The justification is not correct.
> The application is allowed to use RTE_CPUFLAG_NUMFLAGS in array allocation.
> But no API is returning a CPU flag, so the new flags will remain unknown
> to the application.
>
> However, there is a behaviour change:
> The functions rte_cpu_get_flag_name() and rte_cpu_get_flag_enabled()
> will now accept new values, which were previously considered as an error.
> Is it an ABI breakage? I would say no.
We saw something similar with the Cryptodev's rte_crypto_sym_xform_type also.
Libabigail appears to be particularly sensitive to changes to enumerations.
Leaving it to the user to decide if there is a problem.
I am seeing a bit of weirdness though between versions of libabigail.
1.7.1 seems to fine with the change, however 1.2 is reporting an issue.
Kevin - what version are you using?
>
> PS: Who is REALLY maintaining the ABI?
> We really miss someone who carefully check all these things,
> and take care of the doc and tooling.
>
>
I would say that I am missing these changes to libabigail.ignore, which would be useful.
Should we consolidate the ABI Policy and ABI Versioning sections of the MAINTAINERS file?
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt mode
2020-04-25 20:09 3% ` Ferruh Yigit
@ 2020-04-27 9:19 4% ` Dumitrescu, Cristian
2020-04-27 16:12 4% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Dumitrescu, Cristian @ 2020-04-27 9:19 UTC (permalink / raw)
To: Yigit, Ferruh, Nithin Dabilpuram, Singh, Jasvinder,
Thomas Monjalon, Andrew Rybchenko
Cc: dev, jerinj, kkanas, Nithin Dabilpuram
> -----Original Message-----
> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> Sent: Saturday, April 25, 2020 9:09 PM
> To: Dumitrescu, Cristian <cristian.dumitrescu@intel.com>; Nithin Dabilpuram
> <nithind1988@gmail.com>; Singh, Jasvinder <jasvinder.singh@intel.com>;
> Thomas Monjalon <thomas@monjalon.net>; Andrew Rybchenko
> <arybchenko@solarflare.com>
> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
> Dabilpuram <ndabilpuram@marvell.com>
> Subject: Re: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
> mode
>
> On 4/24/2020 11:28 AM, Dumitrescu, Cristian wrote:
> >
> >
> >> -----Original Message-----
> >> From: Nithin Dabilpuram <nithind1988@gmail.com>
> >> Sent: Wednesday, April 22, 2020 6:21 PM
> >> To: Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
> >> <cristian.dumitrescu@intel.com>; Thomas Monjalon
> >> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Andrew
> >> Rybchenko <arybchenko@solarflare.com>
> >> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
> >> Dabilpuram <ndabilpuram@marvell.com>
> >> Subject: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
> >> mode
> >>
> >> From: Nithin Dabilpuram <ndabilpuram@marvell.com>
> >>
> >> Some NIC hardware support shaper to work in packet mode i.e
> >> shaping or ratelimiting traffic is in packets per second (PPS) as
> >> opposed to default bytes per second (BPS). Hence this patch
> >> adds support to configure shared or private shaper in packet mode,
> >> provide rate in PPS and add related tm capabilities in port/level/node
> >> capability structures.
> >>
> >> This patch also updates tm port/level/node capability structures with
> >> exiting features of scheduler wfq packet mode, scheduler wfq byte mode
> >> and private/shared shaper byte mode.
> >>
> >> SoftNIC PMD is also updated with new capabilities.
> >>
> >> Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
> >> ---
> >> v3..v4:
> >> - Update text under packet_mode as per Cristian.
> >> - Update rte_eth_softnic_tm.c based on Jasvinder's comments.
> >> - Add error enum
> RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PACKET_MODE
> >> - Fix shaper_profile_check() with packet mode check
> >> - Fix typo's
> >>
> >
> > Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
> >
>
> Hi Nithin,
>
> It looks like patch is causing ABI break, I am getting following warning [1],
> can you please check?
>
> [1]
> https://pastebin.com/XYNFg14u
Hi Ferruh,
The RTE_TM API is marked as experimental, but it looks that this was not correctly marked when __rte_experimental ABI checker was introduced.
It is marked as experimental at the top of the rte_tm.h, similarly to other APIs introduced around same time, but it was not correctly picked up by the ABI check procedure when later introduced, so __rte_experimental was not added to every function.
Regards,
Cristian
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3] abi: change references to abi 20.0.1 to abi v21
2020-04-27 9:06 11% ` [dpdk-dev] [PATCH v3] " Ray Kinsella
@ 2020-04-27 9:06 16% ` Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-27 9:06 UTC (permalink / raw)
To: dev
Cc: aostruszka, stephen, david.marchand, Ray Kinsella,
Thomas Monjalon, Jingjing Wu, Wenzhuo Lu, Matan Azrad,
Shahaf Shuler, Viacheslav Ovsiienko, Jerin Jacob,
Nithin Dabilpuram, Alfredo Cardigliano, Mahipal Challa,
Cristian Dumitrescu
Change references to abi 20.0.1 to use abi v21, see
https://doc.dpdk.org/guides/contributing/abi_policy.html#general-guidelines.
"Major ABI versions are declared no more frequently than yearly.
Compatibility with the major ABI version is mandatory in subsequent
releases until a new major ABI version is declared."
Add myself as the map file maintainer to more closely monitor future abi
changes.
Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
MAINTAINERS | 2 ++
drivers/common/iavf/rte_common_iavf_version.map | 2 +-
drivers/common/mlx5/rte_common_mlx5_version.map | 2 +-
drivers/common/octeontx2/rte_common_octeontx2_version.map | 2 +-
drivers/net/ionic/rte_pmd_ionic_version.map | 2 +-
drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map | 2 +-
drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map | 2 +-
lib/librte_meter/rte_meter_version.map | 2 +-
8 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index d31a809..7d521f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -86,6 +86,8 @@ F: doc/
ABI Policy
M: Ray Kinsella <mdr@ashroe.eu>
F: doc/guides/contributing/abi_*.rst
+F: drivers/*/*/*.map
+F: lib/*/*.map
Developers and Maintainers Tools
M: Thomas Monjalon <thomas@monjalon.net>
diff --git a/drivers/common/iavf/rte_common_iavf_version.map b/drivers/common/iavf/rte_common_iavf_version.map
index 2f11d67..92ceac1 100644
--- a/drivers/common/iavf/rte_common_iavf_version.map
+++ b/drivers/common/iavf/rte_common_iavf_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
global:
iavf_init_adminq;
diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map
index b58a378..564a9a7 100644
--- a/drivers/common/mlx5/rte_common_mlx5_version.map
+++ b/drivers/common/mlx5/rte_common_mlx5_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
global:
mlx5_class_get;
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 8f2404b..01279c3 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -34,7 +34,7 @@ DPDK_20.0 {
local: *;
};
-DPDK_20.0.1 {
+DPDK_21 {
global:
otx2_eth_dev_is_sec_capable;
diff --git a/drivers/net/ionic/rte_pmd_ionic_version.map b/drivers/net/ionic/rte_pmd_ionic_version.map
index bc8fd6d..acdaf58 100644
--- a/drivers/net/ionic/rte_pmd_ionic_version.map
+++ b/drivers/net/ionic/rte_pmd_ionic_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
local: *;
};
diff --git a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
index bc8fd6d..acdaf58 100644
--- a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
+++ b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
local: *;
};
diff --git a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
index 179f7f1..4a76d1d 100644
--- a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
+++ b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
@@ -1,3 +1,3 @@
-DPDK_20.0.1 {
+DPDK_21 {
local: *;
};
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index fc12cc0..2c7dadb 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -13,7 +13,7 @@ DPDK_20.0 {
local: *;
};
-DPDK_20.0.1 {
+DPDK_21 {
global:
rte_meter_trtcm_rfc4115_color_aware_check;
--
2.7.4
^ permalink raw reply [relevance 16%]
* [dpdk-dev] [PATCH v3] abi: change references to abi 20.0.1 to abi v21
2020-04-20 9:34 15% [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21 Ray Kinsella
2020-04-20 11:57 9% ` Ray Kinsella
2020-04-23 6:41 21% ` [dpdk-dev] [PATCH v2] " Ray Kinsella
@ 2020-04-27 9:06 11% ` Ray Kinsella
2020-04-27 9:06 16% ` Ray Kinsella
2020-04-27 13:45 10% ` [dpdk-dev] [PATCH v4] " Ray Kinsella
3 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-27 9:06 UTC (permalink / raw)
To: dev
Cc: aostruszka, stephen, david.marchand, Ray Kinsella,
Thomas Monjalon, Jingjing Wu, Wenzhuo Lu, Matan Azrad,
Shahaf Shuler, Viacheslav Ovsiienko, Jerin Jacob,
Nithin Dabilpuram, Alfredo Cardigliano, Mahipal Challa,
Cristian Dumitrescu
v3:
* Removed libabigail supressions in previous version.
* Clarified abi policy for only major abi versions in git commit.
Ray Kinsella (1):
abi: change references to abi 20.0.1 to abi v21
MAINTAINERS | 2 ++
drivers/common/iavf/rte_common_iavf_version.map | 2 +-
drivers/common/mlx5/rte_common_mlx5_version.map | 2 +-
drivers/common/octeontx2/rte_common_octeontx2_version.map | 2 +-
drivers/net/ionic/rte_pmd_ionic_version.map | 2 +-
drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map | 2 +-
drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map | 2 +-
lib/librte_meter/rte_meter_version.map | 2 +-
8 files changed, 9 insertions(+), 7 deletions(-)
--
2.7.4
^ permalink raw reply [relevance 11%]
* Re: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status update
2020-04-26 14:20 0% ` Phil Yang
@ 2020-04-26 19:30 0% ` Carrillo, Erik G
0 siblings, 0 replies; 200+ results
From: Carrillo, Erik G @ 2020-04-26 19:30 UTC (permalink / raw)
To: Phil Yang, thomas
Cc: rsanford, dev, david.marchand, Honnappa Nagarahalli, Gavin Hu,
nd, nd, nd
> -----Original Message-----
> From: Phil Yang <Phil.Yang@arm.com>
> Sent: Sunday, April 26, 2020 9:20 AM
> To: Carrillo, Erik G <erik.g.carrillo@intel.com>; thomas@monjalon.net
> Cc: rsanford@akamai.com; dev@dpdk.org; david.marchand@redhat.com;
> Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>; Gavin Hu
> <Gavin.Hu@arm.com>; nd <nd@arm.com>; nd <nd@arm.com>; nd
> <nd@arm.com>
> Subject: RE: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status update
>
> > -----Original Message-----
> > From: Carrillo, Erik G <erik.g.carrillo@intel.com>
> > Sent: Sunday, April 26, 2020 8:19 PM
> > To: Phil Yang <Phil.Yang@arm.com>; thomas@monjalon.net
> > Cc: rsanford@akamai.com; dev@dpdk.org; david.marchand@redhat.com;
> > Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>; Gavin Hu
> > <Gavin.Hu@arm.com>; nd <nd@arm.com>; nd <nd@arm.com>
> > Subject: RE: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status
> > update
> >
> >
> >
> > > -----Original Message-----
> > > From: Phil Yang <Phil.Yang@arm.com>
> > > Sent: Sunday, April 26, 2020 2:36 AM
> > > To: thomas@monjalon.net
> > > Cc: Carrillo, Erik G <erik.g.carrillo@intel.com>;
> > > rsanford@akamai.com; dev@dpdk.org; david.marchand@redhat.com;
> > > Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>; Gavin Hu
> > > <Gavin.Hu@arm.com>; nd <nd@arm.com>; nd <nd@arm.com>
> > > Subject: RE: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for
> > > status
> > update
> > >
> > > > -----Original Message-----
> > > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > Sent: Sunday, April 26, 2020 1:18 AM
> > > > To: Phil Yang <Phil.Yang@arm.com>
> > > > Cc: erik.g.carrillo@intel.com; rsanford@akamai.com; dev@dpdk.org;
> > > > david.marchand@redhat.com; Honnappa Nagarahalli
> > > > <Honnappa.Nagarahalli@arm.com>; Gavin Hu <Gavin.Hu@arm.com>;
> nd
> > > > <nd@arm.com>
> > > > Subject: Re: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for
> > > > status update
> > > >
> > > > 24/04/2020 09:24, Phil Yang:
> > > > > Volatile has no ordering semantics. The rte_timer structure
> > > > > defines timer status as a volatile variable and uses the
> > > > > rte_r/wmb barrier to guarantee inter-thread visibility.
> > > > >
> > > > > This patch optimized the volatile operation with c11 atomic
> > > > > operations and one-way barrier to save the performance penalty.
> > > > > According to the timer_perf_autotest benchmarking results, this
> > > > > patch can uplift 10%~16% timer appending performance, 3%~20%
> > > > > timer resetting performance and
> > > > 45%
> > > > > timer callbacks scheduling performance on aarch64 and no loss in
> > > > > performance for x86.
> > > > >
> > > > > Suggested-by: Honnappa Nagarahalli
> > > > > <honnappa.nagarahalli@arm.com>
> > > > > Signed-off-by: Phil Yang <phil.yang@arm.com>
> > > > > Reviewed-by: Gavin Hu <gavin.hu@arm.com>
> > > > > Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> > > > [...]
> > > > > --- a/lib/librte_timer/rte_timer.h
> > > > > +++ b/lib/librte_timer/rte_timer.h
> > > > > @@ -101,7 +101,7 @@ struct rte_timer
> > > > > - volatile union rte_timer_status status; /**< Status of timer.
> */
> > > > > + union rte_timer_status status; /**< Status of timer. */
> > > >
> > > > Unfortunately, I cannot merge this patch because it breaks the ABI:
> > > >
> > > > [C]'function void rte_timer_init(rte_timer*)' at
> > > > rte_timer.c:214:1 has some indirect sub-type changes:
> > > > parameter 1 of type 'rte_timer*' has sub-type changes:
> > > > in pointed to type 'struct rte_timer' at rte_timer.h:100:1:
> > > > type size hasn't changed
> > > > 1 data member changes (2 filtered):
> > > > type of 'volatile rte_timer_status rte_timer::status' changed:
> > > > entity changed from 'volatile rte_timer_status' to
> > > > 'union rte_timer_status' at rte_timer.h:67:1
> > > > type size hasn't changed
> > > >
> > >
> > > I think we can revert it to the original definition of rte_timer and
> > > keep the union rte_timer_status volatile-qualified.
> > > Because with or without this 'volatile' qualify, it generates the
> > > same code
> > on
> > > aarch64 and x86.
> > > So it seems acceptable to ignore it to make the ABI compatible?
> > >
> > > Thank,
> > > Phil
> >
> > I was wondering about this also. Is the performance improvement on
> > aarch64 still the same in that case?
>
> Yes. it is.
> It got the same performance improvement on aarch64 and no performance
> loss on x86.
>
> I will update it in v4.
Great - thanks, Phil.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4] mempool: return 0 if area is too small on populate
2020-04-25 22:23 12% ` [dpdk-dev] [PATCH v3] " Thomas Monjalon
@ 2020-04-26 16:52 12% ` Thomas Monjalon
2020-04-27 11:44 0% ` [dpdk-dev] [PATCH v3] " Ray Kinsella
1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2020-04-26 16:52 UTC (permalink / raw)
To: dev
Cc: david.marchand, Ray Kinsella, Olivier Matz, Neil Horman,
John McNamara, Marko Kovacevic, Xiaoyun Li, Jingjing Wu,
Andrew Rybchenko
From: Olivier Matz <olivier.matz@6wind.com>
Change rte_mempool_populate_iova() and rte_mempool_populate_iova() to
return 0 instead of -EINVAL when there is not enough room to store one
object, as it can be helpful for applications to distinguish this
specific case.
As this is an ABI change, use symbol versioning to preserve old
behavior for binary applications.
Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
We are missing the symbols versioned for the previous ABI:
rte_mempool_populate_iova@@DPDK_20.0
rte_mempool_populate_virt@@DPDK_20.0
changes in v4:
- move populate_iova trace in v20_0_2 base function
changes in v3:
- rebase
- remove deprecation notice
- notify API change in release notes
- fix ABI version from 20.0.1 to 20.0.2 (should be 21 maybe)
---
doc/guides/rel_notes/deprecation.rst | 5 --
doc/guides/rel_notes/release_20_05.rst | 4 ++
examples/ntb/ntb_fwd.c | 2 +-
lib/librte_mempool/meson.build | 2 +
lib/librte_mempool/rte_mempool.c | 80 ++++++++++++++++++----
lib/librte_mempool/rte_mempool.h | 14 ++--
lib/librte_mempool/rte_mempool_version.map | 7 ++
7 files changed, 92 insertions(+), 22 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1339f54f5f..20aa745b77 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -65,11 +65,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* mempool: starting from v20.05, the API of rte_mempool_populate_iova()
- and rte_mempool_populate_virt() will change to return 0 instead
- of -EINVAL when there is not enough room to store one object. The ABI
- will be preserved until 20.11.
-
* ethdev: the legacy filter API, including
``rte_eth_dev_filter_supported()``, ``rte_eth_dev_filter_ctrl()`` as well
as filter types MACVLAN, ETHERTYPE, FLEXIBLE, SYN, NTUPLE, TUNNEL, FDIR,
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index b124c3f287..ab20a7d021 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -241,6 +241,10 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* mempool: The API of ``rte_mempool_populate_iova()`` and
+ ``rte_mempool_populate_virt()`` changed to return 0 instead of -EINVAL
+ when there is not enough room to store one object.
+
ABI Changes
-----------
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
index d49189e175..eba8ebf9fa 100644
--- a/examples/ntb/ntb_fwd.c
+++ b/examples/ntb/ntb_fwd.c
@@ -1319,7 +1319,7 @@ ntb_mbuf_pool_create(uint16_t mbuf_seg_size, uint32_t nb_mbuf,
mz->len - ntb_info.ntb_hdr_size,
ntb_mempool_mz_free,
(void *)(uintptr_t)mz);
- if (ret < 0) {
+ if (ret <= 0) {
rte_memzone_free(mz);
rte_mempool_free(mp);
return NULL;
diff --git a/lib/librte_mempool/meson.build b/lib/librte_mempool/meson.build
index a6e861cbfc..7dbe6b9bea 100644
--- a/lib/librte_mempool/meson.build
+++ b/lib/librte_mempool/meson.build
@@ -9,6 +9,8 @@ foreach flag: extra_flags
endif
endforeach
+use_function_versioning = true
+
sources = files('rte_mempool.c', 'rte_mempool_ops.c',
'rte_mempool_ops_default.c', 'mempool_trace_points.c')
headers = files('rte_mempool.h', 'rte_mempool_trace.h',
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 0be8f9f59d..0a6119d6ad 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -31,6 +31,7 @@
#include <rte_string_fns.h>
#include <rte_spinlock.h>
#include <rte_tailq.h>
+#include <rte_function_versioning.h>
#include "rte_mempool.h"
#include "rte_mempool_trace.h"
@@ -303,12 +304,17 @@ mempool_ops_alloc_once(struct rte_mempool *mp)
return 0;
}
+__vsym int
+rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
+ rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque);
+
/* Add objects in the pool, using a physically contiguous memory
* zone. Return the number of objects added, or a negative value
* on error.
*/
-static int
-__rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
+__vsym int
+rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
void *opaque)
{
@@ -359,6 +365,8 @@ __rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
STAILQ_INSERT_TAIL(&mp->mem_list, memhdr, next);
mp->nb_mem_chunks++;
+
+ rte_mempool_trace_populate_iova(mp, vaddr, iova, len, free_cb, opaque);
return i;
fail:
@@ -366,21 +374,34 @@ __rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
return ret;
}
-int
-rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
+BIND_DEFAULT_SYMBOL(rte_mempool_populate_iova, _v20_0_2, 20.0.2);
+MAP_STATIC_SYMBOL(
+ int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
+ rte_iova_t iova, size_t len,
+ rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque),
+ rte_mempool_populate_iova_v20_0_2);
+
+__vsym int
+rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
+ rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque);
+
+__vsym int
+rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
void *opaque)
{
int ret;
- ret = __rte_mempool_populate_iova(mp, vaddr, iova, len, free_cb,
+ ret = rte_mempool_populate_iova_v20_0_2(mp, vaddr, iova, len, free_cb,
opaque);
if (ret == 0)
ret = -EINVAL;
- rte_mempool_trace_populate_iova(mp, vaddr, iova, len, free_cb, opaque);
return ret;
}
+VERSION_SYMBOL(rte_mempool_populate_iova, _v20_0, 20.0);
static rte_iova_t
get_iova(void *addr)
@@ -395,11 +416,16 @@ get_iova(void *addr)
return ms->iova + RTE_PTR_DIFF(addr, ms->addr);
}
+__vsym int
+rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
+ size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque);
+
/* Populate the mempool with a virtual area. Return the number of
* objects added, or a negative value on error.
*/
-int
-rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
+__vsym int
+rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
void *opaque)
{
@@ -432,7 +458,7 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
break;
}
- ret = __rte_mempool_populate_iova(mp, addr + off, iova,
+ ret = rte_mempool_populate_iova_v20_0_2(mp, addr + off, iova,
phys_len, free_cb, opaque);
if (ret == 0)
continue;
@@ -443,9 +469,6 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
cnt += ret;
}
- if (cnt == 0)
- return -EINVAL;
-
rte_mempool_trace_populate_virt(mp, addr, len, pg_sz, free_cb, opaque);
return cnt;
@@ -453,6 +476,35 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
rte_mempool_free_memchunks(mp);
return ret;
}
+BIND_DEFAULT_SYMBOL(rte_mempool_populate_virt, _v20_0_2, 20.0.2);
+MAP_STATIC_SYMBOL(
+ int rte_mempool_populate_virt(struct rte_mempool *mp,
+ char *addr, size_t len, size_t pg_sz,
+ rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque),
+ rte_mempool_populate_virt_v20_0_2);
+
+__vsym int
+rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
+ size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque);
+
+__vsym int
+rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
+ size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque)
+{
+ int ret;
+
+ ret = rte_mempool_populate_virt_v20_0_2(mp, addr, len, pg_sz,
+ free_cb, opaque);
+
+ if (ret == 0)
+ ret = -EINVAL;
+
+ return ret;
+}
+VERSION_SYMBOL(rte_mempool_populate_virt, _v20_0, 20.0);
/* Get the minimal page size used in a mempool before populating it. */
int
@@ -609,6 +661,8 @@ rte_mempool_populate_default(struct rte_mempool *mp)
mz->len, pg_sz,
rte_mempool_memchunk_mz_free,
(void *)(uintptr_t)mz);
+ if (ret == 0) /* should not happen */
+ ret = -ENOBUFS;
if (ret < 0) {
rte_memzone_free(mz);
goto fail;
@@ -701,6 +755,8 @@ rte_mempool_populate_anon(struct rte_mempool *mp)
ret = rte_mempool_populate_virt(mp, addr, size, getpagesize(),
rte_mempool_memchunk_anon_free, addr);
+ if (ret == 0) /* should not happen */
+ ret = -ENOBUFS;
if (ret < 0) {
rte_errno = -ret;
goto fail;
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 6e0573ea42..652d19f9f1 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -1112,9 +1112,12 @@ rte_mempool_free(struct rte_mempool *mp);
* @param opaque
* An opaque argument passed to free_cb.
* @return
- * The number of objects added on success.
+ * The number of objects added on success (strictly positive).
* On error, the chunk is not added in the memory list of the
- * mempool and a negative errno is returned.
+ * mempool the following code is returned:
+ * (0): not enough room in chunk for one object.
+ * (-ENOSPC): mempool is already populated.
+ * (-ENOMEM): allocation failure.
*/
int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
@@ -1139,9 +1142,12 @@ int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
* @param opaque
* An opaque argument passed to free_cb.
* @return
- * The number of objects added on success.
+ * The number of objects added on success (strictly positive).
* On error, the chunk is not added in the memory list of the
- * mempool and a negative errno is returned.
+ * mempool the following code is returned:
+ * (0): not enough room in chunk for one object.
+ * (-ENOSPC): mempool is already populated.
+ * (-ENOMEM): allocation failure.
*/
int
rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index 695dd6e04f..9e58093665 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -31,6 +31,13 @@ DPDK_20.0 {
local: *;
};
+DPDK_20.0.2 {
+ global:
+
+ rte_mempool_populate_iova;
+ rte_mempool_populate_virt;
+} DPDK_20.0;
+
EXPERIMENTAL {
global:
--
2.26.0
^ permalink raw reply [relevance 12%]
* [dpdk-dev] [PATCH v4] lib/timer: relax barrier for status update
2020-04-25 17:17 3% ` Thomas Monjalon
@ 2020-04-26 14:45 2% ` Phil Yang
1 sibling, 0 replies; 200+ results
From: Phil Yang @ 2020-04-26 14:45 UTC (permalink / raw)
To: erik.g.carrillo, thomas, dev
Cc: david.marchand, rsanford, Honnappa.Nagarahalli, Gavin.Hu, nd
Volatile has no ordering semantics. The rte_timer structure defines
timer status as a volatile variable and uses the rte_r/wmb barrier
to guarantee inter-thread visibility.
This patch optimized the volatile operation with c11 atomic operations
and one-way barrier to save the performance penalty. According to the
timer_perf_autotest benchmarking results, this patch can uplift 10%~16%
timer appending performance, 3%~20% timer resetting performance and 45%
timer callbacks scheduling performance on aarch64 and no loss in
performance for x86.
Suggested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
Signed-off-by: Phil Yang <phil.yang@arm.com>
Reviewed-by: Gavin Hu <gavin.hu@arm.com>
Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
---
It is still using built-ins as the wrapper functions for C11 built-ins
are not defined yet
v4:
fix ABI break in rte_timer struct.
v3:
fix typo.
v2:
Changed the memory ordering comment in timer_set_config_state.
lib/librte_timer/rte_timer.c | 87 ++++++++++++++++++++++++++++++--------------
1 file changed, 60 insertions(+), 27 deletions(-)
diff --git a/lib/librte_timer/rte_timer.c b/lib/librte_timer/rte_timer.c
index 269e921..6d19ce4 100644
--- a/lib/librte_timer/rte_timer.c
+++ b/lib/librte_timer/rte_timer.c
@@ -10,7 +10,6 @@
#include <assert.h>
#include <sys/queue.h>
-#include <rte_atomic.h>
#include <rte_common.h>
#include <rte_cycles.h>
#include <rte_eal_memconfig.h>
@@ -218,7 +217,7 @@ rte_timer_init(struct rte_timer *tim)
status.state = RTE_TIMER_STOP;
status.owner = RTE_TIMER_NO_OWNER;
- tim->status.u32 = status.u32;
+ __atomic_store_n(&tim->status.u32, status.u32, __ATOMIC_RELAXED);
}
/*
@@ -239,9 +238,9 @@ timer_set_config_state(struct rte_timer *tim,
/* wait that the timer is in correct status before update,
* and mark it as being configured */
- while (success == 0) {
- prev_status.u32 = tim->status.u32;
+ prev_status.u32 = __atomic_load_n(&tim->status.u32, __ATOMIC_RELAXED);
+ while (success == 0) {
/* timer is running on another core
* or ready to run on local core, exit
*/
@@ -258,9 +257,15 @@ timer_set_config_state(struct rte_timer *tim,
* mark it atomically as being configured */
status.state = RTE_TIMER_CONFIG;
status.owner = (int16_t)lcore_id;
- success = rte_atomic32_cmpset(&tim->status.u32,
- prev_status.u32,
- status.u32);
+ /* CONFIG states are acting as locked states. If the
+ * timer is in CONFIG state, the state cannot be changed
+ * by other threads. So, we should use ACQUIRE here.
+ */
+ success = __atomic_compare_exchange_n(&tim->status.u32,
+ &prev_status.u32,
+ status.u32, 0,
+ __ATOMIC_ACQUIRE,
+ __ATOMIC_RELAXED);
}
ret_prev_status->u32 = prev_status.u32;
@@ -279,20 +284,27 @@ timer_set_running_state(struct rte_timer *tim)
/* wait that the timer is in correct status before update,
* and mark it as running */
- while (success == 0) {
- prev_status.u32 = tim->status.u32;
+ prev_status.u32 = __atomic_load_n(&tim->status.u32, __ATOMIC_RELAXED);
+ while (success == 0) {
/* timer is not pending anymore */
if (prev_status.state != RTE_TIMER_PENDING)
return -1;
- /* here, we know that timer is stopped or pending,
- * mark it atomically as being configured */
+ /* we know that the timer will be pending at this point
+ * mark it atomically as being running
+ */
status.state = RTE_TIMER_RUNNING;
status.owner = (int16_t)lcore_id;
- success = rte_atomic32_cmpset(&tim->status.u32,
- prev_status.u32,
- status.u32);
+ /* RUNNING states are acting as locked states. If the
+ * timer is in RUNNING state, the state cannot be changed
+ * by other threads. So, we should use ACQUIRE here.
+ */
+ success = __atomic_compare_exchange_n(&tim->status.u32,
+ &prev_status.u32,
+ status.u32, 0,
+ __ATOMIC_ACQUIRE,
+ __ATOMIC_RELAXED);
}
return 0;
@@ -520,10 +532,12 @@ __rte_timer_reset(struct rte_timer *tim, uint64_t expire,
/* update state: as we are in CONFIG state, only us can modify
* the state so we don't need to use cmpset() here */
- rte_wmb();
status.state = RTE_TIMER_PENDING;
status.owner = (int16_t)tim_lcore;
- tim->status.u32 = status.u32;
+ /* The "RELEASE" ordering guarantees the memory operations above
+ * the status update are observed before the update by all threads
+ */
+ __atomic_store_n(&tim->status.u32, status.u32, __ATOMIC_RELEASE);
if (tim_lcore != lcore_id || !local_is_locked)
rte_spinlock_unlock(&priv_timer[tim_lcore].list_lock);
@@ -600,10 +614,12 @@ __rte_timer_stop(struct rte_timer *tim, int local_is_locked,
}
/* mark timer as stopped */
- rte_wmb();
status.state = RTE_TIMER_STOP;
status.owner = RTE_TIMER_NO_OWNER;
- tim->status.u32 = status.u32;
+ /* The "RELEASE" ordering guarantees the memory operations above
+ * the status update are observed before the update by all threads
+ */
+ __atomic_store_n(&tim->status.u32, status.u32, __ATOMIC_RELEASE);
return 0;
}
@@ -637,7 +653,8 @@ rte_timer_stop_sync(struct rte_timer *tim)
int
rte_timer_pending(struct rte_timer *tim)
{
- return tim->status.state == RTE_TIMER_PENDING;
+ return __atomic_load_n(&tim->status.state,
+ __ATOMIC_RELAXED) == RTE_TIMER_PENDING;
}
/* must be called periodically, run all timer that expired */
@@ -739,8 +756,12 @@ __rte_timer_manage(struct rte_timer_data *timer_data)
/* remove from done list and mark timer as stopped */
status.state = RTE_TIMER_STOP;
status.owner = RTE_TIMER_NO_OWNER;
- rte_wmb();
- tim->status.u32 = status.u32;
+ /* The "RELEASE" ordering guarantees the memory
+ * operations above the status update are observed
+ * before the update by all threads
+ */
+ __atomic_store_n(&tim->status.u32, status.u32,
+ __ATOMIC_RELEASE);
}
else {
/* keep it in list and mark timer as pending */
@@ -748,8 +769,12 @@ __rte_timer_manage(struct rte_timer_data *timer_data)
status.state = RTE_TIMER_PENDING;
__TIMER_STAT_ADD(priv_timer, pending, 1);
status.owner = (int16_t)lcore_id;
- rte_wmb();
- tim->status.u32 = status.u32;
+ /* The "RELEASE" ordering guarantees the memory
+ * operations above the status update are observed
+ * before the update by all threads
+ */
+ __atomic_store_n(&tim->status.u32, status.u32,
+ __ATOMIC_RELEASE);
__rte_timer_reset(tim, tim->expire + tim->period,
tim->period, lcore_id, tim->f, tim->arg, 1,
timer_data);
@@ -919,8 +944,12 @@ rte_timer_alt_manage(uint32_t timer_data_id,
/* remove from done list and mark timer as stopped */
status.state = RTE_TIMER_STOP;
status.owner = RTE_TIMER_NO_OWNER;
- rte_wmb();
- tim->status.u32 = status.u32;
+ /* The "RELEASE" ordering guarantees the memory
+ * operations above the status update are observed
+ * before the update by all threads
+ */
+ __atomic_store_n(&tim->status.u32, status.u32,
+ __ATOMIC_RELEASE);
} else {
/* keep it in list and mark timer as pending */
rte_spinlock_lock(
@@ -928,8 +957,12 @@ rte_timer_alt_manage(uint32_t timer_data_id,
status.state = RTE_TIMER_PENDING;
__TIMER_STAT_ADD(data->priv_timer, pending, 1);
status.owner = (int16_t)this_lcore;
- rte_wmb();
- tim->status.u32 = status.u32;
+ /* The "RELEASE" ordering guarantees the memory
+ * operations above the status update are observed
+ * before the update by all threads
+ */
+ __atomic_store_n(&tim->status.u32, status.u32,
+ __ATOMIC_RELEASE);
__rte_timer_reset(tim, tim->expire + tim->period,
tim->period, this_lcore, tim->f, tim->arg, 1,
data);
--
2.7.4
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status update
2020-04-26 12:18 0% ` Carrillo, Erik G
@ 2020-04-26 14:20 0% ` Phil Yang
2020-04-26 19:30 0% ` Carrillo, Erik G
0 siblings, 1 reply; 200+ results
From: Phil Yang @ 2020-04-26 14:20 UTC (permalink / raw)
To: Carrillo, Erik G, thomas
Cc: rsanford, dev, david.marchand, Honnappa Nagarahalli, Gavin Hu,
nd, nd, nd
> -----Original Message-----
> From: Carrillo, Erik G <erik.g.carrillo@intel.com>
> Sent: Sunday, April 26, 2020 8:19 PM
> To: Phil Yang <Phil.Yang@arm.com>; thomas@monjalon.net
> Cc: rsanford@akamai.com; dev@dpdk.org; david.marchand@redhat.com;
> Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>; Gavin Hu
> <Gavin.Hu@arm.com>; nd <nd@arm.com>; nd <nd@arm.com>
> Subject: RE: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status update
>
>
>
> > -----Original Message-----
> > From: Phil Yang <Phil.Yang@arm.com>
> > Sent: Sunday, April 26, 2020 2:36 AM
> > To: thomas@monjalon.net
> > Cc: Carrillo, Erik G <erik.g.carrillo@intel.com>; rsanford@akamai.com;
> > dev@dpdk.org; david.marchand@redhat.com; Honnappa Nagarahalli
> > <Honnappa.Nagarahalli@arm.com>; Gavin Hu <Gavin.Hu@arm.com>; nd
> > <nd@arm.com>; nd <nd@arm.com>
> > Subject: RE: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status
> update
> >
> > > -----Original Message-----
> > > From: Thomas Monjalon <thomas@monjalon.net>
> > > Sent: Sunday, April 26, 2020 1:18 AM
> > > To: Phil Yang <Phil.Yang@arm.com>
> > > Cc: erik.g.carrillo@intel.com; rsanford@akamai.com; dev@dpdk.org;
> > > david.marchand@redhat.com; Honnappa Nagarahalli
> > > <Honnappa.Nagarahalli@arm.com>; Gavin Hu <Gavin.Hu@arm.com>; nd
> > > <nd@arm.com>
> > > Subject: Re: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status
> > > update
> > >
> > > 24/04/2020 09:24, Phil Yang:
> > > > Volatile has no ordering semantics. The rte_timer structure defines
> > > > timer status as a volatile variable and uses the rte_r/wmb barrier
> > > > to guarantee inter-thread visibility.
> > > >
> > > > This patch optimized the volatile operation with c11 atomic
> > > > operations and one-way barrier to save the performance penalty.
> > > > According to the timer_perf_autotest benchmarking results, this
> > > > patch can uplift 10%~16% timer appending performance, 3%~20% timer
> > > > resetting performance and
> > > 45%
> > > > timer callbacks scheduling performance on aarch64 and no loss in
> > > > performance for x86.
> > > >
> > > > Suggested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > > Signed-off-by: Phil Yang <phil.yang@arm.com>
> > > > Reviewed-by: Gavin Hu <gavin.hu@arm.com>
> > > > Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> > > [...]
> > > > --- a/lib/librte_timer/rte_timer.h
> > > > +++ b/lib/librte_timer/rte_timer.h
> > > > @@ -101,7 +101,7 @@ struct rte_timer
> > > > - volatile union rte_timer_status status; /**< Status of timer. */
> > > > + union rte_timer_status status; /**< Status of timer. */
> > >
> > > Unfortunately, I cannot merge this patch because it breaks the ABI:
> > >
> > > [C]'function void rte_timer_init(rte_timer*)' at rte_timer.c:214:1
> > > has some indirect sub-type changes:
> > > parameter 1 of type 'rte_timer*' has sub-type changes:
> > > in pointed to type 'struct rte_timer' at rte_timer.h:100:1:
> > > type size hasn't changed
> > > 1 data member changes (2 filtered):
> > > type of 'volatile rte_timer_status rte_timer::status' changed:
> > > entity changed from 'volatile rte_timer_status' to 'union
> > > rte_timer_status' at rte_timer.h:67:1
> > > type size hasn't changed
> > >
> >
> > I think we can revert it to the original definition of rte_timer and keep the
> > union rte_timer_status volatile-qualified.
> > Because with or without this 'volatile' qualify, it generates the same code
> on
> > aarch64 and x86.
> > So it seems acceptable to ignore it to make the ABI compatible?
> >
> > Thank,
> > Phil
>
> I was wondering about this also. Is the performance improvement on
> aarch64 still the same in that case?
Yes. it is.
It got the same performance improvement on aarch64 and no performance loss on x86.
I will update it in v4.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status update
2020-04-26 7:36 3% ` Phil Yang
@ 2020-04-26 12:18 0% ` Carrillo, Erik G
2020-04-26 14:20 0% ` Phil Yang
0 siblings, 1 reply; 200+ results
From: Carrillo, Erik G @ 2020-04-26 12:18 UTC (permalink / raw)
To: Phil Yang, thomas
Cc: rsanford, dev, david.marchand, Honnappa Nagarahalli, Gavin Hu, nd, nd
> -----Original Message-----
> From: Phil Yang <Phil.Yang@arm.com>
> Sent: Sunday, April 26, 2020 2:36 AM
> To: thomas@monjalon.net
> Cc: Carrillo, Erik G <erik.g.carrillo@intel.com>; rsanford@akamai.com;
> dev@dpdk.org; david.marchand@redhat.com; Honnappa Nagarahalli
> <Honnappa.Nagarahalli@arm.com>; Gavin Hu <Gavin.Hu@arm.com>; nd
> <nd@arm.com>; nd <nd@arm.com>
> Subject: RE: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status update
>
> > -----Original Message-----
> > From: Thomas Monjalon <thomas@monjalon.net>
> > Sent: Sunday, April 26, 2020 1:18 AM
> > To: Phil Yang <Phil.Yang@arm.com>
> > Cc: erik.g.carrillo@intel.com; rsanford@akamai.com; dev@dpdk.org;
> > david.marchand@redhat.com; Honnappa Nagarahalli
> > <Honnappa.Nagarahalli@arm.com>; Gavin Hu <Gavin.Hu@arm.com>; nd
> > <nd@arm.com>
> > Subject: Re: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status
> > update
> >
> > 24/04/2020 09:24, Phil Yang:
> > > Volatile has no ordering semantics. The rte_timer structure defines
> > > timer status as a volatile variable and uses the rte_r/wmb barrier
> > > to guarantee inter-thread visibility.
> > >
> > > This patch optimized the volatile operation with c11 atomic
> > > operations and one-way barrier to save the performance penalty.
> > > According to the timer_perf_autotest benchmarking results, this
> > > patch can uplift 10%~16% timer appending performance, 3%~20% timer
> > > resetting performance and
> > 45%
> > > timer callbacks scheduling performance on aarch64 and no loss in
> > > performance for x86.
> > >
> > > Suggested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > > Signed-off-by: Phil Yang <phil.yang@arm.com>
> > > Reviewed-by: Gavin Hu <gavin.hu@arm.com>
> > > Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> > [...]
> > > --- a/lib/librte_timer/rte_timer.h
> > > +++ b/lib/librte_timer/rte_timer.h
> > > @@ -101,7 +101,7 @@ struct rte_timer
> > > - volatile union rte_timer_status status; /**< Status of timer. */
> > > + union rte_timer_status status; /**< Status of timer. */
> >
> > Unfortunately, I cannot merge this patch because it breaks the ABI:
> >
> > [C]'function void rte_timer_init(rte_timer*)' at rte_timer.c:214:1
> > has some indirect sub-type changes:
> > parameter 1 of type 'rte_timer*' has sub-type changes:
> > in pointed to type 'struct rte_timer' at rte_timer.h:100:1:
> > type size hasn't changed
> > 1 data member changes (2 filtered):
> > type of 'volatile rte_timer_status rte_timer::status' changed:
> > entity changed from 'volatile rte_timer_status' to 'union
> > rte_timer_status' at rte_timer.h:67:1
> > type size hasn't changed
> >
>
> I think we can revert it to the original definition of rte_timer and keep the
> union rte_timer_status volatile-qualified.
> Because with or without this 'volatile' qualify, it generates the same code on
> aarch64 and x86.
> So it seems acceptable to ignore it to make the ABI compatible?
>
> Thank,
> Phil
I was wondering about this also. Is the performance improvement on aarch64 still the same in that case?
Thanks,
Erik
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status update
2020-04-25 17:17 3% ` Thomas Monjalon
@ 2020-04-26 7:36 3% ` Phil Yang
2020-04-26 12:18 0% ` Carrillo, Erik G
0 siblings, 1 reply; 200+ results
From: Phil Yang @ 2020-04-26 7:36 UTC (permalink / raw)
To: thomas
Cc: erik.g.carrillo, rsanford, dev, david.marchand,
Honnappa Nagarahalli, Gavin Hu, nd, nd
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Sunday, April 26, 2020 1:18 AM
> To: Phil Yang <Phil.Yang@arm.com>
> Cc: erik.g.carrillo@intel.com; rsanford@akamai.com; dev@dpdk.org;
> david.marchand@redhat.com; Honnappa Nagarahalli
> <Honnappa.Nagarahalli@arm.com>; Gavin Hu <Gavin.Hu@arm.com>; nd
> <nd@arm.com>
> Subject: Re: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status update
>
> 24/04/2020 09:24, Phil Yang:
> > Volatile has no ordering semantics. The rte_timer structure defines
> > timer status as a volatile variable and uses the rte_r/wmb barrier
> > to guarantee inter-thread visibility.
> >
> > This patch optimized the volatile operation with c11 atomic operations
> > and one-way barrier to save the performance penalty. According to the
> > timer_perf_autotest benchmarking results, this patch can uplift 10%~16%
> > timer appending performance, 3%~20% timer resetting performance and
> 45%
> > timer callbacks scheduling performance on aarch64 and no loss in
> > performance for x86.
> >
> > Suggested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> > Signed-off-by: Phil Yang <phil.yang@arm.com>
> > Reviewed-by: Gavin Hu <gavin.hu@arm.com>
> > Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> [...]
> > --- a/lib/librte_timer/rte_timer.h
> > +++ b/lib/librte_timer/rte_timer.h
> > @@ -101,7 +101,7 @@ struct rte_timer
> > - volatile union rte_timer_status status; /**< Status of timer. */
> > + union rte_timer_status status; /**< Status of timer. */
>
> Unfortunately, I cannot merge this patch because it breaks the ABI:
>
> [C]'function void rte_timer_init(rte_timer*)' at rte_timer.c:214:1 has some
> indirect sub-type changes:
> parameter 1 of type 'rte_timer*' has sub-type changes:
> in pointed to type 'struct rte_timer' at rte_timer.h:100:1:
> type size hasn't changed
> 1 data member changes (2 filtered):
> type of 'volatile rte_timer_status rte_timer::status' changed:
> entity changed from 'volatile rte_timer_status' to 'union
> rte_timer_status' at rte_timer.h:67:1
> type size hasn't changed
>
I think we can revert it to the original definition of rte_timer and keep the union rte_timer_status volatile-qualified.
Because with or without this 'volatile' qualify, it generates the same code on aarch64 and x86.
So it seems acceptable to ignore it to make the ABI compatible?
Thank,
Phil
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v10 0/2] support for VFIO-PCI VF token interface
` (2 preceding siblings ...)
2020-04-22 5:08 4% ` [dpdk-dev] [PATCH v9 " Haiyue Wang
@ 2020-04-26 1:55 4% ` Haiyue Wang
3 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-26 1:55 UTC (permalink / raw)
To: dev, anatoly.burakov, thomas, vattunuru, jerinj, alex.williamson,
david.marchand
Cc: Haiyue Wang
v10: Use the __rte_internal to mark the internal API changing.
v9: Rewrite the document.
v8: Update the document.
v7: Add the Fixes tag in uuid, the release note and help
document.
v6: Drop the Fixes tag in uuid, since the file has been
moved to another place, not suitable to apply on stable.
And this is not a bug, just some kind of enhancement.
v5: 1. Add the VF token parse error handling.
2. Split into two patches for different logic module.
3. Add more comments into the code for explaining the design.
4. Drop the ABI change workaround, this patch set focuses on code review.
v4: 1. Ignore rte_vfio_setup_device ABI check since it is
for Linux driver use.
v3: Fix the Travis build failed:
(1). rte_uuid.h:97:55: error: unknown type name ‘size_t’
(2). rte_uuid.h:58:2: error: implicit declaration of function ‘memcpy’
v2: Fix the FreeBSD build error.
v1: Update the commit message.
RFC v2:
Based on Vamsi's RFC v1, and Alex's patch for Qemu
[https://lore.kernel.org/lkml/20200204161737.34696b91@w520.home/]:
Use the devarg to pass-down the VF token.
RFC v1: https://patchwork.dpdk.org/patch/66281/ by Vamsi.
Haiyue Wang (2):
eal: add uuid dependent header files explicitly
eal: support for VFIO-PCI VF token
doc/guides/linux_gsg/linux_drivers.rst | 41 +++++++++++++-
doc/guides/rel_notes/release_20_05.rst | 6 +++
drivers/bus/pci/linux/pci_vfio.c | 74 +++++++++++++++++++++++++-
lib/librte_eal/freebsd/eal.c | 3 +-
lib/librte_eal/include/rte_uuid.h | 2 +
lib/librte_eal/include/rte_vfio.h | 26 ++++++++-
lib/librte_eal/linux/eal_vfio.c | 20 +++++--
lib/librte_eal/rte_eal_version.map | 8 ++-
8 files changed, 171 insertions(+), 9 deletions(-)
--
2.26.2
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v3] mempool: return 0 if area is too small on populate
@ 2020-04-25 22:23 12% ` Thomas Monjalon
2020-04-26 16:52 12% ` [dpdk-dev] [PATCH v4] " Thomas Monjalon
2020-04-27 11:44 0% ` [dpdk-dev] [PATCH v3] " Ray Kinsella
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2020-04-25 22:23 UTC (permalink / raw)
To: dev
Cc: david.marchand, Ray Kinsella, Olivier Matz, Neil Horman,
John McNamara, Marko Kovacevic, Xiaoyun Li, Jingjing Wu,
Andrew Rybchenko
From: Olivier Matz <olivier.matz@6wind.com>
Change rte_mempool_populate_iova() and rte_mempool_populate_iova() to
return 0 instead of -EINVAL when there is not enough room to store one
object, as it can be helpful for applications to distinguish this
specific case.
As this is an ABI change, use symbol versioning to preserve old
behavior for binary applications.
Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
---
changes in v3:
- rebase
- remove deprecation notice
- notify API change in release notes
- fix ABI version from 20.0.1 to 20.0.2 (should be 21 maybe)
This v3 cannot be merged because of a false positive ABI check:
2 Removed functions:
'function int rte_mempool_populate_iova(rte_mempool*, char*, rte_iova_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)' {rte_mempool_populate_iova@@DPDK_20.0}
'function int rte_mempool_populate_virt(rte_mempool*, char*, size_t, size_t, rte_mempool_memchunk_free_cb_t*, void*)' {rte_mempool_populate_virt@@DPDK_20.0}
---
doc/guides/rel_notes/deprecation.rst | 5 --
doc/guides/rel_notes/release_20_05.rst | 4 ++
examples/ntb/ntb_fwd.c | 2 +-
lib/librte_mempool/meson.build | 2 +
lib/librte_mempool/rte_mempool.c | 77 ++++++++++++++++++----
lib/librte_mempool/rte_mempool.h | 14 ++--
lib/librte_mempool/rte_mempool_version.map | 7 ++
7 files changed, 90 insertions(+), 21 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 1339f54f5f..20aa745b77 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -65,11 +65,6 @@ Deprecation Notices
structure would be made internal (or removed if all dependencies are cleared)
in future releases.
-* mempool: starting from v20.05, the API of rte_mempool_populate_iova()
- and rte_mempool_populate_virt() will change to return 0 instead
- of -EINVAL when there is not enough room to store one object. The ABI
- will be preserved until 20.11.
-
* ethdev: the legacy filter API, including
``rte_eth_dev_filter_supported()``, ``rte_eth_dev_filter_ctrl()`` as well
as filter types MACVLAN, ETHERTYPE, FLEXIBLE, SYN, NTUPLE, TUNNEL, FDIR,
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index b124c3f287..ab20a7d021 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -241,6 +241,10 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* mempool: The API of ``rte_mempool_populate_iova()`` and
+ ``rte_mempool_populate_virt()`` changed to return 0 instead of -EINVAL
+ when there is not enough room to store one object.
+
ABI Changes
-----------
diff --git a/examples/ntb/ntb_fwd.c b/examples/ntb/ntb_fwd.c
index d49189e175..eba8ebf9fa 100644
--- a/examples/ntb/ntb_fwd.c
+++ b/examples/ntb/ntb_fwd.c
@@ -1319,7 +1319,7 @@ ntb_mbuf_pool_create(uint16_t mbuf_seg_size, uint32_t nb_mbuf,
mz->len - ntb_info.ntb_hdr_size,
ntb_mempool_mz_free,
(void *)(uintptr_t)mz);
- if (ret < 0) {
+ if (ret <= 0) {
rte_memzone_free(mz);
rte_mempool_free(mp);
return NULL;
diff --git a/lib/librte_mempool/meson.build b/lib/librte_mempool/meson.build
index a6e861cbfc..7dbe6b9bea 100644
--- a/lib/librte_mempool/meson.build
+++ b/lib/librte_mempool/meson.build
@@ -9,6 +9,8 @@ foreach flag: extra_flags
endif
endforeach
+use_function_versioning = true
+
sources = files('rte_mempool.c', 'rte_mempool_ops.c',
'rte_mempool_ops_default.c', 'mempool_trace_points.c')
headers = files('rte_mempool.h', 'rte_mempool_trace.h',
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 0be8f9f59d..edbdafaafb 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -31,6 +31,7 @@
#include <rte_string_fns.h>
#include <rte_spinlock.h>
#include <rte_tailq.h>
+#include <rte_function_versioning.h>
#include "rte_mempool.h"
#include "rte_mempool_trace.h"
@@ -303,12 +304,17 @@ mempool_ops_alloc_once(struct rte_mempool *mp)
return 0;
}
+__vsym int
+rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
+ rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque);
+
/* Add objects in the pool, using a physically contiguous memory
* zone. Return the number of objects added, or a negative value
* on error.
*/
-static int
-__rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
+__vsym int
+rte_mempool_populate_iova_v20_0_2(struct rte_mempool *mp, char *vaddr,
rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
void *opaque)
{
@@ -366,14 +372,27 @@ __rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
return ret;
}
-int
-rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
+BIND_DEFAULT_SYMBOL(rte_mempool_populate_iova, _v20_0_2, 20.0.2);
+MAP_STATIC_SYMBOL(
+ int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
+ rte_iova_t iova, size_t len,
+ rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque),
+ rte_mempool_populate_iova_v20_0_2);
+
+__vsym int
+rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
+ rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque);
+
+__vsym int
+rte_mempool_populate_iova_v20(struct rte_mempool *mp, char *vaddr,
rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
void *opaque)
{
int ret;
- ret = __rte_mempool_populate_iova(mp, vaddr, iova, len, free_cb,
+ ret = rte_mempool_populate_iova_v20_0_2(mp, vaddr, iova, len, free_cb,
opaque);
if (ret == 0)
ret = -EINVAL;
@@ -381,6 +400,7 @@ rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
rte_mempool_trace_populate_iova(mp, vaddr, iova, len, free_cb, opaque);
return ret;
}
+VERSION_SYMBOL(rte_mempool_populate_iova, _v20_0, 20.0);
static rte_iova_t
get_iova(void *addr)
@@ -395,11 +415,16 @@ get_iova(void *addr)
return ms->iova + RTE_PTR_DIFF(addr, ms->addr);
}
+__vsym int
+rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
+ size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque);
+
/* Populate the mempool with a virtual area. Return the number of
* objects added, or a negative value on error.
*/
-int
-rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
+__vsym int
+rte_mempool_populate_virt_v20_0_2(struct rte_mempool *mp, char *addr,
size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
void *opaque)
{
@@ -432,7 +457,7 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
break;
}
- ret = __rte_mempool_populate_iova(mp, addr + off, iova,
+ ret = rte_mempool_populate_iova_v20_0_2(mp, addr + off, iova,
phys_len, free_cb, opaque);
if (ret == 0)
continue;
@@ -443,9 +468,6 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
cnt += ret;
}
- if (cnt == 0)
- return -EINVAL;
-
rte_mempool_trace_populate_virt(mp, addr, len, pg_sz, free_cb, opaque);
return cnt;
@@ -453,6 +475,35 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
rte_mempool_free_memchunks(mp);
return ret;
}
+BIND_DEFAULT_SYMBOL(rte_mempool_populate_virt, _v20_0_2, 20.0.2);
+MAP_STATIC_SYMBOL(
+ int rte_mempool_populate_virt(struct rte_mempool *mp,
+ char *addr, size_t len, size_t pg_sz,
+ rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque),
+ rte_mempool_populate_virt_v20_0_2);
+
+__vsym int
+rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
+ size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque);
+
+__vsym int
+rte_mempool_populate_virt_v20(struct rte_mempool *mp, char *addr,
+ size_t len, size_t pg_sz, rte_mempool_memchunk_free_cb_t *free_cb,
+ void *opaque)
+{
+ int ret;
+
+ ret = rte_mempool_populate_virt_v20_0_2(mp, addr, len, pg_sz,
+ free_cb, opaque);
+
+ if (ret == 0)
+ ret = -EINVAL;
+
+ return ret;
+}
+VERSION_SYMBOL(rte_mempool_populate_virt, _v20_0, 20.0);
/* Get the minimal page size used in a mempool before populating it. */
int
@@ -609,6 +660,8 @@ rte_mempool_populate_default(struct rte_mempool *mp)
mz->len, pg_sz,
rte_mempool_memchunk_mz_free,
(void *)(uintptr_t)mz);
+ if (ret == 0) /* should not happen */
+ ret = -ENOBUFS;
if (ret < 0) {
rte_memzone_free(mz);
goto fail;
@@ -701,6 +754,8 @@ rte_mempool_populate_anon(struct rte_mempool *mp)
ret = rte_mempool_populate_virt(mp, addr, size, getpagesize(),
rte_mempool_memchunk_anon_free, addr);
+ if (ret == 0) /* should not happen */
+ ret = -ENOBUFS;
if (ret < 0) {
rte_errno = -ret;
goto fail;
diff --git a/lib/librte_mempool/rte_mempool.h b/lib/librte_mempool/rte_mempool.h
index 6e0573ea42..652d19f9f1 100644
--- a/lib/librte_mempool/rte_mempool.h
+++ b/lib/librte_mempool/rte_mempool.h
@@ -1112,9 +1112,12 @@ rte_mempool_free(struct rte_mempool *mp);
* @param opaque
* An opaque argument passed to free_cb.
* @return
- * The number of objects added on success.
+ * The number of objects added on success (strictly positive).
* On error, the chunk is not added in the memory list of the
- * mempool and a negative errno is returned.
+ * mempool the following code is returned:
+ * (0): not enough room in chunk for one object.
+ * (-ENOSPC): mempool is already populated.
+ * (-ENOMEM): allocation failure.
*/
int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
rte_iova_t iova, size_t len, rte_mempool_memchunk_free_cb_t *free_cb,
@@ -1139,9 +1142,12 @@ int rte_mempool_populate_iova(struct rte_mempool *mp, char *vaddr,
* @param opaque
* An opaque argument passed to free_cb.
* @return
- * The number of objects added on success.
+ * The number of objects added on success (strictly positive).
* On error, the chunk is not added in the memory list of the
- * mempool and a negative errno is returned.
+ * mempool the following code is returned:
+ * (0): not enough room in chunk for one object.
+ * (-ENOSPC): mempool is already populated.
+ * (-ENOMEM): allocation failure.
*/
int
rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
diff --git a/lib/librte_mempool/rte_mempool_version.map b/lib/librte_mempool/rte_mempool_version.map
index 695dd6e04f..9e58093665 100644
--- a/lib/librte_mempool/rte_mempool_version.map
+++ b/lib/librte_mempool/rte_mempool_version.map
@@ -31,6 +31,13 @@ DPDK_20.0 {
local: *;
};
+DPDK_20.0.2 {
+ global:
+
+ rte_mempool_populate_iova;
+ rte_mempool_populate_virt;
+} DPDK_20.0;
+
EXPERIMENTAL {
global:
--
2.26.0
^ permalink raw reply [relevance 12%]
* Re: [dpdk-dev] [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt mode
@ 2020-04-25 20:09 3% ` Ferruh Yigit
2020-04-27 9:19 4% ` Dumitrescu, Cristian
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2020-04-25 20:09 UTC (permalink / raw)
To: Dumitrescu, Cristian, Nithin Dabilpuram, Singh, Jasvinder,
Thomas Monjalon, Andrew Rybchenko
Cc: dev, jerinj, kkanas, Nithin Dabilpuram
On 4/24/2020 11:28 AM, Dumitrescu, Cristian wrote:
>
>
>> -----Original Message-----
>> From: Nithin Dabilpuram <nithind1988@gmail.com>
>> Sent: Wednesday, April 22, 2020 6:21 PM
>> To: Singh, Jasvinder <jasvinder.singh@intel.com>; Dumitrescu, Cristian
>> <cristian.dumitrescu@intel.com>; Thomas Monjalon
>> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Andrew
>> Rybchenko <arybchenko@solarflare.com>
>> Cc: dev@dpdk.org; jerinj@marvell.com; kkanas@marvell.com; Nithin
>> Dabilpuram <ndabilpuram@marvell.com>
>> Subject: [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt
>> mode
>>
>> From: Nithin Dabilpuram <ndabilpuram@marvell.com>
>>
>> Some NIC hardware support shaper to work in packet mode i.e
>> shaping or ratelimiting traffic is in packets per second (PPS) as
>> opposed to default bytes per second (BPS). Hence this patch
>> adds support to configure shared or private shaper in packet mode,
>> provide rate in PPS and add related tm capabilities in port/level/node
>> capability structures.
>>
>> This patch also updates tm port/level/node capability structures with
>> exiting features of scheduler wfq packet mode, scheduler wfq byte mode
>> and private/shared shaper byte mode.
>>
>> SoftNIC PMD is also updated with new capabilities.
>>
>> Signed-off-by: Nithin Dabilpuram <ndabilpuram@marvell.com>
>> ---
>> v3..v4:
>> - Update text under packet_mode as per Cristian.
>> - Update rte_eth_softnic_tm.c based on Jasvinder's comments.
>> - Add error enum RTE_TM_ERROR_TYPE_SHAPER_PROFILE_PACKET_MODE
>> - Fix shaper_profile_check() with packet mode check
>> - Fix typo's
>>
>
> Acked-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
>
Hi Nithin,
It looks like patch is causing ABI break, I am getting following warning [1],
can you please check?
[1]
https://pastebin.com/XYNFg14u
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 00/14] cleanup resources on shutdown
@ 2020-04-25 19:34 0% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2020-04-25 19:34 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
On Sat, Jan 4, 2020 at 2:34 AM Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> Recently started using valgrind with DPDK, and the results
> are not clean.
>
> The DPDK has a function that applications can use to tell it
> to cleanup resources on shutdown (rte_eal_cleanup). But the
> current coverage of that API is spotty. Many internal parts of
> DPDK leave files and allocated memory behind.
>
> This patch set is a start at getting the sub-parts of
> DPDK to cleanup after themselves. These are the easier ones,
> the harder and more critical ones are in the drivers
> and the memory subsystem.
>
> There are no visible API or ABI changes here.
I was about to push the series (except patch 10), but I hit a crash
when passing an invalid option to test-null.sh.
Reproduced with:
Core was generated by
`/home/dmarchan/builds/x86_64-native-linux-gcc+shared+kmods/app/testpmd
-c 0x3 --log-level='.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007fd5231dba64 in pthread_cancel () from /usr/lib64/libpthread.so.0
Missing separate debuginfos, use: dnf debuginfo-install
elfutils-libelf-0.178-7.fc30.x86_64 glibc-2.29-28.fc30.x86_64
jansson-2.12-2.fc30.x86_64 libgcc-9.2.1-1.fc30.x86_64
libpcap-1.9.1-1.fc30.x86_64 numactl-libs-2.0.12-2.fc30.x86_64
zlib-1.2.11-19.fc30.x86_64
(gdb) bt full
#0 0x00007fd5231dba64 in pthread_cancel () from /usr/lib64/libpthread.so.0
No symbol table info available.
#1 0x00007fd52320c586 in rte_eal_cleanup () at
/home/dmarchan/dpdk/lib/librte_eal/linux/eal.c:1339
i = 1
#2 0x00007fd523215f5e in rte_exit (exit_code=exit_code@entry=1,
format=format@entry=0x47ada4 "Cannot init EAL: %s\n") at
/home/dmarchan/dpdk/lib/librte_eal/linux/eal_debug.c:83
ap = {{gp_offset = 24, fp_offset = 48, overflow_arg_area =
0x7ffecdf7aa70, reg_save_area = 0x7ffecdf7a9a0}}
#3 0x000000000043535b in main (argc=21, argv=0x7ffecdf7abc8) at
/home/dmarchan/dpdk/app/test-pmd/testpmd.c:3647
diag = -1
port_id = <optimized out>
count = <optimized out>
ret = <optimized out>
(gdb) f 1
#1 0x00007fd52320c586 in rte_eal_cleanup () at
/home/dmarchan/dpdk/lib/librte_eal/linux/eal.c:1339
1339 pthread_cancel(lcore_config[i].thread_id);
(gdb) p lcore_config[1].thread_id
$1 = 0
rte_eal_cleanup() is called from rte_exit() by testpmd.
But since rte_eal_init() failed at parsing, lcore_config[*].thread_id
are invalid, and we crash on pthread_cancel.
I have no quick idea to fix this, series postponed to rc2.
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag
2020-04-25 14:39 0% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag David Marchand
2020-04-25 16:34 0% ` Wang, Haiyue
@ 2020-04-25 18:09 0% ` Wang, Haiyue
1 sibling, 0 replies; 200+ results
From: Wang, Haiyue @ 2020-04-25 18:09 UTC (permalink / raw)
To: David Marchand
Cc: dev, Thomas Monjalon, Richardson, Bruce, Yigit, Ferruh,
Neil Horman, Ray Kinsella
Hi David,
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Saturday, April 25, 2020 22:39
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev <dev@dpdk.org>; Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce
> <bruce.richardson@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Neil Horman
> <nhorman@tuxdriver.com>; Ray Kinsella <mdr@ashroe.eu>
> Subject: Re: [PATCH v7 0/6] dpdk: introduce __rte_internal tag
>
> On Sat, Apr 25, 2020 at 1:02 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> >
> > Move the internal function into INTERNAL session to avoid the ABI
> > checking, and it is only used for DPDK drivers or related library.
> >
> > __rte_internal funA
> >
> > INTERNAL {
> > global:
> >
> > funA
> > };
>
> Thanks a lot for working on this.
> I did some modifications (see my replies on patch 3 and 5) and applied
> this series.
>
> We are just missing the update on the scripts mentioned in a previous mail.
> Can you work on this for rc2?
>
Do you mean ?
> > > This will apply to common drivers that will be 100% internal.
> > > Not sure if this is an issue.
> >
> > This part should be fine, I want others to be aware of this.
> I am not one of the ABI maintainers, but in my opinion it is OK
> to have "pure internal" libs with version 0.x.
I've tested it with Intel's drivers/common/iavf, it works as expected.
a). librte_common_iavf.so.0.200.2
b). Skipped experimental library librte_common_iavf.dump.
This has been updated by your modification.
+ if is_stable
lib_version = abi_version
so_version = stable_so_version
+ else
+ lib_version = experimental_abi_version
+ so_version = experimental_so_version
endif
> Thanks again!
>
>
> --
> David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] lib/timer: relax barrier for status update
@ 2020-04-25 17:17 3% ` Thomas Monjalon
2020-04-26 7:36 3% ` Phil Yang
2020-04-26 14:45 2% ` [dpdk-dev] [PATCH v4] " Phil Yang
1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-25 17:17 UTC (permalink / raw)
To: Phil Yang
Cc: erik.g.carrillo, rsanford, dev, david.marchand,
Honnappa.Nagarahalli, Gavin.Hu, nd
24/04/2020 09:24, Phil Yang:
> Volatile has no ordering semantics. The rte_timer structure defines
> timer status as a volatile variable and uses the rte_r/wmb barrier
> to guarantee inter-thread visibility.
>
> This patch optimized the volatile operation with c11 atomic operations
> and one-way barrier to save the performance penalty. According to the
> timer_perf_autotest benchmarking results, this patch can uplift 10%~16%
> timer appending performance, 3%~20% timer resetting performance and 45%
> timer callbacks scheduling performance on aarch64 and no loss in
> performance for x86.
>
> Suggested-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> Signed-off-by: Phil Yang <phil.yang@arm.com>
> Reviewed-by: Gavin Hu <gavin.hu@arm.com>
> Acked-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
[...]
> --- a/lib/librte_timer/rte_timer.h
> +++ b/lib/librte_timer/rte_timer.h
> @@ -101,7 +101,7 @@ struct rte_timer
> - volatile union rte_timer_status status; /**< Status of timer. */
> + union rte_timer_status status; /**< Status of timer. */
Unfortunately, I cannot merge this patch because it breaks the ABI:
[C]'function void rte_timer_init(rte_timer*)' at rte_timer.c:214:1 has some indirect sub-type changes:
parameter 1 of type 'rte_timer*' has sub-type changes:
in pointed to type 'struct rte_timer' at rte_timer.h:100:1:
type size hasn't changed
1 data member changes (2 filtered):
type of 'volatile rte_timer_status rte_timer::status' changed:
entity changed from 'volatile rte_timer_status' to 'union rte_timer_status' at rte_timer.h:67:1
type size hasn't changed
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag
2020-04-25 14:39 0% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag David Marchand
@ 2020-04-25 16:34 0% ` Wang, Haiyue
2020-04-25 18:09 0% ` Wang, Haiyue
1 sibling, 0 replies; 200+ results
From: Wang, Haiyue @ 2020-04-25 16:34 UTC (permalink / raw)
To: David Marchand
Cc: dev, Thomas Monjalon, Richardson, Bruce, Yigit, Ferruh,
Neil Horman, Ray Kinsella
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Saturday, April 25, 2020 22:39
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev <dev@dpdk.org>; Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce
> <bruce.richardson@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Neil Horman
> <nhorman@tuxdriver.com>; Ray Kinsella <mdr@ashroe.eu>
> Subject: Re: [PATCH v7 0/6] dpdk: introduce __rte_internal tag
>
> On Sat, Apr 25, 2020 at 1:02 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> >
> > Move the internal function into INTERNAL session to avoid the ABI
> > checking, and it is only used for DPDK drivers or related library.
> >
> > __rte_internal funA
> >
> > INTERNAL {
> > global:
> >
> > funA
> > };
>
> Thanks a lot for working on this.
> I did some modifications (see my replies on patch 3 and 5) and applied
> this series.
>
> We are just missing the update on the scripts mentioned in a previous mail.
> Can you work on this for rc2?
>
Sure, it's my pleasure. ;-)
> Thanks again!
>
>
> --
> David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4] eal/cpuflags: add x86 based cpu flags
@ 2020-04-25 16:04 4% ` Thomas Monjalon
2020-04-27 9:27 4% ` Ray Kinsella
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-25 16:04 UTC (permalink / raw)
To: ray.kinsella, nhorman, Kevin Laatz
Cc: dev, bruce.richardson, harry.van.haaren, david.marchand
16/04/2020 13:00, Kevin Laatz:
> This patch adds CPU flags which will enable the detection of ISA
> features available on more recent x86 based CPUs.
[...]
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> +; Ignore this enum update as it should not be allocated by the application
> +[suppress_type]
> + type_kind = enum
> + name = rte_cpu_flag_t
> + changed_enumerators = RTE_CPUFLAG_NUMFLAGS
The justification is not correct.
The application is allowed to use RTE_CPUFLAG_NUMFLAGS in array allocation.
But no API is returning a CPU flag, so the new flags will remain unknown
to the application.
However, there is a behaviour change:
The functions rte_cpu_get_flag_name() and rte_cpu_get_flag_enabled()
will now accept new values, which were previously considered as an error.
Is it an ABI breakage? I would say no.
PS: Who is REALLY maintaining the ABI?
We really miss someone who carefully check all these things,
and take care of the doc and tooling.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
` (4 preceding siblings ...)
2020-04-25 10:56 7% ` [dpdk-dev] [PATCH v7 5/6] devtools: exempt internal ABI checking Haiyue Wang
@ 2020-04-25 14:39 0% ` David Marchand
2020-04-25 16:34 0% ` Wang, Haiyue
2020-04-25 18:09 0% ` Wang, Haiyue
5 siblings, 2 replies; 200+ results
From: David Marchand @ 2020-04-25 14:39 UTC (permalink / raw)
To: Haiyue Wang
Cc: dev, Thomas Monjalon, Bruce Richardson, Yigit, Ferruh,
Neil Horman, Ray Kinsella
On Sat, Apr 25, 2020 at 1:02 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
>
> Move the internal function into INTERNAL session to avoid the ABI
> checking, and it is only used for DPDK drivers or related library.
>
> __rte_internal funA
>
> INTERNAL {
> global:
>
> funA
> };
Thanks a lot for working on this.
I did some modifications (see my replies on patch 3 and 5) and applied
this series.
We are just missing the update on the scripts mentioned in a previous mail.
Can you work on this for rc2?
Thanks again!
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v7 5/6] devtools: exempt internal ABI checking
2020-04-25 10:56 7% ` [dpdk-dev] [PATCH v7 5/6] devtools: exempt internal ABI checking Haiyue Wang
@ 2020-04-25 14:34 4% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2020-04-25 14:34 UTC (permalink / raw)
To: Haiyue Wang
Cc: dev, Thomas Monjalon, Bruce Richardson, Yigit, Ferruh,
Neil Horman, Ray Kinsella
On Sat, Apr 25, 2020 at 1:02 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
>
> No need to restrict the ABI on symbols that are only used by core
> libraries.
>
> Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
Rather than add a special case for INTERNAL, we can invert the logic
in this script: identify "stable" sections symbol.
I went with the following patch:
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
index ed2178e36e..f329d5fa62 100755
--- a/devtools/check-symbol-change.sh
+++ b/devtools/check-symbol-change.sh
@@ -77,6 +77,10 @@ build_map_changes()
}
+is_stable_section() {
+ [ "$1" != 'EXPERIMENTAL' ] && [ "$1" != 'INTERNAL' ]
+}
+
check_for_rule_violations()
{
local mapdb="$1"
@@ -110,11 +114,11 @@ check_for_rule_violations()
# section directly
if [ -z "$oldsecname" ]
then
- if [ "$secname" = 'EXPERIMENTAL' ]
+ if ! is_stable_section $secname
then
echo -n "INFO: symbol $symname has "
echo -n "been added to the "
- echo -n "EXPERIMENTAL section of the "
+ echo -n "$secname section of the "
echo "version map"
continue
else
@@ -137,7 +141,7 @@ check_for_rule_violations()
# This symbol is moving between two sections (the
# original section is not experimental).
# This can be legit, just warn.
- if [ "$oldsecname" != 'EXPERIMENTAL' ]
+ if is_stable_section $oldsecname
then
echo -n "INFO: symbol $symname is being "
echo -n "moved from $oldsecname to $secname. "
@@ -148,9 +152,9 @@ check_for_rule_violations()
else
if ! grep -q "$mname $symname .* add" "$mapdb" && \
- [ "$secname" != "EXPERIMENTAL" ]
+ is_stable_section $secname
then
- # Just inform users that non-experimenal
+ # Just inform users that stable
# symbols need to go through a deprecation
# process
echo -n "INFO: symbol $symname is being "
--
David Marchand
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v7 3/6] mk: add internal tag check
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 3/6] mk: add internal tag check Haiyue Wang
@ 2020-04-25 14:34 3% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2020-04-25 14:34 UTC (permalink / raw)
To: Haiyue Wang
Cc: dev, Thomas Monjalon, Bruce Richardson, Yigit, Ferruh,
Neil Horman, Ray Kinsella
On Sat, Apr 25, 2020 at 1:02 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
>
> Add checks during build to ensure that all symbols in the INTERNAL
> version map section have __internal tags on their definitions, and
> enable the warnings needed to announce their use.
>
> Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
> ---
> MAINTAINERS | 2 +-
> ...-experimental-syms.sh => check-symbols.sh} | 31 +++++++++++++++++++
> buildtools/meson.build | 2 +-
> mk/internal/rte.compile-pre.mk | 6 ++--
> 4 files changed, 36 insertions(+), 5 deletions(-)
> rename buildtools/{check-experimental-syms.sh => check-symbols.sh} (61%)
Just missing a little update on drivers/meson.build and lib/meson.build.
Squashed with:
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 3e8d31b0c5..d5f8291beb 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -6,7 +6,7 @@ subdir('pmdinfogen')
pkgconf = find_program('pkg-config', 'pkgconf', required: false)
pmdinfo = find_program('gen-pmdinfo-cfile.sh')
list_dir_globs = find_program('list-dir-globs.py')
-check_experimental_syms = find_program('check-symbols.sh')
+check_symbols = find_program('check-symbols.sh')
ldflags_ibverbs_static = find_program('options-ibverbs-static.sh')
# set up map-to-def script using python, either built-in or external
@@ -20,4 +20,4 @@ map_to_def_cmd = py3 + files('map_to_def.py')
sphinx_wrapper = py3 + files('call-sphinx-build.py')
# stable ABI always starts with "DPDK_"
-is_experimental_cmd = [find_program('grep', 'findstr'), '^DPDK_']
+is_stable_cmd = [find_program('grep', 'findstr'), '^DPDK_']
diff --git a/drivers/meson.build b/drivers/meson.build
index f3dd23dd43..dc293b270b 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -131,15 +131,15 @@ foreach class:dpdk_driver_classes
meson.current_source_dir(),
drv_path, lib_name)
- is_experimental = run_command(is_experimental_cmd,
- files(version_map)).returncode()
+ is_stable = run_command(is_stable_cmd,
+ files(version_map)).returncode() == 0
- if is_experimental != 0
- lib_version = experimental_abi_version
- so_version = experimental_so_version
- else
+ if is_stable
lib_version = abi_version
so_version = stable_so_version
+ else
+ lib_version = experimental_abi_version
+ so_version = experimental_so_version
endif
# now build the static driver
@@ -168,14 +168,14 @@ foreach class:dpdk_driver_classes
else
lk_args = ['-Wl,--version-script=' +
version_map]
# on unix systems check the output of the
- # experimental syms script, using it as a
+ # check-symbols.sh script, using it as a
# dependency of the .so build
- lk_deps += custom_target(lib_name + '.exp_chk',
- command: [check_experimental_syms,
+ lk_deps += custom_target(lib_name + '.sym_chk',
+ command: [check_symbols,
version_map, '@INPUT@'],
capture: true,
input: static_lib,
- output: lib_name + '.exp_chk')
+ output: lib_name + '.sym_chk')
endif
shared_lib = shared_library(lib_name,
diff --git a/lib/meson.build b/lib/meson.build
index 8697941ae0..07a65a6256 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -109,15 +109,15 @@ foreach l:libraries
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()
+ is_stable = run_command(is_stable_cmd,
+ files(version_map)).returncode() == 0
- if is_experimental != 0
- lib_version = experimental_abi_version
- so_version = experimental_so_version
- else
+ if is_stable
lib_version = abi_version
so_version = stable_so_version
+ else
+ lib_version = experimental_abi_version
+ so_version = experimental_so_version
endif
# first build static lib
@@ -160,14 +160,14 @@ foreach l:libraries
lk_deps = [version_map, def_file]
if not is_windows
# on unix systems check the output of the
- # experimental syms script, using it as a
+ # check-symbols.sh script, using it as a
# dependency of the .so build
- lk_deps += custom_target(name + '.exp_chk',
- command: [check_experimental_syms,
+ lk_deps += custom_target(name + '.sym_chk',
+ command: [check_symbols,
version_map, '@INPUT@'],
capture: true,
input: static_lib,
- output: name + '.exp_chk')
+ output: name + '.sym_chk')
endif
shared_lib = shared_library(libname,
--
David Marchand
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v5 1/1] eal: add internal ABI marking support
2020-04-25 14:21 4% ` David Marchand
@ 2020-04-25 14:24 7% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2020-04-25 14:24 UTC (permalink / raw)
To: Wang, Haiyue, David Marchand
Cc: dev, Richardson, Bruce, Yigit, Ferruh, Neil Horman, Ray Kinsella
25/04/2020 16:21, David Marchand:
> On Sat, Apr 25, 2020 at 8:10 AM Wang, Haiyue <haiyue.wang@intel.com> wrote:
> > - For fully experimental libraries, we have a special so version:
> > https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131
> >
> > This will apply to common drivers that will be 100% internal.
> > Not sure if this is an issue.
>
> This part should be fine, I want others to be aware of this.
I am not one of the ABI maintainers, but in my opinion it is OK
to have "pure internal" libs with version 0.x.
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH v5 1/1] eal: add internal ABI marking support
2020-04-25 6:10 7% ` Wang, Haiyue
@ 2020-04-25 14:21 4% ` David Marchand
2020-04-25 14:24 7% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2020-04-25 14:21 UTC (permalink / raw)
To: Wang, Haiyue
Cc: dev, Thomas Monjalon, Richardson, Bruce, Yigit, Ferruh,
Neil Horman, Ray Kinsella
On Sat, Apr 25, 2020 at 8:10 AM Wang, Haiyue <haiyue.wang@intel.com> wrote:
>
> Hi David,
>
> Try to fix the issues you mentioned, except below, plan to
> another patch set, I need more time to test these adding.
Thanks for working on this topic.
>
> ====
>
> We are missing updates on devtools/check-abi-version.sh and
> devtools/update_version_map_abi.py.
Those two scripts can be updated later:
- I suspect the first one to be broken already,
- the 2nd one is for 20.11 when we will update all map files.
>
> More importantly on this file:
>
> - drivers/meson.build is not updated to check for internal symbols, see:
> https://git.dpdk.org/dpdk/tree/drivers/meson.build#n166
On this point, your series is almost good to go, I would just get rid
of the "experimental" mentions.
I will reply on the patch.
> - For fully experimental libraries, we have a special so version:
> https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131
>
> This will apply to common drivers that will be 100% internal.
> Not sure if this is an issue.
This part should be fine, I want others to be aware of this.
--
David Marchand
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v7 5/6] devtools: exempt internal ABI checking
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
` (3 preceding siblings ...)
2020-04-25 10:56 13% ` [dpdk-dev] [PATCH v7 4/6] devtools: ignore internal ABI check Haiyue Wang
@ 2020-04-25 10:56 7% ` Haiyue Wang
2020-04-25 14:34 4% ` David Marchand
2020-04-25 14:39 0% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag David Marchand
5 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-25 10:56 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
No need to restrict the ABI on symbols that are only used by core
libraries.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
devtools/check-symbol-change.sh | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
index ed2178e36..7b6d5f40f 100755
--- a/devtools/check-symbol-change.sh
+++ b/devtools/check-symbol-change.sh
@@ -91,6 +91,13 @@ check_for_rule_violations()
if [ "$ar" = "add" ]
then
+ if [ "$secname" = "INTERNAL" ]
+ then
+ # these are absolved from any further checking
+ echo "Skipping symbol $symname in INTERNAL"
+ continue
+ fi
+
if [ "$secname" = "unknown" ]
then
# Just inform the user of this occurrence, but
@@ -148,6 +155,7 @@ check_for_rule_violations()
else
if ! grep -q "$mname $symname .* add" "$mapdb" && \
+ [ "$secname" != "INTERNAL" ] && \
[ "$secname" != "EXPERIMENTAL" ]
then
# Just inform users that non-experimenal
--
2.26.2
^ permalink raw reply [relevance 7%]
* [dpdk-dev] [PATCH v7 4/6] devtools: ignore internal ABI check
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
` (2 preceding siblings ...)
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 3/6] mk: add internal tag check Haiyue Wang
@ 2020-04-25 10:56 13% ` Haiyue Wang
2020-04-25 10:56 7% ` [dpdk-dev] [PATCH v7 5/6] devtools: exempt internal ABI checking Haiyue Wang
2020-04-25 14:39 0% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag David Marchand
5 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-25 10:56 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Ignore the internal version ABI check, this kind of ABI is used only
by drivers and libraries.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
devtools/libabigail.abignore | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 1911890a7..986a52771 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -3,6 +3,11 @@
[suppress_variable]
symbol_version = EXPERIMENTAL
+[suppress_function]
+ symbol_version = INTERNAL
+[suppress_variable]
+ symbol_version = INTERNAL
+
; Explicit ignore for driver-only ABI
[suppress_type]
name = rte_cryptodev_ops
--
2.26.2
^ permalink raw reply [relevance 13%]
* [dpdk-dev] [PATCH v7 3/6] mk: add internal tag check
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-25 10:56 13% ` [dpdk-dev] [PATCH v7 1/6] eal: add internal ABI tag definition Haiyue Wang
2020-04-25 10:56 3% ` [dpdk-dev] [PATCH v7 2/6] build: enable internal API tag Haiyue Wang
@ 2020-04-25 10:56 5% ` Haiyue Wang
2020-04-25 14:34 3% ` David Marchand
2020-04-25 10:56 13% ` [dpdk-dev] [PATCH v7 4/6] devtools: ignore internal ABI check Haiyue Wang
` (2 subsequent siblings)
5 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-25 10:56 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Add checks during build to ensure that all symbols in the INTERNAL
version map section have __internal tags on their definitions, and
enable the warnings needed to announce their use.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
MAINTAINERS | 2 +-
...-experimental-syms.sh => check-symbols.sh} | 31 +++++++++++++++++++
buildtools/meson.build | 2 +-
mk/internal/rte.compile-pre.mk | 6 ++--
4 files changed, 36 insertions(+), 5 deletions(-)
rename buildtools/{check-experimental-syms.sh => check-symbols.sh} (61%)
diff --git a/MAINTAINERS b/MAINTAINERS
index a8d24e332..85298d426 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -153,7 +153,7 @@ F: devtools/libabigail.abignore
F: devtools/update-abi.sh
F: devtools/update_version_map_abi.py
F: devtools/validate-abi.sh
-F: buildtools/check-experimental-syms.sh
+F: buildtools/check-symbols.sh
F: buildtools/map-list-symbol.sh
Driver information
diff --git a/buildtools/check-experimental-syms.sh b/buildtools/check-symbols.sh
similarity index 61%
rename from buildtools/check-experimental-syms.sh
rename to buildtools/check-symbols.sh
index f3603e5ba..3df57c322 100755
--- a/buildtools/check-experimental-syms.sh
+++ b/buildtools/check-symbols.sh
@@ -54,4 +54,35 @@ do
}
done
+for SYM in `$LIST_SYMBOL -S INTERNAL $MAPFILE |cut -d ' ' -f 3`
+do
+ if grep -q "\.text.*[[:space:]]$SYM$" $DUMPFILE &&
+ ! grep -q "\.text\.internal.*[[:space:]]$SYM$" $DUMPFILE
+ then
+ cat >&2 <<- END_OF_MESSAGE
+ $SYM is not flagged as internal
+ but is listed in version map
+ Please add __rte_internal to the definition of $SYM
+ END_OF_MESSAGE
+ ret=1
+ fi
+done
+
+# Filter out symbols suffixed with a . for icc
+for SYM in `awk '{
+ if ($2 != "l" && $4 == ".text.internal" && !($NF ~ /\.$/)) {
+ print $NF
+ }
+}' $DUMPFILE`
+do
+ $LIST_SYMBOL -S INTERNAL -s $SYM -q $MAPFILE || {
+ cat >&2 <<- END_OF_MESSAGE
+ $SYM is flagged as internal
+ but is not listed in version map
+ Please add $SYM to the version map
+ END_OF_MESSAGE
+ ret=1
+ }
+done
+
exit $ret
diff --git a/buildtools/meson.build b/buildtools/meson.build
index 9812917e5..3e8d31b0c 100644
--- a/buildtools/meson.build
+++ b/buildtools/meson.build
@@ -6,7 +6,7 @@ subdir('pmdinfogen')
pkgconf = find_program('pkg-config', 'pkgconf', required: false)
pmdinfo = find_program('gen-pmdinfo-cfile.sh')
list_dir_globs = find_program('list-dir-globs.py')
-check_experimental_syms = find_program('check-experimental-syms.sh')
+check_experimental_syms = find_program('check-symbols.sh')
ldflags_ibverbs_static = find_program('options-ibverbs-static.sh')
# set up map-to-def script using python, either built-in or external
diff --git a/mk/internal/rte.compile-pre.mk b/mk/internal/rte.compile-pre.mk
index 82fe098f7..df05b5576 100644
--- a/mk/internal/rte.compile-pre.mk
+++ b/mk/internal/rte.compile-pre.mk
@@ -56,8 +56,8 @@ C_TO_O = $(CC) -Wp,-MD,$(call obj2dep,$(@)).tmp $(CPPFLAGS) $(CFLAGS) \
C_TO_O_STR = $(subst ','\'',$(C_TO_O)) #'# fix syntax highlight
C_TO_O_DISP = $(if $(V),"$(C_TO_O_STR)"," CC $(@)")
endif
-EXPERIMENTAL_CHECK = $(RTE_SDK)/buildtools/check-experimental-syms.sh
-CHECK_EXPERIMENTAL = $(EXPERIMENTAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
+CHECK_SYMBOLS_SCRIPT = $(RTE_SDK)/buildtools/check-symbols.sh
+CHECK_SYMBOLS = $(CHECK_SYMBOLS_SCRIPT) $(SRCDIR)/$(EXPORT_MAP) $@
PMDINFO_GEN = $(RTE_SDK_BIN)/app/dpdk-pmdinfogen $@ $@.pmd.c
PMDINFO_CC = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@.pmd.o $@.pmd.c
@@ -75,7 +75,7 @@ C_TO_O_DO = @set -e; \
echo $(C_TO_O_DISP); \
$(C_TO_O) && \
$(PMDINFO_TO_O) && \
- $(CHECK_EXPERIMENTAL) && \
+ $(CHECK_SYMBOLS) && \
echo $(C_TO_O_CMD) > $(call obj2cmd,$(@)) && \
sed 's,'$@':,dep_'$@' =,' $(call obj2dep,$(@)).tmp > $(call obj2dep,$(@)) && \
rm -f $(call obj2dep,$(@)).tmp
--
2.26.2
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCH v7 2/6] build: enable internal API tag
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-25 10:56 13% ` [dpdk-dev] [PATCH v7 1/6] eal: add internal ABI tag definition Haiyue Wang
@ 2020-04-25 10:56 3% ` Haiyue Wang
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 3/6] mk: add internal tag check Haiyue Wang
` (3 subsequent siblings)
5 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-25 10:56 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Allow the drivers and libraries to use the internal tag for marking
internal ABI symbols.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
drivers/meson.build | 5 ++++-
lib/meson.build | 5 ++++-
mk/target/generic/rte.vars.mk | 1 +
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/meson.build b/drivers/meson.build
index 4d8f842ab..f3dd23dd4 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -20,7 +20,10 @@ dpdk_driver_classes = ['common',
disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
).stdout().split()
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args
+default_cflags += ['-DALLOW_EXPERIMENTAL_API']
+default_cflags += ['-DALLOW_INTERNAL_API']
+
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/lib/meson.build b/lib/meson.build
index c28b8df83..8697941ae 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -38,7 +38,10 @@ if is_windows
libraries = ['kvargs','eal'] # only supported libraries for windows
endif
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args
+default_cflags += ['-DALLOW_EXPERIMENTAL_API']
+default_cflags += ['-DALLOW_INTERNAL_API']
+
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
index ec2672897..11b0418e5 100644
--- a/mk/target/generic/rte.vars.mk
+++ b/mk/target/generic/rte.vars.mk
@@ -106,6 +106,7 @@ ifeq ($(BUILDING_RTE_SDK),1)
# building sdk
CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -DALLOW_INTERNAL_API
else
# if we are building an external application, include SDK's lib and
# includes too
--
2.26.2
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v7 1/6] eal: add internal ABI tag definition
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
@ 2020-04-25 10:56 13% ` Haiyue Wang
2020-04-25 10:56 3% ` [dpdk-dev] [PATCH v7 2/6] build: enable internal API tag Haiyue Wang
` (4 subsequent siblings)
5 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-25 10:56 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Introduce the __rte_internal tag to mark internal ABI function which is
used only by the drivers or other libraries.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
lib/librte_eal/include/rte_compat.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
index 3eb33784b..4cd8f68d6 100644
--- a/lib/librte_eal/include/rte_compat.h
+++ b/lib/librte_eal/include/rte_compat.h
@@ -19,4 +19,17 @@ __attribute__((section(".text.experimental")))
#endif
+#ifndef ALLOW_INTERNAL_API
+
+#define __rte_internal \
+__attribute__((error("Symbol is not public ABI"), \
+section(".text.internal")))
+
+#else
+
+#define __rte_internal \
+__attribute__((section(".text.internal")))
+
+#endif
+
#endif /* _RTE_COMPAT_H_ */
--
2.26.2
^ permalink raw reply [relevance 13%]
* [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag
` (4 preceding siblings ...)
2020-04-25 6:04 5% ` [dpdk-dev] [PATCH v6 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
@ 2020-04-25 10:56 5% ` Haiyue Wang
2020-04-25 10:56 13% ` [dpdk-dev] [PATCH v7 1/6] eal: add internal ABI tag definition Haiyue Wang
` (5 more replies)
5 siblings, 6 replies; 200+ results
From: Haiyue Wang @ 2020-04-25 10:56 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Move the internal function into INTERNAL session to avoid the ABI
checking, and it is only used for DPDK drivers or related library.
__rte_internal funA
INTERNAL {
global:
funA
};
v7: Fix the meson build error
v6: split into small patches, and add the missed handling.
v5: add the checkpatch for __rte_internal style
v4: add the ABI check suppression rules
v3: based on Neil's v2 patch https://patchwork.dpdk.org/cover/54771/
Use the ALLOW_INTERNAL_API to mark this new feature.
Haiyue Wang (6):
eal: add internal ABI tag definition
build: enable internal API tag
mk: add internal tag check
devtools: ignore internal ABI check
devtools: exempt internal ABI checking
devtools: enforce internal tag at the beginning
MAINTAINERS | 2 +-
...-experimental-syms.sh => check-symbols.sh} | 31 +++++++++++++++
buildtools/meson.build | 2 +-
devtools/check-symbol-change.sh | 8 ++++
devtools/checkpatches.sh | 39 +++++++++++++++++++
devtools/libabigail.abignore | 5 +++
drivers/meson.build | 5 ++-
lib/librte_eal/include/rte_compat.h | 13 +++++++
lib/meson.build | 5 ++-
mk/internal/rte.compile-pre.mk | 6 +--
mk/target/generic/rte.vars.mk | 1 +
11 files changed, 110 insertions(+), 7 deletions(-)
rename buildtools/{check-experimental-syms.sh => check-symbols.sh} (61%)
--
2.26.2
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings
2020-04-24 19:02 0% ` Stephen Hemminger
@ 2020-04-25 9:20 0% ` Ananyev, Konstantin
0 siblings, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2020-04-25 9:20 UTC (permalink / raw)
To: Stephen Hemminger, Honnappa Nagarahalli; +Cc: dev, nd
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Stephen Hemminger
> Sent: Friday, April 24, 2020 8:02 PM
> To: Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>
> Cc: dev@dpdk.org; nd <nd@arm.com>
> Subject: Re: [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings
>
> On Fri, 24 Apr 2020 18:07:15 +0000
> Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com> wrote:
>
> > <snip>
> >
> > >
> > > All API's should check that they support the flag values passed.
> > > These checks ensure that the extra bits can safely be used without risk of ABI
> > > breakage.
> > >
> > > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > > ---
> > > lib/librte_ring/rte_ring.c | 10 ++++++++++
> > > 1 file changed, 10 insertions(+)
> > >
> > > diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c index
> > > ebe5ccf0de68..70685121581f 100644
> > > --- a/lib/librte_ring/rte_ring.c
> > > +++ b/lib/librte_ring/rte_ring.c
> > > @@ -42,6 +42,9 @@ static struct rte_tailq_elem rte_ring_tailq = { };
> > > EAL_REGISTER_TAILQ(rte_ring_tailq)
> > >
> > > +/* mask of all valid flag values to ring_create() */
> > > +#define RING_F_MASK 0x007F
> > Is it better to construct this using the actual flag #defines?
>
> sure, but it gets long
+1 to use public defines here.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v6 5/6] devtools: exempt internal ABI checking
2020-04-25 6:04 5% ` [dpdk-dev] [PATCH v6 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
` (2 preceding siblings ...)
2020-04-25 6:04 13% ` [dpdk-dev] [PATCH v6 4/6] devtools: ignore internal ABI check Haiyue Wang
@ 2020-04-25 6:04 7% ` Haiyue Wang
3 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-25 6:04 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
No need to restrict the ABI on symbols that are only used by core
libraries.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
devtools/check-symbol-change.sh | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
index ed2178e36..7b6d5f40f 100755
--- a/devtools/check-symbol-change.sh
+++ b/devtools/check-symbol-change.sh
@@ -91,6 +91,13 @@ check_for_rule_violations()
if [ "$ar" = "add" ]
then
+ if [ "$secname" = "INTERNAL" ]
+ then
+ # these are absolved from any further checking
+ echo "Skipping symbol $symname in INTERNAL"
+ continue
+ fi
+
if [ "$secname" = "unknown" ]
then
# Just inform the user of this occurrence, but
@@ -148,6 +155,7 @@ check_for_rule_violations()
else
if ! grep -q "$mname $symname .* add" "$mapdb" && \
+ [ "$secname" != "INTERNAL" ] && \
[ "$secname" != "EXPERIMENTAL" ]
then
# Just inform users that non-experimenal
--
2.26.2
^ permalink raw reply [relevance 7%]
* [dpdk-dev] [PATCH v6 4/6] devtools: ignore internal ABI check
2020-04-25 6:04 5% ` [dpdk-dev] [PATCH v6 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-25 6:04 13% ` [dpdk-dev] [PATCH v6 1/6] eal: add internal ABI tag definition Haiyue Wang
2020-04-25 6:04 3% ` [dpdk-dev] [PATCH v6 2/6] build: enable internal API tag Haiyue Wang
@ 2020-04-25 6:04 13% ` Haiyue Wang
2020-04-25 6:04 7% ` [dpdk-dev] [PATCH v6 5/6] devtools: exempt internal ABI checking Haiyue Wang
3 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-25 6:04 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Ignore the internal version ABI check, this kind of ABI is used only
by drivers and libraries.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
devtools/libabigail.abignore | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index 1911890a7..986a52771 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -3,6 +3,11 @@
[suppress_variable]
symbol_version = EXPERIMENTAL
+[suppress_function]
+ symbol_version = INTERNAL
+[suppress_variable]
+ symbol_version = INTERNAL
+
; Explicit ignore for driver-only ABI
[suppress_type]
name = rte_cryptodev_ops
--
2.26.2
^ permalink raw reply [relevance 13%]
* [dpdk-dev] [PATCH v6 2/6] build: enable internal API tag
2020-04-25 6:04 5% ` [dpdk-dev] [PATCH v6 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-25 6:04 13% ` [dpdk-dev] [PATCH v6 1/6] eal: add internal ABI tag definition Haiyue Wang
@ 2020-04-25 6:04 3% ` Haiyue Wang
2020-04-25 6:04 13% ` [dpdk-dev] [PATCH v6 4/6] devtools: ignore internal ABI check Haiyue Wang
2020-04-25 6:04 7% ` [dpdk-dev] [PATCH v6 5/6] devtools: exempt internal ABI checking Haiyue Wang
3 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-25 6:04 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Allow the drivers and libraries to use the internal tag for marking
internal ABI symbols.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
drivers/meson.build | 5 ++++-
lib/meson.build | 5 ++++-
mk/target/generic/rte.vars.mk | 1 +
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/meson.build b/drivers/meson.build
index 4d8f842ab..f3dd23dd4 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -20,7 +20,10 @@ dpdk_driver_classes = ['common',
disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
).stdout().split()
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args
+default_cflags += ['-DALLOW_EXPERIMENTAL_API']
+default_cflags += ['-DALLOW_INTERNAL_API']
+
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/lib/meson.build b/lib/meson.build
index c28b8df83..8697941ae 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -38,7 +38,10 @@ if is_windows
libraries = ['kvargs','eal'] # only supported libraries for windows
endif
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args
+default_cflags += ['-DALLOW_EXPERIMENTAL_API']
+default_cflags += ['-DALLOW_INTERNAL_API']
+
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
index ec2672897..11b0418e5 100644
--- a/mk/target/generic/rte.vars.mk
+++ b/mk/target/generic/rte.vars.mk
@@ -106,6 +106,7 @@ ifeq ($(BUILDING_RTE_SDK),1)
# building sdk
CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -DALLOW_INTERNAL_API
else
# if we are building an external application, include SDK's lib and
# includes too
--
2.26.2
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v6 1/6] eal: add internal ABI tag definition
2020-04-25 6:04 5% ` [dpdk-dev] [PATCH v6 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
@ 2020-04-25 6:04 13% ` Haiyue Wang
2020-04-25 6:04 3% ` [dpdk-dev] [PATCH v6 2/6] build: enable internal API tag Haiyue Wang
` (2 subsequent siblings)
3 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-25 6:04 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Introduce the __rte_internal tag to mark internal ABI function which is
used only by the drivers or other libraries.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
lib/librte_eal/include/rte_compat.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
index 3eb33784b..4cd8f68d6 100644
--- a/lib/librte_eal/include/rte_compat.h
+++ b/lib/librte_eal/include/rte_compat.h
@@ -19,4 +19,17 @@ __attribute__((section(".text.experimental")))
#endif
+#ifndef ALLOW_INTERNAL_API
+
+#define __rte_internal \
+__attribute__((error("Symbol is not public ABI"), \
+section(".text.internal")))
+
+#else
+
+#define __rte_internal \
+__attribute__((section(".text.internal")))
+
+#endif
+
#endif /* _RTE_COMPAT_H_ */
--
2.26.2
^ permalink raw reply [relevance 13%]
* [dpdk-dev] [PATCH v6 0/6] dpdk: introduce __rte_internal tag
` (3 preceding siblings ...)
2020-04-23 3:19 4% ` [dpdk-dev] [PATCH v5 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
@ 2020-04-25 6:04 5% ` Haiyue Wang
2020-04-25 6:04 13% ` [dpdk-dev] [PATCH v6 1/6] eal: add internal ABI tag definition Haiyue Wang
` (3 more replies)
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
5 siblings, 4 replies; 200+ results
From: Haiyue Wang @ 2020-04-25 6:04 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Move the internal function into INTERNAL session to avoid the ABI
checking, and it is only used for DPDK drivers or related library.
__rte_internal funA
INTERNAL {
global:
funA
};
v6: split into small patches, and add the missed handling.
v5: add the checkpatch for __rte_internal style
v4: add the ABI check suppression rules
v3: based on Neil's v2 patch https://patchwork.dpdk.org/cover/54771/
Use the ALLOW_INTERNAL_API to mark this new feature.
Haiyue Wang (6):
eal: add internal ABI tag definition
build: enable internal API tag
mk: add internal tag check
devtools: ignore internal ABI check
devtools: exempt internal ABI checking
devtools: enforce internal tag at the beginning
...-experimental-syms.sh => check-symbols.sh} | 31 +++++++++++++++
devtools/check-symbol-change.sh | 8 ++++
devtools/checkpatches.sh | 39 +++++++++++++++++++
devtools/libabigail.abignore | 5 +++
drivers/meson.build | 5 ++-
lib/librte_eal/include/rte_compat.h | 13 +++++++
lib/meson.build | 5 ++-
mk/internal/rte.compile-pre.mk | 6 +--
mk/target/generic/rte.vars.mk | 1 +
9 files changed, 108 insertions(+), 5 deletions(-)
rename buildtools/{check-experimental-syms.sh => check-symbols.sh} (61%)
--
2.26.2
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH v5 1/1] eal: add internal ABI marking support
2020-04-24 14:52 7% ` David Marchand
@ 2020-04-25 6:10 7% ` Wang, Haiyue
2020-04-25 14:21 4% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2020-04-25 6:10 UTC (permalink / raw)
To: David Marchand
Cc: dev, Thomas Monjalon, Richardson, Bruce, Yigit, Ferruh,
Neil Horman, Ray Kinsella
Hi David,
Try to fix the issues you mentioned, except below, plan to
another patch set, I need more time to test these adding.
====
We are missing updates on devtools/check-abi-version.sh and
devtools/update_version_map_abi.py.
More importantly on this file:
- drivers/meson.build is not updated to check for internal symbols, see:
https://git.dpdk.org/dpdk/tree/drivers/meson.build#n166
- For fully experimental libraries, we have a special so version:
https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131
This will apply to common drivers that will be 100% internal.
Not sure if this is an issue.
BR,
Haiyue
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Friday, April 24, 2020 22:53
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev <dev@dpdk.org>; Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce
> <bruce.richardson@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Neil Horman
> <nhorman@tuxdriver.com>; Ray Kinsella <mdr@ashroe.eu>
> Subject: Re: [PATCH v5 1/1] eal: add internal ABI marking support
>
> On Thu, Apr 23, 2020 at 5:25 AM Haiyue Wang <haiyue.wang@intel.com> wrote:
> >
> > Introduce __rte_internal tag to mark internal ABI function which is used
> > by the drivers or other libraries.
> >
> > Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
> > ---
> > buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
> > devtools/check-symbol-change.sh | 7 ++++
> > devtools/checkpatches.sh | 38 +++++++++++++++++++
> > devtools/libabigail.abignore | 5 +++
> > drivers/meson.build | 2 +-
> > lib/librte_eal/include/rte_compat.h | 13 +++++++
> > lib/meson.build | 2 +-
> > mk/internal/rte.compile-pre.mk | 3 ++
> > mk/target/generic/rte.vars.mk | 1 +
> > 9 files changed, 126 insertions(+), 2 deletions(-)
> > create mode 100755 buildtools/check-internal-syms.sh
>
> We can have a single script (let's say devtools/check-symbols.sh) that
> contains both experimental and internal symbols.
>
>
> > diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
> > index ed2178e36..978979077 100755
> > --- a/devtools/check-symbol-change.sh
> > +++ b/devtools/check-symbol-change.sh
> > @@ -91,6 +91,13 @@ check_for_rule_violations()
> > if [ "$ar" = "add" ]
> > then
> >
> > + if [ "$secname" = "INTERNAL" ]
> > + then
> > + # these are absolved from any further checking
> > + echo "Skipping symbol $symname in INTERNAL"
> > + continue
> > + fi
> > +
> > if [ "$secname" = "unknown" ]
> > then
> > # Just inform the user of this occurrence, but
>
> This only handles symbol additions to the INTERNAL section.
> Other cases like moving or removing a INTERNAL symbol are not handled.
>
>
> > diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
> > index c30ce64cc..2df8d7f2c 100755
> > --- a/devtools/checkpatches.sh
> > +++ b/devtools/checkpatches.sh
> > @@ -111,6 +111,36 @@ check_experimental_tags() { # <patch>
> > return $res
> > }
> >
> > +check_internal_tags() { # <patch>
> > + res=0
> > +
> > + cat "$1" |awk '
> > + BEGIN {
> > + current_file = "";
> > + ret = 0;
> > + }
> > + /^+++ b\// {
> > + current_file = $2;
> > + }
> > + /^+.*__rte_internal/ {
> > + if (current_file ~ ".c$" ) {
> > + print "Please only put __rte_internal tags in " \
> > + "headers ("current_file")";
> > + ret = 1;
> > + }
> > + if ($1 != "+__rte_internal" || $2 != "") {
> > + print "__rte_internal must appear alone on the line" \
> > + " immediately preceding the return type of a function."
> > + ret = 1;
> > + }
> > + }
> > + END {
> > + exit ret;
> > + }' || res=1
> > +
> > + return $res
> > +}
> > +
> > number=0
> > range='origin/master..'
> > quiet=false
> > @@ -194,6 +224,14 @@ check () { # <patch> <commit> <title>
> > ret=1
> > fi
> >
> > + ! $verbose || printf '\nChecking __rte_internal tags:\n'
> > + report=$(check_internal_tags "$tmpinput")
> > + if [ $? -ne 0 ] ; then
> > + $headline_printed || print_headline "$3"
> > + printf '%s\n' "$report"
> > + ret=1
> > + fi
> > +
> > if [ "$tmpinput" != "$1" ]; then
> > rm -f "$tmpinput"
> > trap - INT
> > diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> > index cd86d89ca..3e8e2ea74 100644
> > --- a/devtools/libabigail.abignore
> > +++ b/devtools/libabigail.abignore
> > @@ -3,6 +3,11 @@
> > [suppress_variable]
> > symbol_version = EXPERIMENTAL
> >
> > +[suppress_function]
> > + symbol_version = INTERNAL
> > +[suppress_variable]
> > + symbol_version = INTERNAL
> > +
> > ; Explicit ignore for driver-only ABI
> > [suppress_type]
> > name = rte_cryptodev_ops
> > diff --git a/drivers/meson.build b/drivers/meson.build
> > index 4d8f842ab..cac07161f 100644
> > --- a/drivers/meson.build
> > +++ b/drivers/meson.build
> > @@ -20,7 +20,7 @@ dpdk_driver_classes = ['common',
> > disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
> > ).stdout().split()
> >
> > -default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
> > +default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
>
> Nit:
> default_cflags = machine_args
> default_cflags += ['-DALLOW_EXPERIMENTAL_API']
> default_cflags += ['-DALLOW_INTERNAL_API']
>
> > if cc.has_argument('-Wno-format-truncation')
> > default_cflags += '-Wno-format-truncation'
> > endif
>
> More importantly on this file:
>
> - drivers/meson.build is not updated to check for internal symbols, see:
> https://git.dpdk.org/dpdk/tree/drivers/meson.build#n166
>
>
> - For fully experimental libraries, we have a special so version:
> https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131
>
> This will apply to common drivers that will be 100% internal.
> Not sure if this is an issue.
>
>
> > diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
> > index 3eb33784b..4cd8f68d6 100644
> > --- a/lib/librte_eal/include/rte_compat.h
> > +++ b/lib/librte_eal/include/rte_compat.h
> > @@ -19,4 +19,17 @@ __attribute__((section(".text.experimental")))
> >
> > #endif
> >
> > +#ifndef ALLOW_INTERNAL_API
> > +
> > +#define __rte_internal \
> > +__attribute__((error("Symbol is not public ABI"), \
> > +section(".text.internal")))
> > +
> > +#else
> > +
> > +#define __rte_internal \
> > +__attribute__((section(".text.internal")))
> > +
> > +#endif
> > +
> > #endif /* _RTE_COMPAT_H_ */
> > diff --git a/lib/meson.build b/lib/meson.build
> > index c28b8df83..4d2f90d6a 100644
> > --- a/lib/meson.build
> > +++ b/lib/meson.build
> > @@ -38,7 +38,7 @@ if is_windows
> > libraries = ['kvargs','eal'] # only supported libraries for windows
> > endif
> >
> > -default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
> > +default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
>
> Same comments as for drivers/meson.build.
>
>
> > diff --git a/mk/internal/rte.compile-pre.mk b/mk/internal/rte.compile-pre.mk
> > index 82fe098f7..0369786a5 100644
> > --- a/mk/internal/rte.compile-pre.mk
> > +++ b/mk/internal/rte.compile-pre.mk
> > @@ -58,6 +58,8 @@ C_TO_O_DISP = $(if $(V),"$(C_TO_O_STR)"," CC $(@)")
> > endif
> > EXPERIMENTAL_CHECK = $(RTE_SDK)/buildtools/check-experimental-syms.sh
> > CHECK_EXPERIMENTAL = $(EXPERIMENTAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
> > +INTERNAL_CHECK = $(RTE_SDK)/buildtools/check-internal-syms.sh
> > +CHECK_INTERNAL = $(INTERNAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
>
> With a single script, we can go with:
> CHECK_SYMBOLS_SCRIPT = $(RTE_SDK)/buildtools/check-symbols.sh
> CHECK_SYMBOLS = $(CHECK_SYMBOLS_SCRIPT) $(SRCDIR)/$(EXPORT_MAP) $@
>
> >
> > PMDINFO_GEN = $(RTE_SDK_BIN)/app/dpdk-pmdinfogen $@ $@.pmd.c
> > PMDINFO_CC = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@.pmd.o $@.pmd.c
> > @@ -76,6 +78,7 @@ C_TO_O_DO = @set -e; \
> > $(C_TO_O) && \
> > $(PMDINFO_TO_O) && \
> > $(CHECK_EXPERIMENTAL) && \
> > + $(CHECK_INTERNAL) && \
>
> + $(CHECK_SYMBOLS) && \
>
> > echo $(C_TO_O_CMD) > $(call obj2cmd,$(@)) && \
> > sed 's,'$@':,dep_'$@' =,' $(call obj2dep,$(@)).tmp > $(call obj2dep,$(@)) && \
> > rm -f $(call obj2dep,$(@)).tmp
> > diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
> > index ec2672897..11b0418e5 100644
> > --- a/mk/target/generic/rte.vars.mk
> > +++ b/mk/target/generic/rte.vars.mk
> > @@ -106,6 +106,7 @@ ifeq ($(BUILDING_RTE_SDK),1)
> > # building sdk
> > CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
> > CFLAGS += -DALLOW_EXPERIMENTAL_API
> > +CFLAGS += -DALLOW_INTERNAL_API
> > else
> > # if we are building an external application, include SDK's lib and
> > # includes too
> > --
> > 2.26.2
> >
>
> We are missing updates on devtools/check-abi-version.sh and
> devtools/update_version_map_abi.py.
>
>
> --
> David Marchand
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings
2020-04-24 18:07 0% ` Honnappa Nagarahalli
@ 2020-04-24 19:02 0% ` Stephen Hemminger
2020-04-25 9:20 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2020-04-24 19:02 UTC (permalink / raw)
To: Honnappa Nagarahalli; +Cc: dev, nd
On Fri, 24 Apr 2020 18:07:15 +0000
Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com> wrote:
> <snip>
>
> >
> > All API's should check that they support the flag values passed.
> > These checks ensure that the extra bits can safely be used without risk of ABI
> > breakage.
> >
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> > ---
> > lib/librte_ring/rte_ring.c | 10 ++++++++++
> > 1 file changed, 10 insertions(+)
> >
> > diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c index
> > ebe5ccf0de68..70685121581f 100644
> > --- a/lib/librte_ring/rte_ring.c
> > +++ b/lib/librte_ring/rte_ring.c
> > @@ -42,6 +42,9 @@ static struct rte_tailq_elem rte_ring_tailq = { };
> > EAL_REGISTER_TAILQ(rte_ring_tailq)
> >
> > +/* mask of all valid flag values to ring_create() */
> > +#define RING_F_MASK 0x007F
> Is it better to construct this using the actual flag #defines?
sure, but it gets long
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings Stephen Hemminger
@ 2020-04-24 18:07 0% ` Honnappa Nagarahalli
2020-04-24 19:02 0% ` Stephen Hemminger
0 siblings, 1 reply; 200+ results
From: Honnappa Nagarahalli @ 2020-04-24 18:07 UTC (permalink / raw)
To: Stephen Hemminger, dev; +Cc: nd, Honnappa Nagarahalli, nd
<snip>
>
> All API's should check that they support the flag values passed.
> These checks ensure that the extra bits can safely be used without risk of ABI
> breakage.
>
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> ---
> lib/librte_ring/rte_ring.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c index
> ebe5ccf0de68..70685121581f 100644
> --- a/lib/librte_ring/rte_ring.c
> +++ b/lib/librte_ring/rte_ring.c
> @@ -42,6 +42,9 @@ static struct rte_tailq_elem rte_ring_tailq = { };
> EAL_REGISTER_TAILQ(rte_ring_tailq)
>
> +/* mask of all valid flag values to ring_create() */
> +#define RING_F_MASK 0x007F
Is it better to construct this using the actual flag #defines?
> +
> /* true if x is a power of 2 */
> #define POWEROF2(x) ((((x)-1) & (x)) == 0)
>
> @@ -197,6 +200,13 @@ rte_ring_init(struct rte_ring *r, const char *name,
> unsigned count,
> RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, tail) !=
> offsetof(struct rte_ring_rts_headtail, tail.val.pos));
>
> + /* future proof flags, only allow supported values */
> + if (flags & ~RING_F_MASK) {
> + RTE_LOG(ERR, RING,
> + "Unsupported flags requested %#x\n", flags);
> + return -EINVAL;
> + }
> +
> /* init the ring structure */
> memset(r, 0, sizeof(*r));
> ret = strlcpy(r->name, name, sizeof(r->name));
> --
> 2.20.1
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2 4/4] cfgfile: check flags value
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 0/4] enforce checking on flag values " Stephen Hemminger
` (2 preceding siblings ...)
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 3/4] stack: " Stephen Hemminger
@ 2020-04-24 17:15 3% ` Stephen Hemminger
3 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2020-04-24 17:15 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
All API's should check that they support the flag values
passed. If an application passes an invalid flag it could
cause problems in later ABI.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_cfgfile/rte_cfgfile.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/lib/librte_cfgfile/rte_cfgfile.c b/lib/librte_cfgfile/rte_cfgfile.c
index 9049fd9c2319..714717dd9007 100644
--- a/lib/librte_cfgfile/rte_cfgfile.c
+++ b/lib/librte_cfgfile/rte_cfgfile.c
@@ -272,6 +272,10 @@ rte_cfgfile_create(int flags)
int i;
struct rte_cfgfile *cfg;
+ /* future proof flags usage */
+ if (flags & ~(CFG_FLAG_GLOBAL_SECTION | CFG_FLAG_EMPTY_VALUES))
+ return NULL;
+
cfg = malloc(sizeof(*cfg));
if (cfg == NULL)
--
2.20.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v2 3/4] stack: check flags on creation
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 0/4] enforce checking on flag values " Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 2/4] hash: check flags on creation Stephen Hemminger
@ 2020-04-24 17:15 3% ` Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 4/4] cfgfile: check flags value Stephen Hemminger
3 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2020-04-24 17:15 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
All API's should check that they support the flag values
passed. If an application passes an invalid flag it could
cause problems in later ABI.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_stack/rte_stack.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/lib/librte_stack/rte_stack.c b/lib/librte_stack/rte_stack.c
index d19824f00439..e58fa545fca4 100644
--- a/lib/librte_stack/rte_stack.c
+++ b/lib/librte_stack/rte_stack.c
@@ -59,6 +59,11 @@ rte_stack_create(const char *name, unsigned int count, int socket_id,
unsigned int sz;
int ret;
+ if (flags & ~(RTE_STACK_F_LF)) {
+ STACK_LOG_ERR("Unsupported stack flags %#x\n", flags);
+ return NULL;
+ }
+
#ifdef RTE_ARCH_64
RTE_BUILD_BUG_ON(sizeof(struct rte_stack_lf_head) != 16);
#else
--
2.20.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v2 2/4] hash: check flags on creation
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 0/4] enforce checking on flag values " Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings Stephen Hemminger
@ 2020-04-24 17:15 3% ` Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 3/4] stack: " Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 4/4] cfgfile: check flags value Stephen Hemminger
3 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2020-04-24 17:15 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
All API's should check that they support the flag values
passed. If an application passes an invalid flag it could
cause problems in later ABI.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_hash/rte_cuckoo_hash.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/lib/librte_hash/rte_cuckoo_hash.c b/lib/librte_hash/rte_cuckoo_hash.c
index 6af8ca42e94f..ab9cd91b4955 100644
--- a/lib/librte_hash/rte_cuckoo_hash.c
+++ b/lib/librte_hash/rte_cuckoo_hash.c
@@ -32,6 +32,9 @@
#include "rte_hash.h"
#include "rte_cuckoo_hash.h"
+/* Mask of all flags supported by this version */
+#define RTE_HASH_EXTRA_FLAGS_MASK 0x2f
+
#define FOR_EACH_BUCKET(CURRENT_BKT, START_BUCKET) \
for (CURRENT_BKT = START_BUCKET; \
CURRENT_BKT != NULL; \
@@ -164,6 +167,12 @@ rte_hash_create(const struct rte_hash_parameters *params)
return NULL;
}
+ if (params->extra_flag & ~RTE_HASH_EXTRA_FLAGS_MASK) {
+ rte_errno = EINVAL;
+ RTE_LOG(ERR, HASH, "rte_hash_create: unsupported extra flags\n");
+ return NULL;
+ }
+
/* Validate correct usage of extra options */
if ((params->extra_flag & RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY) &&
(params->extra_flag & RTE_HASH_EXTRA_FLAGS_RW_CONCURRENCY_LF)) {
--
2.20.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 0/4] enforce checking on flag values " Stephen Hemminger
@ 2020-04-24 17:15 3% ` Stephen Hemminger
2020-04-24 18:07 0% ` Honnappa Nagarahalli
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 2/4] hash: check flags on creation Stephen Hemminger
` (2 subsequent siblings)
3 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2020-04-24 17:15 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
All API's should check that they support the flag values passed.
These checks ensure that the extra bits can safely be used
without risk of ABI breakage.
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
lib/librte_ring/rte_ring.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
index ebe5ccf0de68..70685121581f 100644
--- a/lib/librte_ring/rte_ring.c
+++ b/lib/librte_ring/rte_ring.c
@@ -42,6 +42,9 @@ static struct rte_tailq_elem rte_ring_tailq = {
};
EAL_REGISTER_TAILQ(rte_ring_tailq)
+/* mask of all valid flag values to ring_create() */
+#define RING_F_MASK 0x007F
+
/* true if x is a power of 2 */
#define POWEROF2(x) ((((x)-1) & (x)) == 0)
@@ -197,6 +200,13 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, tail) !=
offsetof(struct rte_ring_rts_headtail, tail.val.pos));
+ /* future proof flags, only allow supported values */
+ if (flags & ~RING_F_MASK) {
+ RTE_LOG(ERR, RING,
+ "Unsupported flags requested %#x\n", flags);
+ return -EINVAL;
+ }
+
/* init the ring structure */
memset(r, 0, sizeof(*r));
ret = strlcpy(r->name, name, sizeof(r->name));
--
2.20.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v2 0/4] enforce checking on flag values in API's
@ 2020-04-24 17:15 3% ` Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings Stephen Hemminger
` (3 more replies)
0 siblings, 4 replies; 200+ results
From: Stephen Hemminger @ 2020-04-24 17:15 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger
Since the DPDK api's are lazy about checking for flag values
it means the flags can never be extended in future releases
without causing ABI breakage. This means we end up doing unnecessary
symbol versioning just to work around applications that might
pass in naughty bits.
This is the DPDK analog of the Linux kernel openat() problem.
Openat api was added but since kernel did not check flags it
ended up that another syscall openat2() was necessary before
the flags could be used.
v2 - rebase and fix checkpatch warnings from RFC
Stephen Hemminger (4):
ring: future proof flag settings
hash: check flags on creation
stack: check flags on creation
cfgfile: check flags value
lib/librte_cfgfile/rte_cfgfile.c | 4 ++++
lib/librte_hash/rte_cuckoo_hash.c | 9 +++++++++
lib/librte_ring/rte_ring.c | 10 ++++++++++
lib/librte_stack/rte_stack.c | 5 +++++
4 files changed, 28 insertions(+)
--
2.20.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v4 02/18] telemetry: move code to metrics for later reuse
2020-04-24 15:29 3% ` Stephen Hemminger
@ 2020-04-24 15:49 0% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2020-04-24 15:49 UTC (permalink / raw)
To: Stephen Hemminger
Cc: Ciara Power, dev, kevin.laatz, reshma.pattan, jerinjacobk,
david.marchand, keith.wiles, mb, thomas
On Fri, Apr 24, 2020 at 08:29:53AM -0700, Stephen Hemminger wrote:
> On Fri, 24 Apr 2020 13:41:43 +0100
> Ciara Power <ciara.power@intel.com> wrote:
>
> > This commit moves some of the telemetry library code to a new file in
> > the metrics library. No modifications are made to the moved code,
> > except what is needed to allow it to compile and run. The additional
> > code in metrics is built only when the Jansson library is present.
> > Telemetry functions as normal, using the functions from the
> > metrics_telemetry file. This move will enable code be reused by the new
> > version of telemetry in a later commit, to support backward
> > compatibility with the existing telemetry usage.
> >
> > Signed-off-by: Ciara Power <ciara.power@intel.com>
>
>
> Minor comments, none of these are show stoppers.
>
>
> > diff --git a/lib/librte_metrics/rte_metrics.c b/lib/librte_metrics/rte_metrics.c
> > index df5e32c59f..9b38d7787c 100644
> > --- a/lib/librte_metrics/rte_metrics.c
> > +++ b/lib/librte_metrics/rte_metrics.c
> > @@ -13,7 +13,6 @@
> > #include <rte_memzone.h>
> > #include <rte_spinlock.h>
> >
> > -#define RTE_METRICS_MAX_METRICS 256
> > #define RTE_METRICS_MEMZONE_NAME "RTE_METRICS"
> >
> > /**
> > diff --git a/lib/librte_metrics/rte_metrics.h b/lib/librte_metrics/rte_metrics.h
> > index 77bffe08e4..466ca98c31 100644
> > --- a/lib/librte_metrics/rte_metrics.h
> > +++ b/lib/librte_metrics/rte_metrics.h
> > @@ -32,6 +32,7 @@ extern "C" {
> >
> > /** Maximum length of metric name (including null-terminator) */
> > #define RTE_METRICS_MAX_NAME_LEN 64
> > +#define RTE_METRICS_MAX_METRICS 256
>
> Exposing max metrics to API/ABI does limit you in the future.
>
I'm not sure moving the definition limits us any more than before. So long
as the structures which are defined based on this definition are internal
and only accessed via API functions, there should be no problems with
changing this and using function versioning for compatibility.
/Bruce
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4 02/18] telemetry: move code to metrics for later reuse
@ 2020-04-24 15:29 3% ` Stephen Hemminger
2020-04-24 15:49 0% ` Bruce Richardson
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2020-04-24 15:29 UTC (permalink / raw)
To: Ciara Power
Cc: dev, kevin.laatz, reshma.pattan, jerinjacobk, david.marchand,
keith.wiles, mb, thomas
On Fri, 24 Apr 2020 13:41:43 +0100
Ciara Power <ciara.power@intel.com> wrote:
> This commit moves some of the telemetry library code to a new file in
> the metrics library. No modifications are made to the moved code,
> except what is needed to allow it to compile and run. The additional
> code in metrics is built only when the Jansson library is present.
> Telemetry functions as normal, using the functions from the
> metrics_telemetry file. This move will enable code be reused by the new
> version of telemetry in a later commit, to support backward
> compatibility with the existing telemetry usage.
>
> Signed-off-by: Ciara Power <ciara.power@intel.com>
Minor comments, none of these are show stoppers.
> diff --git a/lib/librte_metrics/rte_metrics.c b/lib/librte_metrics/rte_metrics.c
> index df5e32c59f..9b38d7787c 100644
> --- a/lib/librte_metrics/rte_metrics.c
> +++ b/lib/librte_metrics/rte_metrics.c
> @@ -13,7 +13,6 @@
> #include <rte_memzone.h>
> #include <rte_spinlock.h>
>
> -#define RTE_METRICS_MAX_METRICS 256
> #define RTE_METRICS_MEMZONE_NAME "RTE_METRICS"
>
> /**
> diff --git a/lib/librte_metrics/rte_metrics.h b/lib/librte_metrics/rte_metrics.h
> index 77bffe08e4..466ca98c31 100644
> --- a/lib/librte_metrics/rte_metrics.h
> +++ b/lib/librte_metrics/rte_metrics.h
> @@ -32,6 +32,7 @@ extern "C" {
>
> /** Maximum length of metric name (including null-terminator) */
> #define RTE_METRICS_MAX_NAME_LEN 64
> +#define RTE_METRICS_MAX_METRICS 256
Exposing max metrics to API/ABI does limit you in the future.
> diff --git a/lib/librte_metrics/rte_metrics_telemetry.c b/lib/librte_metrics/rte_metrics_telemetry.c
> new file mode 100644
> index 0000000000..a6b2616714
> --- /dev/null
> +++ b/lib/librte_metrics/rte_metrics_telemetry.c
> @@ -0,0 +1,719 @@
...
> +static int32_t
> +rte_metrics_tel_is_port_active(int port_id)
portid should be uint16_t like rte_ethdev
return bool rather than int
> +{
> + int ret;
> +
> + ret = rte_eth_find_next(port_id);
> + if (ret == port_id)
> + return 1;
> +
> + METRICS_LOG_ERR("port_id: %d is invalid, not active",
> + port_id);
> +
> + return 0;
> +}
> +
> +static int32_t
> +rte_metrics_tel_reg_port_ethdev_to_metrics(uint16_t port_id)
> +{
> + int ret, num_xstats, ret_val, i;
> + struct rte_eth_xstat *eth_xstats = NULL;
> + struct rte_eth_xstat_name *eth_xstats_names = NULL;
You don't need to initialize all variables, and it is actually
bad practice with modern compilers since it breaks checking
for using values before set.
> +
> + if (!rte_eth_dev_is_valid_port(port_id)) {
> + METRICS_LOG_ERR("port_id: %d is invalid", port_id);
> + return -EINVAL;
> + }
Validity of port_id is already checked by rte_eth_xstats_get
> + num_xstats = rte_eth_xstats_get(port_id, NULL, 0);
> + if (num_xstats < 0) {
> + METRICS_LOG_ERR("rte_eth_xstats_get(%u) failed: %d",
> + port_id, num_xstats);
> + return -EPERM;
> + }
> +
> + eth_xstats = malloc(sizeof(struct rte_eth_xstat) * num_xstats);
> + if (eth_xstats == NULL) {
> + METRICS_LOG_ERR("Failed to malloc memory for xstats");
> + return -ENOMEM;
> + }
> +
> + ret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats);
> + const char *xstats_names[num_xstats];
Please don't put declarations in the middle of the code.
You should malloc the names as well
> + eth_xstats_names = malloc(sizeof(struct rte_eth_xstat_name)
> + * num_xstats);
> + if (ret < 0 || ret > num_xstats) {
> + METRICS_LOG_ERR("rte_eth_xstats_get(%u) len%i failed: %d",
> + port_id, num_xstats, ret);
> + ret_val = -EPERM;
> + goto free_xstats;
> + }
> +
> + if (eth_xstats_names == NULL) {
> + METRICS_LOG_ERR("Failed to malloc memory for xstats_names");
> + ret_val = -ENOMEM;
> + goto free_xstats;
> + }
> +
> + ret = rte_eth_xstats_get_names(port_id, eth_xstats_names, num_xstats);
> + if (ret < 0 || ret > num_xstats) {
> + METRICS_LOG_ERR("rte_eth_xstats_get_names(%u) len%i failed: %d",
> + port_id, num_xstats, ret);
> + ret_val = -EPERM;
> + goto free_xstats;
> + }
> +
> + for (i = 0; i < num_xstats; i++)
> + xstats_names[i] = eth_xstats_names[eth_xstats[i].id].name;
> +
> + ret_val = rte_metrics_reg_names(xstats_names, num_xstats);
> + if (ret_val < 0) {
> + METRICS_LOG_ERR("rte_metrics_reg_names failed - metrics may already be registered");
> + ret_val = -1;
> + goto free_xstats;
> + }
> +
> + goto free_xstats;
> +
> +free_xstats:
> + free(eth_xstats);
> + free(eth_xstats_names);
> + return ret_val;
> +}
> +
> +int32_t
> +rte_metrics_tel_reg_all_ethdev(int *metrics_register_done, int *reg_index_list)
> +{
> + struct driver_index {
> + const void *dev_ops;
> + int reg_index;
> + } drv_idx[RTE_MAX_ETHPORTS] = { {0} };
> + int nb_drv_idx = 0;
> + uint16_t pid;
> + int ret;
> +
> + RTE_ETH_FOREACH_DEV(pid) {
> + int i;
> + /* Different device types have different numbers of stats, so
> + * first check if the stats for this type of device have
> + * already been registered
> + */
> + for (i = 0; i < nb_drv_idx; i++) {
> + if (rte_eth_devices[pid].dev_ops ==
> + drv_idx[i].dev_ops) {
> + reg_index_list[pid] = drv_idx[i].reg_index;
> + break;
> + }
> + }
> + if (i < nb_drv_idx)
> + continue; /* we found a match, go to next port */
> +
> + /* No match, register a new set of xstats for this port */
> + ret = rte_metrics_tel_reg_port_ethdev_to_metrics(pid);
> + if (ret < 0) {
> + METRICS_LOG_ERR("Failed to register ethdev metrics");
> + return -1;
> + }
> + reg_index_list[pid] = ret;
> + drv_idx[nb_drv_idx].dev_ops = rte_eth_devices[pid].dev_ops;
> + drv_idx[nb_drv_idx].reg_index = ret;
> + nb_drv_idx++;
> + }
> +
> + *metrics_register_done = 1;
> + return 0;
> +}
> +
> +static int32_t
> +rte_metrics_tel_update_metrics_ethdev(uint16_t port_id, int reg_start_index)
> +{
> + int ret, num_xstats, i;
> + struct rte_eth_xstat *eth_xstats;
> +
> + if (!rte_eth_dev_is_valid_port(port_id)) {
> + METRICS_LOG_ERR("port_id: %d is invalid", port_id);
> + return -EINVAL;
> + }
> +
> + ret = rte_metrics_tel_is_port_active(port_id);
> + if (ret < 1)
> + return -EINVAL;
> +
> + num_xstats = rte_eth_xstats_get(port_id, NULL, 0);
> + if (num_xstats < 0) {
> + METRICS_LOG_ERR("rte_eth_xstats_get(%u) failed: %d", port_id,
> + num_xstats);
> + return -EPERM;
> + }
The number of metrics on a port should not change (as long as it has
not been hot plugged). So you could optimize by knowing number of
stats from last query.
> + eth_xstats = malloc(sizeof(struct rte_eth_xstat) * num_xstats);
> + if (eth_xstats == NULL) {
> + METRICS_LOG_ERR("Failed to malloc memory for xstats");
> + return -ENOMEM;
> + }
> +
> + ret = rte_eth_xstats_get(port_id, eth_xstats, num_xstats);
> + if (ret < 0 || ret > num_xstats) {
> + free(eth_xstats);
> + METRICS_LOG_ERR("rte_eth_xstats_get(%u) len%i failed: %d",
> + port_id, num_xstats, ret);
> + return -EPERM;
> + }
> +
> + uint64_t xstats_values[num_xstats];
> + for (i = 0; i < num_xstats; i++)
> + xstats_values[i] = eth_xstats[i].value;
> +
> + ret = rte_metrics_update_values(port_id, reg_start_index, xstats_values,
> + num_xstats);
> + if (ret < 0) {
> + METRICS_LOG_ERR("Could not update metrics values");
> + free(eth_xstats);
> + return -EPERM;
> + }
> +
> + free(eth_xstats);
> + return 0;
> +}
> +
> +static int
> +rte_metrics_tel_get_metrics(uint32_t port_id, struct rte_metric_value
> + *metrics, struct rte_metric_name *names, int num_metrics)
Don't break awkwardly in the function declaration.
> +{
> + int ret, num_values;
> +
> + if (num_metrics < 0) {
if you don't want negative, make it unsigned.
> + METRICS_LOG_ERR("Invalid metrics count");
> + return -EINVAL;
> + } else if (num_metrics == 0) {
else after return non needed.
> + METRICS_LOG_ERR("No metrics to display (none have been registered)");
> + return -EPERM;
> + }
> +
> + if (metrics == NULL) {
> + METRICS_LOG_ERR("Metrics must be initialised.");
> + return -EINVAL;
> + }
> +
> + if (names == NULL) {
> + METRICS_LOG_ERR("Names must be initialised.");
> + return -EINVAL;
> + }
> +
> + ret = rte_metrics_get_names(names, num_metrics);
> + if (ret < 0 || ret > num_metrics) {
> + METRICS_LOG_ERR("Cannot get metrics names");
> + return -EPERM;
> + }
> +
> + num_values = rte_metrics_get_values(port_id, NULL, 0);
> + ret = rte_metrics_get_values(port_id, metrics, num_values);
> + if (ret < 0 || ret > num_values) {
> + METRICS_LOG_ERR("Cannot get metrics values");
> + return -EPERM;
> + }
> +
> + return 0;
> +}
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] cryptodev: add support for user callback functions
@ 2020-04-24 15:10 3% ` Ananyev, Konstantin
0 siblings, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2020-04-24 15:10 UTC (permalink / raw)
To: Gujjar, Abhinandan S, Doherty, Declan, jerinj, akhil.goyal, dev
Cc: Vangati, Narender, Gujjar, Abhinandan S
> In an eventdev world, multiple workers (with ordered queue) will be
> working on IPsec ESP processing. The ESP header's sequence number is
> unique and has to be sequentially incremented in an orderly manner.
> This rises a need for incrementing sequence number in crypto stage
> especially in event crypto adapter. By adding a user callback to
> cryptodev at enqueue burst, the user callback will get executed
> in the context of event crypto adapter. This helps the application
> to increment the ESP sequence number atomically and orderly manner.
>
> Signed-off-by: Abhinandan Gujjar <abhinandan.gujjar@intel.com>
> ---
> config/common_base | 1 +
> lib/librte_cryptodev/rte_cryptodev.c | 120 ++++++++++++++++++++++++
> lib/librte_cryptodev/rte_cryptodev.h | 125 ++++++++++++++++++++++++-
> lib/librte_cryptodev/rte_cryptodev_version.map | 3 +
> 4 files changed, 248 insertions(+), 1 deletion(-)
>
> diff --git a/config/common_base b/config/common_base
> index 9ec689d..6f93acb 100644
> --- a/config/common_base
> +++ b/config/common_base
> @@ -586,6 +586,7 @@ CONFIG_RTE_LIBRTE_PMD_BBDEV_FPGA_5GNR_FEC=y
> #
> CONFIG_RTE_LIBRTE_CRYPTODEV=y
> CONFIG_RTE_CRYPTO_MAX_DEVS=64
> +CONFIG_RTE_CRYPTODEV_CALLBACKS=y
>
> #
> # Compile PMD for ARMv8 Crypto device
> diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
> index 2849b2e..5a4cba9 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.c
> +++ b/lib/librte_cryptodev/rte_cryptodev.c
> @@ -56,6 +56,9 @@
> /* spinlock for crypto device callbacks */
> static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
>
> +/* spinlock for crypto device enq callbacks */
> +static rte_spinlock_t rte_cryptodev_enq_cb_lock = RTE_SPINLOCK_INITIALIZER;
> +
>
> /**
> * The user application callback description.
> @@ -1256,6 +1259,123 @@ struct rte_cryptodev *
> rte_spinlock_unlock(&rte_cryptodev_cb_lock);
> }
>
> +const struct rte_cryptodev_enq_callback *__rte_experimental
> +rte_cryptodev_add_enq_callback(uint8_t dev_id,
> + uint16_t qp_id,
> + rte_cryptodev_enq_cb_fn cb_fn,
> + void *cb_arg)
> +{
> + struct rte_cryptodev *dev;
> + struct rte_cryptodev_enq_callback *cb, *tail;
> +
> + if (!cb_fn)
> + return NULL;
> +
> + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
> + CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
> + return NULL;
> + }
> +
> + dev = &rte_crypto_devices[dev_id];
> + if (qp_id >= dev->data->nb_queue_pairs) {
> + CDEV_LOG_ERR("Invalid queue_pair_id=%d", qp_id);
> + return NULL;
> + }
> +
> + cb = rte_zmalloc(NULL, sizeof(*cb), 0);
> + if (cb == NULL) {
> + CDEV_LOG_ERR("Failed to allocate memory for callback on "
> + "dev=%d, queue_pair_id=%d", dev_id, qp_id);
> + rte_errno = ENOMEM;
> + return NULL;
> + }
> +
> + cb->fn = cb_fn;
> + cb->arg = cb_arg;
> +
> + rte_spinlock_lock(&rte_cryptodev_enq_cb_lock);
> + if (dev->enq_cbs == NULL) {
> + dev->enq_cbs = rte_zmalloc(NULL, sizeof(cb) *
> + dev->data->nb_queue_pairs, 0);
> + if (dev->enq_cbs == NULL) {
> + CDEV_LOG_ERR("Failed to allocate memory for callbacks");
> + rte_errno = ENOMEM;
> + rte_free(cb);
> + return NULL;
> + }
> + }
> +
> + /* Add the callbacks in fifo order. */
> + tail = dev->enq_cbs[qp_id];
> + if (tail) {
> + while (tail->next)
> + tail = tail->next;
> + tail->next = cb;
> + } else
> + dev->enq_cbs[qp_id] = cb;
> +
> + rte_spinlock_unlock(&rte_cryptodev_enq_cb_lock);
> +
> + return cb;
> +}
> +
> +int __rte_experimental
> +rte_cryptodev_remove_enq_callback(uint8_t dev_id,
> + uint16_t qp_id,
> + const struct rte_cryptodev_enq_callback *cb)
> +{
> + struct rte_cryptodev *dev;
> + struct rte_cryptodev_enq_callback **prev_cb, *curr_cb;
> + uint16_t qp;
> + int free_mem = 1;
> + int ret = -EINVAL;
> +
> + if (!cb)
> + return ret;
> +
> + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
> + CDEV_LOG_ERR("Invalid dev_id=%" PRIu8, dev_id);
> + return ret;
> + }
> +
> + dev = &rte_crypto_devices[dev_id];
> + if (qp_id >= dev->data->nb_queue_pairs) {
> + CDEV_LOG_ERR("Invalid queue_pair_id=%d", qp_id);
> + return ret;
> + }
> +
> + rte_spinlock_lock(&rte_cryptodev_enq_cb_lock);
> + if (dev->enq_cbs == NULL) {
> + rte_spinlock_unlock(&rte_cryptodev_enq_cb_lock);
> + return ret;
> + }
> +
> + prev_cb = &dev->enq_cbs[qp_id];
> + for (; *prev_cb != NULL; prev_cb = &curr_cb->next) {
> + curr_cb = *prev_cb;
> + if (curr_cb == cb) {
> + /* Remove the user cb from the callback list. */
> + *prev_cb = curr_cb->next;
> + ret = 0;
> + break;
> + }
> + }
> +
> + for (qp = 0; qp < dev->data->nb_queue_pairs; qp++)
> + if (dev->enq_cbs[qp] != NULL) {
> + free_mem = 0;
> + break;
> + }
> +
> + if (free_mem) {
> + rte_free(dev->enq_cbs);
> + dev->enq_cbs = NULL;
> + }
> +
> + rte_spinlock_unlock(&rte_cryptodev_enq_cb_lock);
> +
> + return ret;
> +}
Pls don't re-implement pitfall we have with ethdev rx/tx callback:
right now with ethdev approach it is impossible to know when it is safe to free
removed CB and free used by CB resources if any.
Unless you do dev_stop() of course.
So majority of ethdev CB uses have to either leave CB allocated forever
after removal (memory leak), or invent some specific sync methods underneath
that API.
We probably need to introduce some sync mechanism here straightway (RCU or so)
to avoid same issue.
>
> int
> rte_cryptodev_sym_session_init(uint8_t dev_id,
> diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
> index f4846d2..2cf466b 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev.h
> @@ -518,6 +518,32 @@ struct rte_cryptodev_qp_conf {
> };
>
> /**
> + * Function type used for pre processing crypto ops when enqueue burst is
> + * called.
> + *
> + * The callback function is called on enqueue burst immediately
> + * before the crypto ops are put onto the hardware queue for processing.
> + *
> + * @param dev_id The identifier of the device.
> + * @param qp_id The index of the queue pair in which ops are
> + * to be enqueued for processing. The value
> + * must be in the range [0, nb_queue_pairs - 1]
> + * previously supplied to
> + * *rte_cryptodev_configure*.
> + * @param ops The address of an array of *nb_ops* pointers
> + * to *rte_crypto_op* structures which contain
> + * the crypto operations to be processed.
> + * @param nb_ops The number of operations to process.
> + * @param user_param The arbitrary user parameter passed in by the
> + * application when the callback was originally
> + * registered.
> + * @return The number of ops to be enqueued to the
> + * crypto device.
> + */
> +typedef uint16_t (*rte_cryptodev_enq_cb_fn)(uint16_t dev_id, uint16_t qp_id,
> + struct rte_crypto_op **ops, uint16_t nb_ops, void *user_param);
> +
> +/**
> * Typedef for application callback function to be registered by application
> * software for notification of device events
> *
> @@ -800,7 +826,6 @@ struct rte_cryptodev_config {
> enum rte_cryptodev_event_type event,
> rte_cryptodev_cb_fn cb_fn, void *cb_arg);
>
> -
> typedef uint16_t (*dequeue_pkt_burst_t)(void *qp,
> struct rte_crypto_op **ops, uint16_t nb_ops);
> /**< Dequeue processed packets from queue pair of a device. */
> @@ -817,6 +842,17 @@ typedef uint16_t (*enqueue_pkt_burst_t)(void *qp,
> /** Structure to keep track of registered callbacks */
> TAILQ_HEAD(rte_cryptodev_cb_list, rte_cryptodev_callback);
>
> +/**
> + * @internal
> + * Structure used to hold information about the callbacks to be called for a
> + * queue pair on enqueue.
> + */
> +struct rte_cryptodev_enq_callback {
> + struct rte_cryptodev_enq_callback *next;
> + rte_cryptodev_enq_cb_fn fn;
> + void *arg;
> +};
> +
> /** The data structure associated with each crypto device. */
> struct rte_cryptodev {
> dequeue_pkt_burst_t dequeue_burst;
> @@ -839,6 +875,9 @@ struct rte_cryptodev {
> struct rte_cryptodev_cb_list link_intr_cbs;
> /**< User application callback for interrupts if present */
>
> + struct rte_cryptodev_enq_callback **enq_cbs;
> + /**< User application callback for pre enqueue processing */
> +
Why not to put it at the very end of the structure?
Would be safer in terms of ABI breakage problem, etc.
> void *security_ctx;
> /**< Context for security ops */
>
> @@ -966,6 +1005,18 @@ struct rte_cryptodev_data {
> {
> struct rte_cryptodev *dev = &rte_cryptodevs[dev_id];
>
> +#ifdef RTE_CRYPTODEV_CALLBACKS
> + if (unlikely(dev->enq_cbs != NULL && dev->enq_cbs[qp_id] != NULL)) {
> + struct rte_cryptodev_enq_callback *cb =
> + dev->enq_cbs[qp_id];
> +
> + do {
> + nb_ops = cb->fn(dev_id, qp_id, ops, nb_ops,
> + cb->arg);
> + cb = cb->next;
> + } while (cb != NULL);
> + }
> +#endif
> return (*dev->enqueue_burst)(
> dev->data->queue_pairs[qp_id], ops, nb_ops);
> }
> @@ -1296,6 +1347,78 @@ struct rte_cryptodev_asym_session *
> struct rte_cryptodev_sym_session *sess, union rte_crypto_sym_ofs ofs,
> struct rte_crypto_sym_vec *vec);
>
> +
> +/**
> + * Add a user callback for a given crypto device and queue pair which will be
> + * called on crypto ops enqueue.
> + *
> + * This API configures a function to be called for each burst of crypto ops
> + * received on a given crypto device queue pair. The return value is a pointer
> + * that can be used later to remove the callback using
> + * rte_cryptodev_remove_enq_callback().
> + *
> + * Multiple functions are called in the order that they are added.
> + *
> + * @param dev_id The identifier of the device.
> + * @param qp_id The index of the queue pair in which ops are
> + * to be enqueued for processing. The value
> + * must be in the range [0, nb_queue_pairs - 1]
> + * previously supplied to
> + * *rte_cryptodev_configure*.
> + * @param cb_fn The callback function
> + * @param cb_arg A generic pointer parameter which will be passed
> + * to each invocation of the callback function on
> + * this crypto device and queue pair.
> + *
> + * @return
> + * NULL on error.
> + * On success, a pointer value which can later be used to remove the callback.
> + */
> +
> +const struct rte_cryptodev_enq_callback * __rte_experimental
> +rte_cryptodev_add_enq_callback(uint8_t dev_id,
> + uint16_t qp_id,
> + rte_cryptodev_enq_cb_fn cb_fn,
> + void *cb_arg);
> +
> +
> +/**
> + * Remove a user callback function for given crypto device and queue pair.
> + *
> + * This function is used to removed callbacks that were added to a crypto
> + * device queue pair using rte_cryptodev_add_enq_callback().
> + *
> + * Note: the callback is removed from the callback list but it isn't freed
> + * since the it may still be in use. The memory for the callback can be
> + * subsequently freed back by the application by calling rte_free().
> + *
> + * - Immediately - if the crypto device is stopped, or user knows that
> + * no callbacks are in flight e.g. if called from the thread doing enq/deq
> + * on that queue.
> + *
> + * - After a short delay - where the delay is sufficient to allow any
> + * in-flight callbacks to complete.
> + *
> + * @param dev_id The identifier of the device.
> + * @param qp_id The index of the queue pair in which ops are
> + * to be enqueued for processing. The value
> + * must be in the range [0, nb_queue_pairs - 1]
> + * previously supplied to
> + * *rte_cryptodev_configure*.
> + * @param cb Pointer to user supplied callback created via
> + * rte_cryptodev_add_enq_callback().
> + *
> + * @return
> + * - 0: Success. Callback was removed.
> + * - -EINVAL: The dev_id or the qp_id is out of range, or the callback
> + * is NULL or not found for the crypto device queue pair.
> + */
> +
> +int __rte_experimental
> +rte_cryptodev_remove_enq_callback(uint8_t dev_id,
> + uint16_t qp_id,
> + const struct rte_cryptodev_enq_callback *cb);
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
> index 6e41b4b..e8d3e77 100644
> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
> @@ -58,9 +58,11 @@ DPDK_20.0 {
> local: *;
> };
>
> +
> EXPERIMENTAL {
> global:
>
> + rte_cryptodev_add_enq_callback;
> rte_cryptodev_asym_capability_get;
> rte_cryptodev_asym_get_header_session_size;
> rte_cryptodev_asym_get_private_session_size;
> @@ -71,6 +73,7 @@ EXPERIMENTAL {
> rte_cryptodev_asym_session_init;
> rte_cryptodev_asym_xform_capability_check_modlen;
> rte_cryptodev_asym_xform_capability_check_optype;
> + rte_cryptodev_remove_enq_callback;
> rte_cryptodev_sym_cpu_crypto_process;
> rte_cryptodev_sym_get_existing_header_session_size;
> rte_cryptodev_sym_session_get_user_data;
> --
> 1.9.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2] abi: change references to abi 20.0.1 to abi v21
2020-04-24 14:50 6% ` Ray Kinsella
@ 2020-04-24 15:01 6% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2020-04-24 15:01 UTC (permalink / raw)
To: Ray Kinsella
Cc: Dodji Seketeli, dev, Andrzej Ostruszka, Stephen Hemminger,
Thomas Monjalon, Neil Horman, Jingjing Wu, Wenzhuo Lu,
Matan Azrad, Shahaf Shuler, Viacheslav Ovsiienko, Jerin Jacob,
Nithin Dabilpuram, Alfredo Cardigliano, Mahipal Challa,
Cristian Dumitrescu, Wang, Haiyue
On Fri, Apr 24, 2020 at 4:50 PM Ray Kinsella <mdr@ashroe.eu> wrote:
>
> ah ok, the particular system I made the change on was Ubuntu 18.04.2.
> which is libabigail 1.2.0.
>
> Given we still support v19.11 on Ubuntu 18.04.2.
> I think it's worthwhile keeping the suppression until v20.11?
1.2 is fairly old and does not seem maintained by Ubuntu (asked for
backport, and got ignored so far).
https://bugs.launchpad.net/ubuntu/+source/libabigail/+bug/1863607
Dodji told me that there were new checks added in newer sersions.
I also fear that supporting an old libabigail version will force us to
add a lot of other rules.
In Travis, we currently use libabigail 1.6 (mainly because I did not
update to 1.7 when it was released).
--
David Marchand
^ permalink raw reply [relevance 6%]
* Re: [dpdk-dev] [PATCH v5 1/1] eal: add internal ABI marking support
2020-04-23 3:19 15% ` [dpdk-dev] [PATCH v5 1/1] eal: add internal ABI marking support Haiyue Wang
@ 2020-04-24 14:52 7% ` David Marchand
2020-04-25 6:10 7% ` Wang, Haiyue
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2020-04-24 14:52 UTC (permalink / raw)
To: Haiyue Wang
Cc: dev, Thomas Monjalon, Bruce Richardson, Yigit, Ferruh,
Neil Horman, Ray Kinsella
On Thu, Apr 23, 2020 at 5:25 AM Haiyue Wang <haiyue.wang@intel.com> wrote:
>
> Introduce __rte_internal tag to mark internal ABI function which is used
> by the drivers or other libraries.
>
> Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
> ---
> buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
> devtools/check-symbol-change.sh | 7 ++++
> devtools/checkpatches.sh | 38 +++++++++++++++++++
> devtools/libabigail.abignore | 5 +++
> drivers/meson.build | 2 +-
> lib/librte_eal/include/rte_compat.h | 13 +++++++
> lib/meson.build | 2 +-
> mk/internal/rte.compile-pre.mk | 3 ++
> mk/target/generic/rte.vars.mk | 1 +
> 9 files changed, 126 insertions(+), 2 deletions(-)
> create mode 100755 buildtools/check-internal-syms.sh
We can have a single script (let's say devtools/check-symbols.sh) that
contains both experimental and internal symbols.
> diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
> index ed2178e36..978979077 100755
> --- a/devtools/check-symbol-change.sh
> +++ b/devtools/check-symbol-change.sh
> @@ -91,6 +91,13 @@ check_for_rule_violations()
> if [ "$ar" = "add" ]
> then
>
> + if [ "$secname" = "INTERNAL" ]
> + then
> + # these are absolved from any further checking
> + echo "Skipping symbol $symname in INTERNAL"
> + continue
> + fi
> +
> if [ "$secname" = "unknown" ]
> then
> # Just inform the user of this occurrence, but
This only handles symbol additions to the INTERNAL section.
Other cases like moving or removing a INTERNAL symbol are not handled.
> diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
> index c30ce64cc..2df8d7f2c 100755
> --- a/devtools/checkpatches.sh
> +++ b/devtools/checkpatches.sh
> @@ -111,6 +111,36 @@ check_experimental_tags() { # <patch>
> return $res
> }
>
> +check_internal_tags() { # <patch>
> + res=0
> +
> + cat "$1" |awk '
> + BEGIN {
> + current_file = "";
> + ret = 0;
> + }
> + /^+++ b\// {
> + current_file = $2;
> + }
> + /^+.*__rte_internal/ {
> + if (current_file ~ ".c$" ) {
> + print "Please only put __rte_internal tags in " \
> + "headers ("current_file")";
> + ret = 1;
> + }
> + if ($1 != "+__rte_internal" || $2 != "") {
> + print "__rte_internal must appear alone on the line" \
> + " immediately preceding the return type of a function."
> + ret = 1;
> + }
> + }
> + END {
> + exit ret;
> + }' || res=1
> +
> + return $res
> +}
> +
> number=0
> range='origin/master..'
> quiet=false
> @@ -194,6 +224,14 @@ check () { # <patch> <commit> <title>
> ret=1
> fi
>
> + ! $verbose || printf '\nChecking __rte_internal tags:\n'
> + report=$(check_internal_tags "$tmpinput")
> + if [ $? -ne 0 ] ; then
> + $headline_printed || print_headline "$3"
> + printf '%s\n' "$report"
> + ret=1
> + fi
> +
> if [ "$tmpinput" != "$1" ]; then
> rm -f "$tmpinput"
> trap - INT
> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> index cd86d89ca..3e8e2ea74 100644
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> @@ -3,6 +3,11 @@
> [suppress_variable]
> symbol_version = EXPERIMENTAL
>
> +[suppress_function]
> + symbol_version = INTERNAL
> +[suppress_variable]
> + symbol_version = INTERNAL
> +
> ; Explicit ignore for driver-only ABI
> [suppress_type]
> name = rte_cryptodev_ops
> diff --git a/drivers/meson.build b/drivers/meson.build
> index 4d8f842ab..cac07161f 100644
> --- a/drivers/meson.build
> +++ b/drivers/meson.build
> @@ -20,7 +20,7 @@ dpdk_driver_classes = ['common',
> disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
> ).stdout().split()
>
> -default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
> +default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
Nit:
default_cflags = machine_args
default_cflags += ['-DALLOW_EXPERIMENTAL_API']
default_cflags += ['-DALLOW_INTERNAL_API']
> if cc.has_argument('-Wno-format-truncation')
> default_cflags += '-Wno-format-truncation'
> endif
More importantly on this file:
- drivers/meson.build is not updated to check for internal symbols, see:
https://git.dpdk.org/dpdk/tree/drivers/meson.build#n166
- For fully experimental libraries, we have a special so version:
https://git.dpdk.org/dpdk/tree/drivers/meson.build#n131
This will apply to common drivers that will be 100% internal.
Not sure if this is an issue.
> diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
> index 3eb33784b..4cd8f68d6 100644
> --- a/lib/librte_eal/include/rte_compat.h
> +++ b/lib/librte_eal/include/rte_compat.h
> @@ -19,4 +19,17 @@ __attribute__((section(".text.experimental")))
>
> #endif
>
> +#ifndef ALLOW_INTERNAL_API
> +
> +#define __rte_internal \
> +__attribute__((error("Symbol is not public ABI"), \
> +section(".text.internal")))
> +
> +#else
> +
> +#define __rte_internal \
> +__attribute__((section(".text.internal")))
> +
> +#endif
> +
> #endif /* _RTE_COMPAT_H_ */
> diff --git a/lib/meson.build b/lib/meson.build
> index c28b8df83..4d2f90d6a 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -38,7 +38,7 @@ if is_windows
> libraries = ['kvargs','eal'] # only supported libraries for windows
> endif
>
> -default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
> +default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
Same comments as for drivers/meson.build.
> diff --git a/mk/internal/rte.compile-pre.mk b/mk/internal/rte.compile-pre.mk
> index 82fe098f7..0369786a5 100644
> --- a/mk/internal/rte.compile-pre.mk
> +++ b/mk/internal/rte.compile-pre.mk
> @@ -58,6 +58,8 @@ C_TO_O_DISP = $(if $(V),"$(C_TO_O_STR)"," CC $(@)")
> endif
> EXPERIMENTAL_CHECK = $(RTE_SDK)/buildtools/check-experimental-syms.sh
> CHECK_EXPERIMENTAL = $(EXPERIMENTAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
> +INTERNAL_CHECK = $(RTE_SDK)/buildtools/check-internal-syms.sh
> +CHECK_INTERNAL = $(INTERNAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
With a single script, we can go with:
CHECK_SYMBOLS_SCRIPT = $(RTE_SDK)/buildtools/check-symbols.sh
CHECK_SYMBOLS = $(CHECK_SYMBOLS_SCRIPT) $(SRCDIR)/$(EXPORT_MAP) $@
>
> PMDINFO_GEN = $(RTE_SDK_BIN)/app/dpdk-pmdinfogen $@ $@.pmd.c
> PMDINFO_CC = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@.pmd.o $@.pmd.c
> @@ -76,6 +78,7 @@ C_TO_O_DO = @set -e; \
> $(C_TO_O) && \
> $(PMDINFO_TO_O) && \
> $(CHECK_EXPERIMENTAL) && \
> + $(CHECK_INTERNAL) && \
+ $(CHECK_SYMBOLS) && \
> echo $(C_TO_O_CMD) > $(call obj2cmd,$(@)) && \
> sed 's,'$@':,dep_'$@' =,' $(call obj2dep,$(@)).tmp > $(call obj2dep,$(@)) && \
> rm -f $(call obj2dep,$(@)).tmp
> diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
> index ec2672897..11b0418e5 100644
> --- a/mk/target/generic/rte.vars.mk
> +++ b/mk/target/generic/rte.vars.mk
> @@ -106,6 +106,7 @@ ifeq ($(BUILDING_RTE_SDK),1)
> # building sdk
> CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
> CFLAGS += -DALLOW_EXPERIMENTAL_API
> +CFLAGS += -DALLOW_INTERNAL_API
> else
> # if we are building an external application, include SDK's lib and
> # includes too
> --
> 2.26.2
>
We are missing updates on devtools/check-abi-version.sh and
devtools/update_version_map_abi.py.
--
David Marchand
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH v2] abi: change references to abi 20.0.1 to abi v21
2020-04-24 14:10 6% ` David Marchand
@ 2020-04-24 14:50 6% ` Ray Kinsella
2020-04-24 15:01 6% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-24 14:50 UTC (permalink / raw)
To: David Marchand, Dodji Seketeli
Cc: dev, Andrzej Ostruszka, Stephen Hemminger, Thomas Monjalon,
Neil Horman, Jingjing Wu, Wenzhuo Lu, Matan Azrad, Shahaf Shuler,
Viacheslav Ovsiienko, Jerin Jacob, Nithin Dabilpuram,
Alfredo Cardigliano, Mahipal Challa, Cristian Dumitrescu, Wang,
Haiyue
ah ok, the particular system I made the change on was Ubuntu 18.04.2.
which is libabigail 1.2.0.
Given we still support v19.11 on Ubuntu 18.04.2.
I think it's worthwhile keeping the suppression until v20.11?
Ray K
On 24/04/2020 15:10, David Marchand wrote:
> On Thu, Apr 23, 2020 at 8:48 AM Ray Kinsella <mdr@ashroe.eu> wrote:
>>
>> Change references to abi 20.0.1 to use abi v21, add myself as the map
>> file maintainer to more closely monitor future abi changes. Add
>> suppressions that were missed on changes to librte_lpm.
>
> About the lpm change below, this might be because you are using an old
> version of libabigail.
> I think the change went in:
> $ git describe --contains 215b7eb4
> libabigail-1.4~8
>
> I use either libabigail 1.7 or the current master (when testing Dodji
> enhancements).
>
>
>> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
>> index cd86d89ca..20c821cee 100644
>> --- a/devtools/libabigail.abignore
>> +++ b/devtools/libabigail.abignore
>> @@ -2,7 +2,6 @@
>> symbol_version = EXPERIMENTAL
>> [suppress_variable]
>> symbol_version = EXPERIMENTAL
>> -
>> ; Explicit ignore for driver-only ABI
>> [suppress_type]
>> name = rte_cryptodev_ops
>> @@ -18,3 +17,15 @@
>> [suppress_type]
>> type_kind = struct
>> name = rte_event_ring
>> +; Explicit ignore ABI 20.0.1
>> +[suppress_function]
>> + symbol_version = DPDK_20.0.1
>> +[suppress_variable]
>> + symbol_version = DPDK_20.0.1
>> +; Explicit ignore of const lpm6_lookup change
>> +[suppress_function]
>> + name = rte_lpm6_delete
>> + parameter = '1 uint8_t*
>> +[suppress_function]
>> + name = rte_lpm6_is_rule_present
>> + parameter = '1 uint8_t*
>
>
^ permalink raw reply [relevance 6%]
* Re: [dpdk-dev] [PATCH v2] abi: change references to abi 20.0.1 to abi v21
2020-04-23 6:41 21% ` [dpdk-dev] [PATCH v2] " Ray Kinsella
2020-04-24 9:15 6% ` Thomas Monjalon
@ 2020-04-24 14:10 6% ` David Marchand
2020-04-24 14:50 6% ` Ray Kinsella
1 sibling, 1 reply; 200+ results
From: David Marchand @ 2020-04-24 14:10 UTC (permalink / raw)
To: Ray Kinsella, Dodji Seketeli
Cc: dev, Andrzej Ostruszka, Stephen Hemminger, Thomas Monjalon,
Neil Horman, Jingjing Wu, Wenzhuo Lu, Matan Azrad, Shahaf Shuler,
Viacheslav Ovsiienko, Jerin Jacob, Nithin Dabilpuram,
Alfredo Cardigliano, Mahipal Challa, Cristian Dumitrescu, Wang,
Haiyue
On Thu, Apr 23, 2020 at 8:48 AM Ray Kinsella <mdr@ashroe.eu> wrote:
>
> Change references to abi 20.0.1 to use abi v21, add myself as the map
> file maintainer to more closely monitor future abi changes. Add
> suppressions that were missed on changes to librte_lpm.
About the lpm change below, this might be because you are using an old
version of libabigail.
I think the change went in:
$ git describe --contains 215b7eb4
libabigail-1.4~8
I use either libabigail 1.7 or the current master (when testing Dodji
enhancements).
> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
> index cd86d89ca..20c821cee 100644
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> @@ -2,7 +2,6 @@
> symbol_version = EXPERIMENTAL
> [suppress_variable]
> symbol_version = EXPERIMENTAL
> -
> ; Explicit ignore for driver-only ABI
> [suppress_type]
> name = rte_cryptodev_ops
> @@ -18,3 +17,15 @@
> [suppress_type]
> type_kind = struct
> name = rte_event_ring
> +; Explicit ignore ABI 20.0.1
> +[suppress_function]
> + symbol_version = DPDK_20.0.1
> +[suppress_variable]
> + symbol_version = DPDK_20.0.1
> +; Explicit ignore of const lpm6_lookup change
> +[suppress_function]
> + name = rte_lpm6_delete
> + parameter = '1 uint8_t*
> +[suppress_function]
> + name = rte_lpm6_is_rule_present
> + parameter = '1 uint8_t*
--
David Marchand
^ permalink raw reply [relevance 6%]
* Re: [dpdk-dev] [PATCH v2] abi: change references to abi 20.0.1 to abi v21
2020-04-23 6:41 21% ` [dpdk-dev] [PATCH v2] " Ray Kinsella
@ 2020-04-24 9:15 6% ` Thomas Monjalon
2020-04-24 14:10 6% ` David Marchand
1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2020-04-24 9:15 UTC (permalink / raw)
To: Ray Kinsella
Cc: dev, aostruszka, stephen, Neil Horman, Jingjing Wu, Wenzhuo Lu,
Matan Azrad, Shahaf Shuler, Viacheslav Ovsiienko, Jerin Jacob,
Nithin Dabilpuram, Alfredo Cardigliano, Mahipal Challa,
Cristian Dumitrescu
23/04/2020 08:41, Ray Kinsella:
> Change references to abi 20.0.1 to use abi v21, add myself as the map
> file maintainer to more closely monitor future abi changes. Add
> suppressions that were missed on changes to librte_lpm.
>
> Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
Please could you add a reference to the doc chapter stating this rule,
in the commit log? Thanks
^ permalink raw reply [relevance 6%]
* [dpdk-dev] DPDK Release Status Meeting 23/04/2020
@ 2020-04-23 13:08 4% Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2020-04-23 13:08 UTC (permalink / raw)
To: dpdk-dev; +Cc: Thomas Monjalon
Minutes 23 April 2020
---------------------
Agenda:
* Release Dates
* Subtrees
Participants:
* Arm
* Debian/Microsoft
* Intel
* Marvell
* Mellanox
* NXP
* Red Hat
Release Dates
-------------
* v20.05 dates:
* Integration/Merge/RC1 pushed to *Friday 24 April 2020*
* Release: Wednesday 20 May 2020
* PRC holiday on 1-5 May, need to take into account for validation effort
Subtrees
--------
* main
* crypto tree pulled, in progress of pulling next-net
* Not able to review rte_graph, planning to merge it in -rc2
* Merged ring patches from Konstantin and RCU patches from Honnappa
* Looking trace series, planning to have them in -rc1
* Some fixes for eal and vfio merged
* Checking fixes and changes related to ABI, from Ray and Neil
* gcc10 support
* Some fixes are missing
* Fixes can go after -rc1
* Need a long term plan for the new compiler support
* CI checks exists for new compilers
* Hash library not reviewed
* Some patches related atomic discussed in techboard,
not much to do for the release
* Windows, some patches was not ready postponed to 20.08
* Telemetry may go in -rc2
* There will be a new version, possibly today, to make it more generic
* Call to review for Windows patches
* next-net
* closed the tree yesterday, ready for -rc1
* next-crypto
* pulled for -rc1
* There are two existing issues
* Cryptodev ABI versioning, Fiona working on
* Not sure if it will be ready for -rc1
* rte_security issue, mainline is broken as of now
* Fix is in the mail list, should be merged quickly
* next-eventdev
* No more patches for -rc1, already pulled to main
* next-virtio
* Pulled for -rc1
* Some fixes for next -rc
* Mellanox vdpa queue stats patch postponed to next release
* Mellanox vdpa virtq patch requires rebase, it may wait next -rc
* Packet ring vectorized path patch under review, should be OK for -rc2
* Good to ask vector implementation from all architectures
* next-net-intel
* Most patches merged, only some fixes for -rc2
* fm10k still has build errors, postponed to -rc2
* next-net-mlx
* Some small fixes for -rc2
* next-net-mrvl
* All patches merged for -rc1
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%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-22 12:18 4% ` Thomas Monjalon
2020-04-22 13:19 4% ` Ray Kinsella
@ 2020-04-23 11:03 7% ` Neil Horman
1 sibling, 0 replies; 200+ results
From: Neil Horman @ 2020-04-23 11:03 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Ray Kinsella, dev, david.marchand
On Wed, Apr 22, 2020 at 02:18:05PM +0200, Thomas Monjalon wrote:
> 22/04/2020 14:07, Neil Horman:
> > On Wed, Apr 22, 2020 at 12:43:44PM +0100, Ray Kinsella wrote:
> > > On 21/04/2020 22:42, Thomas Monjalon wrote:
> > > > 21/04/2020 20:56, Neil Horman:
> > > >> On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
> > > >>> 21/04/2020 13:12, Neil Horman:
> > > >>>> On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> > > >>>>> On 17/04/2020 13:10, Thomas Monjalon wrote:
> > > >>>>>> 17/04/2020 13:47, Ray Kinsella:
> > > >>>>>>> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > > >>>>>>>> 17/04/2020 12:11, Ray Kinsella:
> > > >>>>>>>>> check-abi.sh appears to be backward step in terms of usability.
> > > >>>>>>>>
> > > >>>>>>>> No, check-abi.sh benefits from a nice integration in build scripts.
> > > >>>>>>>> See below.
> > > >>>>>>>>
> > > >>>>>>>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> > > >>>>>>>>> And it will do the build, install, dump and comparison for me.
> > > >>>>>>>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> > > >>>>>>>>>
> > > >>>>>>>>> With check-abi on the other hand, I need to the build and install myself.
> > > >>>>>>>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> > > >>>>>>>>> It silently fails when it doesn't find any ...
> > > >>>>>>>>>
> > > >>>>>>>>> Do I run abi-dumper on the so's myself, or how does it work?
> > > >>>>>>>>
> > > >>>>>>>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > > >>>>>>>> Probably we should document usage in these scripts.
> > > >>>>>>>
> > > >>>>>>> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> > > >>>>>>> Any tips or tricks would be welcome.
> > > >>>>>>
> > > >>>>>> export DPDK_ABI_REF_VERSION=v20.02
> > > >>>>>> or
> > > >>>>>> export DPDK_ABI_REF_VERSION=v19.11
> > > >>>>>>
> > > >>>>>> Depends on which compatibility you want to test...
> > > >>>>>>
> > > >>>>>
> > > >>>>> Few things ...
> > > >>>>>
> > > >>>>> 1. test-meson-build.sh keep barfing complaining about reference paths.
> > > >>>>> ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> > > >>>>>
> > > >>>>> Under the hood, ninja install is failing complaining that it needs an absolute path.
> > > >>>>> I fixed this in test_meson_build.sh and will send a patch in a minute.
> > > >>>>> Though it's strange no-one else has seen it?
> > > >>>>>
> > > >>>>> 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> > > >>>>>
> > > >>>>> 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> > > >>>>> In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> > > >>>>> I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> > > >>>>>
> > > >>>> I think this code in test-meson-build.sh should probably be fixed:
> > > >>>>
> > > >>>> if [ ! -d $abirefdir/src ]; then
> > > >>>> git clone --local --no-hardlinks \
> > > >>>> --single-branch \
> > > >>>> -b $DPDK_ABI_REF_VERSION \
> > > >>>> $srcdir $abirefdir/src
> > > >>>> fi
> > > >>>>
> > > >>>> Like you noted, using -b allows us to checkout a tag/branch in the cloned
> > > >>>> repository but requires that it exist locally. We should probably prefix the
> > > >>>> checkout with a git fetch --tags
> > > >>>
> > > >>> I don't understand your concern.
> > > >>> A reference is an older version, so it should be in the git tree.
> > > >>>
> > > >> yes, but not unless you've done a recent pull or fetch. If you set
> > > >> DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
> > > >> updated the tree, it won't be there (which it sounds like what is being
> > > >> encountered here). You can fix that by doing a git pull or git fetch prior to
> > > >> running this script (or internal to the script)
> > > >
> > > > Sorry I still don't understand the case.
> > > > We want to compare the current version C with a reference R which is older.
> > > > If the reference R is not in the tree, it means the version C is not in the tree.
> > > > But C is the current version, so it is in the tree by definition.
> > > >
> > >
> > > So I can just relate my experience ....
> > >
> > > root@silpixa00395806:/build/dpdk# DPDK_ABI_REF_VERSION=HEAD~1 ./devtools/test-meson-builds.sh
> > > ninja -C ./build-gcc-static
> > > ninja: Entering directory `./build-gcc-static'
> > > [1766/2204] Compiling C object 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_channel_monitor.c.o'.
> > > ../examples/vm_power_manager/channel_monitor.c:22:9: note: #pragma message: Jansson dev libs unavailable, not including JSON parsing
> > > #pragma message "Jansson dev libs unavailable, not including JSON parsing"
> > > ^~~~~~~
> > > [2204/2204] Linking target drivers/librte_pmd_softnic.so.20.0.2.
> > > Cloning into 'reference/HEAD~1/src'...
> > > warning: Could not find remote branch HEAD~1 to clone.
> > > fatal: Remote branch HEAD~1 not found in upstream origin
> > > fatal: The remote end hung up unexpectedly
> > >
> > Ah, So its not the problem i was describing, I think the problem you are seeing
> > is that the -b option only operates on branches and tags, not arbitrary git
> > revisions.
> >
> > To fix that, what we probably need to do is alter test-build.sh and
> > test-meson-build.sh such that the git clone operation is preceded by something
> > like this:
> > git tag ABI_CHECK_TAG $DPDK_ABI_REF_VERSION
> >
> > git clone ....
> >
> > git tag -d ABI_CHECK_TAG
> >
> > Doing so will guarantee that the source tree has a tag reference that the git
> > clone operation can use to do a checkout with a -b option on.
>
> I don't see the benefit of such test.
> Can we just document that the reference must be an existing tag?
>
We could, but like Ray said, if you want people to use this, you'll want to make
it easy for them. Many people will want to test the ABI against a well known
tag, but some are going to want to test against an arbitrary version (i.e.
against the merge base of their feature branch and the point they branched
from), which means they will attempt to check against an arbitrary hash value or
non-tag symbolic reference. Theres no reason we can't enable that, the only
reason it doesn't work is because of an ideosyncracy of the git branch command,
and the above fixes that.
Neil
>
>
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-22 12:16 4% ` Thomas Monjalon
@ 2020-04-23 10:57 4% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2020-04-23 10:57 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Ray Kinsella, dev, david.marchand
On Wed, Apr 22, 2020 at 02:16:57PM +0200, Thomas Monjalon wrote:
> 22/04/2020 14:01, Neil Horman:
> > On Tue, Apr 21, 2020 at 11:42:42PM +0200, Thomas Monjalon wrote:
> > > 21/04/2020 20:56, Neil Horman:
> > > > On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
> > > > > 21/04/2020 13:12, Neil Horman:
> > > > > > On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> > > > > > > On 17/04/2020 13:10, Thomas Monjalon wrote:
> > > > > > > > 17/04/2020 13:47, Ray Kinsella:
> > > > > > > >> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > > > > > > >>> 17/04/2020 12:11, Ray Kinsella:
> > > > > > > >>>> check-abi.sh appears to be backward step in terms of usability.
> > > > > > > >>>
> > > > > > > >>> No, check-abi.sh benefits from a nice integration in build scripts.
> > > > > > > >>> See below.
> > > > > > > >>>
> > > > > > > >>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> > > > > > > >>>> And it will do the build, install, dump and comparison for me.
> > > > > > > >>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> > > > > > > >>>>
> > > > > > > >>>> With check-abi on the other hand, I need to the build and install myself.
> > > > > > > >>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> > > > > > > >>>> It silently fails when it doesn't find any ...
> > > > > > > >>>>
> > > > > > > >>>> Do I run abi-dumper on the so's myself, or how does it work?
> > > > > > > >>>
> > > > > > > >>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > > > > > > >>> Probably we should document usage in these scripts.
> > > > > > > >>
> > > > > > > >> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> > > > > > > >> Any tips or tricks would be welcome.
> > > > > > > >
> > > > > > > > export DPDK_ABI_REF_VERSION=v20.02
> > > > > > > > or
> > > > > > > > export DPDK_ABI_REF_VERSION=v19.11
> > > > > > > >
> > > > > > > > Depends on which compatibility you want to test...
> > > > > > > >
> > > > > > >
> > > > > > > Few things ...
> > > > > > >
> > > > > > > 1. test-meson-build.sh keep barfing complaining about reference paths.
> > > > > > > ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> > > > > > >
> > > > > > > Under the hood, ninja install is failing complaining that it needs an absolute path.
> > > > > > > I fixed this in test_meson_build.sh and will send a patch in a minute.
> > > > > > > Though it's strange no-one else has seen it?
> > > > > > >
> > > > > > > 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> > > > > > >
> > > > > > > 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> > > > > > > In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> > > > > > > I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> > > > > > >
> > > > > > I think this code in test-meson-build.sh should probably be fixed:
> > > > > >
> > > > > > if [ ! -d $abirefdir/src ]; then
> > > > > > git clone --local --no-hardlinks \
> > > > > > --single-branch \
> > > > > > -b $DPDK_ABI_REF_VERSION \
> > > > > > $srcdir $abirefdir/src
> > > > > > fi
> > > > > >
> > > > > > Like you noted, using -b allows us to checkout a tag/branch in the cloned
> > > > > > repository but requires that it exist locally. We should probably prefix the
> > > > > > checkout with a git fetch --tags
> > > > >
> > > > > I don't understand your concern.
> > > > > A reference is an older version, so it should be in the git tree.
> > > > >
> > > > yes, but not unless you've done a recent pull or fetch. If you set
> > > > DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
> > > > updated the tree, it won't be there (which it sounds like what is being
> > > > encountered here). You can fix that by doing a git pull or git fetch prior to
> > > > running this script (or internal to the script)
> > >
> > > Sorry I still don't understand the case.
> > > We want to compare the current version C with a reference R which is older.
> > > If the reference R is not in the tree, it means the version C is not in the tree.
> > > But C is the current version, so it is in the tree by definition.
> > >
> >
> >
> > +---+
> > | |
> > +---+ | | DPDK 20.11
> > | |Feature Branch commit +-+-+
> > | | |
> > +-+-+ +---+ +-v-+
> > | | | master HEAD | | master HEAD
> > | +-+-+ +-+-+
> > | | |
> > | | |
> > | +-v-+ +-v-+
> > +---->+ | DPDK 19.11 | | DPDK 19.11
> > +---+ +---+
> > X X X X
> > XXXXXXX XXXXXXXXX XXXXXXX XXXXXXXXX
> > XXX XX XXX XX
> > XXXX XXXX
> >
> > Local GIT copy DPDK.ORG
> >
> >
> >
> > If a user clones from dpdk.org when dpdk 19.11 is tagged in the tree, or any
> > time before dpdk 20.11 is tagged, then creates a feature branch, they may want
> > to compare their abi to the latest stable version. If they check dpdk.org and
> > see that dpdk 20.11 is the latest tag in the tree, they can run check-abi.sh
> > with the reference tag specified as 20.11, which exists in the dpdk.org tree,
> > but may not have been pulled into their local copy yet.
> >
> > I'm not saying this is definately what happened, but it would explain the
> > reported observations.
>
> OK now I understand.
> The user specified a reference which is not in his local tree.
> I vote for considering this case as an user mistake,
> and document it as a limitation of the tool integration in our build
> testing scripts.
>
I'd be fine with that, given that this turned out to not be rays issue.
Neil
>
>
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v1] abi: document reasons behind the three part versioning
@ 2020-04-23 10:12 24% Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-23 10:12 UTC (permalink / raw)
To: dev
Cc: ferruh.yigit, Ray Kinsella, Bruce Richardson, John McNamara,
Marko Kovacevic
Clarify the reasons behind the three part version numbering scheme.
Documents the fixes made in f26c2b3.
Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/contributing/abi_policy.rst | 3 ++-
doc/guides/rel_notes/release_20_05.rst | 12 ++++++++++++
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/doc/guides/contributing/abi_policy.rst b/doc/guides/contributing/abi_policy.rst
index 05ca959..86e7dd9 100644
--- a/doc/guides/contributing/abi_policy.rst
+++ b/doc/guides/contributing/abi_policy.rst
@@ -39,7 +39,8 @@ General Guidelines
releases, over a number of release cycles. This change begins with
maintaining ABI stability through one year of DPDK releases starting from
DPDK 19.11. This policy will be reviewed in 2020, with intention of
- lengthening the stability period.
+ lengthening the stability period. Additional implementation detail can be
+ found in the :ref:`release notes <20_05_abi_changes>`.
What is an ABI?
~~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index 7f2049a..8653f7a 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -164,6 +164,7 @@ API Changes
Also, make sure to start the actual text at the margin.
=========================================================
+.. _20_05_abi_changes:
ABI Changes
-----------
@@ -180,6 +181,17 @@ ABI Changes
Also, make sure to start the actual text at the margin.
=========================================================
+* The soname for each stable ABI version should be just the ABI version major
+ number without the minor number. Unfortunately both major and minor were used
+ in the v19.11 release, causing version v20.x releases to be incompatible with
+ ABI v20.0.
+
+ The `commit f26c2b3
+ <https://git.dpdk.org/dpdk/commit/?id=f26c2b39b271cdcd857ba518c5e48c78cb1c30af>`_
+ fixed the issue by switching from 2-part to 3-part ABI version numbers so that
+ we can keep v20.0 as soname and using the final digits to identify the DPDK
+ 20.x releases which are ABI compatible.
+
* No ABI change that would break compatibility with DPDK 20.02 and 19.11.
--
2.7.4
^ permalink raw reply [relevance 24%]
* [dpdk-dev] [PATCH v2] abi: change references to abi 20.0.1 to abi v21
2020-04-20 9:34 15% [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21 Ray Kinsella
2020-04-20 11:57 9% ` Ray Kinsella
@ 2020-04-23 6:41 21% ` Ray Kinsella
2020-04-24 9:15 6% ` Thomas Monjalon
2020-04-24 14:10 6% ` David Marchand
2020-04-27 9:06 11% ` [dpdk-dev] [PATCH v3] " Ray Kinsella
2020-04-27 13:45 10% ` [dpdk-dev] [PATCH v4] " Ray Kinsella
3 siblings, 2 replies; 200+ results
From: Ray Kinsella @ 2020-04-23 6:41 UTC (permalink / raw)
To: dev
Cc: aostruszka, stephen, Ray Kinsella, Thomas Monjalon, Neil Horman,
Jingjing Wu, Wenzhuo Lu, Matan Azrad, Shahaf Shuler,
Viacheslav Ovsiienko, Jerin Jacob, Nithin Dabilpuram,
Alfredo Cardigliano, Mahipal Challa, Cristian Dumitrescu
Change references to abi 20.0.1 to use abi v21, add myself as the map
file maintainer to more closely monitor future abi changes. Add
suppressions that were missed on changes to librte_lpm.
Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
MAINTAINERS | 2 ++
devtools/libabigail.abignore | 13 ++++++++++++-
drivers/common/iavf/rte_common_iavf_version.map | 2 +-
drivers/common/mlx5/rte_common_mlx5_version.map | 2 +-
.../octeontx2/rte_common_octeontx2_version.map | 2 +-
drivers/net/ionic/rte_pmd_ionic_version.map | 2 +-
.../rte_rawdev_octeontx2_ep_version.map | 2 +-
drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map | 2 +-
lib/librte_meter/rte_meter_version.map | 2 +-
9 files changed, 21 insertions(+), 8 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 7b81e2d1b..c24fd374d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -86,6 +86,8 @@ F: doc/
ABI Policy
M: Ray Kinsella <mdr@ashroe.eu>
F: doc/guides/contributing/abi_*.rst
+F: drivers/*/*/*.map
+F: lib/*/*.map
Developers and Maintainers Tools
M: Thomas Monjalon <thomas@monjalon.net>
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index cd86d89ca..20c821cee 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -2,7 +2,6 @@
symbol_version = EXPERIMENTAL
[suppress_variable]
symbol_version = EXPERIMENTAL
-
; Explicit ignore for driver-only ABI
[suppress_type]
name = rte_cryptodev_ops
@@ -18,3 +17,15 @@
[suppress_type]
type_kind = struct
name = rte_event_ring
+; Explicit ignore ABI 20.0.1
+[suppress_function]
+ symbol_version = DPDK_20.0.1
+[suppress_variable]
+ symbol_version = DPDK_20.0.1
+; Explicit ignore of const lpm6_lookup change
+[suppress_function]
+ name = rte_lpm6_delete
+ parameter = '1 uint8_t*
+[suppress_function]
+ name = rte_lpm6_is_rule_present
+ parameter = '1 uint8_t*
diff --git a/drivers/common/iavf/rte_common_iavf_version.map b/drivers/common/iavf/rte_common_iavf_version.map
index 2f11d67c0..92ceac108 100644
--- a/drivers/common/iavf/rte_common_iavf_version.map
+++ b/drivers/common/iavf/rte_common_iavf_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
global:
iavf_init_adminq;
diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map
index aede2a0a5..fe151fe0d 100644
--- a/drivers/common/mlx5/rte_common_mlx5_version.map
+++ b/drivers/common/mlx5/rte_common_mlx5_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
global:
mlx5_class_get;
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 8f2404bd9..01279c339 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -34,7 +34,7 @@ DPDK_20.0 {
local: *;
};
-DPDK_20.0.1 {
+DPDK_21 {
global:
otx2_eth_dev_is_sec_capable;
diff --git a/drivers/net/ionic/rte_pmd_ionic_version.map b/drivers/net/ionic/rte_pmd_ionic_version.map
index bc8fd6d4d..acdaf587d 100644
--- a/drivers/net/ionic/rte_pmd_ionic_version.map
+++ b/drivers/net/ionic/rte_pmd_ionic_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
local: *;
};
diff --git a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
index bc8fd6d4d..acdaf587d 100644
--- a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
+++ b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21 {
local: *;
};
diff --git a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
index 179f7f1ae..4a76d1d52 100644
--- a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
+++ b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
@@ -1,3 +1,3 @@
-DPDK_20.0.1 {
+DPDK_21 {
local: *;
};
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index fc12cc0bf..2c7dadbca 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -13,7 +13,7 @@ DPDK_20.0 {
local: *;
};
-DPDK_20.0.1 {
+DPDK_21 {
global:
rte_meter_trtcm_rfc4115_color_aware_check;
--
2.17.1
^ permalink raw reply [relevance 21%]
* [dpdk-dev] [PATCH v5 1/1] eal: add internal ABI marking support
2020-04-23 3:19 4% ` [dpdk-dev] [PATCH v5 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
@ 2020-04-23 3:19 15% ` Haiyue Wang
2020-04-24 14:52 7% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-23 3:19 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Introduce __rte_internal tag to mark internal ABI function which is used
by the drivers or other libraries.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
devtools/check-symbol-change.sh | 7 ++++
devtools/checkpatches.sh | 38 +++++++++++++++++++
devtools/libabigail.abignore | 5 +++
drivers/meson.build | 2 +-
lib/librte_eal/include/rte_compat.h | 13 +++++++
lib/meson.build | 2 +-
mk/internal/rte.compile-pre.mk | 3 ++
mk/target/generic/rte.vars.mk | 1 +
9 files changed, 126 insertions(+), 2 deletions(-)
create mode 100755 buildtools/check-internal-syms.sh
diff --git a/buildtools/check-internal-syms.sh b/buildtools/check-internal-syms.sh
new file mode 100755
index 000000000..5043acf87
--- /dev/null
+++ b/buildtools/check-internal-syms.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# SPDX-License-Identifier: BSD-3-Clause
+
+MAPFILE=$1
+OBJFILE=$2
+
+LIST_SYMBOL=$(dirname $(readlink -f $0))/map-list-symbol.sh
+
+# added check for "make -C test/" usage
+if [ ! -e $MAPFILE ] || [ ! -f $OBJFILE ]
+then
+ exit 0
+fi
+
+if [ -d $MAPFILE ]
+then
+ exit 0
+fi
+
+DUMPFILE=$(mktemp -t dpdk.${0##*/}.XXX.objdump)
+trap 'rm -f "$DUMPFILE"' EXIT
+objdump -t $OBJFILE >$DUMPFILE
+
+ret=0
+for SYM in `$LIST_SYMBOL -S INTERNAL $MAPFILE |cut -d ' ' -f 3`
+do
+ if grep -q "\.text.*[[:space:]]$SYM$" $DUMPFILE &&
+ ! grep -q "\.text\.internal.*[[:space:]]$SYM$" $DUMPFILE
+ then
+ cat >&2 <<- END_OF_MESSAGE
+ $SYM is not flagged as internal
+ but is listed in version map
+ Please add __rte_internal to the definition of $SYM
+ END_OF_MESSAGE
+ ret=1
+ fi
+done
+
+# Filter out symbols suffixed with a . for icc
+for SYM in `awk '{
+ if ($2 != "l" && $4 == ".text.internal" && !($NF ~ /\.$/)) {
+ print $NF
+ }
+}' $DUMPFILE`
+do
+ $LIST_SYMBOL -S INTERNAL -s $SYM -q $MAPFILE || {
+ cat >&2 <<- END_OF_MESSAGE
+ $SYM is flagged as internal
+ but is not listed in version map
+ Please add $SYM to the version map
+ END_OF_MESSAGE
+ ret=1
+ }
+done
+
+exit $ret
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
index ed2178e36..978979077 100755
--- a/devtools/check-symbol-change.sh
+++ b/devtools/check-symbol-change.sh
@@ -91,6 +91,13 @@ check_for_rule_violations()
if [ "$ar" = "add" ]
then
+ if [ "$secname" = "INTERNAL" ]
+ then
+ # these are absolved from any further checking
+ echo "Skipping symbol $symname in INTERNAL"
+ continue
+ fi
+
if [ "$secname" = "unknown" ]
then
# Just inform the user of this occurrence, but
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index c30ce64cc..2df8d7f2c 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -111,6 +111,36 @@ check_experimental_tags() { # <patch>
return $res
}
+check_internal_tags() { # <patch>
+ res=0
+
+ cat "$1" |awk '
+ BEGIN {
+ current_file = "";
+ ret = 0;
+ }
+ /^+++ b\// {
+ current_file = $2;
+ }
+ /^+.*__rte_internal/ {
+ if (current_file ~ ".c$" ) {
+ print "Please only put __rte_internal tags in " \
+ "headers ("current_file")";
+ ret = 1;
+ }
+ if ($1 != "+__rte_internal" || $2 != "") {
+ print "__rte_internal must appear alone on the line" \
+ " immediately preceding the return type of a function."
+ ret = 1;
+ }
+ }
+ END {
+ exit ret;
+ }' || res=1
+
+ return $res
+}
+
number=0
range='origin/master..'
quiet=false
@@ -194,6 +224,14 @@ check () { # <patch> <commit> <title>
ret=1
fi
+ ! $verbose || printf '\nChecking __rte_internal tags:\n'
+ report=$(check_internal_tags "$tmpinput")
+ if [ $? -ne 0 ] ; then
+ $headline_printed || print_headline "$3"
+ printf '%s\n' "$report"
+ ret=1
+ fi
+
if [ "$tmpinput" != "$1" ]; then
rm -f "$tmpinput"
trap - INT
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index cd86d89ca..3e8e2ea74 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -3,6 +3,11 @@
[suppress_variable]
symbol_version = EXPERIMENTAL
+[suppress_function]
+ symbol_version = INTERNAL
+[suppress_variable]
+ symbol_version = INTERNAL
+
; Explicit ignore for driver-only ABI
[suppress_type]
name = rte_cryptodev_ops
diff --git a/drivers/meson.build b/drivers/meson.build
index 4d8f842ab..cac07161f 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -20,7 +20,7 @@ dpdk_driver_classes = ['common',
disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
).stdout().split()
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
index 3eb33784b..4cd8f68d6 100644
--- a/lib/librte_eal/include/rte_compat.h
+++ b/lib/librte_eal/include/rte_compat.h
@@ -19,4 +19,17 @@ __attribute__((section(".text.experimental")))
#endif
+#ifndef ALLOW_INTERNAL_API
+
+#define __rte_internal \
+__attribute__((error("Symbol is not public ABI"), \
+section(".text.internal")))
+
+#else
+
+#define __rte_internal \
+__attribute__((section(".text.internal")))
+
+#endif
+
#endif /* _RTE_COMPAT_H_ */
diff --git a/lib/meson.build b/lib/meson.build
index c28b8df83..4d2f90d6a 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -38,7 +38,7 @@ if is_windows
libraries = ['kvargs','eal'] # only supported libraries for windows
endif
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/mk/internal/rte.compile-pre.mk b/mk/internal/rte.compile-pre.mk
index 82fe098f7..0369786a5 100644
--- a/mk/internal/rte.compile-pre.mk
+++ b/mk/internal/rte.compile-pre.mk
@@ -58,6 +58,8 @@ C_TO_O_DISP = $(if $(V),"$(C_TO_O_STR)"," CC $(@)")
endif
EXPERIMENTAL_CHECK = $(RTE_SDK)/buildtools/check-experimental-syms.sh
CHECK_EXPERIMENTAL = $(EXPERIMENTAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
+INTERNAL_CHECK = $(RTE_SDK)/buildtools/check-internal-syms.sh
+CHECK_INTERNAL = $(INTERNAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
PMDINFO_GEN = $(RTE_SDK_BIN)/app/dpdk-pmdinfogen $@ $@.pmd.c
PMDINFO_CC = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@.pmd.o $@.pmd.c
@@ -76,6 +78,7 @@ C_TO_O_DO = @set -e; \
$(C_TO_O) && \
$(PMDINFO_TO_O) && \
$(CHECK_EXPERIMENTAL) && \
+ $(CHECK_INTERNAL) && \
echo $(C_TO_O_CMD) > $(call obj2cmd,$(@)) && \
sed 's,'$@':,dep_'$@' =,' $(call obj2dep,$(@)).tmp > $(call obj2dep,$(@)) && \
rm -f $(call obj2dep,$(@)).tmp
diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
index ec2672897..11b0418e5 100644
--- a/mk/target/generic/rte.vars.mk
+++ b/mk/target/generic/rte.vars.mk
@@ -106,6 +106,7 @@ ifeq ($(BUILDING_RTE_SDK),1)
# building sdk
CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -DALLOW_INTERNAL_API
else
# if we are building an external application, include SDK's lib and
# includes too
--
2.26.2
^ permalink raw reply [relevance 15%]
* [dpdk-dev] [PATCH v5 0/1] dpdk: introduce __rte_internal tag
` (2 preceding siblings ...)
2020-04-22 16:37 4% ` [dpdk-dev] [PATCH v4 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
@ 2020-04-23 3:19 4% ` Haiyue Wang
2020-04-23 3:19 15% ` [dpdk-dev] [PATCH v5 1/1] eal: add internal ABI marking support Haiyue Wang
2020-04-25 6:04 5% ` [dpdk-dev] [PATCH v6 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
5 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-23 3:19 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Move the internal function into INTERNAL session to avoid the ABI
checking, and it is only used for DPDK drivers or related library.
__rte_internal funA
INTERNAL {
global:
funA
};
v5: add the checkpatch for __rte_internal style
v4: add the ABI check suppression rules
v3: based on Neil's v2 patch https://patchwork.dpdk.org/cover/54771/
Use the ALLOW_INTERNAL_API to mark this new feature.
Haiyue Wang (1):
eal: add internal ABI marking support
buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
devtools/check-symbol-change.sh | 7 ++++
devtools/checkpatches.sh | 38 +++++++++++++++++++
devtools/libabigail.abignore | 5 +++
drivers/meson.build | 2 +-
lib/librte_eal/include/rte_compat.h | 13 +++++++
lib/meson.build | 2 +-
mk/internal/rte.compile-pre.mk | 3 ++
mk/target/generic/rte.vars.mk | 1 +
9 files changed, 126 insertions(+), 2 deletions(-)
create mode 100755 buildtools/check-internal-syms.sh
--
2.26.2
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 10/10] eal/windows: implement basic memory management
@ 2020-04-23 1:00 3% ` Dmitry Kozlyuk
0 siblings, 0 replies; 200+ results
From: Dmitry Kozlyuk @ 2020-04-23 1:00 UTC (permalink / raw)
To: Ranjit Menon
Cc: dev, Dmitry Malloy (MESHCHANINOV),
Narcisa Ana Maria Vasile, Fady Bader, Tal Shnaiderman,
Thomas Monjalon, Harini Ramakrishnan, Omar Cardona, Kadam,
Pallavi, Mcnamara, John, Kovacevic, Marko, Burakov, Anatoly,
Richardson, Bruce
On 2020-04-16 11:34 GMT-0700 Ranjit Menon wrote:
[snip]
> > --- /dev/null
> > +++ b/lib/librte_eal/windows/include/rte_virt2phys.h
[snip]
>
> This file is a duplicate of: <kmods>: windows/virt2phys/virt2phys.h
> This is by design, since it documents the driver interface.
>
> So, to prevent the two files going out-of-sync, should we:
> 1. Make the two filenames the same?
> 2. Add comments to both files referencing each other and the need to
> keep them both in sync?
> 3. Do both (1) and (2)?
>
> This will also be an issue for the upcoming Windows netuio kernel driver
> and I reckon this could be an issue for Linux kernel modules too.
>
> Thoughts?
I guess it won't be much of an issue in practice. When you edit driver
interface you're already considering user-mode and kernel interaction, by
definition of that interface, so you can't forget about the counterpart.
I'd be more worried about ABI, because memory corruption in driver will crash
the system, being hard to debug. Can we leverage abigail for these interfaces?
--
Dmitry Kozlyuk
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v7 00/32] DPDK Trace support
2020-04-19 10:01 1% ` [dpdk-dev] [PATCH v6 " jerinj
@ 2020-04-22 19:03 1% ` jerinj
1 sibling, 0 replies; 200+ results
From: jerinj @ 2020-04-22 19:03 UTC (permalink / raw)
Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
skori, Jerin Jacob
From: Jerin Jacob <jerinj@marvell.com>
v7
~~
1) Remove "meson: add libatomic as a global dependency for i686 clang"
patch from series as it already applied on master.
2) Doc improvements (Thomas)
Based on http://patches.dpdk.org/patch/68907/ comments.
3) Change tracepoint name(Thomas)
from:
rte_trace_<library_name>_[<domain>_]<name>
to:
rte_<library_name>_trace_[<domain>_]<name>
4) To align with item (3), the trace filename changed. Example:
from:
lib/librte_mempool/rte_trace_mempool.h
to:
lib/librte_mempool/rte_mempool_trace.h
5) change name of performance test case from "trace_perf" to
"test_perf_autotest"
to align with other performance test case name.
6) Add UT and performance test case in meson test infra(David)
7) Remove all the instance of if (.._is_enabled() == false) to if (!.._is_enabled())(David)
8) Fix missing alphabetical sorting in header files
in "eal/trace: implement trace operation APIs patch" (David)
9) trace_point_is_invalid() function cleanup(David)
V6
~~
Following changes are based on David's feedback.
1) Changed rte_trace_t to rte_trace_point_t
2) Reworked the header file to have following API name and filename changes
rte_trace.h has following trace control APIs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a) rte_trace_is_enabled()
b) rte_trace_mode_set()
c) rte_trace_mode_get()
d) rte_trace_pattern()
e) rte_trace_regexp()
f) rte_trace_save()
g) rte_trace_metadata_dump()
h) rte_trace_dump()
rte_trace_point.h has following tracepoint related APIs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a) rte_trace_point_enable()
b) rte_trace_point_disable()
c) rte_trace_point_is_enabled()
d) rte_trace_point_lookup()
e) rte_trace_point_emit_*()
f) RTE_TRACE_POINT_* macros
3) made rte_trace_fp_enabled() as internal.
4) Added common macros to have rte_trace_point_emit_* definition at
single place a.k.a more common code now.
5) git grep -l rte_trace_ctf |xargs sed -i -e
's/rte_trace_ctf_/rte_tracepoint_emit_/g'.
6) Added the reason new section for tracepoint in git commit log
7) Sorted symbols alphabetic order in rte_eal_version.map file.
8) Fix snprint return handling bug in __rte_trace_point_emit_field() function.
9) Doc: added newline for section titles.
10) ctf_field and ctf_count made it as static.
v5
~~
Following API rework based David and Thomas feedback.
1) Rename - "Shell pattern" to "Globbing pattern"
2) Remove the log "level" notion from trace library.
3) Remove rte_trace_global_[level/mode]* API from trace library.
4) EAL command line arg to --trace=regex/globing from --trace-level=regex/globing:level
5) Remove "@b EXPERIMENTAL: this API may change without prior notice" from each functions.
6) Use FP instead of DP for fastpath reference.
7) Updated documentation to reflect the above rework.
8) Updated UT to to reflect the above rework.
8) Updated UT for a FP trace point emit.
9) Updated performance test case for a FP trace point emission.
10) Updated git commit comments to reflect the above rework.
v4:
~~
1) Rebased to master.
2) Adapted to latest EAL directory structure change.
3) Fix possible build issue with out of tree application wherein
it does not define -DALLOW_EXPERIMENTAL_API. Fixed by making
fast path trace functions as NOP as it was getting included
in the inline functions of ethdev,mempool, cryptodev, etc(David)
4) Removed DALLOW_EXPERIMENTAL_API definition from individual driver files.
Now it set as global using http://patches.dpdk.org/patch/67758/ patch (David)
5) Added new meson option(-Denable_trace_dp=true)for enabling the datapath trace point (David, Bruce)
6) Changed the authorship and Rewrote the programmer's guide based on the below feedback(Thomas)
http://patches.dpdk.org/patch/67352/
v3:
~~
1) Fix the following build issues reported by CI
http://mails.dpdk.org/archives/test-report/2020-March/122060.html
a) clang + i686 meson build issue(Fixed in the the patch meson: add libatomic as a global dependency for i686 clang)
b) fixed build issue with FreeBSD with top of tree change.
c) fixed missing experimental API for iavf and ice with meson build in avx512 files.
v2:
~~
Addressed the following review comments from Mattias Rönnblom:
1) Changed
from:
typedef uint64_t* rte_trace_t;
to
typedef uint64_t rte_trace_t;
Initially thought to make the handle as
struct rte_trace {
uint64_t val;
}
but changed to uint64_t for the following reasons
a) It is opaque to the application and it will fix the compile-time type
check as well.
b) The handle has an index that will point to an internal slow-path
structure so no ABI change required in the future.
c) RTE_TRACE_POINT_DEFINE need to expose trace object. So it is better
to keep as uint64_t and avoid one more indirection for no use.
2)
Changed:
from:
enum rte_trace_mode_e {
to:
enum rte_trace_mode {
3) removed [out] "found" param from rte_trace_pattern() and
rte_trace_regexp()
4) Changed rte_trace_from_name to rte_trace_by_name
5) rte_trace_is_dp_enabled() return bool now
6) in __rte_trace_point_register() the argument fn change to register_fn
7) removed !! from rte_trace_is_enabled()
8) Remove uninitialized "rc warning" from rte_trace_pattern() and
rte_trace_regexp()
9) fixup bool return type for trace_entry_compare()
10) fixup calloc casting in trace_mkdir()
11) check fclose() return in trace_meta_save() and trace_mem_save()
12) rte_trace_ctf_* macro cleanup
13) added release notes
14) fix build issues reported by CI
http://mails.dpdk.org/archives/test-report/2020-March/121235.html
This patch set contains
~~~~~~~~~~~~~~~~~~~~~~~~
# The native implementation of common trace format(CTF)[1] based tracer
# Public API to create the trace points.
# Add tracepoints to eal, ethdev, mempool, eventdev and cryptodev
library for tracing support
# A unit test case
# Performance test case to measure the trace overhead. (See eal/trace:
# add trace performance test cases, patch)
# Programmers guide for Trace support(See doc: add trace library guide,
# patch)
# Tested OS:
~~~~~~~~~~~
- Linux
- FreeBSD
# Tested open source CTF trace viewers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Babeltrace
- Tracecompass
# Trace overhead comparison with LTTng
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
trace overhead data on x86:[2]
# 236 cycles with LTTng(>100ns)
# 18 cycles(7ns) with Native DPDK CTF emitter.(See eal/trace: add trace
# performance test cases patch)
trace overhead data on arm64:
# 312 cycles to 1100 cycles with LTTng based on the class of arm64 CPU.
# 11 cycles to 13 cycles with Native DPDK CTF emitter based on the
class of arm64 CPU.
18 cycles(on x86) vs 11 cycles(on arm64) is due to rdtsc() overhead in
x86. It seems rdtsc takes around 15cycles in x86.
More details:
~~~~~~~~~~~~~
# The Native DPDK CTF trace support does not have any dependency on
third-party library.
The generated output file is compatible with LTTng as both are using
CTF trace format.
The performance gain comes from:
1) exploit dpdk worker thread usage model to avoid atomics and use per
core variables
2) use hugepage,
3) avoid a lot function pointers in fast-path etc
4) avoid unaligned store for arm64 etc
Features:
~~~~~~~~~
- No specific limit on the events. A string-based event like rte_log
for pattern matching
- Dynamic enable/disable support.
- Instructmention overhead is ~1 cycle. i.e cost of adding the code
wth out using trace feature.
- Timestamp support for all the events using DPDK rte_rtdsc
- No dependency on another library. Clean room native implementation of CTF.
Functional test case:
a) echo "trace_autotest" | sudo ./build/app/test/dpdk-test -c 0x3 --trace=.*
The above command emits the following trace events
<code>
uint8_t i;
rte_trace_lib_eal_generic_void();
rte_trace_lib_eal_generic_u64(0x10000000000000);
rte_trace_lib_eal_generic_u32(0x10000000);
rte_trace_lib_eal_generic_u16(0xffee);
rte_trace_lib_eal_generic_u8(0xc);
rte_trace_lib_eal_generic_i64(-1234);
rte_trace_lib_eal_generic_i32(-1234567);
rte_trace_lib_eal_generic_i16(12);
rte_trace_lib_eal_generic_i8(-3);
rte_trace_lib_eal_generic_string("my string");
rte_trace_lib_eal_generic_function(__func__);
</code>
Install babeltrace package in Linux and point the generated trace file
to babel trace. By default trace file created under
<user>/dpdk-traces/time_stamp/
example:
# babeltrace /root/dpdk-traces/rte-2020-02-15-PM-02-56-51 | more
[13:27:36.138468807] (+?.?????????) lib.eal.generic.void: { cpu_id =0, name = "dpdk-test" }, { }
[13:27:36.138468851] (+0.000000044) lib.eal.generic.u64: { cpu_id = 0, name = "dpdk-test" }, { in = 4503599627370496 }
[13:27:36.138468860] (+0.000000009) lib.eal.generic.u32: { cpu_id = 0, name = "dpdk-test" }, { in = 268435456 }
[13:27:36.138468934] (+0.000000074) lib.eal.generic.u16: { cpu_id = 0, name = "dpdk-test" }, { in = 65518 }
[13:27:36.138468949] (+0.000000015) lib.eal.generic.u8: { cpu_id = 0, name = "dpdk-test" }, { in = 12 }
[13:27:36.138468956] (+0.000000007) lib.eal.generic.i64: { cpu_id = 0, name = "dpdk-test" }, { in = -1234 }
[13:27:36.138468963] (+0.000000007) lib.eal.generic.i32: { cpu_id = 0, name = "dpdk-test" }, { in = -1234567 }
[13:27:36.138469024] (+0.000000061) lib.eal.generic.i16: { cpu_id = 0, name = "dpdk-test" }, { in = 12 }
[13:27:36.138469044] (+0.000000020) lib.eal.generic.i8: { cpu_id = 0, name = "dpdk-test" }, { in = -3 }
[13:27:36.138469051] (+0.000000007) lib.eal.generic.string: { cpu_id = 0, name = "dpdk-test" }, { str = "my string" }
[13:27:36.138469203] (+0.000000152) lib.eal.generic.func: { cpu_id = 0, name = "dpdk-test" }, { func = "test_trace_points" }
# There is a GUI based trace viewer available in Windows, Linux and Mac.
It is called as tracecompass.(https://www.eclipse.org/tracecompass/)
The example screenshot and Histogram of above DPDK trace using
Tracecompass.
https://github.com/jerinjacobk/share/blob/master/dpdk_trace.JPG
File walk through:
~~~~~~~~~~~~~~~~~~
lib/librte_eal/common/include/rte_trace.h - Public API for Trace
provider and Trace control
lib/librte_eal/common/eal_common_trace.c - main trace implementation
lib/librte_eal/common/eal_common_trace_ctf.c - CTF metadata spec
implementation
lib/librte_eal/common/eal_common_trace_utils.c - command line utils
and filesystem operations.
lib/librte_eal/common/eal_common_trace_points.c - trace points for EAL
library
lib/librte_eal/common/include/rte_trace_eal.h - EAL tracepoint public
API.
lib/librte_eal/common/eal_trace.h - Private trace header file.
[1] https://diamon.org/ctf/
[2] The above test is ported to LTTng for finding the LTTng trace
overhead. It available at
https://github.com/jerinjacobk/lttng-overhead
https://github.com/jerinjacobk/lttng-overhead/blob/master/README
Jerin Jacob (22):
eal: introduce API for getting thread name
eal/trace: define the public API for trace support
eal/trace: implement trace register API
eal/trace: implement trace operation APIs
eal/trace: add internal trace init and fini interface
eal/trace: get bootup timestamp for trace
eal/trace: create CTF TDSL metadata in memory
eal/trace: implement trace memory allocation
eal/trace: implement debug dump function
eal/trace: implement trace save
eal/trace: implement registration payload
eal/trace: implement provider payload
eal/trace: hook internal trace APIs to Linux
eal/trace: hook internal trace APIs to FreeBSD
eal/trace: add generic tracepoints
eal/trace: add alarm tracepoints
eal/trace: add memory tracepoints
eal/trace: add memzone tracepoints
eal/trace: add thread tracepoints
eal/trace: add interrupt tracepoints
eal/trace: add trace performance test cases
doc: add trace library guide
Sunil Kumar Kori (10):
eal/trace: handle CTF keyword collision
eal/trace: add trace configuration parameter
eal/trace: add trace dir configuration parameter
eal/trace: add trace bufsize configuration parameter
eal/trace: add trace mode configuration parameter
eal/trace: add unit test cases
ethdev: add tracepoints
eventdev: add tracepoints
cryptodev: add tracepoints
mempool: add tracepoints
MAINTAINERS | 8 +
app/test/Makefile | 4 +-
app/test/meson.build | 5 +
app/test/test_trace.c | 213 ++++++++
app/test/test_trace.h | 15 +
app/test/test_trace_perf.c | 183 +++++++
app/test/test_trace_register.c | 17 +
config/common_base | 1 +
config/meson.build | 1 +
doc/api/doxy-api-index.md | 4 +-
doc/guides/linux_gsg/eal_args.include.rst | 52 ++
doc/guides/prog_guide/build-sdk-meson.rst | 5 +
doc/guides/prog_guide/index.rst | 1 +
doc/guides/prog_guide/trace_lib.rst | 348 ++++++++++++
doc/guides/rel_notes/release_20_05.rst | 9 +
examples/cmdline/Makefile | 1 +
examples/cmdline/meson.build | 1 +
examples/distributor/Makefile | 1 +
examples/distributor/meson.build | 1 +
examples/ethtool/ethtool-app/Makefile | 1 +
examples/eventdev_pipeline/meson.build | 1 +
examples/flow_filtering/Makefile | 1 +
examples/flow_filtering/meson.build | 1 +
examples/helloworld/Makefile | 1 +
examples/helloworld/meson.build | 1 +
examples/ioat/Makefile | 1 +
examples/ioat/meson.build | 1 +
examples/ip_fragmentation/Makefile | 2 +
examples/ip_fragmentation/meson.build | 1 +
examples/ip_reassembly/Makefile | 1 +
examples/ip_reassembly/meson.build | 1 +
examples/ipv4_multicast/Makefile | 1 +
examples/ipv4_multicast/meson.build | 1 +
examples/l2fwd-cat/Makefile | 1 +
examples/l2fwd-cat/meson.build | 1 +
examples/l2fwd-event/Makefile | 1 +
examples/l2fwd-event/meson.build | 1 +
examples/l2fwd-jobstats/Makefile | 1 +
examples/l2fwd-jobstats/meson.build | 1 +
examples/l2fwd-keepalive/Makefile | 1 +
examples/l2fwd-keepalive/ka-agent/Makefile | 1 +
examples/l2fwd-keepalive/meson.build | 1 +
examples/l3fwd-acl/Makefile | 1 +
examples/l3fwd-acl/meson.build | 1 +
examples/l3fwd/Makefile | 1 +
examples/l3fwd/meson.build | 1 +
examples/link_status_interrupt/Makefile | 1 +
examples/link_status_interrupt/meson.build | 1 +
.../client_server_mp/mp_client/Makefile | 1 +
.../client_server_mp/mp_client/meson.build | 1 +
.../client_server_mp/mp_server/meson.build | 1 +
examples/multi_process/hotplug_mp/Makefile | 1 +
examples/multi_process/hotplug_mp/meson.build | 1 +
examples/multi_process/simple_mp/Makefile | 1 +
examples/multi_process/simple_mp/meson.build | 1 +
examples/multi_process/symmetric_mp/Makefile | 1 +
.../multi_process/symmetric_mp/meson.build | 1 +
examples/ntb/Makefile | 1 +
examples/ntb/meson.build | 1 +
examples/packet_ordering/Makefile | 1 +
examples/packet_ordering/meson.build | 1 +
.../performance-thread/l3fwd-thread/Makefile | 1 +
.../l3fwd-thread/meson.build | 1 +
.../performance-thread/pthread_shim/Makefile | 1 +
.../pthread_shim/meson.build | 1 +
examples/ptpclient/Makefile | 1 +
examples/ptpclient/meson.build | 1 +
examples/qos_meter/Makefile | 1 +
examples/qos_meter/meson.build | 1 +
examples/qos_sched/Makefile | 1 +
examples/qos_sched/meson.build | 1 +
examples/server_node_efd/node/Makefile | 1 +
examples/server_node_efd/node/meson.build | 1 +
examples/server_node_efd/server/Makefile | 1 +
examples/server_node_efd/server/meson.build | 1 +
examples/service_cores/Makefile | 1 +
examples/service_cores/meson.build | 1 +
examples/skeleton/Makefile | 1 +
examples/skeleton/meson.build | 1 +
examples/timer/Makefile | 1 +
examples/timer/meson.build | 1 +
examples/vm_power_manager/Makefile | 1 +
examples/vm_power_manager/meson.build | 1 +
examples/vmdq/Makefile | 1 +
examples/vmdq/meson.build | 1 +
examples/vmdq_dcb/Makefile | 1 +
examples/vmdq_dcb/meson.build | 1 +
lib/librte_cryptodev/Makefile | 4 +-
lib/librte_cryptodev/cryptodev_trace_points.c | 70 +++
lib/librte_cryptodev/meson.build | 6 +-
lib/librte_cryptodev/rte_cryptodev.c | 18 +
lib/librte_cryptodev/rte_cryptodev.h | 6 +
lib/librte_cryptodev/rte_cryptodev_trace.h | 148 ++++++
lib/librte_cryptodev/rte_cryptodev_trace_fp.h | 38 ++
.../rte_cryptodev_version.map | 18 +
lib/librte_eal/common/eal_common_memzone.c | 9 +
lib/librte_eal/common/eal_common_options.c | 65 +++
lib/librte_eal/common/eal_common_thread.c | 4 +-
lib/librte_eal/common/eal_common_trace.c | 494 ++++++++++++++++++
lib/librte_eal/common/eal_common_trace_ctf.c | 488 +++++++++++++++++
.../common/eal_common_trace_points.c | 115 ++++
.../common/eal_common_trace_utils.c | 478 +++++++++++++++++
lib/librte_eal/common/eal_options.h | 8 +
lib/librte_eal/common/eal_private.h | 5 +
lib/librte_eal/common/eal_trace.h | 122 +++++
lib/librte_eal/common/meson.build | 4 +
lib/librte_eal/common/rte_malloc.c | 60 ++-
lib/librte_eal/freebsd/Makefile | 4 +
lib/librte_eal/freebsd/eal.c | 10 +
lib/librte_eal/freebsd/eal_alarm.c | 3 +
lib/librte_eal/freebsd/eal_interrupts.c | 54 +-
lib/librte_eal/freebsd/eal_thread.c | 21 +-
lib/librte_eal/include/meson.build | 5 +
lib/librte_eal/include/rte_eal_trace.h | 278 ++++++++++
lib/librte_eal/include/rte_lcore.h | 17 +
lib/librte_eal/include/rte_trace.h | 141 +++++
lib/librte_eal/include/rte_trace_point.h | 306 +++++++++++
.../include/rte_trace_point_provider.h | 131 +++++
.../include/rte_trace_point_register.h | 39 ++
lib/librte_eal/linux/Makefile | 4 +
lib/librte_eal/linux/eal.c | 9 +
lib/librte_eal/linux/eal_alarm.c | 4 +
lib/librte_eal/linux/eal_interrupts.c | 84 +--
lib/librte_eal/linux/eal_thread.c | 27 +-
lib/librte_eal/rte_eal_version.map | 50 ++
lib/librte_ethdev/Makefile | 3 +
lib/librte_ethdev/ethdev_trace_points.c | 43 ++
lib/librte_ethdev/meson.build | 5 +-
lib/librte_ethdev/rte_ethdev.c | 12 +
lib/librte_ethdev/rte_ethdev.h | 5 +
lib/librte_ethdev/rte_ethdev_trace.h | 97 ++++
lib/librte_ethdev/rte_ethdev_trace_fp.h | 44 ++
lib/librte_ethdev/rte_ethdev_version.map | 10 +
lib/librte_eventdev/Makefile | 3 +
lib/librte_eventdev/eventdev_trace_points.c | 173 ++++++
lib/librte_eventdev/meson.build | 3 +
.../rte_event_crypto_adapter.c | 10 +
.../rte_event_eth_rx_adapter.c | 11 +
.../rte_event_eth_tx_adapter.c | 13 +-
.../rte_event_eth_tx_adapter.h | 2 +
lib/librte_eventdev/rte_event_timer_adapter.c | 8 +-
lib/librte_eventdev/rte_event_timer_adapter.h | 8 +
lib/librte_eventdev/rte_eventdev.c | 9 +
lib/librte_eventdev/rte_eventdev.h | 5 +-
lib/librte_eventdev/rte_eventdev_trace.h | 311 +++++++++++
lib/librte_eventdev/rte_eventdev_trace_fp.h | 85 +++
lib/librte_eventdev/rte_eventdev_version.map | 42 ++
lib/librte_mempool/Makefile | 3 +
lib/librte_mempool/mempool_trace_points.c | 108 ++++
lib/librte_mempool/meson.build | 5 +-
lib/librte_mempool/rte_mempool.c | 16 +
lib/librte_mempool/rte_mempool.h | 13 +
lib/librte_mempool/rte_mempool_ops.c | 7 +
lib/librte_mempool/rte_mempool_trace.h | 178 +++++++
lib/librte_mempool/rte_mempool_trace_fp.h | 116 ++++
lib/librte_mempool/rte_mempool_version.map | 26 +
meson_options.txt | 2 +
157 files changed, 5587 insertions(+), 75 deletions(-)
create mode 100644 app/test/test_trace.c
create mode 100644 app/test/test_trace.h
create mode 100644 app/test/test_trace_perf.c
create mode 100644 app/test/test_trace_register.c
create mode 100644 doc/guides/prog_guide/trace_lib.rst
create mode 100644 lib/librte_cryptodev/cryptodev_trace_points.c
create mode 100644 lib/librte_cryptodev/rte_cryptodev_trace.h
create mode 100644 lib/librte_cryptodev/rte_cryptodev_trace_fp.h
create mode 100644 lib/librte_eal/common/eal_common_trace.c
create mode 100644 lib/librte_eal/common/eal_common_trace_ctf.c
create mode 100644 lib/librte_eal/common/eal_common_trace_points.c
create mode 100644 lib/librte_eal/common/eal_common_trace_utils.c
create mode 100644 lib/librte_eal/common/eal_trace.h
create mode 100644 lib/librte_eal/include/rte_eal_trace.h
create mode 100644 lib/librte_eal/include/rte_trace.h
create mode 100644 lib/librte_eal/include/rte_trace_point.h
create mode 100644 lib/librte_eal/include/rte_trace_point_provider.h
create mode 100644 lib/librte_eal/include/rte_trace_point_register.h
create mode 100644 lib/librte_ethdev/ethdev_trace_points.c
create mode 100644 lib/librte_ethdev/rte_ethdev_trace.h
create mode 100644 lib/librte_ethdev/rte_ethdev_trace_fp.h
create mode 100644 lib/librte_eventdev/eventdev_trace_points.c
create mode 100644 lib/librte_eventdev/rte_eventdev_trace.h
create mode 100644 lib/librte_eventdev/rte_eventdev_trace_fp.h
create mode 100644 lib/librte_mempool/mempool_trace_points.c
create mode 100644 lib/librte_mempool/rte_mempool_trace.h
create mode 100644 lib/librte_mempool/rte_mempool_trace_fp.h
--
2.25.1
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH v3 1/1] eal: add internal ABI mark support
2020-04-22 14:13 4% ` David Marchand
@ 2020-04-22 16:44 4% ` Wang, Haiyue
0 siblings, 0 replies; 200+ results
From: Wang, Haiyue @ 2020-04-22 16:44 UTC (permalink / raw)
To: David Marchand
Cc: dev, Thomas Monjalon, Richardson, Bruce, Yigit, Ferruh, Ray Kinsella
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Wednesday, April 22, 2020 22:14
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev <dev@dpdk.org>; Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce
> <bruce.richardson@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Ray Kinsella <mdr@ashroe.eu>
> Subject: Re: [PATCH v3 1/1] eal: add internal ABI mark support
>
> On Wed, Apr 22, 2020 at 3:58 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> >
> > Introduce __rte_internal tag to mark internal ABI function, this kind of
> > function can't be called by external application.
> >
> > Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
> > ---
> > buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
> > devtools/check-symbol-change.sh | 7 ++++
> > drivers/meson.build | 2 +-
> > lib/librte_eal/include/rte_compat.h | 13 +++++++
> > lib/meson.build | 2 +-
> > mk/internal/rte.compile-pre.mk | 3 ++
> > mk/target/generic/rte.vars.mk | 1 +
> > 7 files changed, 83 insertions(+), 2 deletions(-)
> > create mode 100755 buildtools/check-internal-syms.sh
>
> I did not enter the details, but I suppose this patch lacks an update
> on the suppression rules so that INTERNAL versioned symbols are
> skipped.
> https://git.dpdk.org/dpdk/tree/devtools/libabigail.abignore
>
>
Added it in v4.
> --
> David Marchand
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v4 1/1] eal: add internal ABI mark support
2020-04-22 16:37 4% ` [dpdk-dev] [PATCH v4 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
@ 2020-04-22 16:37 15% ` Haiyue Wang
0 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-22 16:37 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Introduce __rte_internal tag to mark internal ABI function, this kind of
function can't be called by external application.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
devtools/check-symbol-change.sh | 7 ++++
devtools/libabigail.abignore | 5 +++
drivers/meson.build | 2 +-
lib/librte_eal/include/rte_compat.h | 13 +++++++
lib/meson.build | 2 +-
mk/internal/rte.compile-pre.mk | 3 ++
mk/target/generic/rte.vars.mk | 1 +
8 files changed, 88 insertions(+), 2 deletions(-)
create mode 100755 buildtools/check-internal-syms.sh
diff --git a/buildtools/check-internal-syms.sh b/buildtools/check-internal-syms.sh
new file mode 100755
index 000000000..5043acf87
--- /dev/null
+++ b/buildtools/check-internal-syms.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# SPDX-License-Identifier: BSD-3-Clause
+
+MAPFILE=$1
+OBJFILE=$2
+
+LIST_SYMBOL=$(dirname $(readlink -f $0))/map-list-symbol.sh
+
+# added check for "make -C test/" usage
+if [ ! -e $MAPFILE ] || [ ! -f $OBJFILE ]
+then
+ exit 0
+fi
+
+if [ -d $MAPFILE ]
+then
+ exit 0
+fi
+
+DUMPFILE=$(mktemp -t dpdk.${0##*/}.XXX.objdump)
+trap 'rm -f "$DUMPFILE"' EXIT
+objdump -t $OBJFILE >$DUMPFILE
+
+ret=0
+for SYM in `$LIST_SYMBOL -S INTERNAL $MAPFILE |cut -d ' ' -f 3`
+do
+ if grep -q "\.text.*[[:space:]]$SYM$" $DUMPFILE &&
+ ! grep -q "\.text\.internal.*[[:space:]]$SYM$" $DUMPFILE
+ then
+ cat >&2 <<- END_OF_MESSAGE
+ $SYM is not flagged as internal
+ but is listed in version map
+ Please add __rte_internal to the definition of $SYM
+ END_OF_MESSAGE
+ ret=1
+ fi
+done
+
+# Filter out symbols suffixed with a . for icc
+for SYM in `awk '{
+ if ($2 != "l" && $4 == ".text.internal" && !($NF ~ /\.$/)) {
+ print $NF
+ }
+}' $DUMPFILE`
+do
+ $LIST_SYMBOL -S INTERNAL -s $SYM -q $MAPFILE || {
+ cat >&2 <<- END_OF_MESSAGE
+ $SYM is flagged as internal
+ but is not listed in version map
+ Please add $SYM to the version map
+ END_OF_MESSAGE
+ ret=1
+ }
+done
+
+exit $ret
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
index ed2178e36..978979077 100755
--- a/devtools/check-symbol-change.sh
+++ b/devtools/check-symbol-change.sh
@@ -91,6 +91,13 @@ check_for_rule_violations()
if [ "$ar" = "add" ]
then
+ if [ "$secname" = "INTERNAL" ]
+ then
+ # these are absolved from any further checking
+ echo "Skipping symbol $symname in INTERNAL"
+ continue
+ fi
+
if [ "$secname" = "unknown" ]
then
# Just inform the user of this occurrence, but
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index cd86d89ca..3e8e2ea74 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -3,6 +3,11 @@
[suppress_variable]
symbol_version = EXPERIMENTAL
+[suppress_function]
+ symbol_version = INTERNAL
+[suppress_variable]
+ symbol_version = INTERNAL
+
; Explicit ignore for driver-only ABI
[suppress_type]
name = rte_cryptodev_ops
diff --git a/drivers/meson.build b/drivers/meson.build
index 4d8f842ab..cac07161f 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -20,7 +20,7 @@ dpdk_driver_classes = ['common',
disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
).stdout().split()
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
index 3eb33784b..4cd8f68d6 100644
--- a/lib/librte_eal/include/rte_compat.h
+++ b/lib/librte_eal/include/rte_compat.h
@@ -19,4 +19,17 @@ __attribute__((section(".text.experimental")))
#endif
+#ifndef ALLOW_INTERNAL_API
+
+#define __rte_internal \
+__attribute__((error("Symbol is not public ABI"), \
+section(".text.internal")))
+
+#else
+
+#define __rte_internal \
+__attribute__((section(".text.internal")))
+
+#endif
+
#endif /* _RTE_COMPAT_H_ */
diff --git a/lib/meson.build b/lib/meson.build
index 63c17ee75..981c2e397 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -36,7 +36,7 @@ if is_windows
libraries = ['kvargs','eal'] # only supported libraries for windows
endif
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/mk/internal/rte.compile-pre.mk b/mk/internal/rte.compile-pre.mk
index 82fe098f7..0369786a5 100644
--- a/mk/internal/rte.compile-pre.mk
+++ b/mk/internal/rte.compile-pre.mk
@@ -58,6 +58,8 @@ C_TO_O_DISP = $(if $(V),"$(C_TO_O_STR)"," CC $(@)")
endif
EXPERIMENTAL_CHECK = $(RTE_SDK)/buildtools/check-experimental-syms.sh
CHECK_EXPERIMENTAL = $(EXPERIMENTAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
+INTERNAL_CHECK = $(RTE_SDK)/buildtools/check-internal-syms.sh
+CHECK_INTERNAL = $(INTERNAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
PMDINFO_GEN = $(RTE_SDK_BIN)/app/dpdk-pmdinfogen $@ $@.pmd.c
PMDINFO_CC = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@.pmd.o $@.pmd.c
@@ -76,6 +78,7 @@ C_TO_O_DO = @set -e; \
$(C_TO_O) && \
$(PMDINFO_TO_O) && \
$(CHECK_EXPERIMENTAL) && \
+ $(CHECK_INTERNAL) && \
echo $(C_TO_O_CMD) > $(call obj2cmd,$(@)) && \
sed 's,'$@':,dep_'$@' =,' $(call obj2dep,$(@)).tmp > $(call obj2dep,$(@)) && \
rm -f $(call obj2dep,$(@)).tmp
diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
index ec2672897..11b0418e5 100644
--- a/mk/target/generic/rte.vars.mk
+++ b/mk/target/generic/rte.vars.mk
@@ -106,6 +106,7 @@ ifeq ($(BUILDING_RTE_SDK),1)
# building sdk
CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -DALLOW_INTERNAL_API
else
# if we are building an external application, include SDK's lib and
# includes too
--
2.26.2
^ permalink raw reply [relevance 15%]
* [dpdk-dev] [PATCH v4 0/1] dpdk: introduce __rte_internal tag
2020-04-22 13:52 4% ` [dpdk-dev] [PATCH v3 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
@ 2020-04-22 16:37 4% ` Haiyue Wang
2020-04-22 16:37 15% ` [dpdk-dev] [PATCH v4 1/1] eal: add internal ABI mark support Haiyue Wang
2020-04-23 3:19 4% ` [dpdk-dev] [PATCH v5 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
` (2 subsequent siblings)
5 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-22 16:37 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit,
nhorman, mdr
Cc: Haiyue Wang
Move the internal function into INTERNAL session to avoid the ABI
checking, and it is only used for DPDK drivers or related library.
__rte_internal funA
INTERNAL {
global:
funA
};
v4: add the ABI check suppression rules
v3: based on Neil's v2 patch https://patchwork.dpdk.org/cover/54771/
Use the ALLOW_INTERNAL_API to mark this new feature.
Haiyue Wang (1):
eal: add internal ABI mark support
buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
devtools/check-symbol-change.sh | 7 ++++
devtools/libabigail.abignore | 5 +++
drivers/meson.build | 2 +-
lib/librte_eal/include/rte_compat.h | 13 +++++++
lib/meson.build | 2 +-
mk/internal/rte.compile-pre.mk | 3 ++
mk/target/generic/rte.vars.mk | 1 +
8 files changed, 88 insertions(+), 2 deletions(-)
create mode 100755 buildtools/check-internal-syms.sh
--
2.26.2
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 0/4] add AESNI-MB rawdev for multi-function processing
2020-04-22 13:44 3% ` Akhil Goyal
@ 2020-04-22 14:21 0% ` Coyle, David
0 siblings, 0 replies; 200+ results
From: Coyle, David @ 2020-04-22 14:21 UTC (permalink / raw)
To: Akhil Goyal, Doherty, Declan, Thomas Monjalon, Yigit, Ferruh,
Trahe, Fiona
Cc: techboard, dev, De Lara Guarch, Pablo, Ryan, Brendan,
Hemant Agrawal, Anoob Joseph, Ruifeng Wang, Liron Himi,
Nagadheeraj Rottela, Srikanth Jampala, Gagandeep Singh, Jay Zhou,
Ravi Kumar, Richardson, Bruce, olivier.matz,
honnappa.nagarahalli, Stephen Hemminger, alexr
Hi Akhil
> -----Original Message-----
> From: Akhil Goyal <akhil.goyal@nxp.com>
> Sent: Wednesday, April 22, 2020 2:44 PM
>
> Hi David,
> > Hi Akhil,
> >
> > > > >
> > > I did not look at your patches completely, but looking at the ops
> > > that you have added For rawdev are pretty much same as that of a crypto
> device.
> > >
> > > I see that there are 2 types of ops that you need
> > > - session create/destroy
> > > - enq/deq
> > >
> > > On the first impression of your patchset, I see that you want to enq
> > > to driver only once for both The operations - CRC and crypto.
> > >
> > > So what is the issue in using the cryptodev_enqueue for processing
> > > in the existing AESNI-MB driver.
> > > For session creation, the cryptodev layer will not give flexibility
> > > to add
> > > CRC+crypto kind of sessions.
> > > But in case of rte_security, you can define your new session xform
> > > based on your requirement.
> > >
> > > And while doing the cryptodev enq/deq, based on the session type,
> > > you can process the packet Specific to your usecase in your aesni-mb
> > > PMD
> > >
> > > Now if you want to add compression also along with crypto, then you
> > > can define another xform which Will be combination of
> > > crypto+compression and the aesni-mb PMD can have another mode
> which
> > > Can make sessions based on the new xform and the enq and deq can be
> > > done using the cryptodev enq/deq.
> > > For all your cases you will be having only one action type -
> > > lookaside protocol and can define different Protocols (that may not be
> standard).
> > >
> > > So to conclude, your AESNI-MB will have 3 types of operations
> > > - plain crypto
> > > - crc+crypto
> > > - compression+crypto
> > >
> > > I believe this is doable or did I miss something very obvious?
> >
> > [DC] Thank you for this feedback
> >
> > I have done this exact same analysis on rte_security and how we could use
> it.
> >
> > The main issue of this approach (and it may be possible to easily
> > overcome) is that ultimately crypto_op's need to be enqueued into
> > cryptodev. This means we can't easily control the CRC (or compression
> > in the future) at the operation level - application developers using
> > this API would create a
> > Crypto+CRC security xform session for a
> > particular flow but may want to turn off the CRC part for some packets
> > in that flow.
> >
> > There are a number of ways this issue could possibly be overcome:
> > 1) the auth offset/length fields in a rte_crypto_op could be
> > overloaded to control the CRC part of the combined operation
> > - this is not the cleanest approach
> > 2) we add a "security" op struct of some type to the union at end of
> > the rte_crypto_op
> > - to avoid any circular dependencies, this would need to be opaque
> > to rte_cryptodev
> > - rte_cryptodev should not be aware of rte_security
> >
> > Number 2 above is probably the cleaner and more preferable approach.
>
> Yes, it is preferred, but it should be a union to
> rte_crypto_sym_op/rte_crypto_asym_op.
> Crypto_op->type as RTE_CRYPTO_OP_TYPE_SECURITY and sess_type as
> RTE_CRYPTO_OP_SECURITY_SESSION The size of rte_crypto_op will remain
> as is and there will be no ABI breakage I guess.
[DC] Yes we would add to this union at the end of rte_crypto_op
__extension__
union {
struct rte_crypto_sym_op sym[0];
/**< Symmetric operation parameters */
struct rte_crypto_asym_op asym[0];
/**< Asymmetric operation parameters */
}; /**< operation specific parameters */
I haven't figured out the finer details yet, but it should be straightforward to add some security element here.
As these are zero length arrays, we won't be affecting the size of rte_crypto_op if we add another zero length array.
We should not include rte_security.h and add something like struct rte_security_op sec[0] here though, as that would
cause a circular dependency between rte_cryptodev and rte_security.
This should be resolvable though
>
> One more thing that can be looked into is the recently added CPU crypto
> process API If that could of any use, we may extend that if need be.
[DC] This is also being targeted at QAT and we would like to maintain the same
Interface for these use-cases for both AESNI-MB and QAT.
So I think the traditional enqueue/dequeue API is what we would initially use as it
means users of this API can easily switch between AESNI-MB and QAT. However, we
may look at the CPU crypto API for AESNI-MB in the future.
>
> >
> > The other approach is that CRC is either on/off at the session level.
> > That limitation would then need to be adhered by application
> > developers, which is something we would ideally like to avoid.
>
> You mean that CRC can be on/off per session as well as per packet?
> I think that can also be handled when you are defining your own security_op
> for per packet.
[DC] I meant that if we didn't take the approach defining a security_op, then
we would have turn on/off CRC at the session level and impose that limit on
the app developers. But yes, by defining a security_op, we can probably turn
it on/off at both session and op level.
>
> >
> > The rawdev multi-function approach did not have these issues which is
> > one of the reasons we have pursued this approach to date.
> >
> > However, we think the rte_security approach is workable.
> > It still requires some deeper analysis but with your support, we think
> > we can overcome the challenges.
> >
> Yes, please let me know where ever my help is required.
[DC] Thank you, appreciate that
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 1/1] eal: add internal ABI mark support
2020-04-22 13:52 11% ` [dpdk-dev] [PATCH v3 1/1] eal: add internal ABI mark support Haiyue Wang
@ 2020-04-22 14:13 4% ` David Marchand
2020-04-22 16:44 4% ` Wang, Haiyue
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2020-04-22 14:13 UTC (permalink / raw)
To: Haiyue Wang
Cc: dev, Thomas Monjalon, Bruce Richardson, Yigit, Ferruh, Ray Kinsella
On Wed, Apr 22, 2020 at 3:58 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
>
> Introduce __rte_internal tag to mark internal ABI function, this kind of
> function can't be called by external application.
>
> Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
> ---
> buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
> devtools/check-symbol-change.sh | 7 ++++
> drivers/meson.build | 2 +-
> lib/librte_eal/include/rte_compat.h | 13 +++++++
> lib/meson.build | 2 +-
> mk/internal/rte.compile-pre.mk | 3 ++
> mk/target/generic/rte.vars.mk | 1 +
> 7 files changed, 83 insertions(+), 2 deletions(-)
> create mode 100755 buildtools/check-internal-syms.sh
I did not enter the details, but I suppose this patch lacks an update
on the suppression rules so that INTERNAL versioned symbols are
skipped.
https://git.dpdk.org/dpdk/tree/devtools/libabigail.abignore
--
David Marchand
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v9 2/2] eal: support for VFIO-PCI VF token
@ 2020-04-22 14:02 3% ` Wang, Haiyue
0 siblings, 0 replies; 200+ results
From: Wang, Haiyue @ 2020-04-22 14:02 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, Burakov, Anatoly, vattunuru, jerinj, alex.williamson,
david.marchand
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Wednesday, April 22, 2020 16:24
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev@dpdk.org; Burakov, Anatoly <anatoly.burakov@intel.com>; vattunuru@marvell.com;
> jerinj@marvell.com; alex.williamson@redhat.com; david.marchand@redhat.com
> Subject: Re: [PATCH v9 2/2] eal: support for VFIO-PCI VF token
>
> 22/04/2020 07:08, Haiyue Wang:
> > --- a/devtools/libabigail.abignore
> > +++ b/devtools/libabigail.abignore
> > +[suppress_function]
> > + name = rte_vfio_setup_device
>
> There is no comment to justify ignoring this symbol.
>
> The current policy is to reject any change in libabigail.abignore
> which could be better handled with (unfinished) rte_internal mark.
>
>
While updating the vfio patch, also doing the ABI things. Found that:
1). [suppress_function]
name = rte_vfio_setup_device
can make CI happy, but not scale.
2). rte_internal is beautiful, but make CI cry : https://patchwork.dpdk.org/patch/69109/
1 Removed function:
[D] 'function int rte_vfio_setup_device(const char*, const char*, int*, vfio_device_info*)' {rte_vfio_setup_device@@DPDK_20.0}
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v3 1/1] eal: add internal ABI mark support
2020-04-22 13:52 4% ` [dpdk-dev] [PATCH v3 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
@ 2020-04-22 13:52 11% ` Haiyue Wang
2020-04-22 14:13 4% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-22 13:52 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit; +Cc: Haiyue Wang
Introduce __rte_internal tag to mark internal ABI function, this kind of
function can't be called by external application.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
---
buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
devtools/check-symbol-change.sh | 7 ++++
drivers/meson.build | 2 +-
lib/librte_eal/include/rte_compat.h | 13 +++++++
lib/meson.build | 2 +-
mk/internal/rte.compile-pre.mk | 3 ++
mk/target/generic/rte.vars.mk | 1 +
7 files changed, 83 insertions(+), 2 deletions(-)
create mode 100755 buildtools/check-internal-syms.sh
diff --git a/buildtools/check-internal-syms.sh b/buildtools/check-internal-syms.sh
new file mode 100755
index 000000000..5043acf87
--- /dev/null
+++ b/buildtools/check-internal-syms.sh
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# SPDX-License-Identifier: BSD-3-Clause
+
+MAPFILE=$1
+OBJFILE=$2
+
+LIST_SYMBOL=$(dirname $(readlink -f $0))/map-list-symbol.sh
+
+# added check for "make -C test/" usage
+if [ ! -e $MAPFILE ] || [ ! -f $OBJFILE ]
+then
+ exit 0
+fi
+
+if [ -d $MAPFILE ]
+then
+ exit 0
+fi
+
+DUMPFILE=$(mktemp -t dpdk.${0##*/}.XXX.objdump)
+trap 'rm -f "$DUMPFILE"' EXIT
+objdump -t $OBJFILE >$DUMPFILE
+
+ret=0
+for SYM in `$LIST_SYMBOL -S INTERNAL $MAPFILE |cut -d ' ' -f 3`
+do
+ if grep -q "\.text.*[[:space:]]$SYM$" $DUMPFILE &&
+ ! grep -q "\.text\.internal.*[[:space:]]$SYM$" $DUMPFILE
+ then
+ cat >&2 <<- END_OF_MESSAGE
+ $SYM is not flagged as internal
+ but is listed in version map
+ Please add __rte_internal to the definition of $SYM
+ END_OF_MESSAGE
+ ret=1
+ fi
+done
+
+# Filter out symbols suffixed with a . for icc
+for SYM in `awk '{
+ if ($2 != "l" && $4 == ".text.internal" && !($NF ~ /\.$/)) {
+ print $NF
+ }
+}' $DUMPFILE`
+do
+ $LIST_SYMBOL -S INTERNAL -s $SYM -q $MAPFILE || {
+ cat >&2 <<- END_OF_MESSAGE
+ $SYM is flagged as internal
+ but is not listed in version map
+ Please add $SYM to the version map
+ END_OF_MESSAGE
+ ret=1
+ }
+done
+
+exit $ret
diff --git a/devtools/check-symbol-change.sh b/devtools/check-symbol-change.sh
index ed2178e36..978979077 100755
--- a/devtools/check-symbol-change.sh
+++ b/devtools/check-symbol-change.sh
@@ -91,6 +91,13 @@ check_for_rule_violations()
if [ "$ar" = "add" ]
then
+ if [ "$secname" = "INTERNAL" ]
+ then
+ # these are absolved from any further checking
+ echo "Skipping symbol $symname in INTERNAL"
+ continue
+ fi
+
if [ "$secname" = "unknown" ]
then
# Just inform the user of this occurrence, but
diff --git a/drivers/meson.build b/drivers/meson.build
index 4d8f842ab..cac07161f 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -20,7 +20,7 @@ dpdk_driver_classes = ['common',
disabled_drivers = run_command(list_dir_globs, get_option('disable_drivers'),
).stdout().split()
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/lib/librte_eal/include/rte_compat.h b/lib/librte_eal/include/rte_compat.h
index 3eb33784b..4cd8f68d6 100644
--- a/lib/librte_eal/include/rte_compat.h
+++ b/lib/librte_eal/include/rte_compat.h
@@ -19,4 +19,17 @@ __attribute__((section(".text.experimental")))
#endif
+#ifndef ALLOW_INTERNAL_API
+
+#define __rte_internal \
+__attribute__((error("Symbol is not public ABI"), \
+section(".text.internal")))
+
+#else
+
+#define __rte_internal \
+__attribute__((section(".text.internal")))
+
+#endif
+
#endif /* _RTE_COMPAT_H_ */
diff --git a/lib/meson.build b/lib/meson.build
index 63c17ee75..981c2e397 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -36,7 +36,7 @@ if is_windows
libraries = ['kvargs','eal'] # only supported libraries for windows
endif
-default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API']
+default_cflags = machine_args + ['-DALLOW_EXPERIMENTAL_API'] + ['-DALLOW_INTERNAL_API']
if cc.has_argument('-Wno-format-truncation')
default_cflags += '-Wno-format-truncation'
endif
diff --git a/mk/internal/rte.compile-pre.mk b/mk/internal/rte.compile-pre.mk
index 82fe098f7..0369786a5 100644
--- a/mk/internal/rte.compile-pre.mk
+++ b/mk/internal/rte.compile-pre.mk
@@ -58,6 +58,8 @@ C_TO_O_DISP = $(if $(V),"$(C_TO_O_STR)"," CC $(@)")
endif
EXPERIMENTAL_CHECK = $(RTE_SDK)/buildtools/check-experimental-syms.sh
CHECK_EXPERIMENTAL = $(EXPERIMENTAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
+INTERNAL_CHECK = $(RTE_SDK)/buildtools/check-internal-syms.sh
+CHECK_INTERNAL = $(INTERNAL_CHECK) $(SRCDIR)/$(EXPORT_MAP) $@
PMDINFO_GEN = $(RTE_SDK_BIN)/app/dpdk-pmdinfogen $@ $@.pmd.c
PMDINFO_CC = $(CC) $(CPPFLAGS) $(CFLAGS) $(EXTRA_CFLAGS) -c -o $@.pmd.o $@.pmd.c
@@ -76,6 +78,7 @@ C_TO_O_DO = @set -e; \
$(C_TO_O) && \
$(PMDINFO_TO_O) && \
$(CHECK_EXPERIMENTAL) && \
+ $(CHECK_INTERNAL) && \
echo $(C_TO_O_CMD) > $(call obj2cmd,$(@)) && \
sed 's,'$@':,dep_'$@' =,' $(call obj2dep,$(@)).tmp > $(call obj2dep,$(@)) && \
rm -f $(call obj2dep,$(@)).tmp
diff --git a/mk/target/generic/rte.vars.mk b/mk/target/generic/rte.vars.mk
index ec2672897..11b0418e5 100644
--- a/mk/target/generic/rte.vars.mk
+++ b/mk/target/generic/rte.vars.mk
@@ -106,6 +106,7 @@ ifeq ($(BUILDING_RTE_SDK),1)
# building sdk
CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
CFLAGS += -DALLOW_EXPERIMENTAL_API
+CFLAGS += -DALLOW_INTERNAL_API
else
# if we are building an external application, include SDK's lib and
# includes too
--
2.26.2
^ permalink raw reply [relevance 11%]
* [dpdk-dev] [PATCH v3 0/1] dpdk: introduce __rte_internal tag
@ 2020-04-22 13:52 4% ` Haiyue Wang
2020-04-22 13:52 11% ` [dpdk-dev] [PATCH v3 1/1] eal: add internal ABI mark support Haiyue Wang
2020-04-22 16:37 4% ` [dpdk-dev] [PATCH v4 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
` (3 subsequent siblings)
5 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-22 13:52 UTC (permalink / raw)
To: dev, thomas, david.marchand, bruce.richardson, ferruh.yigit; +Cc: Haiyue Wang
Move the internal function into INTERNAL session to avoid the ABI
checking, and it is only used for DPDK drivers or related library.
__rte_internal funA
INTERNAL {
global:
funA
};
v3: based on Neil's v2 patch https://patchwork.dpdk.org/cover/54771/
Use the ALLOW_INTERNAL_API to mark this new feature.
Haiyue Wang (1):
eal: add internal ABI mark support
buildtools/check-internal-syms.sh | 57 +++++++++++++++++++++++++++++
devtools/check-symbol-change.sh | 7 ++++
drivers/meson.build | 2 +-
lib/librte_eal/include/rte_compat.h | 13 +++++++
lib/meson.build | 2 +-
mk/internal/rte.compile-pre.mk | 3 ++
mk/target/generic/rte.vars.mk | 1 +
7 files changed, 83 insertions(+), 2 deletions(-)
create mode 100755 buildtools/check-internal-syms.sh
--
2.26.2
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3 0/4] add AESNI-MB rawdev for multi-function processing
@ 2020-04-22 13:44 3% ` Akhil Goyal
2020-04-22 14:21 0% ` Coyle, David
0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2020-04-22 13:44 UTC (permalink / raw)
To: Coyle, David, Doherty, Declan, Thomas Monjalon, Yigit, Ferruh,
Trahe, Fiona
Cc: techboard, dev, De Lara Guarch, Pablo, Ryan, Brendan,
Hemant Agrawal, Anoob Joseph, Ruifeng Wang, Liron Himi,
Nagadheeraj Rottela, Srikanth Jampala, Gagandeep Singh, Jay Zhou,
Ravi Kumar, Richardson, Bruce, olivier.matz,
honnappa.nagarahalli, Stephen Hemminger, alexr
Hi David,
> Hi Akhil,
>
> > -----Original Message-----
> > From: Akhil Goyal <akhil.goyal@nxp.com>
> > Sent: Wednesday, April 22, 2020 11:51 AM
> > Hi David,
> > > > >>
> > > > >> I don't agree rte_security addresses the problem of different
> > > > >> device types supporting the same services. The problem being
> > > > >> addressed here is a single device which supports the chaining of
> > > > >> multiple services (sym crypto & error detection)
> > > > >
> > > > > Doing IPsec processing in Rx or Tx of a NIC is not chaining?
> > > > >
> > > > I wouldn't consider an inline crypto offload or full IPsec offload a
> > > > chained operation in the vein being proposed here where completely
> > > > independent services (in the view of DPDK which are currently on
> > > > independent devices and APIs) are linked together.
> > > >
> > > > We did look at using rte_security here but it wasn't considered
> > > > suitable for a chaining of non-crypto operations such as CRC or
> > > > possibly compression in the future, as it would still run into the
> > > > issue of having to use the cryptodev enq/deq API in the lookaside offload
> > case.
> > > >
> > > >
> > I did not look at your patches completely, but looking at the ops that you
> > have added For rawdev are pretty much same as that of a crypto device.
> >
> > I see that there are 2 types of ops that you need
> > - session create/destroy
> > - enq/deq
> >
> > On the first impression of your patchset, I see that you want to enq to driver
> > only once for both The operations - CRC and crypto.
> >
> > So what is the issue in using the cryptodev_enqueue for processing in the
> > existing AESNI-MB driver.
> > For session creation, the cryptodev layer will not give flexibility to add
> > CRC+crypto kind of sessions.
> > But in case of rte_security, you can define your new session xform based on
> > your requirement.
> >
> > And while doing the cryptodev enq/deq, based on the session type, you can
> > process the packet Specific to your usecase in your aesni-mb PMD
> >
> > Now if you want to add compression also along with crypto, then you can
> > define another xform which Will be combination of crypto+compression and
> > the aesni-mb PMD can have another mode which Can make sessions based
> > on the new xform and the enq and deq can be done using the cryptodev
> > enq/deq.
> > For all your cases you will be having only one action type - lookaside protocol
> > and can define different Protocols (that may not be standard).
> >
> > So to conclude, your AESNI-MB will have 3 types of operations
> > - plain crypto
> > - crc+crypto
> > - compression+crypto
> >
> > I believe this is doable or did I miss something very obvious?
>
> [DC] Thank you for this feedback
>
> I have done this exact same analysis on rte_security and how we could use it.
>
> The main issue of this approach (and it may be possible to easily overcome) is
> that ultimately crypto_op's need
> to be enqueued into cryptodev. This means we can't easily control the CRC (or
> compression in the future) at the
> operation level - application developers using this API would create a
> Crypto+CRC security xform session for a
> particular flow but may want to turn off the CRC part for some packets in that
> flow.
>
> There are a number of ways this issue could possibly be overcome:
> 1) the auth offset/length fields in a rte_crypto_op could be overloaded to
> control the CRC part of the combined operation
> - this is not the cleanest approach
> 2) we add a "security" op struct of some type to the union at end of the
> rte_crypto_op
> - to avoid any circular dependencies, this would need to be opaque to
> rte_cryptodev
> - rte_cryptodev should not be aware of rte_security
>
> Number 2 above is probably the cleaner and more preferable approach.
Yes, it is preferred, but it should be a union to rte_crypto_sym_op/rte_crypto_asym_op.
Crypto_op->type as RTE_CRYPTO_OP_TYPE_SECURITY and sess_type as
RTE_CRYPTO_OP_SECURITY_SESSION
The size of rte_crypto_op will remain as is and there will be no ABI breakage I guess.
One more thing that can be looked into is the recently added CPU crypto process API
If that could of any use, we may extend that if need be.
>
> The other approach is that CRC is either on/off at the session level. That
> limitation would then need to be adhered
> by application developers, which is something we would ideally like to avoid.
You mean that CRC can be on/off per session as well as per packet?
I think that can also be handled when you are defining your own security_op for per packet.
>
> The rawdev multi-function approach did not have these issues which is one of
> the reasons we have pursued this
> approach to date.
>
> However, we think the rte_security approach is workable.
> It still requires some deeper analysis but with your support, we think we can
> overcome the challenges.
>
Yes, please let me know where ever my help is required.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-22 13:19 4% ` Ray Kinsella
@ 2020-04-22 13:30 4% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2020-04-22 13:30 UTC (permalink / raw)
To: Neil Horman, Ray Kinsella; +Cc: dev, david.marchand
22/04/2020 15:19, Ray Kinsella:
> On 22/04/2020 13:18, Thomas Monjalon wrote:
> > 22/04/2020 14:07, Neil Horman:
> >> On Wed, Apr 22, 2020 at 12:43:44PM +0100, Ray Kinsella wrote:
> >>> On 21/04/2020 22:42, Thomas Monjalon wrote:
> >>>> 21/04/2020 20:56, Neil Horman:
> >>>>> On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
> >>>>>> 21/04/2020 13:12, Neil Horman:
> >>>>>>> On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> >>>>>>>> On 17/04/2020 13:10, Thomas Monjalon wrote:
> >>>>>>>>> 17/04/2020 13:47, Ray Kinsella:
> >>>>>>>>>> On 17/04/2020 11:20, Thomas Monjalon wrote:
> >>>>>>>>>>> 17/04/2020 12:11, Ray Kinsella:
> >>>>>>>>>>>> check-abi.sh appears to be backward step in terms of usability.
> >>>>>>>>>>>
> >>>>>>>>>>> No, check-abi.sh benefits from a nice integration in build scripts.
> >>>>>>>>>>> See below.
> >>>>>>>>>>>
> >>>>>>>>>>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> >>>>>>>>>>>> And it will do the build, install, dump and comparison for me.
> >>>>>>>>>>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> >>>>>>>>>>>>
> >>>>>>>>>>>> With check-abi on the other hand, I need to the build and install myself.
> >>>>>>>>>>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> >>>>>>>>>>>> It silently fails when it doesn't find any ...
> >>>>>>>>>>>>
> >>>>>>>>>>>> Do I run abi-dumper on the so's myself, or how does it work?
> >>>>>>>>>>>
> >>>>>>>>>>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> >>>>>>>>>>> Probably we should document usage in these scripts.
> >>>>>>>>>>
> >>>>>>>>>> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> >>>>>>>>>> Any tips or tricks would be welcome.
> >>>>>>>>>
> >>>>>>>>> export DPDK_ABI_REF_VERSION=v20.02
> >>>>>>>>> or
> >>>>>>>>> export DPDK_ABI_REF_VERSION=v19.11
> >>>>>>>>>
> >>>>>>>>> Depends on which compatibility you want to test...
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> Few things ...
> >>>>>>>>
> >>>>>>>> 1. test-meson-build.sh keep barfing complaining about reference paths.
> >>>>>>>> ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> >>>>>>>>
> >>>>>>>> Under the hood, ninja install is failing complaining that it needs an absolute path.
> >>>>>>>> I fixed this in test_meson_build.sh and will send a patch in a minute.
> >>>>>>>> Though it's strange no-one else has seen it?
> >>>>>>>>
> >>>>>>>> 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> >>>>>>>>
> >>>>>>>> 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> >>>>>>>> In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> >>>>>>>> I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> >>>>>>>>
> >>>>>>> I think this code in test-meson-build.sh should probably be fixed:
> >>>>>>>
> >>>>>>> if [ ! -d $abirefdir/src ]; then
> >>>>>>> git clone --local --no-hardlinks \
> >>>>>>> --single-branch \
> >>>>>>> -b $DPDK_ABI_REF_VERSION \
> >>>>>>> $srcdir $abirefdir/src
> >>>>>>> fi
> >>>>>>>
> >>>>>>> Like you noted, using -b allows us to checkout a tag/branch in the cloned
> >>>>>>> repository but requires that it exist locally. We should probably prefix the
> >>>>>>> checkout with a git fetch --tags
> >>>>>>
> >>>>>> I don't understand your concern.
> >>>>>> A reference is an older version, so it should be in the git tree.
> >>>>>>
> >>>>> yes, but not unless you've done a recent pull or fetch. If you set
> >>>>> DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
> >>>>> updated the tree, it won't be there (which it sounds like what is being
> >>>>> encountered here). You can fix that by doing a git pull or git fetch prior to
> >>>>> running this script (or internal to the script)
> >>>>
> >>>> Sorry I still don't understand the case.
> >>>> We want to compare the current version C with a reference R which is older.
> >>>> If the reference R is not in the tree, it means the version C is not in the tree.
> >>>> But C is the current version, so it is in the tree by definition.
> >>>>
> >>>
> >>> So I can just relate my experience ....
> >>>
> >>> root@silpixa00395806:/build/dpdk# DPDK_ABI_REF_VERSION=HEAD~1 ./devtools/test-meson-builds.sh
> >>> ninja -C ./build-gcc-static
> >>> ninja: Entering directory `./build-gcc-static'
> >>> [1766/2204] Compiling C object 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_channel_monitor.c.o'.
> >>> ../examples/vm_power_manager/channel_monitor.c:22:9: note: #pragma message: Jansson dev libs unavailable, not including JSON parsing
> >>> #pragma message "Jansson dev libs unavailable, not including JSON parsing"
> >>> ^~~~~~~
> >>> [2204/2204] Linking target drivers/librte_pmd_softnic.so.20.0.2.
> >>> Cloning into 'reference/HEAD~1/src'...
> >>> warning: Could not find remote branch HEAD~1 to clone.
> >>> fatal: Remote branch HEAD~1 not found in upstream origin
> >>> fatal: The remote end hung up unexpectedly
> >>>
> >> Ah, So its not the problem i was describing, I think the problem you are seeing
> >> is that the -b option only operates on branches and tags, not arbitrary git
> >> revisions.
> >>
> >> To fix that, what we probably need to do is alter test-build.sh and
> >> test-meson-build.sh such that the git clone operation is preceded by something
> >> like this:
> >> git tag ABI_CHECK_TAG $DPDK_ABI_REF_VERSION
> >>
> >> git clone ....
> >>
> >> git tag -d ABI_CHECK_TAG
> >>
> >> Doing so will guarantee that the source tree has a tag reference that the git
> >> clone operation can use to do a checkout with a -b option on.
> >
> > I don't see the benefit of such test.
> > Can we just document that the reference must be an existing tag?
> >
> You want people to use this thing right?
Yes, compare their own code with a well known tag.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-22 12:18 4% ` Thomas Monjalon
@ 2020-04-22 13:19 4% ` Ray Kinsella
2020-04-22 13:30 4% ` Thomas Monjalon
2020-04-23 11:03 7% ` Neil Horman
1 sibling, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-22 13:19 UTC (permalink / raw)
To: Thomas Monjalon, Neil Horman; +Cc: dev, david.marchand
On 22/04/2020 13:18, Thomas Monjalon wrote:
> 22/04/2020 14:07, Neil Horman:
>> On Wed, Apr 22, 2020 at 12:43:44PM +0100, Ray Kinsella wrote:
>>> On 21/04/2020 22:42, Thomas Monjalon wrote:
>>>> 21/04/2020 20:56, Neil Horman:
>>>>> On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
>>>>>> 21/04/2020 13:12, Neil Horman:
>>>>>>> On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
>>>>>>>> On 17/04/2020 13:10, Thomas Monjalon wrote:
>>>>>>>>> 17/04/2020 13:47, Ray Kinsella:
>>>>>>>>>> On 17/04/2020 11:20, Thomas Monjalon wrote:
>>>>>>>>>>> 17/04/2020 12:11, Ray Kinsella:
>>>>>>>>>>>> check-abi.sh appears to be backward step in terms of usability.
>>>>>>>>>>>
>>>>>>>>>>> No, check-abi.sh benefits from a nice integration in build scripts.
>>>>>>>>>>> See below.
>>>>>>>>>>>
>>>>>>>>>>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
>>>>>>>>>>>> And it will do the build, install, dump and comparison for me.
>>>>>>>>>>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
>>>>>>>>>>>>
>>>>>>>>>>>> With check-abi on the other hand, I need to the build and install myself.
>>>>>>>>>>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
>>>>>>>>>>>> It silently fails when it doesn't find any ...
>>>>>>>>>>>>
>>>>>>>>>>>> Do I run abi-dumper on the so's myself, or how does it work?
>>>>>>>>>>>
>>>>>>>>>>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
>>>>>>>>>>> Probably we should document usage in these scripts.
>>>>>>>>>>
>>>>>>>>>> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
>>>>>>>>>> Any tips or tricks would be welcome.
>>>>>>>>>
>>>>>>>>> export DPDK_ABI_REF_VERSION=v20.02
>>>>>>>>> or
>>>>>>>>> export DPDK_ABI_REF_VERSION=v19.11
>>>>>>>>>
>>>>>>>>> Depends on which compatibility you want to test...
>>>>>>>>>
>>>>>>>>
>>>>>>>> Few things ...
>>>>>>>>
>>>>>>>> 1. test-meson-build.sh keep barfing complaining about reference paths.
>>>>>>>> ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
>>>>>>>>
>>>>>>>> Under the hood, ninja install is failing complaining that it needs an absolute path.
>>>>>>>> I fixed this in test_meson_build.sh and will send a patch in a minute.
>>>>>>>> Though it's strange no-one else has seen it?
>>>>>>>>
>>>>>>>> 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
>>>>>>>>
>>>>>>>> 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
>>>>>>>> In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
>>>>>>>> I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
>>>>>>>>
>>>>>>> I think this code in test-meson-build.sh should probably be fixed:
>>>>>>>
>>>>>>> if [ ! -d $abirefdir/src ]; then
>>>>>>> git clone --local --no-hardlinks \
>>>>>>> --single-branch \
>>>>>>> -b $DPDK_ABI_REF_VERSION \
>>>>>>> $srcdir $abirefdir/src
>>>>>>> fi
>>>>>>>
>>>>>>> Like you noted, using -b allows us to checkout a tag/branch in the cloned
>>>>>>> repository but requires that it exist locally. We should probably prefix the
>>>>>>> checkout with a git fetch --tags
>>>>>>
>>>>>> I don't understand your concern.
>>>>>> A reference is an older version, so it should be in the git tree.
>>>>>>
>>>>> yes, but not unless you've done a recent pull or fetch. If you set
>>>>> DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
>>>>> updated the tree, it won't be there (which it sounds like what is being
>>>>> encountered here). You can fix that by doing a git pull or git fetch prior to
>>>>> running this script (or internal to the script)
>>>>
>>>> Sorry I still don't understand the case.
>>>> We want to compare the current version C with a reference R which is older.
>>>> If the reference R is not in the tree, it means the version C is not in the tree.
>>>> But C is the current version, so it is in the tree by definition.
>>>>
>>>
>>> So I can just relate my experience ....
>>>
>>> root@silpixa00395806:/build/dpdk# DPDK_ABI_REF_VERSION=HEAD~1 ./devtools/test-meson-builds.sh
>>> ninja -C ./build-gcc-static
>>> ninja: Entering directory `./build-gcc-static'
>>> [1766/2204] Compiling C object 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_channel_monitor.c.o'.
>>> ../examples/vm_power_manager/channel_monitor.c:22:9: note: #pragma message: Jansson dev libs unavailable, not including JSON parsing
>>> #pragma message "Jansson dev libs unavailable, not including JSON parsing"
>>> ^~~~~~~
>>> [2204/2204] Linking target drivers/librte_pmd_softnic.so.20.0.2.
>>> Cloning into 'reference/HEAD~1/src'...
>>> warning: Could not find remote branch HEAD~1 to clone.
>>> fatal: Remote branch HEAD~1 not found in upstream origin
>>> fatal: The remote end hung up unexpectedly
>>>
>> Ah, So its not the problem i was describing, I think the problem you are seeing
>> is that the -b option only operates on branches and tags, not arbitrary git
>> revisions.
>>
>> To fix that, what we probably need to do is alter test-build.sh and
>> test-meson-build.sh such that the git clone operation is preceded by something
>> like this:
>> git tag ABI_CHECK_TAG $DPDK_ABI_REF_VERSION
>>
>> git clone ....
>>
>> git tag -d ABI_CHECK_TAG
>>
>> Doing so will guarantee that the source tree has a tag reference that the git
>> clone operation can use to do a checkout with a -b option on.
>
> I don't see the benefit of such test.
> Can we just document that the reference must be an existing tag?
>
You want people to use this thing right?
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-22 12:07 4% ` Neil Horman
@ 2020-04-22 12:18 4% ` Thomas Monjalon
2020-04-22 13:19 4% ` Ray Kinsella
2020-04-23 11:03 7% ` Neil Horman
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2020-04-22 12:18 UTC (permalink / raw)
To: Ray Kinsella, Neil Horman; +Cc: dev, david.marchand
22/04/2020 14:07, Neil Horman:
> On Wed, Apr 22, 2020 at 12:43:44PM +0100, Ray Kinsella wrote:
> > On 21/04/2020 22:42, Thomas Monjalon wrote:
> > > 21/04/2020 20:56, Neil Horman:
> > >> On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
> > >>> 21/04/2020 13:12, Neil Horman:
> > >>>> On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> > >>>>> On 17/04/2020 13:10, Thomas Monjalon wrote:
> > >>>>>> 17/04/2020 13:47, Ray Kinsella:
> > >>>>>>> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > >>>>>>>> 17/04/2020 12:11, Ray Kinsella:
> > >>>>>>>>> check-abi.sh appears to be backward step in terms of usability.
> > >>>>>>>>
> > >>>>>>>> No, check-abi.sh benefits from a nice integration in build scripts.
> > >>>>>>>> See below.
> > >>>>>>>>
> > >>>>>>>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> > >>>>>>>>> And it will do the build, install, dump and comparison for me.
> > >>>>>>>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> > >>>>>>>>>
> > >>>>>>>>> With check-abi on the other hand, I need to the build and install myself.
> > >>>>>>>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> > >>>>>>>>> It silently fails when it doesn't find any ...
> > >>>>>>>>>
> > >>>>>>>>> Do I run abi-dumper on the so's myself, or how does it work?
> > >>>>>>>>
> > >>>>>>>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > >>>>>>>> Probably we should document usage in these scripts.
> > >>>>>>>
> > >>>>>>> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> > >>>>>>> Any tips or tricks would be welcome.
> > >>>>>>
> > >>>>>> export DPDK_ABI_REF_VERSION=v20.02
> > >>>>>> or
> > >>>>>> export DPDK_ABI_REF_VERSION=v19.11
> > >>>>>>
> > >>>>>> Depends on which compatibility you want to test...
> > >>>>>>
> > >>>>>
> > >>>>> Few things ...
> > >>>>>
> > >>>>> 1. test-meson-build.sh keep barfing complaining about reference paths.
> > >>>>> ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> > >>>>>
> > >>>>> Under the hood, ninja install is failing complaining that it needs an absolute path.
> > >>>>> I fixed this in test_meson_build.sh and will send a patch in a minute.
> > >>>>> Though it's strange no-one else has seen it?
> > >>>>>
> > >>>>> 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> > >>>>>
> > >>>>> 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> > >>>>> In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> > >>>>> I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> > >>>>>
> > >>>> I think this code in test-meson-build.sh should probably be fixed:
> > >>>>
> > >>>> if [ ! -d $abirefdir/src ]; then
> > >>>> git clone --local --no-hardlinks \
> > >>>> --single-branch \
> > >>>> -b $DPDK_ABI_REF_VERSION \
> > >>>> $srcdir $abirefdir/src
> > >>>> fi
> > >>>>
> > >>>> Like you noted, using -b allows us to checkout a tag/branch in the cloned
> > >>>> repository but requires that it exist locally. We should probably prefix the
> > >>>> checkout with a git fetch --tags
> > >>>
> > >>> I don't understand your concern.
> > >>> A reference is an older version, so it should be in the git tree.
> > >>>
> > >> yes, but not unless you've done a recent pull or fetch. If you set
> > >> DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
> > >> updated the tree, it won't be there (which it sounds like what is being
> > >> encountered here). You can fix that by doing a git pull or git fetch prior to
> > >> running this script (or internal to the script)
> > >
> > > Sorry I still don't understand the case.
> > > We want to compare the current version C with a reference R which is older.
> > > If the reference R is not in the tree, it means the version C is not in the tree.
> > > But C is the current version, so it is in the tree by definition.
> > >
> >
> > So I can just relate my experience ....
> >
> > root@silpixa00395806:/build/dpdk# DPDK_ABI_REF_VERSION=HEAD~1 ./devtools/test-meson-builds.sh
> > ninja -C ./build-gcc-static
> > ninja: Entering directory `./build-gcc-static'
> > [1766/2204] Compiling C object 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_channel_monitor.c.o'.
> > ../examples/vm_power_manager/channel_monitor.c:22:9: note: #pragma message: Jansson dev libs unavailable, not including JSON parsing
> > #pragma message "Jansson dev libs unavailable, not including JSON parsing"
> > ^~~~~~~
> > [2204/2204] Linking target drivers/librte_pmd_softnic.so.20.0.2.
> > Cloning into 'reference/HEAD~1/src'...
> > warning: Could not find remote branch HEAD~1 to clone.
> > fatal: Remote branch HEAD~1 not found in upstream origin
> > fatal: The remote end hung up unexpectedly
> >
> Ah, So its not the problem i was describing, I think the problem you are seeing
> is that the -b option only operates on branches and tags, not arbitrary git
> revisions.
>
> To fix that, what we probably need to do is alter test-build.sh and
> test-meson-build.sh such that the git clone operation is preceded by something
> like this:
> git tag ABI_CHECK_TAG $DPDK_ABI_REF_VERSION
>
> git clone ....
>
> git tag -d ABI_CHECK_TAG
>
> Doing so will guarantee that the source tree has a tag reference that the git
> clone operation can use to do a checkout with a -b option on.
I don't see the benefit of such test.
Can we just document that the reference must be an existing tag?
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-22 12:01 8% ` Neil Horman
@ 2020-04-22 12:16 4% ` Thomas Monjalon
2020-04-23 10:57 4% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-22 12:16 UTC (permalink / raw)
To: Neil Horman; +Cc: Ray Kinsella, dev, david.marchand
22/04/2020 14:01, Neil Horman:
> On Tue, Apr 21, 2020 at 11:42:42PM +0200, Thomas Monjalon wrote:
> > 21/04/2020 20:56, Neil Horman:
> > > On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
> > > > 21/04/2020 13:12, Neil Horman:
> > > > > On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> > > > > > On 17/04/2020 13:10, Thomas Monjalon wrote:
> > > > > > > 17/04/2020 13:47, Ray Kinsella:
> > > > > > >> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > > > > > >>> 17/04/2020 12:11, Ray Kinsella:
> > > > > > >>>> check-abi.sh appears to be backward step in terms of usability.
> > > > > > >>>
> > > > > > >>> No, check-abi.sh benefits from a nice integration in build scripts.
> > > > > > >>> See below.
> > > > > > >>>
> > > > > > >>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> > > > > > >>>> And it will do the build, install, dump and comparison for me.
> > > > > > >>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> > > > > > >>>>
> > > > > > >>>> With check-abi on the other hand, I need to the build and install myself.
> > > > > > >>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> > > > > > >>>> It silently fails when it doesn't find any ...
> > > > > > >>>>
> > > > > > >>>> Do I run abi-dumper on the so's myself, or how does it work?
> > > > > > >>>
> > > > > > >>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > > > > > >>> Probably we should document usage in these scripts.
> > > > > > >>
> > > > > > >> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> > > > > > >> Any tips or tricks would be welcome.
> > > > > > >
> > > > > > > export DPDK_ABI_REF_VERSION=v20.02
> > > > > > > or
> > > > > > > export DPDK_ABI_REF_VERSION=v19.11
> > > > > > >
> > > > > > > Depends on which compatibility you want to test...
> > > > > > >
> > > > > >
> > > > > > Few things ...
> > > > > >
> > > > > > 1. test-meson-build.sh keep barfing complaining about reference paths.
> > > > > > ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> > > > > >
> > > > > > Under the hood, ninja install is failing complaining that it needs an absolute path.
> > > > > > I fixed this in test_meson_build.sh and will send a patch in a minute.
> > > > > > Though it's strange no-one else has seen it?
> > > > > >
> > > > > > 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> > > > > >
> > > > > > 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> > > > > > In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> > > > > > I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> > > > > >
> > > > > I think this code in test-meson-build.sh should probably be fixed:
> > > > >
> > > > > if [ ! -d $abirefdir/src ]; then
> > > > > git clone --local --no-hardlinks \
> > > > > --single-branch \
> > > > > -b $DPDK_ABI_REF_VERSION \
> > > > > $srcdir $abirefdir/src
> > > > > fi
> > > > >
> > > > > Like you noted, using -b allows us to checkout a tag/branch in the cloned
> > > > > repository but requires that it exist locally. We should probably prefix the
> > > > > checkout with a git fetch --tags
> > > >
> > > > I don't understand your concern.
> > > > A reference is an older version, so it should be in the git tree.
> > > >
> > > yes, but not unless you've done a recent pull or fetch. If you set
> > > DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
> > > updated the tree, it won't be there (which it sounds like what is being
> > > encountered here). You can fix that by doing a git pull or git fetch prior to
> > > running this script (or internal to the script)
> >
> > Sorry I still don't understand the case.
> > We want to compare the current version C with a reference R which is older.
> > If the reference R is not in the tree, it means the version C is not in the tree.
> > But C is the current version, so it is in the tree by definition.
> >
>
>
> +---+
> | |
> +---+ | | DPDK 20.11
> | |Feature Branch commit +-+-+
> | | |
> +-+-+ +---+ +-v-+
> | | | master HEAD | | master HEAD
> | +-+-+ +-+-+
> | | |
> | | |
> | +-v-+ +-v-+
> +---->+ | DPDK 19.11 | | DPDK 19.11
> +---+ +---+
> X X X X
> XXXXXXX XXXXXXXXX XXXXXXX XXXXXXXXX
> XXX XX XXX XX
> XXXX XXXX
>
> Local GIT copy DPDK.ORG
>
>
>
> If a user clones from dpdk.org when dpdk 19.11 is tagged in the tree, or any
> time before dpdk 20.11 is tagged, then creates a feature branch, they may want
> to compare their abi to the latest stable version. If they check dpdk.org and
> see that dpdk 20.11 is the latest tag in the tree, they can run check-abi.sh
> with the reference tag specified as 20.11, which exists in the dpdk.org tree,
> but may not have been pulled into their local copy yet.
>
> I'm not saying this is definately what happened, but it would explain the
> reported observations.
OK now I understand.
The user specified a reference which is not in his local tree.
I vote for considering this case as an user mistake,
and document it as a limitation of the tool integration in our build
testing scripts.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-22 11:43 4% ` Ray Kinsella
@ 2020-04-22 12:07 4% ` Neil Horman
2020-04-22 12:18 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2020-04-22 12:07 UTC (permalink / raw)
To: Ray Kinsella; +Cc: Thomas Monjalon, dev, david.marchand
On Wed, Apr 22, 2020 at 12:43:44PM +0100, Ray Kinsella wrote:
>
>
> On 21/04/2020 22:42, Thomas Monjalon wrote:
> > 21/04/2020 20:56, Neil Horman:
> >> On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
> >>> 21/04/2020 13:12, Neil Horman:
> >>>> On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> >>>>> On 17/04/2020 13:10, Thomas Monjalon wrote:
> >>>>>> 17/04/2020 13:47, Ray Kinsella:
> >>>>>>> On 17/04/2020 11:20, Thomas Monjalon wrote:
> >>>>>>>> 17/04/2020 12:11, Ray Kinsella:
> >>>>>>>>> check-abi.sh appears to be backward step in terms of usability.
> >>>>>>>>
> >>>>>>>> No, check-abi.sh benefits from a nice integration in build scripts.
> >>>>>>>> See below.
> >>>>>>>>
> >>>>>>>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> >>>>>>>>> And it will do the build, install, dump and comparison for me.
> >>>>>>>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> >>>>>>>>>
> >>>>>>>>> With check-abi on the other hand, I need to the build and install myself.
> >>>>>>>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> >>>>>>>>> It silently fails when it doesn't find any ...
> >>>>>>>>>
> >>>>>>>>> Do I run abi-dumper on the so's myself, or how does it work?
> >>>>>>>>
> >>>>>>>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> >>>>>>>> Probably we should document usage in these scripts.
> >>>>>>>
> >>>>>>> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> >>>>>>> Any tips or tricks would be welcome.
> >>>>>>
> >>>>>> export DPDK_ABI_REF_VERSION=v20.02
> >>>>>> or
> >>>>>> export DPDK_ABI_REF_VERSION=v19.11
> >>>>>>
> >>>>>> Depends on which compatibility you want to test...
> >>>>>>
> >>>>>
> >>>>> Few things ...
> >>>>>
> >>>>> 1. test-meson-build.sh keep barfing complaining about reference paths.
> >>>>> ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> >>>>>
> >>>>> Under the hood, ninja install is failing complaining that it needs an absolute path.
> >>>>> I fixed this in test_meson_build.sh and will send a patch in a minute.
> >>>>> Though it's strange no-one else has seen it?
> >>>>>
> >>>>> 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> >>>>>
> >>>>> 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> >>>>> In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> >>>>> I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> >>>>>
> >>>> I think this code in test-meson-build.sh should probably be fixed:
> >>>>
> >>>> if [ ! -d $abirefdir/src ]; then
> >>>> git clone --local --no-hardlinks \
> >>>> --single-branch \
> >>>> -b $DPDK_ABI_REF_VERSION \
> >>>> $srcdir $abirefdir/src
> >>>> fi
> >>>>
> >>>> Like you noted, using -b allows us to checkout a tag/branch in the cloned
> >>>> repository but requires that it exist locally. We should probably prefix the
> >>>> checkout with a git fetch --tags
> >>>
> >>> I don't understand your concern.
> >>> A reference is an older version, so it should be in the git tree.
> >>>
> >> yes, but not unless you've done a recent pull or fetch. If you set
> >> DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
> >> updated the tree, it won't be there (which it sounds like what is being
> >> encountered here). You can fix that by doing a git pull or git fetch prior to
> >> running this script (or internal to the script)
> >
> > Sorry I still don't understand the case.
> > We want to compare the current version C with a reference R which is older.
> > If the reference R is not in the tree, it means the version C is not in the tree.
> > But C is the current version, so it is in the tree by definition.
> >
>
> So I can just relate my experience ....
>
> root@silpixa00395806:/build/dpdk# DPDK_ABI_REF_VERSION=HEAD~1 ./devtools/test-meson-builds.sh
> ninja -C ./build-gcc-static
> ninja: Entering directory `./build-gcc-static'
> [1766/2204] Compiling C object 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_channel_monitor.c.o'.
> ../examples/vm_power_manager/channel_monitor.c:22:9: note: #pragma message: Jansson dev libs unavailable, not including JSON parsing
> #pragma message "Jansson dev libs unavailable, not including JSON parsing"
> ^~~~~~~
> [2204/2204] Linking target drivers/librte_pmd_softnic.so.20.0.2.
> Cloning into 'reference/HEAD~1/src'...
> warning: Could not find remote branch HEAD~1 to clone.
> fatal: Remote branch HEAD~1 not found in upstream origin
> fatal: The remote end hung up unexpectedly
>
Ah, So its not the problem i was describing, I think the problem you are seeing
is that the -b option only operates on branches and tags, not arbitrary git
revisions.
To fix that, what we probably need to do is alter test-build.sh and
test-meson-build.sh such that the git clone operation is preceded by something
like this:
git tag ABI_CHECK_TAG $DPDK_ABI_REF_VERSION
git clone ....
git tag -d ABI_CHECK_TAG
Doing so will guarantee that the source tree has a tag reference that the git
clone operation can use to do a checkout with a -b option on.
Neil
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-21 21:42 4% ` Thomas Monjalon
2020-04-22 11:43 4% ` Ray Kinsella
@ 2020-04-22 12:01 8% ` Neil Horman
2020-04-22 12:16 4% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Neil Horman @ 2020-04-22 12:01 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Ray Kinsella, dev, david.marchand
On Tue, Apr 21, 2020 at 11:42:42PM +0200, Thomas Monjalon wrote:
> 21/04/2020 20:56, Neil Horman:
> > On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
> > > 21/04/2020 13:12, Neil Horman:
> > > > On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> > > > > On 17/04/2020 13:10, Thomas Monjalon wrote:
> > > > > > 17/04/2020 13:47, Ray Kinsella:
> > > > > >> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > > > > >>> 17/04/2020 12:11, Ray Kinsella:
> > > > > >>>> check-abi.sh appears to be backward step in terms of usability.
> > > > > >>>
> > > > > >>> No, check-abi.sh benefits from a nice integration in build scripts.
> > > > > >>> See below.
> > > > > >>>
> > > > > >>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> > > > > >>>> And it will do the build, install, dump and comparison for me.
> > > > > >>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> > > > > >>>>
> > > > > >>>> With check-abi on the other hand, I need to the build and install myself.
> > > > > >>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> > > > > >>>> It silently fails when it doesn't find any ...
> > > > > >>>>
> > > > > >>>> Do I run abi-dumper on the so's myself, or how does it work?
> > > > > >>>
> > > > > >>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > > > > >>> Probably we should document usage in these scripts.
> > > > > >>
> > > > > >> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> > > > > >> Any tips or tricks would be welcome.
> > > > > >
> > > > > > export DPDK_ABI_REF_VERSION=v20.02
> > > > > > or
> > > > > > export DPDK_ABI_REF_VERSION=v19.11
> > > > > >
> > > > > > Depends on which compatibility you want to test...
> > > > > >
> > > > >
> > > > > Few things ...
> > > > >
> > > > > 1. test-meson-build.sh keep barfing complaining about reference paths.
> > > > > ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> > > > >
> > > > > Under the hood, ninja install is failing complaining that it needs an absolute path.
> > > > > I fixed this in test_meson_build.sh and will send a patch in a minute.
> > > > > Though it's strange no-one else has seen it?
> > > > >
> > > > > 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> > > > >
> > > > > 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> > > > > In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> > > > > I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> > > > >
> > > > I think this code in test-meson-build.sh should probably be fixed:
> > > >
> > > > if [ ! -d $abirefdir/src ]; then
> > > > git clone --local --no-hardlinks \
> > > > --single-branch \
> > > > -b $DPDK_ABI_REF_VERSION \
> > > > $srcdir $abirefdir/src
> > > > fi
> > > >
> > > > Like you noted, using -b allows us to checkout a tag/branch in the cloned
> > > > repository but requires that it exist locally. We should probably prefix the
> > > > checkout with a git fetch --tags
> > >
> > > I don't understand your concern.
> > > A reference is an older version, so it should be in the git tree.
> > >
> > yes, but not unless you've done a recent pull or fetch. If you set
> > DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
> > updated the tree, it won't be there (which it sounds like what is being
> > encountered here). You can fix that by doing a git pull or git fetch prior to
> > running this script (or internal to the script)
>
> Sorry I still don't understand the case.
> We want to compare the current version C with a reference R which is older.
> If the reference R is not in the tree, it means the version C is not in the tree.
> But C is the current version, so it is in the tree by definition.
>
+---+
| |
+---+ | | DPDK 20.11
| |Feature Branch commit +-+-+
| | |
+-+-+ +---+ +-v-+
| | | master HEAD | | master HEAD
| +-+-+ +-+-+
| | |
| | |
| +-v-+ +-v-+
+---->+ | DPDK 19.11 | | DPDK 19.11
+---+ +---+
X X X X
XXXXXXX XXXXXXXXX XXXXXXX XXXXXXXXX
XXX XX XXX XX
XXXX XXXX
Local GIT copy DPDK.ORG
If a user clones from dpdk.org when dpdk 19.11 is tagged in the tree, or any
time before dpdk 20.11 is tagged, then creates a feature branch, they may want
to compare their abi to the latest stable version. If they check dpdk.org and
see that dpdk 20.11 is the latest tag in the tree, they can run check-abi.sh
with the reference tag specified as 20.11, which exists in the dpdk.org tree,
but may not have been pulled into their local copy yet.
I'm not saying this is definately what happened, but it would explain the
reported observations.
Neil
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-21 21:42 4% ` Thomas Monjalon
@ 2020-04-22 11:43 4% ` Ray Kinsella
2020-04-22 12:07 4% ` Neil Horman
2020-04-22 12:01 8% ` Neil Horman
1 sibling, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-22 11:43 UTC (permalink / raw)
To: Thomas Monjalon, Neil Horman; +Cc: dev, david.marchand
On 21/04/2020 22:42, Thomas Monjalon wrote:
> 21/04/2020 20:56, Neil Horman:
>> On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
>>> 21/04/2020 13:12, Neil Horman:
>>>> On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
>>>>> On 17/04/2020 13:10, Thomas Monjalon wrote:
>>>>>> 17/04/2020 13:47, Ray Kinsella:
>>>>>>> On 17/04/2020 11:20, Thomas Monjalon wrote:
>>>>>>>> 17/04/2020 12:11, Ray Kinsella:
>>>>>>>>> check-abi.sh appears to be backward step in terms of usability.
>>>>>>>>
>>>>>>>> No, check-abi.sh benefits from a nice integration in build scripts.
>>>>>>>> See below.
>>>>>>>>
>>>>>>>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
>>>>>>>>> And it will do the build, install, dump and comparison for me.
>>>>>>>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
>>>>>>>>>
>>>>>>>>> With check-abi on the other hand, I need to the build and install myself.
>>>>>>>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
>>>>>>>>> It silently fails when it doesn't find any ...
>>>>>>>>>
>>>>>>>>> Do I run abi-dumper on the so's myself, or how does it work?
>>>>>>>>
>>>>>>>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
>>>>>>>> Probably we should document usage in these scripts.
>>>>>>>
>>>>>>> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
>>>>>>> Any tips or tricks would be welcome.
>>>>>>
>>>>>> export DPDK_ABI_REF_VERSION=v20.02
>>>>>> or
>>>>>> export DPDK_ABI_REF_VERSION=v19.11
>>>>>>
>>>>>> Depends on which compatibility you want to test...
>>>>>>
>>>>>
>>>>> Few things ...
>>>>>
>>>>> 1. test-meson-build.sh keep barfing complaining about reference paths.
>>>>> ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
>>>>>
>>>>> Under the hood, ninja install is failing complaining that it needs an absolute path.
>>>>> I fixed this in test_meson_build.sh and will send a patch in a minute.
>>>>> Though it's strange no-one else has seen it?
>>>>>
>>>>> 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
>>>>>
>>>>> 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
>>>>> In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
>>>>> I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
>>>>>
>>>> I think this code in test-meson-build.sh should probably be fixed:
>>>>
>>>> if [ ! -d $abirefdir/src ]; then
>>>> git clone --local --no-hardlinks \
>>>> --single-branch \
>>>> -b $DPDK_ABI_REF_VERSION \
>>>> $srcdir $abirefdir/src
>>>> fi
>>>>
>>>> Like you noted, using -b allows us to checkout a tag/branch in the cloned
>>>> repository but requires that it exist locally. We should probably prefix the
>>>> checkout with a git fetch --tags
>>>
>>> I don't understand your concern.
>>> A reference is an older version, so it should be in the git tree.
>>>
>> yes, but not unless you've done a recent pull or fetch. If you set
>> DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
>> updated the tree, it won't be there (which it sounds like what is being
>> encountered here). You can fix that by doing a git pull or git fetch prior to
>> running this script (or internal to the script)
>
> Sorry I still don't understand the case.
> We want to compare the current version C with a reference R which is older.
> If the reference R is not in the tree, it means the version C is not in the tree.
> But C is the current version, so it is in the tree by definition.
>
So I can just relate my experience ....
root@silpixa00395806:/build/dpdk# DPDK_ABI_REF_VERSION=HEAD~1 ./devtools/test-meson-builds.sh
ninja -C ./build-gcc-static
ninja: Entering directory `./build-gcc-static'
[1766/2204] Compiling C object 'examples/c590b3c@@dpdk-vm_power_manager@exe/vm_power_manager_channel_monitor.c.o'.
../examples/vm_power_manager/channel_monitor.c:22:9: note: #pragma message: Jansson dev libs unavailable, not including JSON parsing
#pragma message "Jansson dev libs unavailable, not including JSON parsing"
^~~~~~~
[2204/2204] Linking target drivers/librte_pmd_softnic.so.20.0.2.
Cloning into 'reference/HEAD~1/src'...
warning: Could not find remote branch HEAD~1 to clone.
fatal: Remote branch HEAD~1 not found in upstream origin
fatal: The remote end hung up unexpectedly
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3] cryptodev: version cryptodev info get function
2020-04-20 17:26 0% ` Ray Kinsella
@ 2020-04-22 8:36 0% ` Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-22 8:36 UTC (permalink / raw)
To: Trahe, Fiona, Akhil Goyal, Kusztal, ArkadiuszX, dev; +Cc: Thomas Monjalon
On 20/04/2020 18:26, Ray Kinsella wrote:
>
>
> On 20/04/2020 17:54, Trahe, Fiona wrote:
>> Hi Ray, Akhil,
>>
>>
>>> On 20/04/2020 15:22, Akhil Goyal wrote:
>>>>
>>>>
>>>>>
>>>>> This patch adds versioned function rte_cryptodev_info_get()
>>>>> to prevent some issues with ABI policy.
>>>>> Node v21 works in same way as before, returning driver capabilities
>>>>> directly to the API caller. These capabilities may include new elements
>>>>> not part of the v20 ABI.
>>>>> Node v20 function maintains compatibility with v20 ABI releases
>>>>> by stripping out elements not supported in v20 ABI. Because
>>>>> rte_cryptodev_info_get is called by other API functions,
>>>>> rte_cryptodev_sym_capability_get function is versioned the same way.
>>>>>
>>>>> Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
>>>>> ---
>>>>> v2:
>>>>> - changed version numbers of symbols to 20.0.2
>>>>> v3:
>>>>> - added v2/v3 informations
>>>>> - changed version numbers of symbols to 21
>>>>> - fixed checkpatch issues
>>>>>
>>>>> This patch depends on following patches:
>>>>>
>>>>> [1] - "[v3] cryptodev: add chacha20-poly1305 aead algorithm"
>>>>> (https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatchwor
>>>>> k.dpdk.org%2Fpatch%2F64549%2F&data=02%7C01%7Cakhil.goyal%40nxp.
>>>>> com%7Ce6789fd42a5946c128e508d7e2dffe2f%7C686ea1d3bc2b4c6fa92cd99c
>>>>> 5c301635%7C0%7C0%7C637227323980059545&sdata=50eQJE7WHTME6d
>>>>> qA7Nfk%2B50PVAyJrpKlMw%2BoGtA1%2FTc%3D&reserved=0)
>>>>
>>>> Please include the dependent patches in a single series in your next version.
>>>>>
>>>>> lib/librte_cryptodev/rte_cryptodev.c | 143 ++++++++++++++++++++++++-
>>>>> lib/librte_cryptodev/rte_cryptodev.h | 39 ++++++-
>>>>> lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++
>>>>> 3 files changed, 186 insertions(+), 3 deletions(-)
>>>>>
>>>>> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
>>>>> b/lib/librte_cryptodev/rte_cryptodev.c
>>>>> index 6d1d0e9..b061447 100644
>>>>> --- a/lib/librte_cryptodev/rte_cryptodev.c
>>>>> +++ b/lib/librte_cryptodev/rte_cryptodev.c
>>>>> @@ -41,6 +41,9 @@
>>>>> #include "rte_cryptodev.h"
>>>>> #include "rte_cryptodev_pmd.h"
>>>>>
>>>>> +#include <rte_compat.h>
>>>>> +#include <rte_function_versioning.h>
>>>>> +
>>>>> static uint8_t nb_drivers;
>>>>>
>>>>> static struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS];
>>>>> @@ -56,6 +59,14 @@ static struct rte_cryptodev_global cryptodev_globals = {
>>>>> /* spinlock for crypto device callbacks */
>>>>> static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
>>>>>
>>>>> +static const struct rte_cryptodev_capabilities
>>>>> + cryptodev_undefined_capabilities[] = {
>>>>> + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
>>>>> +};
>>>>> +
>>>>> +static struct rte_cryptodev_capabilities
>>>>> + *capability_copies[RTE_CRYPTO_MAX_DEVS];
>>>>
>>>> Capabilities_copy is a better name as it is copy of many capabilities.
>> [Fiona] ok
>>
>>
>>>>> const struct rte_cryptodev_symmetric_capability *
>>>>> -rte_cryptodev_sym_capability_get(uint8_t dev_id,
>>>>> +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
>>>>
>>>> __vsym Annotation to be used in a declaration of the internal symbol
>>>> to signal that it is being used as an implementation of a particular
>>>> version of symbol.
>> [Fiona] ok
>>
>>
>>>>> + }
>>>>> +
>>>>> + return NULL;
>>>>> +
>>>>
>>>> Extra line
>> [Fiona] ok
>>
>>>>
>>>>> +}
>>>>> +VERSION_SYMBOL(rte_cryptodev_sym_capability_get, _v20, 20.0);
>>>>> +
>>>>> +const struct rte_cryptodev_symmetric_capability *
>>>>
>>>> __vsym annotation
>> [Fiona] ok
>>
>>
>>>>
>>>>> +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
>>>>> const struct rte_cryptodev_sym_capability_idx *idx)
>>>>> {
>>>>> const struct rte_cryptodev_capabilities *capability;
>>>>> @@ -313,6 +360,10 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
>>>>> return NULL;
>>>>>
>>>>> }
>>>>> +MAP_STATIC_SYMBOL(const struct rte_cryptodev_symmetric_capability *
>>>>> + rte_cryptodev_sym_capability_get(uint8_t dev_id,
>>>>> + const struct rte_cryptodev_sym_capability_idx *idx),
>>>>> + rte_cryptodev_sym_capability_get_v21);
>>>>>
>>>>> static int
>>>>> param_range_check(uint16_t size, const struct rte_crypto_param_range *range)
>>>>> @@ -999,6 +1050,13 @@ rte_cryptodev_close(uint8_t dev_id)
>>>>> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
>>>>> retval = (*dev->dev_ops->dev_close)(dev);
>>>>>
>>>>> +
>>>>> + if (capability_copies[dev_id]) {
>>>>> + free(capability_copies[dev_id]);
>>>>> + capability_copies[dev_id] = NULL;
>>>>> + }
>>>>> + is_capability_checked[dev_id] = 0;
>>>>> +
>>>>> if (retval < 0)
>>>>> return retval;
>>>>>
>>>>> @@ -1111,9 +1169,61 @@ rte_cryptodev_stats_reset(uint8_t dev_id)
>>>>> (*dev->dev_ops->stats_reset)(dev);
>>>>> }
>>>>>
>>>>> +static void
>>>>> +get_v20_capabilities(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
>>>>> +{
>>>>> + const struct rte_cryptodev_capabilities *capability;
>>>>> + uint8_t found_invalid_capa = 0;
>>>>> + uint8_t counter = 0;
>>>>> +
>>>>> + for (capability = dev_info->capabilities;
>>>>> + capability->op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
>>>>> + ++capability, ++counter) {
>>>>> + if (capability->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
>>>>> + capability->sym.xform_type ==
>>>>> + RTE_CRYPTO_SYM_XFORM_AEAD
>>>>> + && capability->sym.aead.algo >=
>>>>> + RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
>>>>> + found_invalid_capa = 1;
>>>>> + counter--;
>>>>> + }
>>>>> + }
>>>>> + is_capability_checked[dev_id] = 1;
>>>>> + if (found_invalid_capa) {
>>>>
>>>> Code becomes unreadable due to indentation which can be avoided.
>> [Fiona] ok
>>
>>
>>
>>>>> +void
>>>>> +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info
>>>>> *dev_info);
>>>>> +BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v21, 21);
>>>>
>>>> I am not sure if we need to bind for _v20 also
>>>> BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v20, 20);
>>>
>>> The correct call to VERSION_SYMBOL is already above.
>> [Fiona] ok, so won't do this.
>>
>>
>>>> Ray, can you please suggest if it required or not? And what all we need to check?
>>>
>>> See below.
>>>
>>>>
>>>> The patch is still showing Incompatibilities
>>>> NOTICE: ABI may be incompatible, check reports/logs for details.
>>>> NOTICE: Incompatible list: librte_cryptodev.so
>>>
>>> So I looked through the issues it is complaining about, these are here.
>>> https://travis-ci.com/github/ovsrobot/dpdk/jobs/320526253#L4540
>>>
>>> Basically they all are warnings related to the changes to the enumeration
>>> rte_crypto_aead_algorithm.
>>>
>>> Essentially the new member RTE_CRYPTO_AEAD_CHACHA20_POLY1305.
>>> The change to the end value RTE_CRYPTO_AEAD_LIST_END.
>>> Members of this type "enum rte_crypto_aead_algorithm algo" are demeeded to also have changed,
>>> but they haven't.
>>>
>>> With the additional work to create the v20 version of rte_cryptodev_info_get.
>>> I think all reasonable steps have been been taken here.
>> [Fiona] Do we need to change the tool or somehow mark as a false positive?
>
> Yes, I will take a look at it.
So take a look at devtools/libabigail.abignore.
Suppressions on 'enum rte_crypto_aead_algorithm' & 'rte_crypto_aead_algorithm_strings',
_should_ take care of it.
Please check with test_build.sh & test_meson_build.sh with DPDK_ABI_REF_VERSION=v19.11
>
>>
>>
>>>>> /**
>>>>> * Register a callback function for specific device id.
>>>>> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map
>>>>> b/lib/librte_cryptodev/rte_cryptodev_version.map
>>>>> index 6e41b4b..512a4a7 100644
>>>>> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
>>>>> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
>>>>> @@ -58,6 +58,13 @@ DPDK_20.0 {
>>>>> local: *;
>>>>> };
>>>>>
>>>>> +DPDK_21 {
>>>
>>> Should be DPDK_21.0
>> [Fiona] Can you explain why?
>> I thought it could go back to a 2-number system with _v21 ABI.
>> I thought we'd clarified that DPDK_20.0 is only there due to a mistake, that should have been DPDK_20.
>>
>>
>>>>> + global:
>>>>> + rte_cryptodev_info_get;
>>>>> + rte_cryptodev_sym_capability_get;
>>>>> +} DPDK_20.0;
>>>>> +
>>>>> +
>>>>> EXPERIMENTAL {
>>>>> global:
>>>>>
>>>>> --
>>>>> 2.1.0
>>>>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21
2020-04-22 8:18 9% ` Thomas Monjalon
@ 2020-04-22 8:28 6% ` Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-22 8:28 UTC (permalink / raw)
To: Thomas Monjalon, David Marchand
Cc: dev, Wang, Haiyue, Matan Azrad, Anoob Joseph, Yigit, Ferruh,
Mahipal Challa, Eelco Chaudron, Cristian Dumitrescu, Jingjing Wu,
Wenzhuo Lu, Shahaf Shuler, Viacheslav Ovsiienko,
Jerin Jacob Kollanukkaran, Nithin Dabilpuram,
Alfredo Cardigliano, Neil Horman
On 22/04/2020 09:18, Thomas Monjalon wrote:
> 22/04/2020 10:07, Ray Kinsella:
>> On 20/04/2020 13:20, David Marchand wrote:
>>> On Mon, Apr 20, 2020 at 1:57 PM Ray Kinsella <mdr@ashroe.eu> wrote:
>>>>
>>>> Travis ABI check warnings, can be safely ignored in this case, I think.
>>>>
>>>> https://travis-ci.com/github/ovsrobot/dpdk/builds/161009923
>>>
>>> How about comparing to 19.11 ABI then?
>>>
>> Concluded on separate thread it is best to leave this as v20.02.
>
> It means the ABI tool will be reporting a failure?
> The tool needs to reliably report zero false positive.
> How can we mitigate this issue?
>
>
So I suggest we handle by adding
[suppress_function]
symbol_version = 20.0.1
[suppress_variable]
symbol_version = 20.0.1
to libabigail.abignore.
libabigail will then ignore the removals?
Ray K
^ permalink raw reply [relevance 6%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-21 9:36 0% ` Thomas Monjalon
@ 2020-04-22 8:21 0% ` Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-22 8:21 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Trahe, Fiona, Richardson, Bruce, dev, Kusztal, ArkadiuszX,
Neil Horman, Luca Boccassi, Kevin Traynor, Yigit, Ferruh,
Akhil Goyal, David Marchand
On 21/04/2020 10:36, Thomas Monjalon wrote:
> 21/04/2020 08:01, Ray Kinsella:
>>
>> On 20/04/2020 18:37, Thomas Monjalon wrote:
>>> 20/04/2020 19:31, Ray Kinsella:
>>>>
>>>> Our only commitment is to the stability of the v19.11/v20 ABI, until v21.
>>>>
>>>> That said, once an ABI migrates from EXPERIMENTAL to v21, it _shouldn't_ be changing.
>>>> We don't have a strict commitment to the v21 ABI until v20.11.
>>>>
>>>> However if v21 is changing across quarterlies (outside of additions) ... something else is wrong.
>>>
>>> The only way to check a symbol is not changing in a quarterly release
>>> is to test it. That's what we wanted to enforce:
>>> compare 20.02 ABI in 20.05 release.
>>>
>>> What other process do you suggest?
>>>
>>
>> Well I guess it's understanding the reason why you are doing something.
>> I can see reasons for wanting to test against both v19.11 and v20.02.
>>
>> v19.11 because our strict commitment is to the v20 abi.
>> v20.02 to ensure that v21 symbols are not changing between quarterly releases.
>>
>> On v20, since you tested v20.02 against v19.11 during the v20.02 release cycle.
>> The v20 symbols should not have changed during the v20.02 release cycle.
>>
>> I take your point, that then testing v20.05 against v20.02 would catch both v20 and v21 changes.
>
> OK, so we need a policy or process update to make this conclusion clear to everybody.
>
yes, I replied to David Marchand on this separately.
In the case the process is already in place ... Travis is routinely testing against v20.02.
If we wanted to make this abundantly clear we could add a note/section explaining the process to
guides/contributing/abi_versioning.rst ?
So I think we need two other policy additions.
1. Fiona is clear, that we need a note on the policy document to cover the version numbering error
that was made in DPDK 19.11. Bruce's commit (f26c2b39b271cdcd857ba518c5e48c78cb1c30af) on the subject,
explains it very well ...
2. We also need to merge "doc: alias to experimental tag for stable apis"
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21
2020-04-22 8:07 6% ` Ray Kinsella
2020-04-22 8:11 6% ` David Marchand
@ 2020-04-22 8:18 9% ` Thomas Monjalon
2020-04-22 8:28 6% ` Ray Kinsella
1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-22 8:18 UTC (permalink / raw)
To: David Marchand, Ray Kinsella
Cc: dev, Wang, Haiyue, Matan Azrad, Anoob Joseph, Yigit, Ferruh,
Mahipal Challa, Eelco Chaudron, Cristian Dumitrescu, Jingjing Wu,
Wenzhuo Lu, Shahaf Shuler, Viacheslav Ovsiienko,
Jerin Jacob Kollanukkaran, Nithin Dabilpuram,
Alfredo Cardigliano, Neil Horman
22/04/2020 10:07, Ray Kinsella:
> On 20/04/2020 13:20, David Marchand wrote:
> > On Mon, Apr 20, 2020 at 1:57 PM Ray Kinsella <mdr@ashroe.eu> wrote:
> >>
> >> Travis ABI check warnings, can be safely ignored in this case, I think.
> >>
> >> https://travis-ci.com/github/ovsrobot/dpdk/builds/161009923
> >
> > How about comparing to 19.11 ABI then?
> >
> Concluded on separate thread it is best to leave this as v20.02.
It means the ABI tool will be reporting a failure?
The tool needs to reliably report zero false positive.
How can we mitigate this issue?
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21
2020-04-22 8:07 6% ` Ray Kinsella
@ 2020-04-22 8:11 6% ` David Marchand
2020-04-22 8:18 9% ` Thomas Monjalon
1 sibling, 0 replies; 200+ results
From: David Marchand @ 2020-04-22 8:11 UTC (permalink / raw)
To: Ray Kinsella
Cc: dev, Wang, Haiyue, Matan Azrad, Anoob Joseph, Yigit, Ferruh,
Mahipal Challa, Eelco Chaudron, Cristian Dumitrescu,
Thomas Monjalon, Jingjing Wu, Wenzhuo Lu, Shahaf Shuler,
Viacheslav Ovsiienko, Jerin Jacob Kollanukkaran,
Nithin Dabilpuram, Alfredo Cardigliano, Neil Horman
On Wed, Apr 22, 2020 at 10:08 AM Ray Kinsella <mdr@ashroe.eu> wrote:
>
> Concluded on separate thread it is best to leave this as v20.02.
Ok, thanks for confirming.
--
David Marchand
^ permalink raw reply [relevance 6%]
* Re: [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21
2020-04-20 12:20 9% ` David Marchand
2020-04-20 15:25 9% ` Ray Kinsella
@ 2020-04-22 8:07 6% ` Ray Kinsella
2020-04-22 8:11 6% ` David Marchand
2020-04-22 8:18 9% ` Thomas Monjalon
1 sibling, 2 replies; 200+ results
From: Ray Kinsella @ 2020-04-22 8:07 UTC (permalink / raw)
To: David Marchand
Cc: dev, Wang, Haiyue, Matan Azrad, Anoob Joseph, Yigit, Ferruh,
Mahipal Challa, Eelco Chaudron, Cristian Dumitrescu,
Thomas Monjalon, Jingjing Wu, Wenzhuo Lu, Shahaf Shuler,
Viacheslav Ovsiienko, Jerin Jacob Kollanukkaran,
Nithin Dabilpuram, Alfredo Cardigliano, Neil Horman
Concluded on separate thread it is best to leave this as v20.02.
Thanks,
Ray K
On 20/04/2020 13:20, David Marchand wrote:
> On Mon, Apr 20, 2020 at 1:57 PM Ray Kinsella <mdr@ashroe.eu> wrote:
>>
>> Travis ABI check warnings, can be safely ignored in this case, I think.
>>
>> https://travis-ci.com/github/ovsrobot/dpdk/builds/161009923
>
> How about comparing to 19.11 ABI then?
>
>
> --- a/.travis.yml
> +++ b/.travis.yml
> @@ -36,7 +36,7 @@ script: ./.ci/${TRAVIS_OS_NAME}-build.sh
>
> env:
> global:
> - - REF_GIT_TAG=v20.02
> + - REF_GIT_TAG=v19.11
>
> jobs:
> include:
>
>
^ permalink raw reply [relevance 6%]
* [dpdk-dev] [PATCH v9 2/2] eal: support for VFIO-PCI VF token
2020-04-22 5:08 4% ` [dpdk-dev] [PATCH v9 " Haiyue Wang
@ 2020-04-22 5:08 3% ` Haiyue Wang
0 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-22 5:08 UTC (permalink / raw)
To: dev, anatoly.burakov, thomas, vattunuru, jerinj, alex.williamson,
david.marchand
Cc: Haiyue Wang
The kernel module vfio-pci introduces the VF token to enable SR-IOV
support since 5.7.
The VF token can be set by a vfio-pci based PF driver and must be known
by the vfio-pci based VF driver in order to gain access to the device.
Signed-off-by: Haiyue Wang <haiyue.wang@intel.com>
Acked-by: Vamsi Attunuru <vattunuru@marvell.com>
Tested-by: Vamsi Attunuru <vattunuru@marvell.com>
---
devtools/libabigail.abignore | 2 +
doc/guides/linux_gsg/linux_drivers.rst | 41 +++++++++++++-
doc/guides/rel_notes/release_20_05.rst | 5 ++
drivers/bus/pci/linux/pci_vfio.c | 74 +++++++++++++++++++++++++-
lib/librte_eal/freebsd/eal.c | 3 +-
lib/librte_eal/include/rte_vfio.h | 24 ++++++++-
lib/librte_eal/linux/eal_vfio.c | 20 +++++--
7 files changed, 161 insertions(+), 8 deletions(-)
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index cd86d89ca..01d987a1e 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -6,6 +6,8 @@
; Explicit ignore for driver-only ABI
[suppress_type]
name = rte_cryptodev_ops
+[suppress_function]
+ name = rte_vfio_setup_device
; Ignore this enum update as it is part of an experimental API
[suppress_type]
type_kind = enum
diff --git a/doc/guides/linux_gsg/linux_drivers.rst b/doc/guides/linux_gsg/linux_drivers.rst
index 238f3e900..b42fd708b 100644
--- a/doc/guides/linux_gsg/linux_drivers.rst
+++ b/doc/guides/linux_gsg/linux_drivers.rst
@@ -72,11 +72,50 @@ Note that in order to use VFIO, your kernel must support it.
VFIO kernel modules have been included in the Linux kernel since version 3.6.0 and are usually present by default,
however please consult your distributions documentation to make sure that is the case.
+The ``vfio-pci`` module since Linux version 5.7 supports the creation of virtual
+functions. After the PF is bound to vfio-pci module, the user can create the VFs
+by sysfs interface, and these VFs are bound to vfio-pci module automatically.
+
+When the PF is bound to vfio-pci, it has initial VF token generated by random. For
+security reason, this token is write only, the user can't read it from the kernel
+directly. For accessing the VF, the user needs to start the PF with token parameter
+to setup a VF token (uuid format), then the VF can be accessed with this new known
+VF token.
+
+Also if the DPDK application running on the PF device exits, the user wants to start
+the PF with another different VF token value, it has no issue if no application like
+DPDK or KVM runs on VFs. Otherwise, the PF will fail to start until all VFs are free
+to use, after that, the user can select a new VF token to start the PF device.
+
+DPDK will use the keyword ``vf_token`` as the device argument to pass the VF token
+value to PF and its related VFs, the PMD should not use it, and this argument will
+be pruned from the device argument list, so the PMD can parse its own valid device
+arguments successfully.
+
+.. code-block:: console
+
+ 1. Generate the VF token by uuid command
+ 14d63f20-8445-11ea-8900-1f9ce7d5650d
+
+ 2. sudo modprobe vfio-pci enable_sriov=1
+
+ 2. ./usertools/dpdk-devbind.py -b vfio-pci 0000:86:00.0
+
+ 3. echo 2 > /sys/bus/pci/devices/0000:86:00.0/sriov_numvfs
+
+ 4. Start the PF:
+ ./x86_64-native-linux-gcc/app/testpmd -l 22-25 -n 4 \
+ -w 86:00.0,vf_token=14d63f20-8445-11ea-8900-1f9ce7d5650d --file-prefix=pf -- -i
+
+ 5. Start the VF:
+ ./x86_64-native-linux-gcc/app/testpmd -l 26-29 -n 4 \
+ -w 86:02.0,vf_token=14d63f20-8445-11ea-8900-1f9ce7d5650d --file-prefix=vf0 -- -i
+
Also, to use VFIO, both kernel and BIOS must support and be configured to use IO virtualization (such as Intel® VT-d).
.. note::
- ``vfio-pci`` module doesn't support the creation of virtual functions.
+ ``vfio-pci`` module doesn't support the creation of virtual functions before Linux version 5.7.
For proper operation of VFIO when running DPDK applications as a non-privileged user, correct permissions should also be set up.
This can be done by using the DPDK setup script (called dpdk-setup.sh and located in the usertools directory).
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index 709372e5e..9460e1eb2 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -97,6 +97,11 @@ New Features
by making use of the event device capabilities. The event mode currently supports
only inline IPsec protocol offload.
+* **Added the support for vfio-pci new VF token interface.**
+
+ Since Linux version 5.7, vfio-pci supports a shared VF token (UUID) to represent
+ the trust between SR-IOV PF and the created VFs. Update the method to gain access
+ to the device by appending the VF token.
Removed Items
-------------
diff --git a/drivers/bus/pci/linux/pci_vfio.c b/drivers/bus/pci/linux/pci_vfio.c
index 64cd84a68..efb64e2ba 100644
--- a/drivers/bus/pci/linux/pci_vfio.c
+++ b/drivers/bus/pci/linux/pci_vfio.c
@@ -11,6 +11,7 @@
#include <sys/mman.h>
#include <stdbool.h>
+#include <rte_devargs.h>
#include <rte_log.h>
#include <rte_pci.h>
#include <rte_bus_pci.h>
@@ -644,12 +645,72 @@ pci_vfio_msix_is_mappable(int vfio_dev_fd, int msix_region)
return ret;
}
+static int
+vfio_pci_vf_token_arg(struct rte_devargs *devargs, rte_uuid_t uuid)
+{
+#define VF_TOKEN_ARG "vf_token="
+ char c, *p, *vf_token;
+
+ memset(uuid, 0, sizeof(rte_uuid_t));
+
+ if (devargs == NULL)
+ return 0;
+
+ p = strstr(devargs->args, VF_TOKEN_ARG);
+ if (!p)
+ return 0;
+
+ vf_token = p + strlen(VF_TOKEN_ARG);
+ if (strlen(vf_token) < (RTE_UUID_STRLEN - 1)) {
+ RTE_LOG(ERR, EAL, "The VF token length is too short\n");
+ return -1;
+ }
+
+ c = vf_token[RTE_UUID_STRLEN - 1];
+ if (c != '\0' && c != ',') {
+ RTE_LOG(ERR, EAL,
+ "The VF token ends with a invalid character : %c\n", c);
+ return -1;
+ }
+
+ vf_token[RTE_UUID_STRLEN - 1] = '\0';
+ if (rte_uuid_parse(vf_token, uuid)) {
+ RTE_LOG(ERR, EAL,
+ "The VF token is invalid : %s\n", vf_token);
+ vf_token[RTE_UUID_STRLEN - 1] = c;
+ return -1;
+ }
+
+ RTE_LOG(DEBUG, EAL,
+ "The VF token is found : %s\n", vf_token);
+
+ vf_token[RTE_UUID_STRLEN - 1] = c;
+
+ /* This VF token will be treated as a invalid device argument if the
+ * PMD calls the rte_devargs parse API with its own valid argument list,
+ * so it needs to purge this vfio-pci specific argument.
+ */
+ if (c != '\0') {
+ /* 1. Handle the case : 'vf_token=uuid,arg1=val1' */
+ memmove(p, vf_token + RTE_UUID_STRLEN,
+ strlen(vf_token + RTE_UUID_STRLEN) + 1);
+ } else {
+ /* 2. Handle the case : 'arg1=val1,vf_token=uuid' */
+ if (p != devargs->args)
+ p--;
+
+ *p = '\0';
+ }
+
+ return 0;
+}
static int
pci_vfio_map_resource_primary(struct rte_pci_device *dev)
{
struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
char pci_addr[PATH_MAX] = {0};
+ rte_uuid_t vf_token;
int vfio_dev_fd;
struct rte_pci_addr *loc = &dev->addr;
int i, ret;
@@ -668,8 +729,12 @@ pci_vfio_map_resource_primary(struct rte_pci_device *dev)
snprintf(pci_addr, sizeof(pci_addr), PCI_PRI_FMT,
loc->domain, loc->bus, loc->devid, loc->function);
+ ret = vfio_pci_vf_token_arg(dev->device.devargs, vf_token);
+ if (ret)
+ return ret;
+
ret = rte_vfio_setup_device(rte_pci_get_sysfs_path(), pci_addr,
- &vfio_dev_fd, &device_info);
+ &vfio_dev_fd, &device_info, vf_token);
if (ret)
return ret;
@@ -798,6 +863,7 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
{
struct vfio_device_info device_info = { .argsz = sizeof(device_info) };
char pci_addr[PATH_MAX] = {0};
+ rte_uuid_t vf_token;
int vfio_dev_fd;
struct rte_pci_addr *loc = &dev->addr;
int i, ret;
@@ -830,8 +896,12 @@ pci_vfio_map_resource_secondary(struct rte_pci_device *dev)
return -1;
}
+ ret = vfio_pci_vf_token_arg(dev->device.devargs, vf_token);
+ if (ret)
+ return ret;
+
ret = rte_vfio_setup_device(rte_pci_get_sysfs_path(), pci_addr,
- &vfio_dev_fd, &device_info);
+ &vfio_dev_fd, &device_info, vf_token);
if (ret)
return ret;
diff --git a/lib/librte_eal/freebsd/eal.c b/lib/librte_eal/freebsd/eal.c
index 80dc9aa78..86d5a5f49 100644
--- a/lib/librte_eal/freebsd/eal.c
+++ b/lib/librte_eal/freebsd/eal.c
@@ -995,7 +995,8 @@ rte_eal_vfio_intr_mode(void)
int rte_vfio_setup_device(__rte_unused const char *sysfs_base,
__rte_unused const char *dev_addr,
__rte_unused int *vfio_dev_fd,
- __rte_unused struct vfio_device_info *device_info)
+ __rte_unused struct vfio_device_info *device_info,
+ __rte_unused rte_uuid_t vf_token)
{
return -1;
}
diff --git a/lib/librte_eal/include/rte_vfio.h b/lib/librte_eal/include/rte_vfio.h
index 20ed8c45a..28d918cde 100644
--- a/lib/librte_eal/include/rte_vfio.h
+++ b/lib/librte_eal/include/rte_vfio.h
@@ -16,6 +16,8 @@ extern "C" {
#include <stdint.h>
+#include <rte_uuid.h>
+
/*
* determine if VFIO is present on the system
*/
@@ -102,13 +104,33 @@ struct vfio_device_info;
* @param device_info
* Device information.
*
+ * @param vf_token
+ * Before linux 5.7, the PF bound to vfio-pci doesn't support SR-IOV to
+ * create VFs for security reason. Now the VF token is introduced to work
+ * as some degree of trust or collaboration between PF and VFs.
+ *
+ * A). as VF device, if the PF is a vfio device and it is bound to the
+ * vfio-pci driver, the user needs to provide a VF token to access the
+ * device, in the form of appending a vf_token to the device name, for
+ * example:
+ * "-w 04:10.0,vf_token=bd8d9d2b-5a5f-4f5a-a211-f591514ba1f3"
+ *
+ * B). as PF device, When presented with a PF which has VFs in use, the
+ * user must also provide the current VF token to prove collaboration with
+ * existing VF users. If VFs are not in use, the VF token provided for the
+ * PF device will act to set the VF token.
+ *
+ * The vf_token can be zero uuid, which will be ignored to pass into the
+ * vfio-pci module.
+ *
* @return
* 0 on success.
* <0 on failure.
* >1 if the device cannot be managed this way.
*/
int rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr,
- int *vfio_dev_fd, struct vfio_device_info *device_info);
+ int *vfio_dev_fd, struct vfio_device_info *device_info,
+ rte_uuid_t vf_token);
/**
* Release a device mapped to a VFIO-managed I/O MMU group.
diff --git a/lib/librte_eal/linux/eal_vfio.c b/lib/librte_eal/linux/eal_vfio.c
index d26e1649a..e8d7cbda5 100644
--- a/lib/librte_eal/linux/eal_vfio.c
+++ b/lib/librte_eal/linux/eal_vfio.c
@@ -702,7 +702,8 @@ rte_vfio_clear_group(int vfio_group_fd)
int
rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr,
- int *vfio_dev_fd, struct vfio_device_info *device_info)
+ int *vfio_dev_fd, struct vfio_device_info *device_info,
+ rte_uuid_t vf_token)
{
struct vfio_group_status group_status = {
.argsz = sizeof(group_status)
@@ -712,6 +713,7 @@ rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr,
int vfio_container_fd;
int vfio_group_fd;
int iommu_group_num;
+ char dev[PATH_MAX];
int i, ret;
/* get group number */
@@ -895,8 +897,19 @@ rte_vfio_setup_device(const char *sysfs_base, const char *dev_addr,
t->type_id, t->name);
}
+ if (!rte_uuid_is_null(vf_token)) {
+ char vf_token_str[RTE_UUID_STRLEN];
+
+ rte_uuid_unparse(vf_token, vf_token_str, sizeof(vf_token_str));
+ snprintf(dev, sizeof(dev),
+ "%s vf_token=%s", dev_addr, vf_token_str);
+ } else {
+ snprintf(dev, sizeof(dev),
+ "%s", dev_addr);
+ }
+
/* get a file descriptor for the device */
- *vfio_dev_fd = ioctl(vfio_group_fd, VFIO_GROUP_GET_DEVICE_FD, dev_addr);
+ *vfio_dev_fd = ioctl(vfio_group_fd, VFIO_GROUP_GET_DEVICE_FD, dev);
if (*vfio_dev_fd < 0) {
/* if we cannot get a device fd, this implies a problem with
* the VFIO group or the container not having IOMMU configured.
@@ -2083,7 +2096,8 @@ int
rte_vfio_setup_device(__rte_unused const char *sysfs_base,
__rte_unused const char *dev_addr,
__rte_unused int *vfio_dev_fd,
- __rte_unused struct vfio_device_info *device_info)
+ __rte_unused struct vfio_device_info *device_info,
+ __rte_unused rte_uuid_t vf_token)
{
return -1;
}
--
2.26.2
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v9 0/2] support for VFIO-PCI VF token interface
2020-04-18 11:16 4% ` [dpdk-dev] [PATCH v7 0/2] support for VFIO-PCI VF token interface Haiyue Wang
2020-04-18 17:30 4% ` [dpdk-dev] [PATCH v8 " Haiyue Wang
@ 2020-04-22 5:08 4% ` Haiyue Wang
2020-04-22 5:08 3% ` [dpdk-dev] [PATCH v9 2/2] eal: support for VFIO-PCI VF token Haiyue Wang
2020-04-26 1:55 4% ` [dpdk-dev] [PATCH v10 0/2] support for VFIO-PCI VF token interface Haiyue Wang
3 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-22 5:08 UTC (permalink / raw)
To: dev, anatoly.burakov, thomas, vattunuru, jerinj, alex.williamson,
david.marchand
Cc: Haiyue Wang
v9: Rewrite the document.
v8: Update the document.
https://patchwork.dpdk.org/cover/68859/
v7: Add the Fixes tag in uuid, the release note and help
document.
https://patchwork.dpdk.org/cover/68845/
v6: Drop the Fixes tag in uuid, since the file has been
moved to another place, not suitable to apply on stable.
And this is not a bug, just some kind of enhancement.
https://patchwork.dpdk.org/cover/68367/
v5: 1. Add the VF token parse error handling.
2. Split into two patches for different logic module.
3. Add more comments into the code for explaining the design.
4. Drop the ABI change workaround, this patch set focuses on code review.
https://patchwork.dpdk.org/cover/68364/
v4: 1. Ignore rte_vfio_setup_device ABI check since it is
for Linux driver use.
https://patchwork.dpdk.org/patch/68255/
v3: Fix the Travis build failed:
(1). rte_uuid.h:97:55: error: unknown type name ‘size_t’
(2). rte_uuid.h:58:2: error: implicit declaration of function ‘memcpy’
https://patchwork.dpdk.org/patch/68254/
v2: Fix the FreeBSD build error.
https://patchwork.dpdk.org/patch/68240/
v1: Update the commit message.
https://patchwork.dpdk.org/patch/68237/
RFC v2: https://patchwork.dpdk.org/patch/68114/
Based on Vamsi's RFC v1, and Alex's patch for Qemu
[https://lore.kernel.org/lkml/20200204161737.34696b91@w520.home/]:
Use the devarg to pass-down the VF token.
RFC v1: https://patchwork.dpdk.org/patch/66281/ by Vamsi.
Haiyue Wang (2):
eal: add uuid dependent header files explicitly
eal: support for VFIO-PCI VF token
devtools/libabigail.abignore | 2 +
doc/guides/linux_gsg/linux_drivers.rst | 41 +++++++++++++-
doc/guides/rel_notes/release_20_05.rst | 5 ++
drivers/bus/pci/linux/pci_vfio.c | 74 +++++++++++++++++++++++++-
lib/librte_eal/freebsd/eal.c | 3 +-
lib/librte_eal/include/rte_uuid.h | 2 +
lib/librte_eal/include/rte_vfio.h | 24 ++++++++-
lib/librte_eal/linux/eal_vfio.c | 20 +++++--
8 files changed, 163 insertions(+), 8 deletions(-)
--
2.26.2
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-21 18:56 4% ` Neil Horman
@ 2020-04-21 21:42 4% ` Thomas Monjalon
2020-04-22 11:43 4% ` Ray Kinsella
2020-04-22 12:01 8% ` Neil Horman
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2020-04-21 21:42 UTC (permalink / raw)
To: Neil Horman; +Cc: Ray Kinsella, dev, david.marchand
21/04/2020 20:56, Neil Horman:
> On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
> > 21/04/2020 13:12, Neil Horman:
> > > On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> > > > On 17/04/2020 13:10, Thomas Monjalon wrote:
> > > > > 17/04/2020 13:47, Ray Kinsella:
> > > > >> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > > > >>> 17/04/2020 12:11, Ray Kinsella:
> > > > >>>> check-abi.sh appears to be backward step in terms of usability.
> > > > >>>
> > > > >>> No, check-abi.sh benefits from a nice integration in build scripts.
> > > > >>> See below.
> > > > >>>
> > > > >>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> > > > >>>> And it will do the build, install, dump and comparison for me.
> > > > >>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> > > > >>>>
> > > > >>>> With check-abi on the other hand, I need to the build and install myself.
> > > > >>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> > > > >>>> It silently fails when it doesn't find any ...
> > > > >>>>
> > > > >>>> Do I run abi-dumper on the so's myself, or how does it work?
> > > > >>>
> > > > >>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > > > >>> Probably we should document usage in these scripts.
> > > > >>
> > > > >> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> > > > >> Any tips or tricks would be welcome.
> > > > >
> > > > > export DPDK_ABI_REF_VERSION=v20.02
> > > > > or
> > > > > export DPDK_ABI_REF_VERSION=v19.11
> > > > >
> > > > > Depends on which compatibility you want to test...
> > > > >
> > > >
> > > > Few things ...
> > > >
> > > > 1. test-meson-build.sh keep barfing complaining about reference paths.
> > > > ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> > > >
> > > > Under the hood, ninja install is failing complaining that it needs an absolute path.
> > > > I fixed this in test_meson_build.sh and will send a patch in a minute.
> > > > Though it's strange no-one else has seen it?
> > > >
> > > > 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> > > >
> > > > 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> > > > In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> > > > I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> > > >
> > > I think this code in test-meson-build.sh should probably be fixed:
> > >
> > > if [ ! -d $abirefdir/src ]; then
> > > git clone --local --no-hardlinks \
> > > --single-branch \
> > > -b $DPDK_ABI_REF_VERSION \
> > > $srcdir $abirefdir/src
> > > fi
> > >
> > > Like you noted, using -b allows us to checkout a tag/branch in the cloned
> > > repository but requires that it exist locally. We should probably prefix the
> > > checkout with a git fetch --tags
> >
> > I don't understand your concern.
> > A reference is an older version, so it should be in the git tree.
> >
> yes, but not unless you've done a recent pull or fetch. If you set
> DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
> updated the tree, it won't be there (which it sounds like what is being
> encountered here). You can fix that by doing a git pull or git fetch prior to
> running this script (or internal to the script)
Sorry I still don't understand the case.
We want to compare the current version C with a reference R which is older.
If the reference R is not in the tree, it means the version C is not in the tree.
But C is the current version, so it is in the tree by definition.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-21 11:46 4% ` Thomas Monjalon
@ 2020-04-21 18:56 4% ` Neil Horman
2020-04-21 21:42 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2020-04-21 18:56 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Ray Kinsella, dev, david.marchand
On Tue, Apr 21, 2020 at 01:46:43PM +0200, Thomas Monjalon wrote:
> 21/04/2020 13:12, Neil Horman:
> > On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> > > On 17/04/2020 13:10, Thomas Monjalon wrote:
> > > > 17/04/2020 13:47, Ray Kinsella:
> > > >> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > > >>> 17/04/2020 12:11, Ray Kinsella:
> > > >>>> check-abi.sh appears to be backward step in terms of usability.
> > > >>>
> > > >>> No, check-abi.sh benefits from a nice integration in build scripts.
> > > >>> See below.
> > > >>>
> > > >>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> > > >>>> And it will do the build, install, dump and comparison for me.
> > > >>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> > > >>>>
> > > >>>> With check-abi on the other hand, I need to the build and install myself.
> > > >>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> > > >>>> It silently fails when it doesn't find any ...
> > > >>>>
> > > >>>> Do I run abi-dumper on the so's myself, or how does it work?
> > > >>>
> > > >>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > > >>> Probably we should document usage in these scripts.
> > > >>
> > > >> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> > > >> Any tips or tricks would be welcome.
> > > >
> > > > export DPDK_ABI_REF_VERSION=v20.02
> > > > or
> > > > export DPDK_ABI_REF_VERSION=v19.11
> > > >
> > > > Depends on which compatibility you want to test...
> > > >
> > >
> > > Few things ...
> > >
> > > 1. test-meson-build.sh keep barfing complaining about reference paths.
> > > ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> > >
> > > Under the hood, ninja install is failing complaining that it needs an absolute path.
> > > I fixed this in test_meson_build.sh and will send a patch in a minute.
> > > Though it's strange no-one else has seen it?
> > >
> > > 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> > >
> > > 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> > > In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> > > I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> > >
> > I think this code in test-meson-build.sh should probably be fixed:
> >
> > if [ ! -d $abirefdir/src ]; then
> > git clone --local --no-hardlinks \
> > --single-branch \
> > -b $DPDK_ABI_REF_VERSION \
> > $srcdir $abirefdir/src
> > fi
> >
> > Like you noted, using -b allows us to checkout a tag/branch in the cloned
> > repository but requires that it exist locally. We should probably prefix the
> > checkout with a git fetch --tags
>
> I don't understand your concern.
> A reference is an older version, so it should be in the git tree.
>
yes, but not unless you've done a recent pull or fetch. If you set
DPDK_ABI_REF_VERSION to a tag/branch that didn't exist as of the last time you
updated the tree, it won't be there (which it sounds like what is being
encountered here). You can fix that by doing a git pull or git fetch prior to
running this script (or internal to the script)
Neil
>
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-21 8:47 0% ` Thomas Monjalon
@ 2020-04-21 17:35 0% ` Wang, Haiyue
0 siblings, 0 replies; 200+ results
From: Wang, Haiyue @ 2020-04-21 17:35 UTC (permalink / raw)
To: Thomas Monjalon, David Marchand
Cc: Neil Horman, dev, Burakov, Anatoly, Vamsi Attunuru,
Jerin Jacob Kollanukkaran, Yigit, Ferruh, Richardson, Bruce,
Kinsella, Ray
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, April 21, 2020 16:48
> To: David Marchand <david.marchand@redhat.com>; Wang, Haiyue <haiyue.wang@intel.com>
> Cc: Neil Horman <nhorman@tuxdriver.com>; dev <dev@dpdk.org>; Burakov, Anatoly
> <anatoly.burakov@intel.com>; Vamsi Attunuru <vattunuru@marvell.com>; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Kinsella, Ray <ray.kinsella@intel.com>
> Subject: Re: [PATCH v8 0/2] support for VFIO-PCI VF token interface
>
> 21/04/2020 04:52, Wang, Haiyue:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > > 21/04/2020 03:38, Wang, Haiyue:
> > > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > > 20/04/2020 19:37, Wang, Haiyue:
> > > > > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > > > > 20/04/2020 19:02, Wang, Haiyue:
> > > > > > > > From: David Marchand <david.marchand@redhat.com>
> > > > > > > > > I had a look at the CI, I can see we are still missing bits to handle
> > > > > > > > > the ABI failure on rte_vfio_setup_device.
> > > > > > > >
> > > > > > > > Yes, not handle it now.
> > > > > > > >
> > > > > > > > If 'rte_vfio_setup_device' can be internal, not official DPDK API, then __rte_internal
> > > > > > > > is the best way to handle ABI issue.
> > > > > > >
> > > > > > > Please could you help finishing integration of __rte_internal?
> > > > > >
> > > > > > I thought it should be Neil ? "Yes, I'll get back to this today" ;-)
> > > > > >
> http://inbox.dpdk.org/dev/CAJFAV8ydLkV0afEHqbh6KeA3Box0Yxb3N0MNGtMD4S9bmSgT0A@mail.gmail.com/
> > > > >
> > > > > It did not happen after several months.
> > > > > If you want to unblock your patches, I think it is safer to finish yourself.
> > > > >
> > > >
> > > > Unfortunately, this __rte_internal will still make the ci fail to run when move the function
> > > > to INTERNAL session:
> > > [...]
> > > > +INTERNAL {
> > > > + global:
> > > > +
> > > > + # added in 20.05
> > > > + rte_vfio_setup_device;
> > > > +};
> > >
> > > Why do you need to move the symbol explicitly in .map?
> > > The tool should ignore symbols moving to internal, as an exception until 20.11.
> >
> > If not move the symbol explicitly in .map, another kind of error happened.
> >
> > ./devtools/check-abi.sh old_abi new_abi
> > Functions changes summary: 0 Removed, 1 Changed, 0 Added function
> > Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
> >
> > 1 function with some indirect sub-type change:
> >
> > [C] 'function int rte_vfio_setup_device(const char*, const char*, int*, vfio_device_info*)' at
> eal_vfio.c:704:1 has some indirect sub-type changes:
> > parameter 5 of type 'unsigned char*' was added
> >
> > Error: ABI issue reported for 'abidiff --suppr ./devtools/libabigail.abignore --no-added-syms --
> headers-dir1 old_abi/include --headers-dir2 new_abi/include old_abi/dump/librte_eal.dump
> new_abi/dump/librte_eal.dump'
>
> This is what I said: you need to add a rule to ignore internal symbols.
>
Got the kind reply from Dodji, the maintainer of libabigail, his suggestion
meets what we have done for 'EXPERIMENTAL'. So it seems that have to mark
all needed functions as INTERNAL firstly, which obviously will break the CI
as the public functions are removed....
"
__PROJECT_INTERNAL_USE_ONLY_VERSION__ {
global: funA
};
...
Then, once you have all your internal functions marked in the ELF binary
with the proper ELF version string, you can tell libabigail to suppress
all functions that have that version by writing a suppression
specification file that has this content:
[suppress_function]
symbol_version = __PROJECT_INTERNAL_USE_ONLY_VERSION__
"
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v4] ethdev: support flow aging
2020-04-21 10:11 2% ` [dpdk-dev] [PATCH v4] " Bill Zhou
@ 2020-04-21 17:13 0% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2020-04-21 17:13 UTC (permalink / raw)
To: Bill Zhou, orika, matan, wenzhuo.lu, jingjing.wu,
bernard.iremonger, john.mcnamara, marko.kovacevic, thomas,
arybchenko
Cc: dev
On 4/21/2020 11:11 AM, Bill Zhou wrote:
> From: Dong Zhou <dongz@mellanox.com>
>
> One of the reasons to destroy a flow is the fact that no packet matches the
> flow for "timeout" time.
> For example, when TCP\UDP sessions are suddenly closed.
>
> Currently, there is not any DPDK mechanism for flow aging and the
> applications use their own ways to detect and destroy aged-out flows.
>
> The flow aging implementation need include:
> - A new rte_flow action: RTE_FLOW_ACTION_TYPE_AGE to set the timeout and
> the application flow context for each flow.
> - A new ethdev event: RTE_ETH_EVENT_FLOW_AGED for the driver to report
> that there are new aged-out flows.
> - A new rte_flow API: rte_flow_get_aged_flows to get the aged-out flows
> contexts from the port.
> - Support input flow aging command line in Testpmd.
>
> The new event type addition in the enum is flagged as an ABI breakage, so
> an ignore rule is added for these reasons:
> - It is not changing value of existing types (except MAX)
> - The new value is not used by existing API if the event is not registered
> In general, it is safe adding new ethdev event types at the end of the
> enum, because of event callback registration mechanism.
>
> Signed-off-by: Dong Zhou <dongz@mellanox.com>
Carrying ack from prev versions:
Acked-by: Ori Kam <orika@mellanox.com>
Acked-by: Andrew Rybchenko <arybchenko@solarflare.com>
Acked-by: Jerin Jacob <jerinj@marvell.com>
Acked-by: Matan Azrad <matan@mellanox.com>
Applied to dpdk-next-net/master, thanks.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
2020-04-21 10:04 0% ` Ferruh Yigit
2020-04-21 10:09 0% ` Thomas Monjalon
@ 2020-04-21 15:59 0% ` Andrew Rybchenko
1 sibling, 0 replies; 200+ results
From: Andrew Rybchenko @ 2020-04-21 15:59 UTC (permalink / raw)
To: Ferruh Yigit, Thomas Monjalon, Bill Zhou
Cc: Ori Kam, Matan Azrad, wenzhuo.lu, jingjing.wu, bernard.iremonger,
john.mcnamara, marko.kovacevic, dev
On 4/21/20 1:04 PM, Ferruh Yigit wrote:
> On 4/20/2020 5:10 PM, Thomas Monjalon wrote:
>> 20/04/2020 16:06, Ferruh Yigit:
>>> On 4/18/2020 10:44 AM, Thomas Monjalon wrote:
>>>> 18/04/2020 07:04, Bill Zhou:
>>>>> From: Ferruh Yigit <ferruh.yigit@intel.com>
>>>>>> On 4/14/2020 9:32 AM, Dong Zhou wrote:
>>>>>>> --- a/lib/librte_ethdev/rte_ethdev.h
>>>>>>> +++ b/lib/librte_ethdev/rte_ethdev.h
>>>>>>> @@ -3015,6 +3015,7 @@ enum rte_eth_event_type {
>>>>>>> RTE_ETH_EVENT_NEW, /**< port is probed */
>>>>>>> RTE_ETH_EVENT_DESTROY, /**< port is released */
>>>>>>> RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
>>>>>>> + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected
>>>>>> */
>>>>>>> RTE_ETH_EVENT_MAX /**< max value of this enum */
>>>>>>> };
>>>>>>
>>>>>>
>>>>>> Just recognized that this is failing in ABI check [1], as far as last time for a
>>>>>> similar enum warning a QAT patch has been dropped, should this need to
>>>>>> wait for
>>>>>> 20.11 too?
>>>>>
>>>>> This patch is commonly used for flow aging, there are 2 other patches have
>>>>> implement flow aging in mlx5 driver reply to this patch.
>> [...]
>>>> These MAX values in enums are a pain.
>>>> We can try to think what can be done, waiting 20.11.
>>>> Not sure there is a solution, except hijacking an existing value
>>>> not used in the PMD, waiting the definitive value in 20.11...
>>>
>>> Dropping from the tree as of now, to not cause more merge conflicts, we can add
>>> it later when issue is resolved.
>>
>> Thanks for dropping, that's the right thing to do
>> when a patch is breaking ABI check.
>>
>> After some thoughts, I think it is acceptable to make a v3
>> which ignore this specific enum change. I explain my thought below:
>>
>> An enum can accept a new value at 2 conditions:
>> - added as last value (not changing old values)
>> - new value not used by existing API
>>
>> The value RTE_ETH_EVENT_FLOW_AGED meet the above 2 conditions:
>> - only RTE_ETH_EVENT_MAX is changed, which is consistent
>> - new value sent to the app only if the app registered for it
>>
>
> Same here, as far as I can see it is safe to get this change.
>
> If any DPDK API returns this enum, either as return of the API or as output
> parameter, this still can be problem, because application may use that returned
> value, this was the concern in the QAT sample.
>
> But here application registers an event and DPDK library process callback for
> it, so application callbacks won't be called for anything that application
> doesn't already know about, in that respect this should be safe for old
> applications.
>
> Not sure if we can generalize above two conditions for all enum changes, but we
> can investigate them case by case as we get the warnings.
>
>> So, except if I miss something, I suggest we add this exception:
>> Allow new value in rte_eth_event_type if added just before RTE_ETH_EVENT_MAX.
>> In other words, allow changing the value of RTE_ETH_EVENT_MAX.
>> The file to add such exception is devtools/libabigail.abignore.
>>
>
> OK to exception.
Me too
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v6 05/33] eal/trace: implement trace operation APIs
2020-04-21 13:40 3% ` Jerin Jacob
@ 2020-04-21 14:09 0% ` David Marchand
0 siblings, 0 replies; 200+ results
From: David Marchand @ 2020-04-21 14:09 UTC (permalink / raw)
To: Jerin Jacob
Cc: Jerin Jacob Kollanukkaran, Sunil Kumar Kori, dev,
Thomas Monjalon, Bruce Richardson, Mattias Rönnblom
On Tue, Apr 21, 2020 at 3:47 PM Jerin Jacob <jerinjacobk@gmail.com> wrote:
> > > @@ -20,6 +22,151 @@ static RTE_DEFINE_PER_LCORE(int, ctf_count);
> > > static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
> > > static struct trace trace;
> > >
> > > +bool
> > > +rte_trace_is_enabled(void)
> > > +{
> > > + return trace.status;
> > > +}
> > > +
> > > +static void
> > > +trace_mode_set(rte_trace_point_t *trace, enum rte_trace_mode mode)
> > > +{
> > > + if (mode == RTE_TRACE_MODE_OVERWRITE)
> > > + __atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_DISCARD,
> > > + __ATOMIC_RELEASE);
> > > + else
> > > + __atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_DISCARD,
> > > + __ATOMIC_RELEASE);
> > > +}
> > > +
> > > +void
> > > +rte_trace_mode_set(enum rte_trace_mode mode)
> > > +{
> > > + struct trace_point *tp;
> > > +
> > > + if (rte_trace_is_enabled() == false)
> > > + return;
> >
> > rte_trace_is_enabled() returns a boolean, no need to test its value, should be:
> > if (!rte_trace_is_enabled())
>
> I like the ! scheme. I thought, DPDK community like == false scheme.
> I will change it in v7.
Not obvious, but I understand this part as talking about the boolean case:
https://doc.dpdk.org/guides/contributing/coding_style.html#null-pointers
"Do not use ! for tests unless it is a boolean, for example, use:"
> > > +int
> > > +rte_trace_point_enable(rte_trace_point_t *trace)
> > > +{
> > > + if (trace_point_is_invalid(trace))
> > > + return -ERANGE;
> > > +
> > > + __atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_MASK,
> > > + __ATOMIC_RELEASE);
> > > + return 0;
> > > +}
> > > +
> > > +int
> > > +rte_trace_point_disable(rte_trace_point_t *trace)
> > > +{
> > > + if (trace_point_is_invalid(trace))
> > > + return -ERANGE;
> > > +
> > > + __atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_MASK,
> > > + __ATOMIC_RELEASE);
> > > + return 0;
> > > +}
> >
> > For both rte_trace_point_enable/disable, we only check tracepoint validity.
> > Can't we just return a boolean, do we expect many error codes?
>
> I think, it is better to return "int" so that we may not ABI the
> change in future.
Ok, fair enough.
> > > +
> > > +int
> > > +rte_trace_pattern(const char *pattern, bool enable)
> > > +{
> > > + struct trace_point *tp;
> > > + int rc = 0, found = 0;
> > > +
> > > + STAILQ_FOREACH(tp, &tp_list, next) {
> > > + if (fnmatch(pattern, tp->name, 0) == 0) {
> > > + if (enable)
> > > + rc = rte_trace_point_enable(tp->handle);
> > > + else
> > > + rc = rte_trace_point_disable(tp->handle);
> > > + found = 1;
> > > + }
> > > + if (rc < 0)
> > > + return rc;
> > > + }
> > > +
> > > + return rc | found;
> > > +}
> > > +
> > > +int
> > > +rte_trace_regexp(const char *regex, bool enable)
> > > +{
> > > + struct trace_point *tp;
> > > + int rc = 0, found = 0;
> > > + regex_t r;
> > > +
> > > + if (regcomp(&r, regex, 0) != 0)
> > > + return -EINVAL;
> > > +
> > > + STAILQ_FOREACH(tp, &tp_list, next) {
> > > + if (regexec(&r, tp->name, 0, NULL, 0) == 0) {
> > > + if (enable)
> > > + rc = rte_trace_point_enable(tp->handle);
> > > + else
> > > + rc = rte_trace_point_disable(tp->handle);
> > > + found = 1;
> > > + }
> > > + if (rc < 0)
> > > + return rc;
> > > + }
> > > + regfree(&r);
> > > +
> > > + return rc | found;
> > > +}
> >
> > For both rte_trace_pattern/rte_trace_regexp, tp is a member of tp_list.
> > It means this tracepoint went through proper registration.
> > Hence, checking for a return value from rte_trace_point_(en|dis)able
> > is unneeded.
>
> Yes. I thought of it, But I think, it is safe to check the return code
> as it absorbs any
> future rte_trace_point_enable() changes. It slow-path code, so it OK IMO.
Would be odd to predict what happened if we broke for this loop on one
tracepoint error, but ok to leave as is.
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v6 05/33] eal/trace: implement trace operation APIs
@ 2020-04-21 13:40 3% ` Jerin Jacob
2020-04-21 14:09 0% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2020-04-21 13:40 UTC (permalink / raw)
To: David Marchand
Cc: Jerin Jacob Kollanukkaran, Sunil Kumar Kori, dev,
Thomas Monjalon, Bruce Richardson, Mattias Rönnblom
On Tue, Apr 21, 2020 at 6:19 PM David Marchand
<david.marchand@redhat.com> wrote:
>
> On Sun, Apr 19, 2020 at 12:02 PM <jerinj@marvell.com> wrote:
> > diff --git a/lib/librte_eal/common/eal_common_trace.c b/lib/librte_eal/common/eal_common_trace.c
> > index 5c5cbd2a1..1ca702f68 100644
> > --- a/lib/librte_eal/common/eal_common_trace.c
> > +++ b/lib/librte_eal/common/eal_common_trace.c
> > @@ -3,7 +3,9 @@
> > */
> >
> > #include <inttypes.h>
> > +#include <fnmatch.h>
> > #include <sys/queue.h>
> > +#include <regex.h>
>
> Alphabetical sort when possible.
Ack. Wil fix it v7
>
> >
> > #include <rte_common.h>
> > #include <rte_errno.h>
> > @@ -20,6 +22,151 @@ static RTE_DEFINE_PER_LCORE(int, ctf_count);
> > static struct trace_point_head tp_list = STAILQ_HEAD_INITIALIZER(tp_list);
> > static struct trace trace;
> >
> > +bool
> > +rte_trace_is_enabled(void)
> > +{
> > + return trace.status;
> > +}
> > +
> > +static void
> > +trace_mode_set(rte_trace_point_t *trace, enum rte_trace_mode mode)
> > +{
> > + if (mode == RTE_TRACE_MODE_OVERWRITE)
> > + __atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_DISCARD,
> > + __ATOMIC_RELEASE);
> > + else
> > + __atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_DISCARD,
> > + __ATOMIC_RELEASE);
> > +}
> > +
> > +void
> > +rte_trace_mode_set(enum rte_trace_mode mode)
> > +{
> > + struct trace_point *tp;
> > +
> > + if (rte_trace_is_enabled() == false)
> > + return;
>
> rte_trace_is_enabled() returns a boolean, no need to test its value, should be:
> if (!rte_trace_is_enabled())
I like the ! scheme. I thought, DPDK community like == false scheme.
I will change it in v7.
>
>
> > +
> > + STAILQ_FOREACH(tp, &tp_list, next)
> > + trace_mode_set(tp->handle, mode);
> > +
> > + trace.mode = mode;
> > +}
> > +
> > +enum
> > +rte_trace_mode rte_trace_mode_get(void)
> > +{
> > + return trace.mode;
> > +}
> > +
> > +static bool
> > +trace_point_is_invalid(rte_trace_point_t *t)
> > +{
> > + if (t == NULL)
> > + return false;
>
> Should be "return true"?
>
> Or maybe simply rewrite as:
>
> static bool
> trace_point_is_invalid(rte_trace_point_t *t)
> {
> return (t == NULL) || (trace_id_get(t) >= trace.nb_trace_points);
> }
Ack.
>
> > +
> > + if (trace_id_get(t) >= trace.nb_trace_points)
> > + return true;
> > +
> > + return false;
> > +}
> > +
> > +bool
> > +rte_trace_point_is_enabled(rte_trace_point_t *trace)
> > +{
> > + uint64_t val;
> > +
> > + if (trace_point_is_invalid(trace))
> > + return false;
> > +
> > + val = __atomic_load_n(trace, __ATOMIC_ACQUIRE);
> > + return val & __RTE_TRACE_FIELD_ENABLE_MASK;
>
> We return a boolean, should be
> return (val & __RTE_TRACE_FIELD_ENABLE_MASK) != 0;
Ack.
>
>
> > +}
> > +
> > +int
> > +rte_trace_point_enable(rte_trace_point_t *trace)
> > +{
> > + if (trace_point_is_invalid(trace))
> > + return -ERANGE;
> > +
> > + __atomic_or_fetch(trace, __RTE_TRACE_FIELD_ENABLE_MASK,
> > + __ATOMIC_RELEASE);
> > + return 0;
> > +}
> > +
> > +int
> > +rte_trace_point_disable(rte_trace_point_t *trace)
> > +{
> > + if (trace_point_is_invalid(trace))
> > + return -ERANGE;
> > +
> > + __atomic_and_fetch(trace, ~__RTE_TRACE_FIELD_ENABLE_MASK,
> > + __ATOMIC_RELEASE);
> > + return 0;
> > +}
>
> For both rte_trace_point_enable/disable, we only check tracepoint validity.
> Can't we just return a boolean, do we expect many error codes?
I think, it is better to return "int" so that we may not ABI the
change in future.
>
>
> > +
> > +int
> > +rte_trace_pattern(const char *pattern, bool enable)
> > +{
> > + struct trace_point *tp;
> > + int rc = 0, found = 0;
> > +
> > + STAILQ_FOREACH(tp, &tp_list, next) {
> > + if (fnmatch(pattern, tp->name, 0) == 0) {
> > + if (enable)
> > + rc = rte_trace_point_enable(tp->handle);
> > + else
> > + rc = rte_trace_point_disable(tp->handle);
> > + found = 1;
> > + }
> > + if (rc < 0)
> > + return rc;
> > + }
> > +
> > + return rc | found;
> > +}
> > +
> > +int
> > +rte_trace_regexp(const char *regex, bool enable)
> > +{
> > + struct trace_point *tp;
> > + int rc = 0, found = 0;
> > + regex_t r;
> > +
> > + if (regcomp(&r, regex, 0) != 0)
> > + return -EINVAL;
> > +
> > + STAILQ_FOREACH(tp, &tp_list, next) {
> > + if (regexec(&r, tp->name, 0, NULL, 0) == 0) {
> > + if (enable)
> > + rc = rte_trace_point_enable(tp->handle);
> > + else
> > + rc = rte_trace_point_disable(tp->handle);
> > + found = 1;
> > + }
> > + if (rc < 0)
> > + return rc;
> > + }
> > + regfree(&r);
> > +
> > + return rc | found;
> > +}
>
> For both rte_trace_pattern/rte_trace_regexp, tp is a member of tp_list.
> It means this tracepoint went through proper registration.
> Hence, checking for a return value from rte_trace_point_(en|dis)able
> is unneeded.
Yes. I thought of it, But I think, it is safe to check the return code
as it absorbs any
future rte_trace_point_enable() changes. It slow-path code, so it OK IMO.
>
>
> --
> David Marchand
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-21 11:12 4% ` Neil Horman
@ 2020-04-21 11:46 4% ` Thomas Monjalon
2020-04-21 18:56 4% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-21 11:46 UTC (permalink / raw)
To: Ray Kinsella, Neil Horman; +Cc: dev, david.marchand
21/04/2020 13:12, Neil Horman:
> On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
> > On 17/04/2020 13:10, Thomas Monjalon wrote:
> > > 17/04/2020 13:47, Ray Kinsella:
> > >> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > >>> 17/04/2020 12:11, Ray Kinsella:
> > >>>> check-abi.sh appears to be backward step in terms of usability.
> > >>>
> > >>> No, check-abi.sh benefits from a nice integration in build scripts.
> > >>> See below.
> > >>>
> > >>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> > >>>> And it will do the build, install, dump and comparison for me.
> > >>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> > >>>>
> > >>>> With check-abi on the other hand, I need to the build and install myself.
> > >>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> > >>>> It silently fails when it doesn't find any ...
> > >>>>
> > >>>> Do I run abi-dumper on the so's myself, or how does it work?
> > >>>
> > >>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > >>> Probably we should document usage in these scripts.
> > >>
> > >> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> > >> Any tips or tricks would be welcome.
> > >
> > > export DPDK_ABI_REF_VERSION=v20.02
> > > or
> > > export DPDK_ABI_REF_VERSION=v19.11
> > >
> > > Depends on which compatibility you want to test...
> > >
> >
> > Few things ...
> >
> > 1. test-meson-build.sh keep barfing complaining about reference paths.
> > ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
> >
> > Under the hood, ninja install is failing complaining that it needs an absolute path.
> > I fixed this in test_meson_build.sh and will send a patch in a minute.
> > Though it's strange no-one else has seen it?
> >
> > 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
> >
> > 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> > In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> > I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
> >
> I think this code in test-meson-build.sh should probably be fixed:
>
> if [ ! -d $abirefdir/src ]; then
> git clone --local --no-hardlinks \
> --single-branch \
> -b $DPDK_ABI_REF_VERSION \
> $srcdir $abirefdir/src
> fi
>
> Like you noted, using -b allows us to checkout a tag/branch in the cloned
> repository but requires that it exist locally. We should probably prefix the
> checkout with a git fetch --tags
I don't understand your concern.
A reference is an older version, so it should be in the git tree.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v7 00/10] New sync modes for ring
2020-04-20 12:28 3% ` [dpdk-dev] [PATCH v7 00/10] New sync modes for ring Konstantin Ananyev
2020-04-20 12:28 9% ` [dpdk-dev] [PATCH v7 02/10] ring: prepare ring to allow new sync schemes Konstantin Ananyev
2020-04-20 12:28 1% ` [dpdk-dev] [PATCH v7 03/10] ring: introduce RTS ring mode Konstantin Ananyev
@ 2020-04-21 11:31 0% ` David Marchand
2 siblings, 0 replies; 200+ results
From: David Marchand @ 2020-04-21 11:31 UTC (permalink / raw)
To: Konstantin Ananyev, Honnappa Nagarahalli
Cc: dev, jielong.zjl, Pavan Nikhilesh, Jerin Jacob Kollanukkaran,
Thomas Monjalon
On Mon, Apr 20, 2020 at 2:28 PM Konstantin Ananyev
<konstantin.ananyev@intel.com> wrote:
> These days more and more customers use(/try to use) DPDK based apps within
> overcommitted systems (multiple acttive threads over same pysical cores):
> VM, container deployments, etc.
> One quite common problem they hit:
> Lock-Holder-Preemption/Lock-Waiter-Preemption with rte_ring.
> LHP is quite a common problem for spin-based sync primitives
> (spin-locks, etc.) on overcommitted systems.
> The situation gets much worse when some sort of
> fair-locking technique is used (ticket-lock, etc.).
> As now not only lock-owner but also lock-waiters scheduling
> order matters a lot (LWP).
> These two problems are well-known for kernel within VMs:
> http://www-archive.xenproject.org/files/xensummitboston08/LHP.pdf
> https://www.cs.hs-rm.de/~kaiser/events/wamos2017/Slides/selcuk.pdf
> The problem with rte_ring is that while head accusion is sort of
> un-fair locking, waiting on tail is very similar to ticket lock schema -
> tail has to be updated in particular order.
> That makes current rte_ring implementation to perform
> really pure on some overcommited scenarios.
> It is probably not possible to completely resolve LHP problem in
> userspace only (without some kernel communication/intervention).
> But removing fairness at tail update helps to avoid LWP and
> can mitigate the situation significantly.
> This patch proposes two new optional ring synchronization modes:
> 1) Head/Tail Sync (HTS) mode
> In that mode enqueue/dequeue operation is fully serialized:
> only one thread at a time is allowed to perform given op.
> As another enhancement provide ability to split enqueue/dequeue
> operation into two phases:
> - enqueue/dequeue start
> - enqueue/dequeue finish
> That allows user to inspect objects in the ring without removing
> them from it (aka MT safe peek).
> 2) Relaxed Tail Sync (RTS)
> The main difference from original MP/MC algorithm is that
> tail value is increased not by every thread that finished enqueue/dequeue,
> but only by the last one.
> That allows threads to avoid spinning on ring tail value,
> leaving actual tail value change to the last thread in the update queue.
>
> Note that these new sync modes are optional.
> For current rte_ring users nothing should change
> (both in terms of API/ABI and performance).
> Existing sync modes MP/MC,SP/SC kept untouched, set up in the same
> way (via flags and _init_), and MP/MC remains as default one.
> The only thing that changed:
> Format of prod/cons now could differ depending on mode selected at _init_.
> So user has to stick with one sync model through whole ring lifetime.
> In other words, user can't create a ring for let say SP mode and then
> in the middle of data-path change his mind and start using MP_RTS mode.
> For existing modes (SP/MP, SC/MC) format remains the same and
> user can still use them interchangeably, though of course it is an
> error prone practice.
>
> Test results on IA (see below) show significant improvements
> for average enqueue/dequeue op times on overcommitted systems.
> For 'classic' DPDK deployments (one thread per core) original MP/MC
> algorithm still shows best numbers, though for 64-bit target
> RTS numbers are not that far away.
> Numbers were produced by new UT test-case: ring_stress_autotest, i.e.:
> echo ring_stress_autotest | ./dpdk-test -n 4 --lcores='...'
>
> X86_64 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
> DEQ+ENQ average cycles/obj
> MP/MC HTS RTS
> 1thread@1core(--lcores=6-7) 8.00 8.15 8.99
> 2thread@2core(--lcores=6-8) 19.14 19.61 20.35
> 4thread@4core(--lcores=6-10) 29.43 29.79 31.82
> 8thread@8core(--lcores=6-14) 110.59 192.81 119.50
> 16thread@16core(--lcores=6-22) 461.03 813.12 495.59
> 32thread/@32core(--lcores='6-22,55-70') 982.90 1972.38 1160.51
>
> 2thread@1core(--lcores='6,(10-11)@7' 20140.50 23.58 25.14
> 4thread@2core(--lcores='6,(10-11)@7,(20-21)@8' 153680.60 76.88 80.05
> 8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 280314.32 294.72 318.79
> 16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 643176.59 1144.02 1175.14
> 32thread@2core(--lcores='6,(10-25)@7,(30-45)@8' 4264238.80 4627.48 4892.68
>
> 8thread@2core(--lcores='6,(10-17)@(7,8))' 321085.98 298.59 307.47
> 16thread@4core(--lcores='6,(20-35)@(7-10))' 1900705.61 575.35 678.29
> 32thread@4core(--lcores='6,(20-51)@(7-10))' 5510445.85 2164.36 2714.12
>
> i686 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
> DEQ+ENQ average cycles/obj
> MP/MC HTS RTS
> 1thread@1core(--lcores=6-7) 7.85 12.13 11.31
> 2thread@2core(--lcores=6-8) 17.89 24.52 21.86
> 8thread@8core(--lcores=6-14) 32.58 354.20 54.58
> 32thread/@32core(--lcores='6-22,55-70') 813.77 6072.41 2169.91
>
> 2thread@1core(--lcores='6,(10-11)@7' 16095.00 36.06 34.74
> 8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 1140354.54 346.61 361.57
> 16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 1920417.86 1314.90 1416.65
>
> 8thread@2core(--lcores='6,(10-17)@(7,8))' 594358.61 332.70 357.74
> 32thread@4core(--lcores='6,(20-51)@(7-10))' 5319896.86 2836.44 3028.87
I fixed a couple of typos and split the doc updates.
Series applied with the patch from Pavan.
Thanks for the work Konstantin, Honnappa.
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-17 15:42 9% ` Ray Kinsella
2020-04-17 16:10 4% ` Thomas Monjalon
@ 2020-04-21 11:12 4% ` Neil Horman
2020-04-21 11:46 4% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Neil Horman @ 2020-04-21 11:12 UTC (permalink / raw)
To: Ray Kinsella; +Cc: Thomas Monjalon, dev, david.marchand
On Fri, Apr 17, 2020 at 04:42:38PM +0100, Ray Kinsella wrote:
>
>
> On 17/04/2020 13:10, Thomas Monjalon wrote:
> > 17/04/2020 13:47, Ray Kinsella:
> >> On 17/04/2020 11:20, Thomas Monjalon wrote:
> >>> 17/04/2020 12:11, Ray Kinsella:
> >>>> check-abi.sh appears to be backward step in terms of usability.
> >>>
> >>> No, check-abi.sh benefits from a nice integration in build scripts.
> >>> See below.
> >>>
> >>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> >>>> And it will do the build, install, dump and comparison for me.
> >>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> >>>>
> >>>> With check-abi on the other hand, I need to the build and install myself.
> >>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> >>>> It silently fails when it doesn't find any ...
> >>>>
> >>>> Do I run abi-dumper on the so's myself, or how does it work?
> >>>
> >>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> >>> Probably we should document usage in these scripts.
> >>
> >> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> >> Any tips or tricks would be welcome.
> >
> > export DPDK_ABI_REF_VERSION=v20.02
> > or
> > export DPDK_ABI_REF_VERSION=v19.11
> >
> > Depends on which compatibility you want to test...
> >
>
> Few things ...
>
> 1. test-meson-build.sh keep barfing complaining about reference paths.
> ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
>
> Under the hood, ninja install is failing complaining that it needs an absolute path.
> I fixed this in test_meson_build.sh and will send a patch in a minute.
> Though it's strange no-one else has seen it?
>
> 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
>
> 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
>
I think this code in test-meson-build.sh should probably be fixed:
if [ ! -d $abirefdir/src ]; then
git clone --local --no-hardlinks \
--single-branch \
-b $DPDK_ABI_REF_VERSION \
$srcdir $abirefdir/src
fi
Like you noted, using -b allows us to checkout a tag/branch in the cloned
repository but requires that it exist locally. We should probably prefix the
checkout with a git fetch --tags
Neil
> Thanks,
>
> Ray K
>
>
>
> Ray K
>
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] devtools: remove useless files from ABI reference
2020-04-21 9:26 4% ` David Marchand
@ 2020-04-21 10:33 4% ` Bruce Richardson
0 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2020-04-21 10:33 UTC (permalink / raw)
To: David Marchand; +Cc: Thomas Monjalon, dev
On Tue, Apr 21, 2020 at 11:26:58AM +0200, David Marchand wrote:
> On Tue, Apr 21, 2020 at 11:22 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> >
> > 21/04/2020 09:49, David Marchand:
> > > On Tue, Apr 21, 2020 at 4:05 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> > > > + rm $abirefdir/$targetdir/usr/local/lib/*.a
> > >
> > > The install directory for libraries is not lib/ in all cases.
> > > This breaks the ABI generation for gcc-shared:
> > >
> > > DESTDIR=/home/dmarchan/abi/v20.02/build-gcc-shared ninja -C
> > > /home/dmarchan/abi/v20.02/build install >/dev/null
> > > rm: cannot remove
> > > '/home/dmarchan/abi/v20.02/build-gcc-shared/usr/local/lib/*.a': No
> > > such file or directory
> > >
> > > $ ls ~/abi/v20.02/build-gcc-shared/usr/local/
> > > bin include lib64 share
> >
> > Is it enough to change lib to lib* ?
>
> I can see only lib/ or lib64/ so ok for me.
>
If it's using lib, then the .a files could be in /lib/x86_64-linux-gnu/,
rather than in lib directly. Therefore I think it's better to use find or
similar to remove the .a files from /usr/local/:
find /usr/local -name 'librte*.a' -exec rm -f {}
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v4] ethdev: support flow aging
@ 2020-04-21 10:11 2% ` Bill Zhou
2020-04-21 17:13 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Bill Zhou @ 2020-04-21 10:11 UTC (permalink / raw)
To: orika, matan, wenzhuo.lu, jingjing.wu, bernard.iremonger,
john.mcnamara, marko.kovacevic, thomas, ferruh.yigit, arybchenko
Cc: dev, Dong Zhou
From: Dong Zhou <dongz@mellanox.com>
One of the reasons to destroy a flow is the fact that no packet matches the
flow for "timeout" time.
For example, when TCP\UDP sessions are suddenly closed.
Currently, there is not any DPDK mechanism for flow aging and the
applications use their own ways to detect and destroy aged-out flows.
The flow aging implementation need include:
- A new rte_flow action: RTE_FLOW_ACTION_TYPE_AGE to set the timeout and
the application flow context for each flow.
- A new ethdev event: RTE_ETH_EVENT_FLOW_AGED for the driver to report
that there are new aged-out flows.
- A new rte_flow API: rte_flow_get_aged_flows to get the aged-out flows
contexts from the port.
- Support input flow aging command line in Testpmd.
The new event type addition in the enum is flagged as an ABI breakage, so
an ignore rule is added for these reasons:
- It is not changing value of existing types (except MAX)
- The new value is not used by existing API if the event is not registered
In general, it is safe adding new ethdev event types at the end of the
enum, because of event callback registration mechanism.
Signed-off-by: Dong Zhou <dongz@mellanox.com>
---
v2: Removing "* Added support for flow Aging mechanism base on counter."
this line from doc/guides/rel_notes/release_20_05.rst, this patch does not
include this support.
v3: Update file libabigail.abignore, add one new suppressed enumeration
type for RTE_ETH_EVENT_MAX.
v4: Add justification in devtools/libabigail.abignore and in the commit
log about the modification of v3.
---
app/test-pmd/cmdline_flow.c | 26 ++++++++++
devtools/libabigail.abignore | 6 +++
doc/guides/prog_guide/rte_flow.rst | 22 +++++++++
doc/guides/rel_notes/release_20_05.rst | 11 +++++
lib/librte_ethdev/rte_ethdev.h | 1 +
lib/librte_ethdev/rte_ethdev_version.map | 3 ++
lib/librte_ethdev/rte_flow.c | 18 +++++++
lib/librte_ethdev/rte_flow.h | 62 ++++++++++++++++++++++++
lib/librte_ethdev/rte_flow_driver.h | 6 +++
9 files changed, 155 insertions(+)
diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
index e6ab8ff2f7..45bcff3cf5 100644
--- a/app/test-pmd/cmdline_flow.c
+++ b/app/test-pmd/cmdline_flow.c
@@ -343,6 +343,8 @@ enum index {
ACTION_SET_IPV4_DSCP_VALUE,
ACTION_SET_IPV6_DSCP,
ACTION_SET_IPV6_DSCP_VALUE,
+ ACTION_AGE,
+ ACTION_AGE_TIMEOUT,
};
/** Maximum size for pattern in struct rte_flow_item_raw. */
@@ -1145,6 +1147,7 @@ static const enum index next_action[] = {
ACTION_SET_META,
ACTION_SET_IPV4_DSCP,
ACTION_SET_IPV6_DSCP,
+ ACTION_AGE,
ZERO,
};
@@ -1370,6 +1373,13 @@ static const enum index action_set_ipv6_dscp[] = {
ZERO,
};
+static const enum index action_age[] = {
+ ACTION_AGE,
+ ACTION_AGE_TIMEOUT,
+ ACTION_NEXT,
+ ZERO,
+};
+
static int parse_set_raw_encap_decap(struct context *, const struct token *,
const char *, unsigned int,
void *, unsigned int);
@@ -3694,6 +3704,22 @@ static const struct token token_list[] = {
(struct rte_flow_action_set_dscp, dscp)),
.call = parse_vc_conf,
},
+ [ACTION_AGE] = {
+ .name = "age",
+ .help = "set a specific metadata header",
+ .next = NEXT(action_age),
+ .priv = PRIV_ACTION(AGE,
+ sizeof(struct rte_flow_action_age)),
+ .call = parse_vc,
+ },
+ [ACTION_AGE_TIMEOUT] = {
+ .name = "timeout",
+ .help = "flow age timeout value",
+ .args = ARGS(ARGS_ENTRY_BF(struct rte_flow_action_age,
+ timeout, 24)),
+ .next = NEXT(action_age, NEXT_ENTRY(UNSIGNED)),
+ .call = parse_vc_conf,
+ },
};
/** Remove and return last entry from argument stack. */
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index a59df8f135..c047adbd79 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -11,3 +11,9 @@
type_kind = enum
name = rte_crypto_asym_xform_type
changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
+; Ignore ethdev event enum update because new event cannot be
+; received if not registered
+[suppress_type]
+ type_kind = enum
+ name = rte_eth_event_type
+ changed_enumerators = RTE_ETH_EVENT_MAX
diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
index 41c147913c..cf4368e1c4 100644
--- a/doc/guides/prog_guide/rte_flow.rst
+++ b/doc/guides/prog_guide/rte_flow.rst
@@ -2616,6 +2616,28 @@ Otherwise, RTE_FLOW_ERROR_TYPE_ACTION error will be returned.
| ``dscp`` | DSCP in low 6 bits, rest ignore |
+-----------+---------------------------------+
+Action: ``AGE``
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set ageing timeout configuration to a flow.
+
+Event RTE_ETH_EVENT_FLOW_AGED will be reported if
+timeout passed without any matching on the flow.
+
+.. _table_rte_flow_action_age:
+
+.. table:: AGE
+
+ +--------------+---------------------------------+
+ | Field | Value |
+ +==============+=================================+
+ | ``timeout`` | 24 bits timeout value |
+ +--------------+---------------------------------+
+ | ``reserved`` | 8 bits reserved, must be zero |
+ +--------------+---------------------------------+
+ | ``context`` | user input flow context |
+ +--------------+---------------------------------+
+
Negative types
~~~~~~~~~~~~~~
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index bacd4c65a2..ff0cf9f1d6 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -135,6 +135,17 @@ New Features
by making use of the event device capabilities. The event mode currently supports
only inline IPsec protocol offload.
+* **Added flow Aging Support.**
+
+ Added flow Aging support to detect and report aged-out flows, including:
+
+ * Added new action: RTE_FLOW_ACTION_TYPE_AGE to set the timeout and the
+ application flow context for each flow.
+ * Added new event: RTE_ETH_EVENT_FLOW_AGED for the driver to report that
+ there are new aged-out flows.
+ * Added new API: rte_flow_get_aged_flows to get the aged-out flows contexts
+ from the port.
+
Removed Items
-------------
diff --git a/lib/librte_ethdev/rte_ethdev.h b/lib/librte_ethdev/rte_ethdev.h
index 8d69b88f9e..00cc7b4052 100644
--- a/lib/librte_ethdev/rte_ethdev.h
+++ b/lib/librte_ethdev/rte_ethdev.h
@@ -3018,6 +3018,7 @@ enum rte_eth_event_type {
RTE_ETH_EVENT_NEW, /**< port is probed */
RTE_ETH_EVENT_DESTROY, /**< port is released */
RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
+ RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected */
RTE_ETH_EVENT_MAX /**< max value of this enum */
};
diff --git a/lib/librte_ethdev/rte_ethdev_version.map b/lib/librte_ethdev/rte_ethdev_version.map
index 3f32fdecf7..fa4b5816be 100644
--- a/lib/librte_ethdev/rte_ethdev_version.map
+++ b/lib/librte_ethdev/rte_ethdev_version.map
@@ -230,4 +230,7 @@ EXPERIMENTAL {
# added in 20.02
rte_flow_dev_dump;
+
+ # added in 20.05
+ rte_flow_get_aged_flows;
};
diff --git a/lib/librte_ethdev/rte_flow.c b/lib/librte_ethdev/rte_flow.c
index a5ac1c7fbd..3699edce49 100644
--- a/lib/librte_ethdev/rte_flow.c
+++ b/lib/librte_ethdev/rte_flow.c
@@ -172,6 +172,7 @@ static const struct rte_flow_desc_data rte_flow_desc_action[] = {
MK_FLOW_ACTION(SET_META, sizeof(struct rte_flow_action_set_meta)),
MK_FLOW_ACTION(SET_IPV4_DSCP, sizeof(struct rte_flow_action_set_dscp)),
MK_FLOW_ACTION(SET_IPV6_DSCP, sizeof(struct rte_flow_action_set_dscp)),
+ MK_FLOW_ACTION(AGE, sizeof(struct rte_flow_action_age)),
};
int
@@ -1232,3 +1233,20 @@ rte_flow_dev_dump(uint16_t port_id, FILE *file, struct rte_flow_error *error)
RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
NULL, rte_strerror(ENOSYS));
}
+
+int
+rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
+ uint32_t nb_contexts, struct rte_flow_error *error)
+{
+ struct rte_eth_dev *dev = &rte_eth_devices[port_id];
+ const struct rte_flow_ops *ops = rte_flow_ops_get(port_id, error);
+
+ if (unlikely(!ops))
+ return -rte_errno;
+ if (likely(!!ops->get_aged_flows))
+ return flow_err(port_id, ops->get_aged_flows(dev, contexts,
+ nb_contexts, error), error);
+ return rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_UNSPECIFIED,
+ NULL, rte_strerror(ENOTSUP));
+}
diff --git a/lib/librte_ethdev/rte_flow.h b/lib/librte_ethdev/rte_flow.h
index 7f3e08fad3..fab44f6c0b 100644
--- a/lib/librte_ethdev/rte_flow.h
+++ b/lib/librte_ethdev/rte_flow.h
@@ -2081,6 +2081,16 @@ enum rte_flow_action_type {
* See struct rte_flow_action_set_dscp.
*/
RTE_FLOW_ACTION_TYPE_SET_IPV6_DSCP,
+
+ /**
+ * Report as aged flow if timeout passed without any matching on the
+ * flow.
+ *
+ * See struct rte_flow_action_age.
+ * See function rte_flow_get_aged_flows
+ * see enum RTE_ETH_EVENT_FLOW_AGED
+ */
+ RTE_FLOW_ACTION_TYPE_AGE,
};
/**
@@ -2122,6 +2132,25 @@ struct rte_flow_action_queue {
uint16_t index; /**< Queue index to use. */
};
+/**
+ * @warning
+ * @b EXPERIMENTAL: this structure may change without prior notice
+ *
+ * RTE_FLOW_ACTION_TYPE_AGE
+ *
+ * Report flow as aged-out if timeout passed without any matching
+ * on the flow. RTE_ETH_EVENT_FLOW_AGED event is triggered when a
+ * port detects new aged-out flows.
+ *
+ * The flow context and the flow handle will be reported by the
+ * rte_flow_get_aged_flows API.
+ */
+struct rte_flow_action_age {
+ uint32_t timeout:24; /**< Time in seconds. */
+ uint32_t reserved:8; /**< Reserved, must be zero. */
+ void *context;
+ /**< The user flow context, NULL means the rte_flow pointer. */
+};
/**
* @warning
@@ -3254,6 +3283,39 @@ rte_flow_conv(enum rte_flow_conv_op op,
const void *src,
struct rte_flow_error *error);
+/**
+ * Get aged-out flows of a given port.
+ *
+ * RTE_ETH_EVENT_FLOW_AGED event will be triggered when at least one new aged
+ * out flow was detected after the last call to rte_flow_get_aged_flows.
+ * This function can be called to get the aged flows usynchronously from the
+ * event callback or synchronously regardless the event.
+ * This is not safe to call rte_flow_get_aged_flows function with other flow
+ * functions from multiple threads simultaneously.
+ *
+ * @param port_id
+ * Port identifier of Ethernet device.
+ * @param[in, out] contexts
+ * The address of an array of pointers to the aged-out flows contexts.
+ * @param[in] nb_contexts
+ * The length of context array pointers.
+ * @param[out] error
+ * Perform verbose error reporting if not NULL. Initialized in case of
+ * error only.
+ *
+ * @return
+ * if nb_contexts is 0, return the amount of all aged contexts.
+ * if nb_contexts is not 0 , return the amount of aged flows reported
+ * in the context array, otherwise negative errno value.
+ *
+ * @see rte_flow_action_age
+ * @see RTE_ETH_EVENT_FLOW_AGED
+ */
+__rte_experimental
+int
+rte_flow_get_aged_flows(uint16_t port_id, void **contexts,
+ uint32_t nb_contexts, struct rte_flow_error *error);
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_ethdev/rte_flow_driver.h b/lib/librte_ethdev/rte_flow_driver.h
index 51a9a57a0f..881cc469b7 100644
--- a/lib/librte_ethdev/rte_flow_driver.h
+++ b/lib/librte_ethdev/rte_flow_driver.h
@@ -101,6 +101,12 @@ struct rte_flow_ops {
(struct rte_eth_dev *dev,
FILE *file,
struct rte_flow_error *error);
+ /** See rte_flow_get_aged_flows() */
+ int (*get_aged_flows)
+ (struct rte_eth_dev *dev,
+ void **context,
+ uint32_t nb_contexts,
+ struct rte_flow_error *err);
};
/**
--
2.21.0
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
2020-04-21 10:04 0% ` Ferruh Yigit
@ 2020-04-21 10:09 0% ` Thomas Monjalon
2020-04-21 15:59 0% ` Andrew Rybchenko
1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2020-04-21 10:09 UTC (permalink / raw)
To: Bill Zhou, Ferruh Yigit
Cc: Ori Kam, Matan Azrad, wenzhuo.lu, jingjing.wu, bernard.iremonger,
john.mcnamara, marko.kovacevic, arybchenko, dev
21/04/2020 12:04, Ferruh Yigit:
> On 4/20/2020 5:10 PM, Thomas Monjalon wrote:
> > 20/04/2020 16:06, Ferruh Yigit:
> >> On 4/18/2020 10:44 AM, Thomas Monjalon wrote:
> >>> 18/04/2020 07:04, Bill Zhou:
> >>>> From: Ferruh Yigit <ferruh.yigit@intel.com>
> >>>>> On 4/14/2020 9:32 AM, Dong Zhou wrote:
> >>>>>> --- a/lib/librte_ethdev/rte_ethdev.h
> >>>>>> +++ b/lib/librte_ethdev/rte_ethdev.h
> >>>>>> @@ -3015,6 +3015,7 @@ enum rte_eth_event_type {
> >>>>>> RTE_ETH_EVENT_NEW, /**< port is probed */
> >>>>>> RTE_ETH_EVENT_DESTROY, /**< port is released */
> >>>>>> RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
> >>>>>> + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected
> >>>>> */
> >>>>>> RTE_ETH_EVENT_MAX /**< max value of this enum */
> >>>>>> };
> >>>>>
> >>>>>
> >>>>> Just recognized that this is failing in ABI check [1], as far as last time for a
> >>>>> similar enum warning a QAT patch has been dropped, should this need to
> >>>>> wait for
> >>>>> 20.11 too?
> >>>>
> >>>> This patch is commonly used for flow aging, there are 2 other patches have
> >>>> implement flow aging in mlx5 driver reply to this patch.
> > [...]
> >>> These MAX values in enums are a pain.
> >>> We can try to think what can be done, waiting 20.11.
> >>> Not sure there is a solution, except hijacking an existing value
> >>> not used in the PMD, waiting the definitive value in 20.11...
> >>
> >> Dropping from the tree as of now, to not cause more merge conflicts, we can add
> >> it later when issue is resolved.
> >
> > Thanks for dropping, that's the right thing to do
> > when a patch is breaking ABI check.
> >
> > After some thoughts, I think it is acceptable to make a v3
> > which ignore this specific enum change. I explain my thought below:
> >
> > An enum can accept a new value at 2 conditions:
> > - added as last value (not changing old values)
> > - new value not used by existing API
> >
> > The value RTE_ETH_EVENT_FLOW_AGED meet the above 2 conditions:
> > - only RTE_ETH_EVENT_MAX is changed, which is consistent
> > - new value sent to the app only if the app registered for it
> >
>
> Same here, as far as I can see it is safe to get this change.
>
> If any DPDK API returns this enum, either as return of the API or as output
> parameter, this still can be problem, because application may use that returned
> value, this was the concern in the QAT sample.
>
> But here application registers an event and DPDK library process callback for
> it, so application callbacks won't be called for anything that application
> doesn't already know about, in that respect this should be safe for old
> applications.
>
> Not sure if we can generalize above two conditions for all enum changes, but we
> can investigate them case by case as we get the warnings.
>
> > So, except if I miss something, I suggest we add this exception:
> > Allow new value in rte_eth_event_type if added just before RTE_ETH_EVENT_MAX.
> > In other words, allow changing the value of RTE_ETH_EVENT_MAX.
> > The file to add such exception is devtools/libabigail.abignore.
> >
>
> OK to exception.
v3 was sent.
I hope we'll get a v4 with justification for the exception.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
2020-04-20 16:10 3% ` Thomas Monjalon
@ 2020-04-21 10:04 0% ` Ferruh Yigit
2020-04-21 10:09 0% ` Thomas Monjalon
2020-04-21 15:59 0% ` Andrew Rybchenko
0 siblings, 2 replies; 200+ results
From: Ferruh Yigit @ 2020-04-21 10:04 UTC (permalink / raw)
To: Thomas Monjalon, Bill Zhou
Cc: Ori Kam, Matan Azrad, wenzhuo.lu, jingjing.wu, bernard.iremonger,
john.mcnamara, marko.kovacevic, arybchenko, dev
On 4/20/2020 5:10 PM, Thomas Monjalon wrote:
> 20/04/2020 16:06, Ferruh Yigit:
>> On 4/18/2020 10:44 AM, Thomas Monjalon wrote:
>>> 18/04/2020 07:04, Bill Zhou:
>>>> From: Ferruh Yigit <ferruh.yigit@intel.com>
>>>>> On 4/14/2020 9:32 AM, Dong Zhou wrote:
>>>>>> --- a/lib/librte_ethdev/rte_ethdev.h
>>>>>> +++ b/lib/librte_ethdev/rte_ethdev.h
>>>>>> @@ -3015,6 +3015,7 @@ enum rte_eth_event_type {
>>>>>> RTE_ETH_EVENT_NEW, /**< port is probed */
>>>>>> RTE_ETH_EVENT_DESTROY, /**< port is released */
>>>>>> RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
>>>>>> + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected
>>>>> */
>>>>>> RTE_ETH_EVENT_MAX /**< max value of this enum */
>>>>>> };
>>>>>
>>>>>
>>>>> Just recognized that this is failing in ABI check [1], as far as last time for a
>>>>> similar enum warning a QAT patch has been dropped, should this need to
>>>>> wait for
>>>>> 20.11 too?
>>>>
>>>> This patch is commonly used for flow aging, there are 2 other patches have
>>>> implement flow aging in mlx5 driver reply to this patch.
> [...]
>>> These MAX values in enums are a pain.
>>> We can try to think what can be done, waiting 20.11.
>>> Not sure there is a solution, except hijacking an existing value
>>> not used in the PMD, waiting the definitive value in 20.11...
>>
>> Dropping from the tree as of now, to not cause more merge conflicts, we can add
>> it later when issue is resolved.
>
> Thanks for dropping, that's the right thing to do
> when a patch is breaking ABI check.
>
> After some thoughts, I think it is acceptable to make a v3
> which ignore this specific enum change. I explain my thought below:
>
> An enum can accept a new value at 2 conditions:
> - added as last value (not changing old values)
> - new value not used by existing API
>
> The value RTE_ETH_EVENT_FLOW_AGED meet the above 2 conditions:
> - only RTE_ETH_EVENT_MAX is changed, which is consistent
> - new value sent to the app only if the app registered for it
>
Same here, as far as I can see it is safe to get this change.
If any DPDK API returns this enum, either as return of the API or as output
parameter, this still can be problem, because application may use that returned
value, this was the concern in the QAT sample.
But here application registers an event and DPDK library process callback for
it, so application callbacks won't be called for anything that application
doesn't already know about, in that respect this should be safe for old
applications.
Not sure if we can generalize above two conditions for all enum changes, but we
can investigate them case by case as we get the warnings.
> So, except if I miss something, I suggest we add this exception:
> Allow new value in rte_eth_event_type if added just before RTE_ETH_EVENT_MAX.
> In other words, allow changing the value of RTE_ETH_EVENT_MAX.
> The file to add such exception is devtools/libabigail.abignore.
>
OK to exception.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] rte_vfio_container_dma_map/unmap functions
2020-04-20 17:39 3% ` Thomas Monjalon
@ 2020-04-21 9:50 0% ` Burakov, Anatoly
0 siblings, 0 replies; 200+ results
From: Burakov, Anatoly @ 2020-04-21 9:50 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, Tal Shnaiderman, bruce.richardson, david.marchand
On 20-Apr-20 6:39 PM, Thomas Monjalon wrote:
> 20/04/2020 16:07, Burakov, Anatoly:
>> On 19-Apr-20 2:10 PM, Thomas Monjalon wrote:
>>> 19/04/2020 15:09, Thomas Monjalon:
>>>> 17/04/2020 16:09, Burakov, Anatoly:
>>>>> On 17-Apr-20 3:05 PM, Burakov, Anatoly wrote:
>>>>>> On 22-Mar-20 5:20 PM, Tal Shnaiderman wrote:
>>>>>>> Hi Anatoly,
>>>>>>>
>>>>>>> I’m working on the implementation of bus/pci driver for Windows,
>>>>>>> pci_common.c uses the titled functions however they are relevant only
>>>>>>> for Linux OS.
>>>>>>>
>>>>>>> I’m wondering if the implementation of those functions should be moved
>>>>>>> to a Linux specific area since FreeBSD (and now Windows) are forced to
>>>>>>> implemented those in the current state.
>>>>>
>>>>> Unfortunately, we don't have a generic API for these, but since we
>>>>> export a single API on all platforms, either all platforms have to
>>>>> implement these functions, or none of them do. There's simply no way to
>>>>> avoid implementing stubs for these functions, short of coming up with a
>>>>> generic API that would replace these. Given that this API is heavily
>>>>> Linux specific, i don't see that happening.
>>>>
>>>> Because it is Linux specific, we should not force FreeBSD and Windows
>>>> having stubs. Can we move VFIO calls in Linux-specific files?
>>>>
>>>> I think rte_vfio.h should be moved in lib/librte_eal/linux/include.
>>>
>>> +Cc Bruce and David
>>
>> ...and have a Linux-specific ABI?
>
> Yes, the ABI is different depending on arch and OS.
> That's a fact, and I don't see any problem with it.
>
OK, no objections then :)
--
Thanks,
Anatoly
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-21 6:01 3% ` Ray Kinsella
@ 2020-04-21 9:36 0% ` Thomas Monjalon
2020-04-22 8:21 0% ` Ray Kinsella
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-21 9:36 UTC (permalink / raw)
To: Ray Kinsella
Cc: Trahe, Fiona, Richardson, Bruce, dev, Kusztal, ArkadiuszX,
Neil Horman, Luca Boccassi, Kevin Traynor, Yigit, Ferruh,
Akhil Goyal
21/04/2020 08:01, Ray Kinsella:
>
> On 20/04/2020 18:37, Thomas Monjalon wrote:
> > 20/04/2020 19:31, Ray Kinsella:
> >>
> >> Our only commitment is to the stability of the v19.11/v20 ABI, until v21.
> >>
> >> That said, once an ABI migrates from EXPERIMENTAL to v21, it _shouldn't_ be changing.
> >> We don't have a strict commitment to the v21 ABI until v20.11.
> >>
> >> However if v21 is changing across quarterlies (outside of additions) ... something else is wrong.
> >
> > The only way to check a symbol is not changing in a quarterly release
> > is to test it. That's what we wanted to enforce:
> > compare 20.02 ABI in 20.05 release.
> >
> > What other process do you suggest?
> >
>
> Well I guess it's understanding the reason why you are doing something.
> I can see reasons for wanting to test against both v19.11 and v20.02.
>
> v19.11 because our strict commitment is to the v20 abi.
> v20.02 to ensure that v21 symbols are not changing between quarterly releases.
>
> On v20, since you tested v20.02 against v19.11 during the v20.02 release cycle.
> The v20 symbols should not have changed during the v20.02 release cycle.
>
> I take your point, that then testing v20.05 against v20.02 would catch both v20 and v21 changes.
OK, so we need a policy or process update to make this conclusion clear to everybody.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] devtools: remove useless files from ABI reference
2020-04-21 9:22 4% ` Thomas Monjalon
@ 2020-04-21 9:26 4% ` David Marchand
2020-04-21 10:33 4% ` Bruce Richardson
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2020-04-21 9:26 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, Bruce Richardson
On Tue, Apr 21, 2020 at 11:22 AM Thomas Monjalon <thomas@monjalon.net> wrote:
>
> 21/04/2020 09:49, David Marchand:
> > On Tue, Apr 21, 2020 at 4:05 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> > > + rm $abirefdir/$targetdir/usr/local/lib/*.a
> >
> > The install directory for libraries is not lib/ in all cases.
> > This breaks the ABI generation for gcc-shared:
> >
> > DESTDIR=/home/dmarchan/abi/v20.02/build-gcc-shared ninja -C
> > /home/dmarchan/abi/v20.02/build install >/dev/null
> > rm: cannot remove
> > '/home/dmarchan/abi/v20.02/build-gcc-shared/usr/local/lib/*.a': No
> > such file or directory
> >
> > $ ls ~/abi/v20.02/build-gcc-shared/usr/local/
> > bin include lib64 share
>
> Is it enough to change lib to lib* ?
I can see only lib/ or lib64/ so ok for me.
--
David Marchand
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] devtools: remove useless files from ABI reference
2020-04-21 7:49 9% ` David Marchand
@ 2020-04-21 9:22 4% ` Thomas Monjalon
2020-04-21 9:26 4% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-21 9:22 UTC (permalink / raw)
To: David Marchand; +Cc: dev, Bruce Richardson
21/04/2020 09:49, David Marchand:
> On Tue, Apr 21, 2020 at 4:05 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> > + rm $abirefdir/$targetdir/usr/local/lib/*.a
>
> The install directory for libraries is not lib/ in all cases.
> This breaks the ABI generation for gcc-shared:
>
> DESTDIR=/home/dmarchan/abi/v20.02/build-gcc-shared ninja -C
> /home/dmarchan/abi/v20.02/build install >/dev/null
> rm: cannot remove
> '/home/dmarchan/abi/v20.02/build-gcc-shared/usr/local/lib/*.a': No
> such file or directory
>
> $ ls ~/abi/v20.02/build-gcc-shared/usr/local/
> bin include lib64 share
Is it enough to change lib to lib* ?
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] devtools: skip ABI check in static builds
2020-04-21 8:02 4% ` David Marchand
@ 2020-04-21 9:20 4% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2020-04-21 9:20 UTC (permalink / raw)
To: dev; +Cc: Ray Kinsella, David Marchand
21/04/2020 10:02, David Marchand:
> On Tue, Apr 21, 2020 at 3:33 AM Thomas Monjalon <thomas@monjalon.net> wrote:
> >
> > When running make with CONFIG_RTE_BUILD_SHARED_LIB=n,
> > no shared library is built.
> > In this case, no need to run ABI check.
> >
> > With meson, both shared and static libraries are always built.
> >
> > Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
>
> Acked-by: David Marchand <david.marchand@redhat.com>
Reviewed-by: Ray Kinsella <mdr@ashroe.eu>
Applied
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] devtools: skip ABI check in static builds
2020-04-21 6:11 4% ` Ray Kinsella
@ 2020-04-21 9:15 4% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2020-04-21 9:15 UTC (permalink / raw)
To: Ray Kinsella; +Cc: dev, david.marchand
21/04/2020 08:11, Ray Kinsella:
>
> On 21/04/2020 02:33, Thomas Monjalon wrote:
> > When running make with CONFIG_RTE_BUILD_SHARED_LIB=n,
> > no shared library is built.
> > In this case, no need to run ABI check.
> >
> > With meson, both shared and static libraries are always built.
>
> You can easily do the same thing for meson, by checking the 3rd parameter to build() in test-meson-build.sh,
No, both library types are always compiled.
The only option is to choose which library to link in built-in apps.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-21 2:52 4% ` Wang, Haiyue
@ 2020-04-21 8:47 0% ` Thomas Monjalon
2020-04-21 17:35 0% ` Wang, Haiyue
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-21 8:47 UTC (permalink / raw)
To: David Marchand, Wang, Haiyue
Cc: Neil Horman, dev, Burakov, Anatoly, Vamsi Attunuru,
Jerin Jacob Kollanukkaran, Yigit, Ferruh, Richardson, Bruce,
Kinsella, Ray
21/04/2020 04:52, Wang, Haiyue:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 21/04/2020 03:38, Wang, Haiyue:
> > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > 20/04/2020 19:37, Wang, Haiyue:
> > > > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > > > 20/04/2020 19:02, Wang, Haiyue:
> > > > > > > From: David Marchand <david.marchand@redhat.com>
> > > > > > > > I had a look at the CI, I can see we are still missing bits to handle
> > > > > > > > the ABI failure on rte_vfio_setup_device.
> > > > > > >
> > > > > > > Yes, not handle it now.
> > > > > > >
> > > > > > > If 'rte_vfio_setup_device' can be internal, not official DPDK API, then __rte_internal
> > > > > > > is the best way to handle ABI issue.
> > > > > >
> > > > > > Please could you help finishing integration of __rte_internal?
> > > > >
> > > > > I thought it should be Neil ? "Yes, I'll get back to this today" ;-)
> > > > > http://inbox.dpdk.org/dev/CAJFAV8ydLkV0afEHqbh6KeA3Box0Yxb3N0MNGtMD4S9bmSgT0A@mail.gmail.com/
> > > >
> > > > It did not happen after several months.
> > > > If you want to unblock your patches, I think it is safer to finish yourself.
> > > >
> > >
> > > Unfortunately, this __rte_internal will still make the ci fail to run when move the function
> > > to INTERNAL session:
> > [...]
> > > +INTERNAL {
> > > + global:
> > > +
> > > + # added in 20.05
> > > + rte_vfio_setup_device;
> > > +};
> >
> > Why do you need to move the symbol explicitly in .map?
> > The tool should ignore symbols moving to internal, as an exception until 20.11.
>
> If not move the symbol explicitly in .map, another kind of error happened.
>
> ./devtools/check-abi.sh old_abi new_abi
> Functions changes summary: 0 Removed, 1 Changed, 0 Added function
> Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
>
> 1 function with some indirect sub-type change:
>
> [C] 'function int rte_vfio_setup_device(const char*, const char*, int*, vfio_device_info*)' at eal_vfio.c:704:1 has some indirect sub-type changes:
> parameter 5 of type 'unsigned char*' was added
>
> Error: ABI issue reported for 'abidiff --suppr ./devtools/libabigail.abignore --no-added-syms --headers-dir1 old_abi/include --headers-dir2 new_abi/include old_abi/dump/librte_eal.dump new_abi/dump/librte_eal.dump'
This is what I said: you need to add a rule to ignore internal symbols.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] devtools: skip ABI check in static builds
2020-04-21 1:33 13% [dpdk-dev] [PATCH] devtools: skip ABI check in static builds Thomas Monjalon
2020-04-21 6:11 4% ` Ray Kinsella
@ 2020-04-21 8:02 4% ` David Marchand
2020-04-21 9:20 4% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: David Marchand @ 2020-04-21 8:02 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, Ray Kinsella
On Tue, Apr 21, 2020 at 3:33 AM Thomas Monjalon <thomas@monjalon.net> wrote:
>
> When running make with CONFIG_RTE_BUILD_SHARED_LIB=n,
> no shared library is built.
> In this case, no need to run ABI check.
>
> With meson, both shared and static libraries are always built.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
Acked-by: David Marchand <david.marchand@redhat.com>
--
David Marchand
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] devtools: remove useless files from ABI reference
2020-04-21 2:04 13% [dpdk-dev] [PATCH] devtools: remove useless files from ABI reference Thomas Monjalon
@ 2020-04-21 7:49 9% ` David Marchand
2020-04-21 9:22 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2020-04-21 7:49 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, Bruce Richardson
On Tue, Apr 21, 2020 at 4:05 AM Thomas Monjalon <thomas@monjalon.net> wrote:
>
> When building an ABI reference with meson, some static libraries
> are built and linked in apps. They are useless and take a lot of space.
> Those binaries, and other useless files (examples and doc files)
> in the share/ directory, are removed after being installed.
>
> In order to save time when building the ABI reference,
> the examples (which are not installed anyway) are not compiled.
>
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> devtools/test-meson-builds.sh | 7 ++++++-
> 1 file changed, 6 insertions(+), 1 deletion(-)
>
> diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh
> index e8df017596..16271e057d 100755
> --- a/devtools/test-meson-builds.sh
> +++ b/devtools/test-meson-builds.sh
> @@ -141,10 +141,15 @@ build () # <directory> <target compiler> <meson options>
> fi
>
> rm -rf $abirefdir/build
> - config $abirefdir/src $abirefdir/build $*
> + config $abirefdir/src $abirefdir/build -Dexamples= $*
> compile $abirefdir/build
> install_target $abirefdir/build $abirefdir/$targetdir
> $srcdir/devtools/gen-abi.sh $abirefdir/$targetdir
> +
> + # save disk space by removing static libs and apps
> + rm $abirefdir/$targetdir/usr/local/lib/*.a
The install directory for libraries is not lib/ in all cases.
This breaks the ABI generation for gcc-shared:
DESTDIR=/home/dmarchan/abi/v20.02/build-gcc-shared ninja -C
/home/dmarchan/abi/v20.02/build install >/dev/null
rm: cannot remove
'/home/dmarchan/abi/v20.02/build-gcc-shared/usr/local/lib/*.a': No
such file or directory
$ ls ~/abi/v20.02/build-gcc-shared/usr/local/
bin include lib64 share
--
David Marchand
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH] devtools: skip ABI check in static builds
2020-04-21 1:33 13% [dpdk-dev] [PATCH] devtools: skip ABI check in static builds Thomas Monjalon
@ 2020-04-21 6:11 4% ` Ray Kinsella
2020-04-21 9:15 4% ` Thomas Monjalon
2020-04-21 8:02 4% ` David Marchand
1 sibling, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-21 6:11 UTC (permalink / raw)
To: Thomas Monjalon, dev; +Cc: david.marchand
On 21/04/2020 02:33, Thomas Monjalon wrote:
> When running make with CONFIG_RTE_BUILD_SHARED_LIB=n,
> no shared library is built.
> In this case, no need to run ABI check.
>
> With meson, both shared and static libraries are always built.
You can easily do the same thing for meson, by checking the 3rd parameter to build() in test-meson-build.sh,
> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
> ---
> devtools/test-build.sh | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/devtools/test-build.sh b/devtools/test-build.sh
> index a298115002..6e53f86fc8 100755
> --- a/devtools/test-build.sh
> +++ b/devtools/test-build.sh
> @@ -262,6 +262,7 @@ for conf in $configs ; do
> EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \
> O=$(readlink -f $dir)/examples
> unset RTE_TARGET
> + grep -q 'SHARED_LIB=n' $dir/.config || # skip ABI check with static libs
> if [ -n "$DPDK_ABI_REF_VERSION" ]; then
> abirefdir=${DPDK_ABI_REF_DIR:-reference}/$DPDK_ABI_REF_VERSION
> if [ ! -d $abirefdir/$conf ]; then
>
Reviewed-by: Ray Kinsella <mdr@ashroe.eu>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-20 17:37 3% ` Thomas Monjalon
@ 2020-04-21 6:01 3% ` Ray Kinsella
2020-04-21 9:36 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-21 6:01 UTC (permalink / raw)
To: Thomas Monjalon, Trahe, Fiona, Richardson, Bruce
Cc: dev, Kusztal, ArkadiuszX, Neil Horman, Luca Boccassi,
Kevin Traynor, Yigit, Ferruh, Akhil Goyal
On 20/04/2020 18:37, Thomas Monjalon wrote:
> 20/04/2020 19:31, Ray Kinsella:
>>
>> Our only commitment is to the stability of the v19.11/v20 ABI, until v21.
>>
>> That said, once an ABI migrates from EXPERIMENTAL to v21, it _shouldn't_ be changing.
>> We don't have a strict commitment to the v21 ABI until v20.11.
>>
>> However if v21 is changing across quarterlies (outside of additions) ... something else is wrong.
>
> The only way to check a symbol is not changing in a quarterly release
> is to test it. That's what we wanted to enforce:
> compare 20.02 ABI in 20.05 release.
>
> What other process do you suggest?
>
Well I guess it's understanding the reason why you are doing something.
I can see reasons for wanting to test against both v19.11 and v20.02.
v19.11 because our strict commitment is to the v20 abi.
v20.02 to ensure that v21 symbols are not changing between quarterly releases.
On v20, since you tested v20.02 against v19.11 during the v20.02 release cycle.
The v20 symbols should not have changed during the v20.02 release cycle.
I take your point, that then testing v20.05 against v20.02 would catch both v20 and v21 changes.
Thanks,
Ray K
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-21 2:12 0% ` Thomas Monjalon
@ 2020-04-21 2:52 4% ` Wang, Haiyue
2020-04-21 8:47 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2020-04-21 2:52 UTC (permalink / raw)
To: Thomas Monjalon, David Marchand
Cc: Neil Horman, dev, Burakov, Anatoly, Vamsi Attunuru,
Jerin Jacob Kollanukkaran, Yigit, Ferruh, Richardson, Bruce,
Kinsella, Ray
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, April 21, 2020 10:13
> To: David Marchand <david.marchand@redhat.com>; Wang, Haiyue <haiyue.wang@intel.com>
> Cc: Neil Horman <nhorman@tuxdriver.com>; dev <dev@dpdk.org>; Burakov, Anatoly
> <anatoly.burakov@intel.com>; Vamsi Attunuru <vattunuru@marvell.com>; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Kinsella, Ray <ray.kinsella@intel.com>
> Subject: Re: [PATCH v8 0/2] support for VFIO-PCI VF token interface
>
> 21/04/2020 03:38, Wang, Haiyue:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > > 20/04/2020 19:37, Wang, Haiyue:
> > > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > > 20/04/2020 19:02, Wang, Haiyue:
> > > > > > From: David Marchand <david.marchand@redhat.com>
> > > > > > > I had a look at the CI, I can see we are still missing bits to handle
> > > > > > > the ABI failure on rte_vfio_setup_device.
> > > > > >
> > > > > > Yes, not handle it now.
> > > > > >
> > > > > > If 'rte_vfio_setup_device' can be internal, not official DPDK API, then __rte_internal
> > > > > > is the best way to handle ABI issue.
> > > > >
> > > > > Please could you help finishing integration of __rte_internal?
> > > >
> > > > I thought it should be Neil ? "Yes, I'll get back to this today" ;-)
> > > > http://inbox.dpdk.org/dev/CAJFAV8ydLkV0afEHqbh6KeA3Box0Yxb3N0MNGtMD4S9bmSgT0A@mail.gmail.com/
> > >
> > > It did not happen after several months.
> > > If you want to unblock your patches, I think it is safer to finish yourself.
> > >
> >
> > Unfortunately, this __rte_internal will still make the ci fail to run when move the function
> > to INTERNAL session:
> [...]
> > +INTERNAL {
> > + global:
> > +
> > + # added in 20.05
> > + rte_vfio_setup_device;
> > +};
>
> Why do you need to move the symbol explicitly in .map?
> The tool should ignore symbols moving to internal, as an exception until 20.11.
>
If not move the symbol explicitly in .map, another kind of error happened.
./devtools/check-abi.sh old_abi new_abi
Functions changes summary: 0 Removed, 1 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 function with some indirect sub-type change:
[C] 'function int rte_vfio_setup_device(const char*, const char*, int*, vfio_device_info*)' at eal_vfio.c:704:1 has some indirect sub-type changes:
parameter 5 of type 'unsigned char*' was added
Error: ABI issue reported for 'abidiff --suppr ./devtools/libabigail.abignore --no-added-syms --headers-dir1 old_abi/include --headers-dir2 new_abi/include old_abi/dump/librte_eal.dump new_abi/dump/librte_eal.dump'
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-21 1:38 3% ` Wang, Haiyue
@ 2020-04-21 2:12 0% ` Thomas Monjalon
2020-04-21 2:52 4% ` Wang, Haiyue
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-21 2:12 UTC (permalink / raw)
To: David Marchand, Wang, Haiyue
Cc: Neil Horman, dev, Burakov, Anatoly, Vamsi Attunuru,
Jerin Jacob Kollanukkaran, Yigit, Ferruh, Richardson, Bruce,
Kinsella, Ray
21/04/2020 03:38, Wang, Haiyue:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 20/04/2020 19:37, Wang, Haiyue:
> > > From: Thomas Monjalon <thomas@monjalon.net>
> > > > 20/04/2020 19:02, Wang, Haiyue:
> > > > > From: David Marchand <david.marchand@redhat.com>
> > > > > > I had a look at the CI, I can see we are still missing bits to handle
> > > > > > the ABI failure on rte_vfio_setup_device.
> > > > >
> > > > > Yes, not handle it now.
> > > > >
> > > > > If 'rte_vfio_setup_device' can be internal, not official DPDK API, then __rte_internal
> > > > > is the best way to handle ABI issue.
> > > >
> > > > Please could you help finishing integration of __rte_internal?
> > >
> > > I thought it should be Neil ? "Yes, I'll get back to this today" ;-)
> > > http://inbox.dpdk.org/dev/CAJFAV8ydLkV0afEHqbh6KeA3Box0Yxb3N0MNGtMD4S9bmSgT0A@mail.gmail.com/
> >
> > It did not happen after several months.
> > If you want to unblock your patches, I think it is safer to finish yourself.
> >
>
> Unfortunately, this __rte_internal will still make the ci fail to run when move the function
> to INTERNAL session:
[...]
> +INTERNAL {
> + global:
> +
> + # added in 20.05
> + rte_vfio_setup_device;
> +};
Why do you need to move the symbol explicitly in .map?
The tool should ignore symbols moving to internal, as an exception until 20.11.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] devtools: remove useless files from ABI reference
@ 2020-04-21 2:04 13% Thomas Monjalon
2020-04-21 7:49 9% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-21 2:04 UTC (permalink / raw)
To: dev; +Cc: bruce.richardson, david.marchand
When building an ABI reference with meson, some static libraries
are built and linked in apps. They are useless and take a lot of space.
Those binaries, and other useless files (examples and doc files)
in the share/ directory, are removed after being installed.
In order to save time when building the ABI reference,
the examples (which are not installed anyway) are not compiled.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
devtools/test-meson-builds.sh | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh
index e8df017596..16271e057d 100755
--- a/devtools/test-meson-builds.sh
+++ b/devtools/test-meson-builds.sh
@@ -141,10 +141,15 @@ build () # <directory> <target compiler> <meson options>
fi
rm -rf $abirefdir/build
- config $abirefdir/src $abirefdir/build $*
+ config $abirefdir/src $abirefdir/build -Dexamples= $*
compile $abirefdir/build
install_target $abirefdir/build $abirefdir/$targetdir
$srcdir/devtools/gen-abi.sh $abirefdir/$targetdir
+
+ # save disk space by removing static libs and apps
+ rm $abirefdir/$targetdir/usr/local/lib/*.a
+ rm -rf $abirefdir/$targetdir/usr/local/bin
+ rm -rf $abirefdir/$targetdir/usr/local/share
fi
install_target $builds_dir/$targetdir \
--
2.26.0
^ permalink raw reply [relevance 13%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-20 17:42 0% ` Thomas Monjalon
@ 2020-04-21 1:38 3% ` Wang, Haiyue
2020-04-21 2:12 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2020-04-21 1:38 UTC (permalink / raw)
To: Thomas Monjalon, David Marchand
Cc: Neil Horman, dev, Burakov, Anatoly, Vamsi Attunuru,
Jerin Jacob Kollanukkaran, Yigit, Ferruh, Richardson, Bruce,
Kinsella, Ray
Hi Thomas & David,
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, April 21, 2020 01:43
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: Neil Horman <nhorman@tuxdriver.com>; David Marchand <david.marchand@redhat.com>; dev
> <dev@dpdk.org>; Burakov, Anatoly <anatoly.burakov@intel.com>; Vamsi Attunuru <vattunuru@marvell.com>;
> Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Alex Williamson <alex.williamson@redhat.com>
> Subject: Re: [PATCH v8 0/2] support for VFIO-PCI VF token interface
>
> 20/04/2020 19:37, Wang, Haiyue:
> > From: Thomas Monjalon <thomas@monjalon.net>
> > > 20/04/2020 19:02, Wang, Haiyue:
> > > > From: David Marchand <david.marchand@redhat.com>
> > > > > I had a look at the CI, I can see we are still missing bits to handle
> > > > > the ABI failure on rte_vfio_setup_device.
> > > >
> > > > Yes, not handle it now.
> > > >
> > > > If 'rte_vfio_setup_device' can be internal, not official DPDK API, then __rte_internal
> > > > is the best way to handle ABI issue.
> > >
> > > Please could you help finishing integration of __rte_internal?
> >
> > I thought it should be Neil ? "Yes, I'll get back to this today" ;-)
> > http://inbox.dpdk.org/dev/CAJFAV8ydLkV0afEHqbh6KeA3Box0Yxb3N0MNGtMD4S9bmSgT0A@mail.gmail.com/
>
> It did not happen after several months.
> If you want to unblock your patches, I think it is safer to finish yourself.
>
Unfortunately, this __rte_internal will still make the ci fail to run when move the function
to INTERNAL session:
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -3,6 +3,11 @@
[suppress_variable]
symbol_version = EXPERIMENTAL
+[suppress_function]
+ symbol_version = INTERNAL
+[suppress_variable]
+ symbol_version = INTERNAL
+
--- a/lib/librte_eal/rte_eal_version.map
+++ b/lib/librte_eal/rte_eal_version.map
@@ -213,7 +213,6 @@ DPDK_20.0 {
rte_vfio_is_enabled;
rte_vfio_noiommu_is_enabled;
rte_vfio_release_device;
- rte_vfio_setup_device;
rte_vlog;
rte_zmalloc;
rte_zmalloc_socket;
@@ -339,3 +338,10 @@ EXPERIMENTAL {
# added in 20.05
rte_log_can_log;
};
+
+INTERNAL {
+ global:
+
+ # added in 20.05
+ rte_vfio_setup_device;
+};
Functions changes summary: 1 Removed, 0 Changed, 0 Added function
Variables changes summary: 0 Removed, 0 Changed, 0 Added variable
1 Removed function:
[D] 'function int rte_vfio_setup_device(const char*, const char*, int*, vfio_device_info*)' {rte_vfio_setup_device@@DPDK_20.0}
Error: ABI issue reported for 'abidiff --suppr ./devtools/libabigail.abignore --no-added-syms --headers-dir1 old_abi/include --headers-dir2 new_abi/include old_abi/dump/librte_eal.dump new_abi/dump/librte_eal.dump'
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH] devtools: skip ABI check in static builds
@ 2020-04-21 1:33 13% Thomas Monjalon
2020-04-21 6:11 4% ` Ray Kinsella
2020-04-21 8:02 4% ` David Marchand
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2020-04-21 1:33 UTC (permalink / raw)
To: dev; +Cc: david.marchand, mdr
When running make with CONFIG_RTE_BUILD_SHARED_LIB=n,
no shared library is built.
In this case, no need to run ABI check.
With meson, both shared and static libraries are always built.
Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
---
devtools/test-build.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/devtools/test-build.sh b/devtools/test-build.sh
index a298115002..6e53f86fc8 100755
--- a/devtools/test-build.sh
+++ b/devtools/test-build.sh
@@ -262,6 +262,7 @@ for conf in $configs ; do
EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \
O=$(readlink -f $dir)/examples
unset RTE_TARGET
+ grep -q 'SHARED_LIB=n' $dir/.config || # skip ABI check with static libs
if [ -n "$DPDK_ABI_REF_VERSION" ]; then
abirefdir=${DPDK_ABI_REF_DIR:-reference}/$DPDK_ABI_REF_VERSION
if [ ! -d $abirefdir/$conf ]; then
--
2.26.0
^ permalink raw reply [relevance 13%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-20 17:37 0% ` Wang, Haiyue
@ 2020-04-20 17:42 0% ` Thomas Monjalon
2020-04-21 1:38 3% ` Wang, Haiyue
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-20 17:42 UTC (permalink / raw)
To: Wang, Haiyue
Cc: Neil Horman, David Marchand, dev, Burakov, Anatoly,
Vamsi Attunuru, Jerin Jacob Kollanukkaran, Alex Williamson
20/04/2020 19:37, Wang, Haiyue:
> From: Thomas Monjalon <thomas@monjalon.net>
> > 20/04/2020 19:02, Wang, Haiyue:
> > > From: David Marchand <david.marchand@redhat.com>
> > > > I had a look at the CI, I can see we are still missing bits to handle
> > > > the ABI failure on rte_vfio_setup_device.
> > >
> > > Yes, not handle it now.
> > >
> > > If 'rte_vfio_setup_device' can be internal, not official DPDK API, then __rte_internal
> > > is the best way to handle ABI issue.
> >
> > Please could you help finishing integration of __rte_internal?
>
> I thought it should be Neil ? "Yes, I'll get back to this today" ;-)
> http://inbox.dpdk.org/dev/CAJFAV8ydLkV0afEHqbh6KeA3Box0Yxb3N0MNGtMD4S9bmSgT0A@mail.gmail.com/
It did not happen after several months.
If you want to unblock your patches, I think it is safer to finish yourself.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] rte_vfio_container_dma_map/unmap functions
2020-04-20 14:07 3% ` Burakov, Anatoly
@ 2020-04-20 17:39 3% ` Thomas Monjalon
2020-04-21 9:50 0% ` Burakov, Anatoly
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-20 17:39 UTC (permalink / raw)
To: Burakov, Anatoly; +Cc: dev, Tal Shnaiderman, bruce.richardson, david.marchand
20/04/2020 16:07, Burakov, Anatoly:
> On 19-Apr-20 2:10 PM, Thomas Monjalon wrote:
> > 19/04/2020 15:09, Thomas Monjalon:
> >> 17/04/2020 16:09, Burakov, Anatoly:
> >>> On 17-Apr-20 3:05 PM, Burakov, Anatoly wrote:
> >>>> On 22-Mar-20 5:20 PM, Tal Shnaiderman wrote:
> >>>>> Hi Anatoly,
> >>>>>
> >>>>> I’m working on the implementation of bus/pci driver for Windows,
> >>>>> pci_common.c uses the titled functions however they are relevant only
> >>>>> for Linux OS.
> >>>>>
> >>>>> I’m wondering if the implementation of those functions should be moved
> >>>>> to a Linux specific area since FreeBSD (and now Windows) are forced to
> >>>>> implemented those in the current state.
> >>>
> >>> Unfortunately, we don't have a generic API for these, but since we
> >>> export a single API on all platforms, either all platforms have to
> >>> implement these functions, or none of them do. There's simply no way to
> >>> avoid implementing stubs for these functions, short of coming up with a
> >>> generic API that would replace these. Given that this API is heavily
> >>> Linux specific, i don't see that happening.
> >>
> >> Because it is Linux specific, we should not force FreeBSD and Windows
> >> having stubs. Can we move VFIO calls in Linux-specific files?
> >>
> >> I think rte_vfio.h should be moved in lib/librte_eal/linux/include.
> >
> > +Cc Bruce and David
>
> ...and have a Linux-specific ABI?
Yes, the ABI is different depending on arch and OS.
That's a fact, and I don't see any problem with it.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-20 17:31 4% ` Ray Kinsella
@ 2020-04-20 17:37 3% ` Thomas Monjalon
2020-04-21 6:01 3% ` Ray Kinsella
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-20 17:37 UTC (permalink / raw)
To: Trahe, Fiona, Richardson, Bruce, Ray Kinsella
Cc: dev, Kusztal, ArkadiuszX, Neil Horman, Luca Boccassi,
Kevin Traynor, Yigit, Ferruh, Akhil Goyal
20/04/2020 19:31, Ray Kinsella:
>
> Our only commitment is to the stability of the v19.11/v20 ABI, until v21.
>
> That said, once an ABI migrates from EXPERIMENTAL to v21, it _shouldn't_ be changing.
> We don't have a strict commitment to the v21 ABI until v20.11.
>
> However if v21 is changing across quarterlies (outside of additions) ... something else is wrong.
The only way to check a symbol is not changing in a quarterly release
is to test it. That's what we wanted to enforce:
compare 20.02 ABI in 20.05 release.
What other process do you suggest?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-20 17:13 0% ` Thomas Monjalon
@ 2020-04-20 17:37 0% ` Wang, Haiyue
2020-04-20 17:42 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2020-04-20 17:37 UTC (permalink / raw)
To: Thomas Monjalon, Neil Horman
Cc: David Marchand, dev, Burakov, Anatoly, Vamsi Attunuru,
Jerin Jacob Kollanukkaran, Alex Williamson
+Neil,
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, April 21, 2020 01:13
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: David Marchand <david.marchand@redhat.com>; dev <dev@dpdk.org>; Burakov, Anatoly
> <anatoly.burakov@intel.com>; Vamsi Attunuru <vattunuru@marvell.com>; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; Alex Williamson <alex.williamson@redhat.com>
> Subject: Re: [PATCH v8 0/2] support for VFIO-PCI VF token interface
>
> 20/04/2020 19:02, Wang, Haiyue:
> > From: David Marchand <david.marchand@redhat.com>
> > >
> > > Hello,
> > >
> > > On Sat, Apr 18, 2020 at 7:36 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> > > >
> > > > v8: Update the document.
> > >
> > > Thanks for the last version.
> > > I had a look at the CI, I can see we are still missing bits to handle
> > > the ABI failure on rte_vfio_setup_device.
> >
> > Yes, not handle it now.
> >
> > If 'rte_vfio_setup_device' can be internal, not official DPDK API, then __rte_internal
> > is the best way to handle ABI issue.
>
> Please could you help finishing integration of __rte_internal?
>
I thought it should be Neil ? "Yes, I'll get back to this today" ;-)
http://inbox.dpdk.org/dev/CAJFAV8ydLkV0afEHqbh6KeA3Box0Yxb3N0MNGtMD4S9bmSgT0A@mail.gmail.com/
> This patch is blocked for now.
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-20 16:59 3% ` Trahe, Fiona
@ 2020-04-20 17:31 4% ` Ray Kinsella
2020-04-20 17:37 3% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-20 17:31 UTC (permalink / raw)
To: Trahe, Fiona, Thomas Monjalon, Richardson, Bruce
Cc: dev, Kusztal, ArkadiuszX, Neil Horman, Luca Boccassi,
Kevin Traynor, Yigit, Ferruh, Akhil Goyal
Our only commitment is to the stability of the v19.11/v20 ABI, until v21.
That said, once an ABI migrates from EXPERIMENTAL to v21, it _shouldn't_ be changing.
We don't have a strict commitment to the v21 ABI until v20.11.
However if v21 is changing across quarterlies (outside of additions) ... something else is wrong.
Ray K
On 20/04/2020 17:59, Trahe, Fiona wrote:
> Gentle reminder that we still haven't come to a consensus about
> whether ABI compatibility is required across quarterly releases or not.
> See below.
>
>> -----Original Message-----
>> From: Trahe, Fiona <fiona.trahe@intel.com>
>> Sent: Friday, April 17, 2020 12:47 PM
>> To: Ray Kinsella <mdr@ashroe.eu>; Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce
>> <bruce.richardson@intel.com>
>> Cc: dev@dpdk.org; Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; Neil Horman
>> <nhorman@tuxdriver.com>; Luca Boccassi <bluca@debian.org>; Kevin Traynor
>> <ktraynor@redhat.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Trahe, Fiona
>> <fiona.trahe@intel.com>
>> Subject: RE: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
>>
>> Hi all,
>>
>>> -----Original Message-----
>>> From: Ray Kinsella <mdr@ashroe.eu>
>>> Sent: Friday, April 17, 2020 11:34 AM
>>> To: Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce <bruce.richardson@intel.com>
>>> Cc: Trahe, Fiona <fiona.trahe@intel.com>; dev@dpdk.org; Kusztal, ArkadiuszX
>>> <arkadiuszx.kusztal@intel.com>; Neil Horman <nhorman@tuxdriver.com>; Luca Boccassi
>>> <bluca@debian.org>; Kevin Traynor <ktraynor@redhat.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
>>> Subject: Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
>>>
>>>
>>>
>>> On 17/04/2020 11:17, Thomas Monjalon wrote:
>>>> 17/04/2020 11:42, Ray Kinsella:
>>>>> On 17/04/2020 10:31, Bruce Richardson wrote:
>>>>>> On Fri, Apr 17, 2020 at 08:24:30AM +0100, Ray Kinsella wrote:
>>>>>>> On 16/04/2020 11:01, Thomas Monjalon wrote:
>>>>>>>> 16/04/2020 11:51, Bruce Richardson:
>>>>>>>>> On Wed, Apr 15, 2020 at 06:24:19PM +0100, Trahe, Fiona wrote:
>>>>>>>>>> 5a. If in 20.05 we add a version of a fn which breaks ABI 20.0, what should the name of the
>>> original function be? fn_v20, or fn_v20.0
>>>>>>>>>
>>>>>>>>> In technical terms it really doesn't matter, it's just a name that will be
>>>>>>>>> looked up in a table. I don't think we strictly enforce the naming, so
>>>>>>>>> whatever is clearest is best. I'd suggest the former.
>>>>>>>>
>>>>>>>> Each release can have a new ABI.
>>>>>>>
>>>>>>> How many ABI's do we want to support?
>>>>>>>
>>>>>> It's not how many we want to support, but for me it's a matter of how many
>>>>>> do we need to support. If an API is part of the stable set, it can't just
>>>>>> drop to being experimental for one or two releases - it's always stable
>>>>>> until deprecated. We also shouldn't have a situation where release 20.08 is
>>>>>> ABI compatible with 19.11 but not 20.02 and 20.05.
>>>>>
>>>>> True. Let me say it differently.
>>>>>
>>>>> Our only commitment is to support v20 - 19.11
>>>>> However you are correct, if something gets committed as v21 in 20.02, in practise should also be
>>> there in 20.05+ also.
>>>>> Because if it is committed as v21 and not as experimental, it should not be changing once
>>> committed.
>>>>>
>>>>> In answering Thomas,
>>>>> I was more commenting on the proliferation of ABI numbers & symbols we need to track in the
>>> build.
>>>>> With v20, v21 & Experimental we need to keep track of 3.
>>>>> If we start allowing quarterly builds to have managed ABI's, it will get confusing.
>>>>
>>>> I don't remember why we are using intermediate ABI versions
>>>> between v20 and v21.
>>>> If we can use v21 for new ABI and make sure compatibility is maintained
>>>> between all versions from 19.11 to 20.08, I'm fine.
>> [Fiona] Here's a hypothetical case, but it illustrates why I don't think there
>> should be an expectation to maintain ABI compatibility here.
>> Example: in 20.05 add a new info_get_v21() which includes ChaChaPoly.
>> In 20.08 add another new algorithm. info_get_v21() return now includes this.
>> info_get_v21() will become stable in 20.11 and compatibility must be maintained from then on.
>> In the meantime, the fn is not experimental - that wouldn't be appropriate as it was a stable API.
>> But an app either wants stability and so should build against 19.11, or if prepared to move up to
>> one non-stable-ABI quarterly release should be willing to rebuild for the next non-stable-ABI quarterly
>> release.
>> I think it's an unnecessary burden to require ABI compatibility across quarterly releases.
>> And if required could end up with the version tracking hassle Ray referred to above with fn versions
>> of 20.0.1, 20.0.2, 20.0.3, v21, and potentially several versions of same fn.
>>
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3] cryptodev: version cryptodev info get function
2020-04-20 16:54 3% ` Trahe, Fiona
2020-04-20 17:24 0% ` Ray Kinsella
@ 2020-04-20 17:26 0% ` Ray Kinsella
2020-04-22 8:36 0% ` Ray Kinsella
1 sibling, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-20 17:26 UTC (permalink / raw)
To: Trahe, Fiona, Akhil Goyal, Kusztal, ArkadiuszX, dev; +Cc: Thomas Monjalon
On 20/04/2020 17:54, Trahe, Fiona wrote:
> Hi Ray, Akhil,
>
>
>> On 20/04/2020 15:22, Akhil Goyal wrote:
>>>
>>>
>>>>
>>>> This patch adds versioned function rte_cryptodev_info_get()
>>>> to prevent some issues with ABI policy.
>>>> Node v21 works in same way as before, returning driver capabilities
>>>> directly to the API caller. These capabilities may include new elements
>>>> not part of the v20 ABI.
>>>> Node v20 function maintains compatibility with v20 ABI releases
>>>> by stripping out elements not supported in v20 ABI. Because
>>>> rte_cryptodev_info_get is called by other API functions,
>>>> rte_cryptodev_sym_capability_get function is versioned the same way.
>>>>
>>>> Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
>>>> ---
>>>> v2:
>>>> - changed version numbers of symbols to 20.0.2
>>>> v3:
>>>> - added v2/v3 informations
>>>> - changed version numbers of symbols to 21
>>>> - fixed checkpatch issues
>>>>
>>>> This patch depends on following patches:
>>>>
>>>> [1] - "[v3] cryptodev: add chacha20-poly1305 aead algorithm"
>>>> (https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatchwor
>>>> k.dpdk.org%2Fpatch%2F64549%2F&data=02%7C01%7Cakhil.goyal%40nxp.
>>>> com%7Ce6789fd42a5946c128e508d7e2dffe2f%7C686ea1d3bc2b4c6fa92cd99c
>>>> 5c301635%7C0%7C0%7C637227323980059545&sdata=50eQJE7WHTME6d
>>>> qA7Nfk%2B50PVAyJrpKlMw%2BoGtA1%2FTc%3D&reserved=0)
>>>
>>> Please include the dependent patches in a single series in your next version.
>>>>
>>>> lib/librte_cryptodev/rte_cryptodev.c | 143 ++++++++++++++++++++++++-
>>>> lib/librte_cryptodev/rte_cryptodev.h | 39 ++++++-
>>>> lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++
>>>> 3 files changed, 186 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
>>>> b/lib/librte_cryptodev/rte_cryptodev.c
>>>> index 6d1d0e9..b061447 100644
>>>> --- a/lib/librte_cryptodev/rte_cryptodev.c
>>>> +++ b/lib/librte_cryptodev/rte_cryptodev.c
>>>> @@ -41,6 +41,9 @@
>>>> #include "rte_cryptodev.h"
>>>> #include "rte_cryptodev_pmd.h"
>>>>
>>>> +#include <rte_compat.h>
>>>> +#include <rte_function_versioning.h>
>>>> +
>>>> static uint8_t nb_drivers;
>>>>
>>>> static struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS];
>>>> @@ -56,6 +59,14 @@ static struct rte_cryptodev_global cryptodev_globals = {
>>>> /* spinlock for crypto device callbacks */
>>>> static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
>>>>
>>>> +static const struct rte_cryptodev_capabilities
>>>> + cryptodev_undefined_capabilities[] = {
>>>> + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
>>>> +};
>>>> +
>>>> +static struct rte_cryptodev_capabilities
>>>> + *capability_copies[RTE_CRYPTO_MAX_DEVS];
>>>
>>> Capabilities_copy is a better name as it is copy of many capabilities.
> [Fiona] ok
>
>
>>>> const struct rte_cryptodev_symmetric_capability *
>>>> -rte_cryptodev_sym_capability_get(uint8_t dev_id,
>>>> +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
>>>
>>> __vsym Annotation to be used in a declaration of the internal symbol
>>> to signal that it is being used as an implementation of a particular
>>> version of symbol.
> [Fiona] ok
>
>
>>>> + }
>>>> +
>>>> + return NULL;
>>>> +
>>>
>>> Extra line
> [Fiona] ok
>
>>>
>>>> +}
>>>> +VERSION_SYMBOL(rte_cryptodev_sym_capability_get, _v20, 20.0);
>>>> +
>>>> +const struct rte_cryptodev_symmetric_capability *
>>>
>>> __vsym annotation
> [Fiona] ok
>
>
>>>
>>>> +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
>>>> const struct rte_cryptodev_sym_capability_idx *idx)
>>>> {
>>>> const struct rte_cryptodev_capabilities *capability;
>>>> @@ -313,6 +360,10 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
>>>> return NULL;
>>>>
>>>> }
>>>> +MAP_STATIC_SYMBOL(const struct rte_cryptodev_symmetric_capability *
>>>> + rte_cryptodev_sym_capability_get(uint8_t dev_id,
>>>> + const struct rte_cryptodev_sym_capability_idx *idx),
>>>> + rte_cryptodev_sym_capability_get_v21);
>>>>
>>>> static int
>>>> param_range_check(uint16_t size, const struct rte_crypto_param_range *range)
>>>> @@ -999,6 +1050,13 @@ rte_cryptodev_close(uint8_t dev_id)
>>>> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
>>>> retval = (*dev->dev_ops->dev_close)(dev);
>>>>
>>>> +
>>>> + if (capability_copies[dev_id]) {
>>>> + free(capability_copies[dev_id]);
>>>> + capability_copies[dev_id] = NULL;
>>>> + }
>>>> + is_capability_checked[dev_id] = 0;
>>>> +
>>>> if (retval < 0)
>>>> return retval;
>>>>
>>>> @@ -1111,9 +1169,61 @@ rte_cryptodev_stats_reset(uint8_t dev_id)
>>>> (*dev->dev_ops->stats_reset)(dev);
>>>> }
>>>>
>>>> +static void
>>>> +get_v20_capabilities(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
>>>> +{
>>>> + const struct rte_cryptodev_capabilities *capability;
>>>> + uint8_t found_invalid_capa = 0;
>>>> + uint8_t counter = 0;
>>>> +
>>>> + for (capability = dev_info->capabilities;
>>>> + capability->op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
>>>> + ++capability, ++counter) {
>>>> + if (capability->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
>>>> + capability->sym.xform_type ==
>>>> + RTE_CRYPTO_SYM_XFORM_AEAD
>>>> + && capability->sym.aead.algo >=
>>>> + RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
>>>> + found_invalid_capa = 1;
>>>> + counter--;
>>>> + }
>>>> + }
>>>> + is_capability_checked[dev_id] = 1;
>>>> + if (found_invalid_capa) {
>>>
>>> Code becomes unreadable due to indentation which can be avoided.
> [Fiona] ok
>
>
>
>>>> +void
>>>> +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info
>>>> *dev_info);
>>>> +BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v21, 21);
>>>
>>> I am not sure if we need to bind for _v20 also
>>> BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v20, 20);
>>
>> The correct call to VERSION_SYMBOL is already above.
> [Fiona] ok, so won't do this.
>
>
>>> Ray, can you please suggest if it required or not? And what all we need to check?
>>
>> See below.
>>
>>>
>>> The patch is still showing Incompatibilities
>>> NOTICE: ABI may be incompatible, check reports/logs for details.
>>> NOTICE: Incompatible list: librte_cryptodev.so
>>
>> So I looked through the issues it is complaining about, these are here.
>> https://travis-ci.com/github/ovsrobot/dpdk/jobs/320526253#L4540
>>
>> Basically they all are warnings related to the changes to the enumeration
>> rte_crypto_aead_algorithm.
>>
>> Essentially the new member RTE_CRYPTO_AEAD_CHACHA20_POLY1305.
>> The change to the end value RTE_CRYPTO_AEAD_LIST_END.
>> Members of this type "enum rte_crypto_aead_algorithm algo" are demeeded to also have changed,
>> but they haven't.
>>
>> With the additional work to create the v20 version of rte_cryptodev_info_get.
>> I think all reasonable steps have been been taken here.
> [Fiona] Do we need to change the tool or somehow mark as a false positive?
Yes, I will take a look at it.
>
>
>>>> /**
>>>> * Register a callback function for specific device id.
>>>> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map
>>>> b/lib/librte_cryptodev/rte_cryptodev_version.map
>>>> index 6e41b4b..512a4a7 100644
>>>> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
>>>> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
>>>> @@ -58,6 +58,13 @@ DPDK_20.0 {
>>>> local: *;
>>>> };
>>>>
>>>> +DPDK_21 {
>>
>> Should be DPDK_21.0
> [Fiona] Can you explain why?
> I thought it could go back to a 2-number system with _v21 ABI.
> I thought we'd clarified that DPDK_20.0 is only there due to a mistake, that should have been DPDK_20.
>
>
>>>> + global:
>>>> + rte_cryptodev_info_get;
>>>> + rte_cryptodev_sym_capability_get;
>>>> +} DPDK_20.0;
>>>> +
>>>> +
>>>> EXPERIMENTAL {
>>>> global:
>>>>
>>>> --
>>>> 2.1.0
>>>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] cryptodev: version cryptodev info get function
2020-04-20 16:54 3% ` Trahe, Fiona
@ 2020-04-20 17:24 0% ` Ray Kinsella
2020-04-20 17:26 0% ` Ray Kinsella
1 sibling, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-20 17:24 UTC (permalink / raw)
To: Trahe, Fiona, Akhil Goyal, Kusztal, ArkadiuszX, dev
Cc: Thomas Monjalon, Richardson, Bruce
On 20/04/2020 17:54, Trahe, Fiona wrote:
> Hi Ray, Akhil,
>
>
>> On 20/04/2020 15:22, Akhil Goyal wrote:
>>>
>>>
>>>>
>>>> This patch adds versioned function rte_cryptodev_info_get()
>>>> to prevent some issues with ABI policy.
>>>> Node v21 works in same way as before, returning driver capabilities
>>>> directly to the API caller. These capabilities may include new elements
>>>> not part of the v20 ABI.
>>>> Node v20 function maintains compatibility with v20 ABI releases
>>>> by stripping out elements not supported in v20 ABI. Because
>>>> rte_cryptodev_info_get is called by other API functions,
>>>> rte_cryptodev_sym_capability_get function is versioned the same way.
>>>>
>>>> Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
>>>> ---
>>>> v2:
>>>> - changed version numbers of symbols to 20.0.2
>>>> v3:
>>>> - added v2/v3 informations
>>>> - changed version numbers of symbols to 21
>>>> - fixed checkpatch issues
>>>>
>>>> This patch depends on following patches:
>>>>
>>>> [1] - "[v3] cryptodev: add chacha20-poly1305 aead algorithm"
>>>> (https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatchwor
>>>> k.dpdk.org%2Fpatch%2F64549%2F&data=02%7C01%7Cakhil.goyal%40nxp.
>>>> com%7Ce6789fd42a5946c128e508d7e2dffe2f%7C686ea1d3bc2b4c6fa92cd99c
>>>> 5c301635%7C0%7C0%7C637227323980059545&sdata=50eQJE7WHTME6d
>>>> qA7Nfk%2B50PVAyJrpKlMw%2BoGtA1%2FTc%3D&reserved=0)
>>>
>>> Please include the dependent patches in a single series in your next version.
>>>>
>>>> lib/librte_cryptodev/rte_cryptodev.c | 143 ++++++++++++++++++++++++-
>>>> lib/librte_cryptodev/rte_cryptodev.h | 39 ++++++-
>>>> lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++
>>>> 3 files changed, 186 insertions(+), 3 deletions(-)
>>>>
>>>> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
>>>> b/lib/librte_cryptodev/rte_cryptodev.c
>>>> index 6d1d0e9..b061447 100644
>>>> --- a/lib/librte_cryptodev/rte_cryptodev.c
>>>> +++ b/lib/librte_cryptodev/rte_cryptodev.c
>>>> @@ -41,6 +41,9 @@
>>>> #include "rte_cryptodev.h"
>>>> #include "rte_cryptodev_pmd.h"
>>>>
>>>> +#include <rte_compat.h>
>>>> +#include <rte_function_versioning.h>
>>>> +
>>>> static uint8_t nb_drivers;
>>>>
>>>> static struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS];
>>>> @@ -56,6 +59,14 @@ static struct rte_cryptodev_global cryptodev_globals = {
>>>> /* spinlock for crypto device callbacks */
>>>> static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
>>>>
>>>> +static const struct rte_cryptodev_capabilities
>>>> + cryptodev_undefined_capabilities[] = {
>>>> + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
>>>> +};
>>>> +
>>>> +static struct rte_cryptodev_capabilities
>>>> + *capability_copies[RTE_CRYPTO_MAX_DEVS];
>>>
>>> Capabilities_copy is a better name as it is copy of many capabilities.
> [Fiona] ok
>
>
>>>> const struct rte_cryptodev_symmetric_capability *
>>>> -rte_cryptodev_sym_capability_get(uint8_t dev_id,
>>>> +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
>>>
>>> __vsym Annotation to be used in a declaration of the internal symbol
>>> to signal that it is being used as an implementation of a particular
>>> version of symbol.
> [Fiona] ok
>
>
>>>> + }
>>>> +
>>>> + return NULL;
>>>> +
>>>
>>> Extra line
> [Fiona] ok
>
>>>
>>>> +}
>>>> +VERSION_SYMBOL(rte_cryptodev_sym_capability_get, _v20, 20.0);
>>>> +
>>>> +const struct rte_cryptodev_symmetric_capability *
>>>
>>> __vsym annotation
> [Fiona] ok
>
>
>>>
>>>> +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
>>>> const struct rte_cryptodev_sym_capability_idx *idx)
>>>> {
>>>> const struct rte_cryptodev_capabilities *capability;
>>>> @@ -313,6 +360,10 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
>>>> return NULL;
>>>>
>>>> }
>>>> +MAP_STATIC_SYMBOL(const struct rte_cryptodev_symmetric_capability *
>>>> + rte_cryptodev_sym_capability_get(uint8_t dev_id,
>>>> + const struct rte_cryptodev_sym_capability_idx *idx),
>>>> + rte_cryptodev_sym_capability_get_v21);
>>>>
>>>> static int
>>>> param_range_check(uint16_t size, const struct rte_crypto_param_range *range)
>>>> @@ -999,6 +1050,13 @@ rte_cryptodev_close(uint8_t dev_id)
>>>> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
>>>> retval = (*dev->dev_ops->dev_close)(dev);
>>>>
>>>> +
>>>> + if (capability_copies[dev_id]) {
>>>> + free(capability_copies[dev_id]);
>>>> + capability_copies[dev_id] = NULL;
>>>> + }
>>>> + is_capability_checked[dev_id] = 0;
>>>> +
>>>> if (retval < 0)
>>>> return retval;
>>>>
>>>> @@ -1111,9 +1169,61 @@ rte_cryptodev_stats_reset(uint8_t dev_id)
>>>> (*dev->dev_ops->stats_reset)(dev);
>>>> }
>>>>
>>>> +static void
>>>> +get_v20_capabilities(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
>>>> +{
>>>> + const struct rte_cryptodev_capabilities *capability;
>>>> + uint8_t found_invalid_capa = 0;
>>>> + uint8_t counter = 0;
>>>> +
>>>> + for (capability = dev_info->capabilities;
>>>> + capability->op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
>>>> + ++capability, ++counter) {
>>>> + if (capability->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
>>>> + capability->sym.xform_type ==
>>>> + RTE_CRYPTO_SYM_XFORM_AEAD
>>>> + && capability->sym.aead.algo >=
>>>> + RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
>>>> + found_invalid_capa = 1;
>>>> + counter--;
>>>> + }
>>>> + }
>>>> + is_capability_checked[dev_id] = 1;
>>>> + if (found_invalid_capa) {
>>>
>>> Code becomes unreadable due to indentation which can be avoided.
> [Fiona] ok
>
>
>
>>>> +void
>>>> +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info
>>>> *dev_info);
>>>> +BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v21, 21);
>>>
>>> I am not sure if we need to bind for _v20 also
>>> BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v20, 20);
>>
>> The correct call to VERSION_SYMBOL is already above.
> [Fiona] ok, so won't do this.
>
>
>>> Ray, can you please suggest if it required or not? And what all we need to check?
>>
>> See below.
>>
>>>
>>> The patch is still showing Incompatibilities
>>> NOTICE: ABI may be incompatible, check reports/logs for details.
>>> NOTICE: Incompatible list: librte_cryptodev.so
>>
>> So I looked through the issues it is complaining about, these are here.
>> https://travis-ci.com/github/ovsrobot/dpdk/jobs/320526253#L4540
>>
>> Basically they all are warnings related to the changes to the enumeration
>> rte_crypto_aead_algorithm.
>>
>> Essentially the new member RTE_CRYPTO_AEAD_CHACHA20_POLY1305.
>> The change to the end value RTE_CRYPTO_AEAD_LIST_END.
>> Members of this type "enum rte_crypto_aead_algorithm algo" are demeeded to also have changed,
>> but they haven't.
>>
>> With the additional work to create the v20 version of rte_cryptodev_info_get.
>> I think all reasonable steps have been been taken here.
> [Fiona] Do we need to change the tool or somehow mark as a false positive?
>
>
>>>> /**
>>>> * Register a callback function for specific device id.
>>>> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map
>>>> b/lib/librte_cryptodev/rte_cryptodev_version.map
>>>> index 6e41b4b..512a4a7 100644
>>>> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
>>>> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
>>>> @@ -58,6 +58,13 @@ DPDK_20.0 {
>>>> local: *;
>>>> };
>>>>
>>>> +DPDK_21 {
>>
>> Should be DPDK_21.0
> [Fiona] Can you explain why?
> I thought it could go back to a 2-number system with _v21 ABI> I thought we'd clarified that DPDK_20.0 is only there due to a mistake, that should have been DPDK_20.
True.
So I thought we should keep the DPDK_NN.0 numbering scheme at least consistent with v19.11
To reduce any further confusion caused by this issue.
I did so, in a similar in a seperate patch to remove maps file references to DPDK_20.0.1.
We will need to a wholesale update of the map files in any case at 20.11, to v21.
However you are 100% correct on this.
Go direct to DPDK_21?
>
>
>>>> + global:
>>>> + rte_cryptodev_info_get;
>>>> + rte_cryptodev_sym_capability_get;
>>>> +} DPDK_20.0;
>>>> +
>>>> +
>>>> EXPERIMENTAL {
>>>> global:
>>>>
>>>> --
>>>> 2.1.0
>>>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-20 17:02 3% ` Wang, Haiyue
@ 2020-04-20 17:13 0% ` Thomas Monjalon
2020-04-20 17:37 0% ` Wang, Haiyue
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-20 17:13 UTC (permalink / raw)
To: Wang, Haiyue
Cc: David Marchand, dev, Burakov, Anatoly, Vamsi Attunuru,
Jerin Jacob Kollanukkaran, Alex Williamson
20/04/2020 19:02, Wang, Haiyue:
> From: David Marchand <david.marchand@redhat.com>
> >
> > Hello,
> >
> > On Sat, Apr 18, 2020 at 7:36 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> > >
> > > v8: Update the document.
> >
> > Thanks for the last version.
> > I had a look at the CI, I can see we are still missing bits to handle
> > the ABI failure on rte_vfio_setup_device.
>
> Yes, not handle it now.
>
> If 'rte_vfio_setup_device' can be internal, not official DPDK API, then __rte_internal
> is the best way to handle ABI issue.
Please could you help finishing integration of __rte_internal?
This patch is blocked for now.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-20 16:53 3% ` David Marchand
@ 2020-04-20 17:02 3% ` Wang, Haiyue
2020-04-20 17:13 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Wang, Haiyue @ 2020-04-20 17:02 UTC (permalink / raw)
To: David Marchand
Cc: dev, Burakov, Anatoly, Thomas Monjalon, Vamsi Attunuru,
Jerin Jacob Kollanukkaran, Alex Williamson
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Tuesday, April 21, 2020 00:53
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev <dev@dpdk.org>; Burakov, Anatoly <anatoly.burakov@intel.com>; Thomas Monjalon
> <thomas@monjalon.net>; Vamsi Attunuru <vattunuru@marvell.com>; Jerin Jacob Kollanukkaran
> <jerinj@marvell.com>; Alex Williamson <alex.williamson@redhat.com>
> Subject: Re: [PATCH v8 0/2] support for VFIO-PCI VF token interface
>
> Hello,
>
> On Sat, Apr 18, 2020 at 7:36 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
> >
> > v8: Update the document.
>
> Thanks for the last version.
> I had a look at the CI, I can see we are still missing bits to handle
> the ABI failure on rte_vfio_setup_device.
Yes, not handle it now.
If 'rte_vfio_setup_device' can be internal, not official DPDK API, then __rte_internal
is the best way to handle ABI issue.
>
>
> --
> David Marchand
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-17 11:46 5% ` Trahe, Fiona
2020-04-17 16:01 0% ` Ray Kinsella
@ 2020-04-20 16:59 3% ` Trahe, Fiona
2020-04-20 17:31 4% ` Ray Kinsella
1 sibling, 1 reply; 200+ results
From: Trahe, Fiona @ 2020-04-20 16:59 UTC (permalink / raw)
To: Ray Kinsella, Thomas Monjalon, Richardson, Bruce
Cc: dev, Kusztal, ArkadiuszX, Neil Horman, Luca Boccassi,
Kevin Traynor, Yigit, Ferruh, Trahe, Fiona, Akhil Goyal
Gentle reminder that we still haven't come to a consensus about
whether ABI compatibility is required across quarterly releases or not.
See below.
> -----Original Message-----
> From: Trahe, Fiona <fiona.trahe@intel.com>
> Sent: Friday, April 17, 2020 12:47 PM
> To: Ray Kinsella <mdr@ashroe.eu>; Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce
> <bruce.richardson@intel.com>
> Cc: dev@dpdk.org; Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; Neil Horman
> <nhorman@tuxdriver.com>; Luca Boccassi <bluca@debian.org>; Kevin Traynor
> <ktraynor@redhat.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Trahe, Fiona
> <fiona.trahe@intel.com>
> Subject: RE: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
>
> Hi all,
>
> > -----Original Message-----
> > From: Ray Kinsella <mdr@ashroe.eu>
> > Sent: Friday, April 17, 2020 11:34 AM
> > To: Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce <bruce.richardson@intel.com>
> > Cc: Trahe, Fiona <fiona.trahe@intel.com>; dev@dpdk.org; Kusztal, ArkadiuszX
> > <arkadiuszx.kusztal@intel.com>; Neil Horman <nhorman@tuxdriver.com>; Luca Boccassi
> > <bluca@debian.org>; Kevin Traynor <ktraynor@redhat.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
> >
> >
> >
> > On 17/04/2020 11:17, Thomas Monjalon wrote:
> > > 17/04/2020 11:42, Ray Kinsella:
> > >> On 17/04/2020 10:31, Bruce Richardson wrote:
> > >>> On Fri, Apr 17, 2020 at 08:24:30AM +0100, Ray Kinsella wrote:
> > >>>> On 16/04/2020 11:01, Thomas Monjalon wrote:
> > >>>>> 16/04/2020 11:51, Bruce Richardson:
> > >>>>>> On Wed, Apr 15, 2020 at 06:24:19PM +0100, Trahe, Fiona wrote:
> > >>>>>>> 5a. If in 20.05 we add a version of a fn which breaks ABI 20.0, what should the name of the
> > original function be? fn_v20, or fn_v20.0
> > >>>>>>
> > >>>>>> In technical terms it really doesn't matter, it's just a name that will be
> > >>>>>> looked up in a table. I don't think we strictly enforce the naming, so
> > >>>>>> whatever is clearest is best. I'd suggest the former.
> > >>>>>
> > >>>>> Each release can have a new ABI.
> > >>>>
> > >>>> How many ABI's do we want to support?
> > >>>>
> > >>> It's not how many we want to support, but for me it's a matter of how many
> > >>> do we need to support. If an API is part of the stable set, it can't just
> > >>> drop to being experimental for one or two releases - it's always stable
> > >>> until deprecated. We also shouldn't have a situation where release 20.08 is
> > >>> ABI compatible with 19.11 but not 20.02 and 20.05.
> > >>
> > >> True. Let me say it differently.
> > >>
> > >> Our only commitment is to support v20 - 19.11
> > >> However you are correct, if something gets committed as v21 in 20.02, in practise should also be
> > there in 20.05+ also.
> > >> Because if it is committed as v21 and not as experimental, it should not be changing once
> > committed.
> > >>
> > >> In answering Thomas,
> > >> I was more commenting on the proliferation of ABI numbers & symbols we need to track in the
> > build.
> > >> With v20, v21 & Experimental we need to keep track of 3.
> > >> If we start allowing quarterly builds to have managed ABI's, it will get confusing.
> > >
> > > I don't remember why we are using intermediate ABI versions
> > > between v20 and v21.
> > > If we can use v21 for new ABI and make sure compatibility is maintained
> > > between all versions from 19.11 to 20.08, I'm fine.
> [Fiona] Here's a hypothetical case, but it illustrates why I don't think there
> should be an expectation to maintain ABI compatibility here.
> Example: in 20.05 add a new info_get_v21() which includes ChaChaPoly.
> In 20.08 add another new algorithm. info_get_v21() return now includes this.
> info_get_v21() will become stable in 20.11 and compatibility must be maintained from then on.
> In the meantime, the fn is not experimental - that wouldn't be appropriate as it was a stable API.
> But an app either wants stability and so should build against 19.11, or if prepared to move up to
> one non-stable-ABI quarterly release should be willing to rebuild for the next non-stable-ABI quarterly
> release.
> I think it's an unnecessary burden to require ABI compatibility across quarterly releases.
> And if required could end up with the version tracking hassle Ray referred to above with fn versions
> of 20.0.1, 20.0.2, 20.0.3, v21, and potentially several versions of same fn.
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3] cryptodev: version cryptodev info get function
2020-04-20 15:21 0% ` Ray Kinsella
@ 2020-04-20 16:54 3% ` Trahe, Fiona
2020-04-20 17:24 0% ` Ray Kinsella
2020-04-20 17:26 0% ` Ray Kinsella
0 siblings, 2 replies; 200+ results
From: Trahe, Fiona @ 2020-04-20 16:54 UTC (permalink / raw)
To: Ray Kinsella, Akhil Goyal, Kusztal, ArkadiuszX, dev
Cc: Thomas Monjalon, Trahe, Fiona
Hi Ray, Akhil,
> On 20/04/2020 15:22, Akhil Goyal wrote:
> >
> >
> >>
> >> This patch adds versioned function rte_cryptodev_info_get()
> >> to prevent some issues with ABI policy.
> >> Node v21 works in same way as before, returning driver capabilities
> >> directly to the API caller. These capabilities may include new elements
> >> not part of the v20 ABI.
> >> Node v20 function maintains compatibility with v20 ABI releases
> >> by stripping out elements not supported in v20 ABI. Because
> >> rte_cryptodev_info_get is called by other API functions,
> >> rte_cryptodev_sym_capability_get function is versioned the same way.
> >>
> >> Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> >> ---
> >> v2:
> >> - changed version numbers of symbols to 20.0.2
> >> v3:
> >> - added v2/v3 informations
> >> - changed version numbers of symbols to 21
> >> - fixed checkpatch issues
> >>
> >> This patch depends on following patches:
> >>
> >> [1] - "[v3] cryptodev: add chacha20-poly1305 aead algorithm"
> >> (https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatchwor
> >> k.dpdk.org%2Fpatch%2F64549%2F&data=02%7C01%7Cakhil.goyal%40nxp.
> >> com%7Ce6789fd42a5946c128e508d7e2dffe2f%7C686ea1d3bc2b4c6fa92cd99c
> >> 5c301635%7C0%7C0%7C637227323980059545&sdata=50eQJE7WHTME6d
> >> qA7Nfk%2B50PVAyJrpKlMw%2BoGtA1%2FTc%3D&reserved=0)
> >
> > Please include the dependent patches in a single series in your next version.
> >>
> >> lib/librte_cryptodev/rte_cryptodev.c | 143 ++++++++++++++++++++++++-
> >> lib/librte_cryptodev/rte_cryptodev.h | 39 ++++++-
> >> lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++
> >> 3 files changed, 186 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> >> b/lib/librte_cryptodev/rte_cryptodev.c
> >> index 6d1d0e9..b061447 100644
> >> --- a/lib/librte_cryptodev/rte_cryptodev.c
> >> +++ b/lib/librte_cryptodev/rte_cryptodev.c
> >> @@ -41,6 +41,9 @@
> >> #include "rte_cryptodev.h"
> >> #include "rte_cryptodev_pmd.h"
> >>
> >> +#include <rte_compat.h>
> >> +#include <rte_function_versioning.h>
> >> +
> >> static uint8_t nb_drivers;
> >>
> >> static struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS];
> >> @@ -56,6 +59,14 @@ static struct rte_cryptodev_global cryptodev_globals = {
> >> /* spinlock for crypto device callbacks */
> >> static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
> >>
> >> +static const struct rte_cryptodev_capabilities
> >> + cryptodev_undefined_capabilities[] = {
> >> + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
> >> +};
> >> +
> >> +static struct rte_cryptodev_capabilities
> >> + *capability_copies[RTE_CRYPTO_MAX_DEVS];
> >
> > Capabilities_copy is a better name as it is copy of many capabilities.
[Fiona] ok
> >> const struct rte_cryptodev_symmetric_capability *
> >> -rte_cryptodev_sym_capability_get(uint8_t dev_id,
> >> +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
> >
> > __vsym Annotation to be used in a declaration of the internal symbol
> > to signal that it is being used as an implementation of a particular
> > version of symbol.
[Fiona] ok
> >> + }
> >> +
> >> + return NULL;
> >> +
> >
> > Extra line
[Fiona] ok
> >
> >> +}
> >> +VERSION_SYMBOL(rte_cryptodev_sym_capability_get, _v20, 20.0);
> >> +
> >> +const struct rte_cryptodev_symmetric_capability *
> >
> > __vsym annotation
[Fiona] ok
> >
> >> +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
> >> const struct rte_cryptodev_sym_capability_idx *idx)
> >> {
> >> const struct rte_cryptodev_capabilities *capability;
> >> @@ -313,6 +360,10 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
> >> return NULL;
> >>
> >> }
> >> +MAP_STATIC_SYMBOL(const struct rte_cryptodev_symmetric_capability *
> >> + rte_cryptodev_sym_capability_get(uint8_t dev_id,
> >> + const struct rte_cryptodev_sym_capability_idx *idx),
> >> + rte_cryptodev_sym_capability_get_v21);
> >>
> >> static int
> >> param_range_check(uint16_t size, const struct rte_crypto_param_range *range)
> >> @@ -999,6 +1050,13 @@ rte_cryptodev_close(uint8_t dev_id)
> >> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
> >> retval = (*dev->dev_ops->dev_close)(dev);
> >>
> >> +
> >> + if (capability_copies[dev_id]) {
> >> + free(capability_copies[dev_id]);
> >> + capability_copies[dev_id] = NULL;
> >> + }
> >> + is_capability_checked[dev_id] = 0;
> >> +
> >> if (retval < 0)
> >> return retval;
> >>
> >> @@ -1111,9 +1169,61 @@ rte_cryptodev_stats_reset(uint8_t dev_id)
> >> (*dev->dev_ops->stats_reset)(dev);
> >> }
> >>
> >> +static void
> >> +get_v20_capabilities(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
> >> +{
> >> + const struct rte_cryptodev_capabilities *capability;
> >> + uint8_t found_invalid_capa = 0;
> >> + uint8_t counter = 0;
> >> +
> >> + for (capability = dev_info->capabilities;
> >> + capability->op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
> >> + ++capability, ++counter) {
> >> + if (capability->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
> >> + capability->sym.xform_type ==
> >> + RTE_CRYPTO_SYM_XFORM_AEAD
> >> + && capability->sym.aead.algo >=
> >> + RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
> >> + found_invalid_capa = 1;
> >> + counter--;
> >> + }
> >> + }
> >> + is_capability_checked[dev_id] = 1;
> >> + if (found_invalid_capa) {
> >
> > Code becomes unreadable due to indentation which can be avoided.
[Fiona] ok
> >> +void
> >> +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info
> >> *dev_info);
> >> +BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v21, 21);
> >
> > I am not sure if we need to bind for _v20 also
> > BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v20, 20);
>
> The correct call to VERSION_SYMBOL is already above.
[Fiona] ok, so won't do this.
> > Ray, can you please suggest if it required or not? And what all we need to check?
>
> See below.
>
> >
> > The patch is still showing Incompatibilities
> > NOTICE: ABI may be incompatible, check reports/logs for details.
> > NOTICE: Incompatible list: librte_cryptodev.so
>
> So I looked through the issues it is complaining about, these are here.
> https://travis-ci.com/github/ovsrobot/dpdk/jobs/320526253#L4540
>
> Basically they all are warnings related to the changes to the enumeration
> rte_crypto_aead_algorithm.
>
> Essentially the new member RTE_CRYPTO_AEAD_CHACHA20_POLY1305.
> The change to the end value RTE_CRYPTO_AEAD_LIST_END.
> Members of this type "enum rte_crypto_aead_algorithm algo" are demeeded to also have changed,
> but they haven't.
>
> With the additional work to create the v20 version of rte_cryptodev_info_get.
> I think all reasonable steps have been been taken here.
[Fiona] Do we need to change the tool or somehow mark as a false positive?
> >> /**
> >> * Register a callback function for specific device id.
> >> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map
> >> b/lib/librte_cryptodev/rte_cryptodev_version.map
> >> index 6e41b4b..512a4a7 100644
> >> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
> >> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
> >> @@ -58,6 +58,13 @@ DPDK_20.0 {
> >> local: *;
> >> };
> >>
> >> +DPDK_21 {
>
> Should be DPDK_21.0
[Fiona] Can you explain why?
I thought it could go back to a 2-number system with _v21 ABI.
I thought we'd clarified that DPDK_20.0 is only there due to a mistake, that should have been DPDK_20.
> >> + global:
> >> + rte_cryptodev_info_get;
> >> + rte_cryptodev_sym_capability_get;
> >> +} DPDK_20.0;
> >> +
> >> +
> >> EXPERIMENTAL {
> >> global:
> >>
> >> --
> >> 2.1.0
> >
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-18 17:30 4% ` [dpdk-dev] [PATCH v8 " Haiyue Wang
@ 2020-04-20 16:53 3% ` David Marchand
2020-04-20 17:02 3% ` Wang, Haiyue
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2020-04-20 16:53 UTC (permalink / raw)
To: Haiyue Wang
Cc: dev, Burakov, Anatoly, Thomas Monjalon, Vamsi Attunuru,
Jerin Jacob Kollanukkaran, Alex Williamson
Hello,
On Sat, Apr 18, 2020 at 7:36 PM Haiyue Wang <haiyue.wang@intel.com> wrote:
>
> v8: Update the document.
Thanks for the last version.
I had a look at the CI, I can see we are still missing bits to handle
the ABI failure on rte_vfio_setup_device.
--
David Marchand
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/4] vhost: inroduce operation to get vDPA queue stats
2020-04-20 15:57 0% ` Shahaf Shuler
@ 2020-04-20 16:18 0% ` Maxime Coquelin
0 siblings, 0 replies; 200+ results
From: Maxime Coquelin @ 2020-04-20 16:18 UTC (permalink / raw)
To: Shahaf Shuler, Matan Azrad, dev, Xiao Wang; +Cc: Slava Ovsiienko
On 4/20/20 5:57 PM, Shahaf Shuler wrote:
> Monday, April 20, 2020 10:13 AM, Maxime Coquelin:
>> Subject: Re: [PATCH 1/4] vhost: inroduce operation to get vDPA queue stats
>>
>> Hi Shahaf,
>>
>> On 4/19/20 8:18 AM, Shahaf Shuler wrote:
>>> Thursday, April 16, 2020 4:20 PM, Maxime Coquelin:
>>>> Subject: Re: [PATCH 1/4] vhost: inroduce operation to get vDPA queue
>>>> stats
>>>>
>>>> Hi Matan,
>>>>
>>>> On 4/16/20 11:06 AM, Matan Azrad wrote:
>>>>> Hi Maxime
>>>>>
>>>>> Can you point on specific vendor specific counter I suggested?
>>>>
>>>> No, I can't, but I think we can expect that other vendors may have
>>>> other counters they would be interested to dump.
>>>>
>>>> Maybe Intel has some counters in the IFC that they could dump.
>>>> Xiao, any thoughts?
>>>>
>>>>> I think all of them come directly from virtio protocols.
>>>>
>>>> exceed_max_chain, for example. Doesn't the spec specify that a
>>>> descriptors chain can be as long as the size of the virtqueue?
>>>>
>>>> Here it seems to indicate the device could support less.
>>>
>>> Spec allows device to limit the max supported chain (see [1]).
>>
>> Ha ok, I missed that. Please note that this is only allowed for packed ring, it is
>> not in the split ring part.
>
> On my version of spec (csprd01) it is also for split, however it was removed on the latest version not sure why.
Problem is that older drivers may assume max chain size is the virtio
ring size.
By the way, how is the guest Virtio driver made aware of the max
chain size? Isn't that missing in the spec?
>>
>>>>
>>>> Also, as the spec evolves, we may have new counters that comes up, so
>>>> better to have something flexible from the start IMHO to avoid ABI
>>>> breakages.
>>>
>>> I think there are better ways to address that, e.g.:
>>> 1. have some reserved fields for future 2. have the option to point to
>>> next item, and by that link chain of stat structures
>>>
>>>>
>>>> Maybe we can have some common xstats names for the Virtio related
>>>> counters define in vdpa lib, and then the vendors can specify more
>>>> vendor- specific counters if they wish?
>>>
>>> xstats are good, and we should have it to expose the vendor specific
>> counters. The basic counters though, should be simple and vendor agnostic
>> so that any SW/scripting layer on top of the DPDK can easily use and expose
>> it.
>>> Hence I think it will be good to have the basic counters with well-defined
>> stats structure as part of the vdpa stats API. Is the exceed_max_chain is the
>> only counter you find odd or there are more?
>>
>> Problem is that not all the vDPA NIC will implement these counters, so with
>> only proposed implementation, the user cannot know whether counter
>> value is 0 or counter is just not implemented. For example, the Virtio
>> specification does not specify counters, so a full Virtio HW offload device
>> won't have them.
>
> Yeah, full virtio emulated device is a good example.
> I think it is odd virtio doesn’t provide any statistics, e.g. how would the Netdev on top of the virtio device report anything? How will ppl debug?
> I think sooner or later we will need a way to expose stats.
I agree.
These missing counters were not blocking when using a SW backend, but
with HW Offload I agree such counters would be welcome.
>>
>> So I think the xstat is the right thing to do, with standardized names for the
>> standard counters.
>
> Yeah tend to agree on this one due to the lack of spec statistics.
>
>>
>> Regards,
>> Maxime
>>>>
>>>> Thanks,
>>>> Maxime
>>>
>>> [1]
>>> https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
>>> ub.com%2Foasis-tcs%2Fvirtio-spec%2Fblob%2Fmaster%2Fpacked-
>> ring.tex%23L
>>>
>> 498&data=02%7C01%7Cshahafs%40mellanox.com%7C2fbf00c6e115488f
>> 483e08
>>>
>> d7e4fa4940%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C0%7C6372296
>> 3594175
>>>
>> 9512&sdata=m2rPPMM%2Fen9Vkbp%2Fg5xz0MSTWYURh7woI7w5%2B
>> b2Zjy8%3D&am
>>> p;reserved=0
>>>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
2020-04-20 14:06 0% ` Ferruh Yigit
@ 2020-04-20 16:10 3% ` Thomas Monjalon
2020-04-21 10:04 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-20 16:10 UTC (permalink / raw)
To: Bill Zhou, Ferruh Yigit
Cc: Ori Kam, Matan Azrad, wenzhuo.lu, jingjing.wu, bernard.iremonger,
john.mcnamara, marko.kovacevic, arybchenko, dev
20/04/2020 16:06, Ferruh Yigit:
> On 4/18/2020 10:44 AM, Thomas Monjalon wrote:
> > 18/04/2020 07:04, Bill Zhou:
> >> From: Ferruh Yigit <ferruh.yigit@intel.com>
> >>> On 4/14/2020 9:32 AM, Dong Zhou wrote:
> >>>> --- a/lib/librte_ethdev/rte_ethdev.h
> >>>> +++ b/lib/librte_ethdev/rte_ethdev.h
> >>>> @@ -3015,6 +3015,7 @@ enum rte_eth_event_type {
> >>>> RTE_ETH_EVENT_NEW, /**< port is probed */
> >>>> RTE_ETH_EVENT_DESTROY, /**< port is released */
> >>>> RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
> >>>> + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected
> >>> */
> >>>> RTE_ETH_EVENT_MAX /**< max value of this enum */
> >>>> };
> >>>
> >>>
> >>> Just recognized that this is failing in ABI check [1], as far as last time for a
> >>> similar enum warning a QAT patch has been dropped, should this need to
> >>> wait for
> >>> 20.11 too?
> >>
> >> This patch is commonly used for flow aging, there are 2 other patches have
> >> implement flow aging in mlx5 driver reply to this patch.
[...]
> > These MAX values in enums are a pain.
> > We can try to think what can be done, waiting 20.11.
> > Not sure there is a solution, except hijacking an existing value
> > not used in the PMD, waiting the definitive value in 20.11...
>
> Dropping from the tree as of now, to not cause more merge conflicts, we can add
> it later when issue is resolved.
Thanks for dropping, that's the right thing to do
when a patch is breaking ABI check.
After some thoughts, I think it is acceptable to make a v3
which ignore this specific enum change. I explain my thought below:
An enum can accept a new value at 2 conditions:
- added as last value (not changing old values)
- new value not used by existing API
The value RTE_ETH_EVENT_FLOW_AGED meet the above 2 conditions:
- only RTE_ETH_EVENT_MAX is changed, which is consistent
- new value sent to the app only if the app registered for it
So, except if I miss something, I suggest we add this exception:
Allow new value in rte_eth_event_type if added just before RTE_ETH_EVENT_MAX.
In other words, allow changing the value of RTE_ETH_EVENT_MAX.
The file to add such exception is devtools/libabigail.abignore.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/4] vhost: inroduce operation to get vDPA queue stats
2020-04-20 7:13 0% ` Maxime Coquelin
@ 2020-04-20 15:57 0% ` Shahaf Shuler
2020-04-20 16:18 0% ` Maxime Coquelin
0 siblings, 1 reply; 200+ results
From: Shahaf Shuler @ 2020-04-20 15:57 UTC (permalink / raw)
To: Maxime Coquelin, Matan Azrad, dev, Xiao Wang; +Cc: Slava Ovsiienko
Monday, April 20, 2020 10:13 AM, Maxime Coquelin:
> Subject: Re: [PATCH 1/4] vhost: inroduce operation to get vDPA queue stats
>
> Hi Shahaf,
>
> On 4/19/20 8:18 AM, Shahaf Shuler wrote:
> > Thursday, April 16, 2020 4:20 PM, Maxime Coquelin:
> >> Subject: Re: [PATCH 1/4] vhost: inroduce operation to get vDPA queue
> >> stats
> >>
> >> Hi Matan,
> >>
> >> On 4/16/20 11:06 AM, Matan Azrad wrote:
> >>> Hi Maxime
> >>>
> >>> Can you point on specific vendor specific counter I suggested?
> >>
> >> No, I can't, but I think we can expect that other vendors may have
> >> other counters they would be interested to dump.
> >>
> >> Maybe Intel has some counters in the IFC that they could dump.
> >> Xiao, any thoughts?
> >>
> >>> I think all of them come directly from virtio protocols.
> >>
> >> exceed_max_chain, for example. Doesn't the spec specify that a
> >> descriptors chain can be as long as the size of the virtqueue?
> >>
> >> Here it seems to indicate the device could support less.
> >
> > Spec allows device to limit the max supported chain (see [1]).
>
> Ha ok, I missed that. Please note that this is only allowed for packed ring, it is
> not in the split ring part.
On my version of spec (csprd01) it is also for split, however it was removed on the latest version not sure why.
>
> >>
> >> Also, as the spec evolves, we may have new counters that comes up, so
> >> better to have something flexible from the start IMHO to avoid ABI
> >> breakages.
> >
> > I think there are better ways to address that, e.g.:
> > 1. have some reserved fields for future 2. have the option to point to
> > next item, and by that link chain of stat structures
> >
> >>
> >> Maybe we can have some common xstats names for the Virtio related
> >> counters define in vdpa lib, and then the vendors can specify more
> >> vendor- specific counters if they wish?
> >
> > xstats are good, and we should have it to expose the vendor specific
> counters. The basic counters though, should be simple and vendor agnostic
> so that any SW/scripting layer on top of the DPDK can easily use and expose
> it.
> > Hence I think it will be good to have the basic counters with well-defined
> stats structure as part of the vdpa stats API. Is the exceed_max_chain is the
> only counter you find odd or there are more?
>
> Problem is that not all the vDPA NIC will implement these counters, so with
> only proposed implementation, the user cannot know whether counter
> value is 0 or counter is just not implemented. For example, the Virtio
> specification does not specify counters, so a full Virtio HW offload device
> won't have them.
Yeah, full virtio emulated device is a good example.
I think it is odd virtio doesn’t provide any statistics, e.g. how would the Netdev on top of the virtio device report anything? How will ppl debug?
I think sooner or later we will need a way to expose stats.
>
> So I think the xstat is the right thing to do, with standardized names for the
> standard counters.
Yeah tend to agree on this one due to the lack of spec statistics.
>
> Regards,
> Maxime
> >>
> >> Thanks,
> >> Maxime
> >
> > [1]
> > https://eur03.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgith
> > ub.com%2Foasis-tcs%2Fvirtio-spec%2Fblob%2Fmaster%2Fpacked-
> ring.tex%23L
> >
> 498&data=02%7C01%7Cshahafs%40mellanox.com%7C2fbf00c6e115488f
> 483e08
> >
> d7e4fa4940%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C0%7C6372296
> 3594175
> >
> 9512&sdata=m2rPPMM%2Fen9Vkbp%2Fg5xz0MSTWYURh7woI7w5%2B
> b2Zjy8%3D&am
> > p;reserved=0
> >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21
2020-04-20 12:20 9% ` David Marchand
@ 2020-04-20 15:25 9% ` Ray Kinsella
2020-04-22 8:07 6% ` Ray Kinsella
1 sibling, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-20 15:25 UTC (permalink / raw)
To: David Marchand
Cc: dev, Wang, Haiyue, Matan Azrad, Anoob Joseph, Yigit, Ferruh,
Mahipal Challa, Eelco Chaudron, Cristian Dumitrescu,
Thomas Monjalon, Jingjing Wu, Wenzhuo Lu, Shahaf Shuler,
Viacheslav Ovsiienko, Jerin Jacob Kollanukkaran,
Nithin Dabilpuram, Alfredo Cardigliano, Neil Horman
On 20/04/2020 13:20, David Marchand wrote:
> On Mon, Apr 20, 2020 at 1:57 PM Ray Kinsella <mdr@ashroe.eu> wrote:
>>
>> Travis ABI check warnings, can be safely ignored in this case, I think.
>>
>> https://travis-ci.com/github/ovsrobot/dpdk/builds/161009923
>
> How about comparing to 19.11 ABI then?
Theory is we should always be checking against v19.11 abi.
So this _should_ be v19.11 ...
I will change in v2 and see what it throws up.
>
> --- a/.travis.yml
> +++ b/.travis.yml
> @@ -36,7 +36,7 @@ script: ./.ci/${TRAVIS_OS_NAME}-build.sh
>
> env:
> global:
> - - REF_GIT_TAG=v20.02
> + - REF_GIT_TAG=v19.11
>
> jobs:
> include:
>
>
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH v3] cryptodev: version cryptodev info get function
2020-04-20 14:22 3% ` Akhil Goyal
@ 2020-04-20 15:21 0% ` Ray Kinsella
2020-04-20 16:54 3% ` Trahe, Fiona
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-20 15:21 UTC (permalink / raw)
To: Akhil Goyal, Arek Kusztal, dev; +Cc: fiona.trahe, Thomas Monjalon
On 20/04/2020 15:22, Akhil Goyal wrote:
>
>
>>
>> This patch adds versioned function rte_cryptodev_info_get()
>> to prevent some issues with ABI policy.
>> Node v21 works in same way as before, returning driver capabilities
>> directly to the API caller. These capabilities may include new elements
>> not part of the v20 ABI.
>> Node v20 function maintains compatibility with v20 ABI releases
>> by stripping out elements not supported in v20 ABI. Because
>> rte_cryptodev_info_get is called by other API functions,
>> rte_cryptodev_sym_capability_get function is versioned the same way.
>>
>> Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
>> ---
>> v2:
>> - changed version numbers of symbols to 20.0.2
>> v3:
>> - added v2/v3 informations
>> - changed version numbers of symbols to 21
>> - fixed checkpatch issues
>>
>> This patch depends on following patches:
>>
>> [1] - "[v3] cryptodev: add chacha20-poly1305 aead algorithm"
>> (https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatchwor
>> k.dpdk.org%2Fpatch%2F64549%2F&data=02%7C01%7Cakhil.goyal%40nxp.
>> com%7Ce6789fd42a5946c128e508d7e2dffe2f%7C686ea1d3bc2b4c6fa92cd99c
>> 5c301635%7C0%7C0%7C637227323980059545&sdata=50eQJE7WHTME6d
>> qA7Nfk%2B50PVAyJrpKlMw%2BoGtA1%2FTc%3D&reserved=0)
>
> Please include the dependent patches in a single series in your next version.
>>
>> lib/librte_cryptodev/rte_cryptodev.c | 143 ++++++++++++++++++++++++-
>> lib/librte_cryptodev/rte_cryptodev.h | 39 ++++++-
>> lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++
>> 3 files changed, 186 insertions(+), 3 deletions(-)
>>
>> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
>> b/lib/librte_cryptodev/rte_cryptodev.c
>> index 6d1d0e9..b061447 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev.c
>> +++ b/lib/librte_cryptodev/rte_cryptodev.c
>> @@ -41,6 +41,9 @@
>> #include "rte_cryptodev.h"
>> #include "rte_cryptodev_pmd.h"
>>
>> +#include <rte_compat.h>
>> +#include <rte_function_versioning.h>
>> +
>> static uint8_t nb_drivers;
>>
>> static struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS];
>> @@ -56,6 +59,14 @@ static struct rte_cryptodev_global cryptodev_globals = {
>> /* spinlock for crypto device callbacks */
>> static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
>>
>> +static const struct rte_cryptodev_capabilities
>> + cryptodev_undefined_capabilities[] = {
>> + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
>> +};
>> +
>> +static struct rte_cryptodev_capabilities
>> + *capability_copies[RTE_CRYPTO_MAX_DEVS];
>
> Capabilities_copy is a better name as it is copy of many capabilities.
>
>> +static uint8_t is_capability_checked[RTE_CRYPTO_MAX_DEVS];
>>
>> /**
>> * The user application callback description.
>> @@ -280,7 +291,43 @@ rte_crypto_auth_operation_strings[] = {
>> };
>>
>> const struct rte_cryptodev_symmetric_capability *
>> -rte_cryptodev_sym_capability_get(uint8_t dev_id,
>> +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
>
> __vsym Annotation to be used in a declaration of the internal symbol
> to signal that it is being used as an implementation of a particular
> version of symbol.
>
>> + const struct rte_cryptodev_sym_capability_idx *idx)
>> +{
>> + const struct rte_cryptodev_capabilities *capability;
>> + struct rte_cryptodev_info dev_info;
>> + int i = 0;
>> +
>> + rte_cryptodev_info_get_v20(dev_id, &dev_info);
>> +
>> + while ((capability = &dev_info.capabilities[i++])->op !=
>> + RTE_CRYPTO_OP_TYPE_UNDEFINED) {
>> + if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC)
>> + continue;
>> +
>> + if (capability->sym.xform_type != idx->type)
>> + continue;
>> +
>> + if (idx->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
>> + capability->sym.auth.algo == idx->algo.auth)
>> + return &capability->sym;
>> +
>> + if (idx->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
>> + capability->sym.cipher.algo == idx->algo.cipher)
>> + return &capability->sym;
>> +
>> + if (idx->type == RTE_CRYPTO_SYM_XFORM_AEAD &&
>> + capability->sym.aead.algo == idx->algo.aead)
>> + return &capability->sym;
>> + }
>> +
>> + return NULL;
>> +
>
> Extra line
>
>> +}
>> +VERSION_SYMBOL(rte_cryptodev_sym_capability_get, _v20, 20.0);
>> +
>> +const struct rte_cryptodev_symmetric_capability *
>
> __vsym annotation
>
>> +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
>> const struct rte_cryptodev_sym_capability_idx *idx)
>> {
>> const struct rte_cryptodev_capabilities *capability;
>> @@ -313,6 +360,10 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
>> return NULL;
>>
>> }
>> +MAP_STATIC_SYMBOL(const struct rte_cryptodev_symmetric_capability *
>> + rte_cryptodev_sym_capability_get(uint8_t dev_id,
>> + const struct rte_cryptodev_sym_capability_idx *idx),
>> + rte_cryptodev_sym_capability_get_v21);
>>
>> static int
>> param_range_check(uint16_t size, const struct rte_crypto_param_range *range)
>> @@ -999,6 +1050,13 @@ rte_cryptodev_close(uint8_t dev_id)
>> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
>> retval = (*dev->dev_ops->dev_close)(dev);
>>
>> +
>> + if (capability_copies[dev_id]) {
>> + free(capability_copies[dev_id]);
>> + capability_copies[dev_id] = NULL;
>> + }
>> + is_capability_checked[dev_id] = 0;
>> +
>> if (retval < 0)
>> return retval;
>>
>> @@ -1111,9 +1169,61 @@ rte_cryptodev_stats_reset(uint8_t dev_id)
>> (*dev->dev_ops->stats_reset)(dev);
>> }
>>
>> +static void
>> +get_v20_capabilities(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
>> +{
>> + const struct rte_cryptodev_capabilities *capability;
>> + uint8_t found_invalid_capa = 0;
>> + uint8_t counter = 0;
>> +
>> + for (capability = dev_info->capabilities;
>> + capability->op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
>> + ++capability, ++counter) {
>> + if (capability->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
>> + capability->sym.xform_type ==
>> + RTE_CRYPTO_SYM_XFORM_AEAD
>> + && capability->sym.aead.algo >=
>> + RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
>> + found_invalid_capa = 1;
>> + counter--;
>> + }
>> + }
>> + is_capability_checked[dev_id] = 1;
>> + if (found_invalid_capa) {
>
> Code becomes unreadable due to indentation which can be avoided.
>
> if (!found_invalid_capa)
> return;
> capability_copies[dev_id] = malloc(counter * sizeof(struct rte_cryptodev_capabilities));
> if (capability_copies[dev_id] == NULL) {
> dev_info->capabilities = cryptodev_undefined_capabilities;
> is_capability_checked[dev_id] = 0;
> return;
> }
>
> counter = 0;
> for(...) {
> ...
> }
>> + capability_copies[dev_id] = malloc(counter *
>> + sizeof(struct rte_cryptodev_capabilities));
>> + if (capability_copies[dev_id] == NULL) {
>> + /*
>> + * error case - no memory to store the trimmed
>> + * list, so have to return an empty list
>> + */
>> + dev_info->capabilities =
>> + cryptodev_undefined_capabilities;
>> + is_capability_checked[dev_id] = 0;
>> + } else {
>> + counter = 0;
>> + for (capability = dev_info->capabilities;
>> + capability->op !=
>> + RTE_CRYPTO_OP_TYPE_UNDEFINED;
>> + capability++) {
>> + if (!(capability->op ==
>> + RTE_CRYPTO_OP_TYPE_SYMMETRIC
>> + && capability->sym.xform_type ==
>> + RTE_CRYPTO_SYM_XFORM_AEAD
>> + && capability->sym.aead.algo >=
>> +
>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305)) {
>> + capability_copies[dev_id][counter++] =
>> + *capability;
>> + }
>> + }
>> + dev_info->capabilities =
>> + capability_copies[dev_id];
>> + }
>> + }
>> +}
>>
>> void
>> -rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
>> +rte_cryptodev_info_get_v20(uint8_t dev_id, struct rte_cryptodev_info
>> *dev_info)
>> {
>> struct rte_cryptodev *dev;
>>
>> @@ -1129,10 +1239,39 @@ rte_cryptodev_info_get(uint8_t dev_id, struct
>> rte_cryptodev_info *dev_info)
>> RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
>> (*dev->dev_ops->dev_infos_get)(dev, dev_info);
>>
>> + if (capability_copies[dev_id] == NULL) {
>> + if (!is_capability_checked[dev_id])
>> + get_v20_capabilities(dev_id, dev_info);
>> + } else
>> + dev_info->capabilities = capability_copies[dev_id];
>> +
>> dev_info->driver_name = dev->device->driver->name;
>> dev_info->device = dev->device;
>> }
>> +VERSION_SYMBOL(rte_cryptodev_info_get, _v20, 20.0);
>> +
>> +void
>> +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info
>> *dev_info)
>> +{
>> + struct rte_cryptodev *dev;
>> +
>> + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
>> + CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
>> + return;
>> + }
>> +
>> + dev = &rte_crypto_devices[dev_id];
>>
>> + memset(dev_info, 0, sizeof(struct rte_cryptodev_info));
>> +
>> + RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
>> + (*dev->dev_ops->dev_infos_get)(dev, dev_info);
>> +
>> + dev_info->driver_name = dev->device->driver->name;
>> + dev_info->device = dev->device;
>> +}
>> +MAP_STATIC_SYMBOL(void rte_cryptodev_info_get(uint8_t dev_id,
>> + struct rte_cryptodev_info *dev_info), rte_cryptodev_info_get_v21);
>>
>> int
>> rte_cryptodev_callback_register(uint8_t dev_id,
>> diff --git a/lib/librte_cryptodev/rte_cryptodev.h
>> b/lib/librte_cryptodev/rte_cryptodev.h
>> index 437b8a9..7f1bc90 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev.h
>> +++ b/lib/librte_cryptodev/rte_cryptodev.h
>> @@ -24,6 +24,9 @@ extern "C" {
>> #include <rte_common.h>
>> #include <rte_config.h>
>>
>> +#include <rte_compat.h>
>> +#include <rte_function_versioning.h>
>> +
>> extern const char **rte_cyptodev_names;
>>
>> /* Logging Macros */
>> @@ -217,6 +220,15 @@ struct rte_cryptodev_asym_capability_idx {
>> * - Return NULL if the capability not exist.
>> */
>> const struct rte_cryptodev_symmetric_capability *
>> +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
>> + const struct rte_cryptodev_sym_capability_idx *idx);
>> +
>> +const struct rte_cryptodev_symmetric_capability *
>> +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
>> + const struct rte_cryptodev_sym_capability_idx *idx);
>> +BIND_DEFAULT_SYMBOL(rte_cryptodev_sym_capability_get, _v21, 21);
>> +
>> +const struct rte_cryptodev_symmetric_capability *
>> rte_cryptodev_sym_capability_get(uint8_t dev_id,
>> const struct rte_cryptodev_sym_capability_idx *idx);
>>
>> @@ -758,9 +770,34 @@ rte_cryptodev_stats_reset(uint8_t dev_id);
>> * the last valid element has it's op field set to
>> * RTE_CRYPTO_OP_TYPE_UNDEFINED.
>> */
>> -extern void
>> +
>> +void
>> rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info);
>>
>> +/* An extra element RTE_CRYPTO_AEAD_CHACHA20_POLY1305 is added
>> + * to enum rte_crypto_aead_algorithm, also changing the value of
>> + * RTE_CRYPTO_AEAD_LIST_END. To maintain ABI compatibility with
>> applications
>> + * which linked against earlier versions, preventing them, for example, from
>> + * picking up the new value and using it to index into an array sized too small
>> + * for it, it is necessary to have two versions of rte_cryptodev_info_get()
>> + * The latest version just returns directly the capabilities retrieved from
>> + * the device. The compatible version inspects the capabilities retrieved
>> + * from the device, but only returns them directly if the new value
>> + * is not included. If the new value is included, it allocates space
>> + * for a copy of the device capabilities, trims the new value from this
>> + * and returns this copy. It only needs to do this once per device.
>> + * For the corner case of a corner case when the alloc may fail,
>> + * an empty capability list is returned, as there is no mechanism to return
>> + * an error and adding such a mechanism would itself be an ABI breakage.
>> + * The compatible version can be removed after the next major ABI release.
>> + */
>> +
>> +void
>> +rte_cryptodev_info_get_v20(uint8_t dev_id, struct rte_cryptodev_info
>> *dev_info);
>> +
>> +void
>> +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info
>> *dev_info);
>> +BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v21, 21);
>
> I am not sure if we need to bind for _v20 also
> BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v20, 20);
The correct call to VERSION_SYMBOL is already above.
>
> Ray, can you please suggest if it required or not? And what all we need to check?
See below.
>
> The patch is still showing Incompatibilities
> NOTICE: ABI may be incompatible, check reports/logs for details.
> NOTICE: Incompatible list: librte_cryptodev.so
So I looked through the issues it is complaining about, these are here.
https://travis-ci.com/github/ovsrobot/dpdk/jobs/320526253#L4540
Basically they all are warnings related to the changes to the enumeration rte_crypto_aead_algorithm.
Essentially the new member RTE_CRYPTO_AEAD_CHACHA20_POLY1305.
The change to the end value RTE_CRYPTO_AEAD_LIST_END.
Members of this type "enum rte_crypto_aead_algorithm algo" are demeeded to also have changed, but they haven't.
With the additional work to create the v20 version of rte_cryptodev_info_get.
I think all reasonable steps have been been taken here.
>
>>
>> /**
>> * Register a callback function for specific device id.
>> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map
>> b/lib/librte_cryptodev/rte_cryptodev_version.map
>> index 6e41b4b..512a4a7 100644
>> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
>> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
>> @@ -58,6 +58,13 @@ DPDK_20.0 {
>> local: *;
>> };
>>
>> +DPDK_21 {
Should be DPDK_21.0
>> + global:
>> + rte_cryptodev_info_get;
>> + rte_cryptodev_sym_capability_get;
>> +} DPDK_20.0;
>> +
>> +
>> EXPERIMENTAL {
>> global:
>>
>> --
>> 2.1.0
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 00/16] update and simplifytelemetrylibrary.
2020-04-20 13:18 0% ` Bruce Richardson
@ 2020-04-20 14:55 0% ` Morten Brørup
0 siblings, 0 replies; 200+ results
From: Morten Brørup @ 2020-04-20 14:55 UTC (permalink / raw)
To: Bruce Richardson, thomas
Cc: Wiles, Keith, Power, Ciara, dev, Laatz, Kevin, Pattan, Reshma,
jerinjacobk, david.marchand, thomas
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bruce Richardson
> Sent: Monday, April 20, 2020 3:19 PM
>
> On Fri, Apr 10, 2020 at 08:06:23PM +0200, Morten Brørup wrote:
> > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wiles, Keith
> > > Sent: Friday, April 10, 2020 4:22 PM
> > >
> > > > On Apr 10, 2020, at 5:49 AM, Morten Brørup
> <mb@smartsharesystems.com>
> > > wrote:
> > > >
> > > >> From: Ciara Power [mailto:ciara.power@intel.com]
> > > >> Sent: Wednesday, April 8, 2020 6:50 PM
> > > >>
> > > >> This patchset extensively reworks the telemetry library adding
> new
> > > >> functionality and simplifying much of the existing code, while
> > > >> maintaining backward compatibility.
> > > >>
> > > >> This work is based on the previously sent RFC for a "process
> info"
> > > >> library:
> https://patchwork.dpdk.org/project/dpdk/list/?series=7741
> > > >> However, rather than creating a new library, this patchset takes
> > > >> that work and merges it into the existing telemetry library, as
> > > >> mentioned above.
> > > >>
> > > >> The telemetry library as shipped in 19.11 is based upon the
> metrics
> > > >> library and outputs all statistics based on that as a source.
> However,
> > > >> this limits the telemetry output to only port-level statistics
> > > >> information, rather than allowing it to be used as a general
> scheme for
> > > >> telemetry information across all DPDK libraries.
> > > >>
> > > >> With this patchset applied, rather than the telemetry library
> being
> > > >> responsible for pulling ethdev stats and pushing them into the
> metrics
> > > >> library for retrieval later, each library e.g. ethdev, rawdev,
> and even
> > > >> the metrics library itself (for backwards compatiblity) now
> handle
> > > >> their
> > > >> own stats. Any library or app can register a callback function
> with
> > > >> telemetry, which will be called if requested by the client
> connected
> > > >> via
> > > >> the telemetry socket.
> > > >
> > > > Great. Standardization across libraries is a good improvement.
> > > >
> > > >> The callback function in the library/app then
> > > >> formats its stats, or other data, into a JSON string, and
> returns it to
> > > >> telemetry to be sent to the client.
> > > >
> > > > I am strongly opposed to using JSON as the standard format in
> DPDK, and
> > > instead prefer a binary format with zero (or minimal) type
> conversion.
> > > >
> > > > Here is one reason why I dislike JSON for this: A part of our
> application
> > > samples 100k+ counters every second to be able to provide drill-
> down
> > > statistics through the GUI. Converting these counters from uint64_t
> to JSON
> > > and back to uint64_t for data processing is not going to fly. And I
> assume
> > > that we are not the only company developing equipment with drill-
> down
> > > statistics.
> > > >
> > > > I am aware that there is a difference between statistics for
> *drill-down
> > > and data processing* purposes and statistics for *telemetry eyeball
> viewing
> > > only* purposes, but the line is blurry, and I see a big risk of
> setting a
> > > path that leads to JSON being used in places where it shouldn't.
> > > >
> > > > Here is another reason why I dislike JSON for this: JSON is fine
> for the
> > > LAMP stack with REST protocols. But other systems use other
> protocols with
> > > other formats, e.g. the TICK stack uses an even simpler text based
> format.
> > > So DPDK based systems supporting the TICK stack will need to
> convert to
> > > first JSON format (in the DPDK libraries), and then from JSON
> format to
> > > InfluxDB format (in the DPDK application).
> > > >
> > > > I think that type conversion does not belong inside deep inside
> the DPDK
> > > libraries, but is a job for the DPDK application. However, DPDK
> could
> > > provide libraries for efficient bulk conversion to popular formats
> like
> > > JSON. And other formats, if they are relevant, e.g. ASN.1 used by
> old
> > > school SNMP.
> > >
> > > I believe JSON has it place in this library and in DPDK as it is a
> good
> > > conversion tool and easy to utilize with a huge number of
> tools/languages.
> >
> > JSON is extremely heavy compared to a raw binary format.
> >
> > It makes sense for low volume, hierarchical structured data, but not
> for large tables or arrays of counters.
> >
> > > Binary output gets into endianness issues and a number of other
> problems,
> > > so I would not want all of the data exported from DPDK to be in
> binary
> > > format.
> >
> > Endianness considerations are only relevant for data exchanged across
> the network; not data exchanged across processes inside the same
> machine.
> >
> > And if you are exchanging data across the network, you would usually
> implement one or more well known protocols for that, e.g. JSON over
> HTTPS, or ASN.1 over SNMP, or InfluxDB over UDP. This means that the
> application needs to implement a protocol handler, which - in my
> opinion - should handle the relevant data type conversions from the raw
> format provided by DPDK.
> >
> > I think it would be silly for DPDK core libraries to provide counters
> in JSON format, so an SNMP Agent would need to convert them from JSON
> back to binary and then to ASN.1.
> >
> > > If the layout of the structure changes then the code would need to
> > > know that on both side to be able to convert the data into the
> correct
> > > values.
> >
> > I may be exaggerating here, but trying to prove a point: This is what
> we have ABI stability for. Structures should be designed cleverly and
> future proof, e.g. like the ethdev xstats. Using text based APIs is a
> circumvention of ABI stability.
> >
> > >
> > > With that stated, the new telemetry code allows the application to
> add new
> > > commands and with that you can create a binary set of commands
> along side
> > > the JSON or any other output format. With the new register command
> we can
> > > create say a ‘/ethdevraw/stats,X’ set of commands that can emit
> binary
> > > format.
> >
> > That would be silly. The protocol handler should make the protocol
> specific conversion, not the driver! Again, going to the extreme to
> prove a point: If I understand you correctly, this would mean that PMDs
> would have provide counters in ASN.1 format for SNMP.
> >
> > Our application provides a HTTPS/REST based communication interface
> for multiple purposes, e.g. getting tables of data. And if you want to
> get a table of some data via this interface, you can specify the output
> format in the request, so you can get it in e.g. TSV format (tabulator
> separated with a headline) for scripts, HTML format for human eyeballs.
> This data conversion happens at a common location, so we can easily add
> other output formats. You don't want to push this all the way down to
> the originator of the data.
> >
> > >
> > > Using this method we get the best of both worlds and when using
> languages
> > > like Go or Python to collect these stats we have a standard format
> for
> > > conversion. In Go it is pretty hard to do binary conversion and
> JSON
> > > conversion is just a few lines.
> >
> > I don't think DPDK should provide preferential treatment to Go or
> Python. DPDK is based on C, and should mainly cater for C.
> >
> > > JSON may not be the fastest, but if you are
> > > requesting stats faster than a second then use the raw commands to
> get the
> > > data, which anyone can add to its application or we can add them to
> DPDK as
> > > a standard command set.
> >
> > APIs in the libraries are currently available to get data in raw
> format. My main concern is that libraries in the future will not
> provide functions to get raw data, like they do now, but only JSON
> formatted data for the telemetry library. This is what I want to avoid.
> >
>
> Hi Morten,
>
> thanks for all the feedback.
>
> Firstly on the performance side, we did some basic benchmarking of the
> output capabilities of the current proposal. Using a dummy client that
> had
> two queries constantly outstanding (to avoid dead time between one
> response
> and next request), we measured the number of replies per second from
> the
> ethdev xstats call.
> * with a 2.3 GHz Xeon system, we got 3,500 responses per second, with
> 146
> stats per response, giving a total of >500k stats per second encoded
> and
> transmitted.
> * for those 500k stats, looking at the cpu time on the core doing the
> telemetry work, ~80% of CPU time was spent inside the ixgbe driver
> getting the stats from the NIC card itself.
> * replacing the ixgbe NIC with a ring vdev increased the responses per
> second to >100k, though with only 13 stats per response this time,
> giving
> 1.3M stats per second.
> * Splitting the existing xstats call in this RFC into separate xstat
> names and xstat values calls (something I think is a good idea to do
> generally), and only calling the xstat values call each time, gives
> further perf increases to 163k responses per second.
>
> Overall so, at least on the json generation side, it appears we can do
> things rather quickly, though I admit that we did not look into the
> parsing
> cost on the other side.
>
> All that being said, however, I do understand your point about having
> everything work internally in json - something that ties in with Thomas
> concern about having flexibility. Therefore, while we will upstream a
> v3
> very shortly with the few incremental comments on v2, we can thereafter
> look to switch the internal communication between callbacks and
> telemetry
> library to use a regular data structure, and then leave the json
> encoding
> to the library itself just before output. That would:
> a) allow the addition of other output types in the future without
> needing
> new callbacks.
> b) allow more flexibility for integrating with a future one-IPC
> mechanism
> for DPDK.
>
> I hope this option will resolve most concerns and allow for a 20.05
> integration.
>
> Regards.
> /Bruce
Yes. Thank you.
Med venlig hilsen / kind regards
- Morten Brørup
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] cryptodev: version cryptodev info get function
2020-04-17 14:59 11% [dpdk-dev] [PATCH v3] cryptodev: version cryptodev info get function Arek Kusztal
@ 2020-04-20 14:22 3% ` Akhil Goyal
2020-04-20 15:21 0% ` Ray Kinsella
0 siblings, 1 reply; 200+ results
From: Akhil Goyal @ 2020-04-20 14:22 UTC (permalink / raw)
To: Arek Kusztal, dev, Ray Kinsella; +Cc: fiona.trahe, Thomas Monjalon
>
> This patch adds versioned function rte_cryptodev_info_get()
> to prevent some issues with ABI policy.
> Node v21 works in same way as before, returning driver capabilities
> directly to the API caller. These capabilities may include new elements
> not part of the v20 ABI.
> Node v20 function maintains compatibility with v20 ABI releases
> by stripping out elements not supported in v20 ABI. Because
> rte_cryptodev_info_get is called by other API functions,
> rte_cryptodev_sym_capability_get function is versioned the same way.
>
> Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
> ---
> v2:
> - changed version numbers of symbols to 20.0.2
> v3:
> - added v2/v3 informations
> - changed version numbers of symbols to 21
> - fixed checkpatch issues
>
> This patch depends on following patches:
>
> [1] - "[v3] cryptodev: add chacha20-poly1305 aead algorithm"
> (https://eur01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fpatchwor
> k.dpdk.org%2Fpatch%2F64549%2F&data=02%7C01%7Cakhil.goyal%40nxp.
> com%7Ce6789fd42a5946c128e508d7e2dffe2f%7C686ea1d3bc2b4c6fa92cd99c
> 5c301635%7C0%7C0%7C637227323980059545&sdata=50eQJE7WHTME6d
> qA7Nfk%2B50PVAyJrpKlMw%2BoGtA1%2FTc%3D&reserved=0)
Please include the dependent patches in a single series in your next version.
>
> lib/librte_cryptodev/rte_cryptodev.c | 143 ++++++++++++++++++++++++-
> lib/librte_cryptodev/rte_cryptodev.h | 39 ++++++-
> lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++
> 3 files changed, 186 insertions(+), 3 deletions(-)
>
> diff --git a/lib/librte_cryptodev/rte_cryptodev.c
> b/lib/librte_cryptodev/rte_cryptodev.c
> index 6d1d0e9..b061447 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.c
> +++ b/lib/librte_cryptodev/rte_cryptodev.c
> @@ -41,6 +41,9 @@
> #include "rte_cryptodev.h"
> #include "rte_cryptodev_pmd.h"
>
> +#include <rte_compat.h>
> +#include <rte_function_versioning.h>
> +
> static uint8_t nb_drivers;
>
> static struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS];
> @@ -56,6 +59,14 @@ static struct rte_cryptodev_global cryptodev_globals = {
> /* spinlock for crypto device callbacks */
> static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
>
> +static const struct rte_cryptodev_capabilities
> + cryptodev_undefined_capabilities[] = {
> + RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
> +};
> +
> +static struct rte_cryptodev_capabilities
> + *capability_copies[RTE_CRYPTO_MAX_DEVS];
Capabilities_copy is a better name as it is copy of many capabilities.
> +static uint8_t is_capability_checked[RTE_CRYPTO_MAX_DEVS];
>
> /**
> * The user application callback description.
> @@ -280,7 +291,43 @@ rte_crypto_auth_operation_strings[] = {
> };
>
> const struct rte_cryptodev_symmetric_capability *
> -rte_cryptodev_sym_capability_get(uint8_t dev_id,
> +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
__vsym Annotation to be used in a declaration of the internal symbol
to signal that it is being used as an implementation of a particular
version of symbol.
> + const struct rte_cryptodev_sym_capability_idx *idx)
> +{
> + const struct rte_cryptodev_capabilities *capability;
> + struct rte_cryptodev_info dev_info;
> + int i = 0;
> +
> + rte_cryptodev_info_get_v20(dev_id, &dev_info);
> +
> + while ((capability = &dev_info.capabilities[i++])->op !=
> + RTE_CRYPTO_OP_TYPE_UNDEFINED) {
> + if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC)
> + continue;
> +
> + if (capability->sym.xform_type != idx->type)
> + continue;
> +
> + if (idx->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
> + capability->sym.auth.algo == idx->algo.auth)
> + return &capability->sym;
> +
> + if (idx->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
> + capability->sym.cipher.algo == idx->algo.cipher)
> + return &capability->sym;
> +
> + if (idx->type == RTE_CRYPTO_SYM_XFORM_AEAD &&
> + capability->sym.aead.algo == idx->algo.aead)
> + return &capability->sym;
> + }
> +
> + return NULL;
> +
Extra line
> +}
> +VERSION_SYMBOL(rte_cryptodev_sym_capability_get, _v20, 20.0);
> +
> +const struct rte_cryptodev_symmetric_capability *
__vsym annotation
> +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
> const struct rte_cryptodev_sym_capability_idx *idx)
> {
> const struct rte_cryptodev_capabilities *capability;
> @@ -313,6 +360,10 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
> return NULL;
>
> }
> +MAP_STATIC_SYMBOL(const struct rte_cryptodev_symmetric_capability *
> + rte_cryptodev_sym_capability_get(uint8_t dev_id,
> + const struct rte_cryptodev_sym_capability_idx *idx),
> + rte_cryptodev_sym_capability_get_v21);
>
> static int
> param_range_check(uint16_t size, const struct rte_crypto_param_range *range)
> @@ -999,6 +1050,13 @@ rte_cryptodev_close(uint8_t dev_id)
> RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
> retval = (*dev->dev_ops->dev_close)(dev);
>
> +
> + if (capability_copies[dev_id]) {
> + free(capability_copies[dev_id]);
> + capability_copies[dev_id] = NULL;
> + }
> + is_capability_checked[dev_id] = 0;
> +
> if (retval < 0)
> return retval;
>
> @@ -1111,9 +1169,61 @@ rte_cryptodev_stats_reset(uint8_t dev_id)
> (*dev->dev_ops->stats_reset)(dev);
> }
>
> +static void
> +get_v20_capabilities(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
> +{
> + const struct rte_cryptodev_capabilities *capability;
> + uint8_t found_invalid_capa = 0;
> + uint8_t counter = 0;
> +
> + for (capability = dev_info->capabilities;
> + capability->op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
> + ++capability, ++counter) {
> + if (capability->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
> + capability->sym.xform_type ==
> + RTE_CRYPTO_SYM_XFORM_AEAD
> + && capability->sym.aead.algo >=
> + RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
> + found_invalid_capa = 1;
> + counter--;
> + }
> + }
> + is_capability_checked[dev_id] = 1;
> + if (found_invalid_capa) {
Code becomes unreadable due to indentation which can be avoided.
if (!found_invalid_capa)
return;
capability_copies[dev_id] = malloc(counter * sizeof(struct rte_cryptodev_capabilities));
if (capability_copies[dev_id] == NULL) {
dev_info->capabilities = cryptodev_undefined_capabilities;
is_capability_checked[dev_id] = 0;
return;
}
counter = 0;
for(...) {
...
}
> + capability_copies[dev_id] = malloc(counter *
> + sizeof(struct rte_cryptodev_capabilities));
> + if (capability_copies[dev_id] == NULL) {
> + /*
> + * error case - no memory to store the trimmed
> + * list, so have to return an empty list
> + */
> + dev_info->capabilities =
> + cryptodev_undefined_capabilities;
> + is_capability_checked[dev_id] = 0;
> + } else {
> + counter = 0;
> + for (capability = dev_info->capabilities;
> + capability->op !=
> + RTE_CRYPTO_OP_TYPE_UNDEFINED;
> + capability++) {
> + if (!(capability->op ==
> + RTE_CRYPTO_OP_TYPE_SYMMETRIC
> + && capability->sym.xform_type ==
> + RTE_CRYPTO_SYM_XFORM_AEAD
> + && capability->sym.aead.algo >=
> +
> RTE_CRYPTO_AEAD_CHACHA20_POLY1305)) {
> + capability_copies[dev_id][counter++] =
> + *capability;
> + }
> + }
> + dev_info->capabilities =
> + capability_copies[dev_id];
> + }
> + }
> +}
>
> void
> -rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
> +rte_cryptodev_info_get_v20(uint8_t dev_id, struct rte_cryptodev_info
> *dev_info)
> {
> struct rte_cryptodev *dev;
>
> @@ -1129,10 +1239,39 @@ rte_cryptodev_info_get(uint8_t dev_id, struct
> rte_cryptodev_info *dev_info)
> RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
> (*dev->dev_ops->dev_infos_get)(dev, dev_info);
>
> + if (capability_copies[dev_id] == NULL) {
> + if (!is_capability_checked[dev_id])
> + get_v20_capabilities(dev_id, dev_info);
> + } else
> + dev_info->capabilities = capability_copies[dev_id];
> +
> dev_info->driver_name = dev->device->driver->name;
> dev_info->device = dev->device;
> }
> +VERSION_SYMBOL(rte_cryptodev_info_get, _v20, 20.0);
> +
> +void
> +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info
> *dev_info)
> +{
> + struct rte_cryptodev *dev;
> +
> + if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
> + CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
> + return;
> + }
> +
> + dev = &rte_crypto_devices[dev_id];
>
> + memset(dev_info, 0, sizeof(struct rte_cryptodev_info));
> +
> + RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
> + (*dev->dev_ops->dev_infos_get)(dev, dev_info);
> +
> + dev_info->driver_name = dev->device->driver->name;
> + dev_info->device = dev->device;
> +}
> +MAP_STATIC_SYMBOL(void rte_cryptodev_info_get(uint8_t dev_id,
> + struct rte_cryptodev_info *dev_info), rte_cryptodev_info_get_v21);
>
> int
> rte_cryptodev_callback_register(uint8_t dev_id,
> diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> b/lib/librte_cryptodev/rte_cryptodev.h
> index 437b8a9..7f1bc90 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev.h
> @@ -24,6 +24,9 @@ extern "C" {
> #include <rte_common.h>
> #include <rte_config.h>
>
> +#include <rte_compat.h>
> +#include <rte_function_versioning.h>
> +
> extern const char **rte_cyptodev_names;
>
> /* Logging Macros */
> @@ -217,6 +220,15 @@ struct rte_cryptodev_asym_capability_idx {
> * - Return NULL if the capability not exist.
> */
> const struct rte_cryptodev_symmetric_capability *
> +rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
> + const struct rte_cryptodev_sym_capability_idx *idx);
> +
> +const struct rte_cryptodev_symmetric_capability *
> +rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
> + const struct rte_cryptodev_sym_capability_idx *idx);
> +BIND_DEFAULT_SYMBOL(rte_cryptodev_sym_capability_get, _v21, 21);
> +
> +const struct rte_cryptodev_symmetric_capability *
> rte_cryptodev_sym_capability_get(uint8_t dev_id,
> const struct rte_cryptodev_sym_capability_idx *idx);
>
> @@ -758,9 +770,34 @@ rte_cryptodev_stats_reset(uint8_t dev_id);
> * the last valid element has it's op field set to
> * RTE_CRYPTO_OP_TYPE_UNDEFINED.
> */
> -extern void
> +
> +void
> rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info);
>
> +/* An extra element RTE_CRYPTO_AEAD_CHACHA20_POLY1305 is added
> + * to enum rte_crypto_aead_algorithm, also changing the value of
> + * RTE_CRYPTO_AEAD_LIST_END. To maintain ABI compatibility with
> applications
> + * which linked against earlier versions, preventing them, for example, from
> + * picking up the new value and using it to index into an array sized too small
> + * for it, it is necessary to have two versions of rte_cryptodev_info_get()
> + * The latest version just returns directly the capabilities retrieved from
> + * the device. The compatible version inspects the capabilities retrieved
> + * from the device, but only returns them directly if the new value
> + * is not included. If the new value is included, it allocates space
> + * for a copy of the device capabilities, trims the new value from this
> + * and returns this copy. It only needs to do this once per device.
> + * For the corner case of a corner case when the alloc may fail,
> + * an empty capability list is returned, as there is no mechanism to return
> + * an error and adding such a mechanism would itself be an ABI breakage.
> + * The compatible version can be removed after the next major ABI release.
> + */
> +
> +void
> +rte_cryptodev_info_get_v20(uint8_t dev_id, struct rte_cryptodev_info
> *dev_info);
> +
> +void
> +rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info
> *dev_info);
> +BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v21, 21);
I am not sure if we need to bind for _v20 also
BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v20, 20);
Ray, can you please suggest if it required or not? And what all we need to check?
The patch is still showing Incompatibilities
NOTICE: ABI may be incompatible, check reports/logs for details.
NOTICE: Incompatible list: librte_cryptodev.so
>
> /**
> * Register a callback function for specific device id.
> diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map
> b/lib/librte_cryptodev/rte_cryptodev_version.map
> index 6e41b4b..512a4a7 100644
> --- a/lib/librte_cryptodev/rte_cryptodev_version.map
> +++ b/lib/librte_cryptodev/rte_cryptodev_version.map
> @@ -58,6 +58,13 @@ DPDK_20.0 {
> local: *;
> };
>
> +DPDK_21 {
> + global:
> + rte_cryptodev_info_get;
> + rte_cryptodev_sym_capability_get;
> +} DPDK_20.0;
> +
> +
> EXPERIMENTAL {
> global:
>
> --
> 2.1.0
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] rte_vfio_container_dma_map/unmap functions
@ 2020-04-20 14:07 3% ` Burakov, Anatoly
2020-04-20 17:39 3% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Burakov, Anatoly @ 2020-04-20 14:07 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, Tal Shnaiderman, bruce.richardson, david.marchand
On 19-Apr-20 2:10 PM, Thomas Monjalon wrote:
> 19/04/2020 15:09, Thomas Monjalon:
>> 17/04/2020 16:09, Burakov, Anatoly:
>>> On 17-Apr-20 3:05 PM, Burakov, Anatoly wrote:
>>>> On 22-Mar-20 5:20 PM, Tal Shnaiderman wrote:
>>>>> Hi Anatoly,
>>>>>
>>>>> I’m working on the implementation of bus/pci driver for Windows,
>>>>> pci_common.c uses the titled functions however they are relevant only
>>>>> for Linux OS.
>>>>>
>>>>> I’m wondering if the implementation of those functions should be moved
>>>>> to a Linux specific area since FreeBSD (and now Windows) are forced to
>>>>> implemented those in the current state.
>>>
>>> Unfortunately, we don't have a generic API for these, but since we
>>> export a single API on all platforms, either all platforms have to
>>> implement these functions, or none of them do. There's simply no way to
>>> avoid implementing stubs for these functions, short of coming up with a
>>> generic API that would replace these. Given that this API is heavily
>>> Linux specific, i don't see that happening.
>>
>> Because it is Linux specific, we should not force FreeBSD and Windows
>> having stubs. Can we move VFIO calls in Linux-specific files?
>>
>> I think rte_vfio.h should be moved in lib/librte_eal/linux/include.
>
> +Cc Bruce and David
>
>
...and have a Linux-specific ABI?
--
Thanks,
Anatoly
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
2020-04-18 9:44 0% ` Thomas Monjalon
@ 2020-04-20 14:06 0% ` Ferruh Yigit
2020-04-20 16:10 3% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2020-04-20 14:06 UTC (permalink / raw)
To: Thomas Monjalon, Ori Kam, Matan Azrad, wenzhuo.lu, jingjing.wu,
bernard.iremonger, john.mcnamara, marko.kovacevic, arybchenko,
Bill Zhou
Cc: dev
On 4/18/2020 10:44 AM, Thomas Monjalon wrote:
> 18/04/2020 07:04, Bill Zhou:
>> From: Ferruh Yigit <ferruh.yigit@intel.com>
>>> On 4/14/2020 9:32 AM, Dong Zhou wrote:
>>>> --- a/lib/librte_ethdev/rte_ethdev.h
>>>> +++ b/lib/librte_ethdev/rte_ethdev.h
>>>> @@ -3015,6 +3015,7 @@ enum rte_eth_event_type {
>>>> RTE_ETH_EVENT_NEW, /**< port is probed */
>>>> RTE_ETH_EVENT_DESTROY, /**< port is released */
>>>> RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
>>>> + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected
>>> */
>>>> RTE_ETH_EVENT_MAX /**< max value of this enum */
>>>> };
>>>
>>>
>>> Just recognized that this is failing in ABI check [1], as far as last time for a
>>> similar enum warning a QAT patch has been dropped, should this need to
>>> wait for
>>> 20.11 too?
>>
>> This patch is commonly used for flow aging, there are 2 other patches have
>> implement flow aging in mlx5 driver reply to this patch.
>> In our schedule, this feature is merged in 20.05 for some customers. Can it
>> be fixed?
>
> These MAX values in enums are a pain.
> We can try to think what can be done, waiting 20.11.
> Not sure there is a solution, except hijacking an existing value
> not used in the PMD, waiting the definitive value in 20.11...
>
Dropping from the tree as of now, to not cause more merge conflicts, we can add
it later when issue is resolved.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 00/16] update and simplify telemetrylibrary.
@ 2020-04-20 13:18 0% ` Bruce Richardson
2020-04-20 14:55 0% ` [dpdk-dev] [PATCH v2 00/16] update and simplifytelemetrylibrary Morten Brørup
0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2020-04-20 13:18 UTC (permalink / raw)
To: Morten Brørup, thomas
Cc: Wiles, Keith, Power, Ciara, dev, Laatz, Kevin, Pattan, Reshma,
jerinjacobk, david.marchand, thomas
On Fri, Apr 10, 2020 at 08:06:23PM +0200, Morten Brørup wrote:
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Wiles, Keith
> > Sent: Friday, April 10, 2020 4:22 PM
> >
> > > On Apr 10, 2020, at 5:49 AM, Morten Brørup <mb@smartsharesystems.com>
> > wrote:
> > >
> > >> From: Ciara Power [mailto:ciara.power@intel.com]
> > >> Sent: Wednesday, April 8, 2020 6:50 PM
> > >>
> > >> This patchset extensively reworks the telemetry library adding new
> > >> functionality and simplifying much of the existing code, while
> > >> maintaining backward compatibility.
> > >>
> > >> This work is based on the previously sent RFC for a "process info"
> > >> library: https://patchwork.dpdk.org/project/dpdk/list/?series=7741
> > >> However, rather than creating a new library, this patchset takes
> > >> that work and merges it into the existing telemetry library, as
> > >> mentioned above.
> > >>
> > >> The telemetry library as shipped in 19.11 is based upon the metrics
> > >> library and outputs all statistics based on that as a source. However,
> > >> this limits the telemetry output to only port-level statistics
> > >> information, rather than allowing it to be used as a general scheme for
> > >> telemetry information across all DPDK libraries.
> > >>
> > >> With this patchset applied, rather than the telemetry library being
> > >> responsible for pulling ethdev stats and pushing them into the metrics
> > >> library for retrieval later, each library e.g. ethdev, rawdev, and even
> > >> the metrics library itself (for backwards compatiblity) now handle
> > >> their
> > >> own stats. Any library or app can register a callback function with
> > >> telemetry, which will be called if requested by the client connected
> > >> via
> > >> the telemetry socket.
> > >
> > > Great. Standardization across libraries is a good improvement.
> > >
> > >> The callback function in the library/app then
> > >> formats its stats, or other data, into a JSON string, and returns it to
> > >> telemetry to be sent to the client.
> > >
> > > I am strongly opposed to using JSON as the standard format in DPDK, and
> > instead prefer a binary format with zero (or minimal) type conversion.
> > >
> > > Here is one reason why I dislike JSON for this: A part of our application
> > samples 100k+ counters every second to be able to provide drill-down
> > statistics through the GUI. Converting these counters from uint64_t to JSON
> > and back to uint64_t for data processing is not going to fly. And I assume
> > that we are not the only company developing equipment with drill-down
> > statistics.
> > >
> > > I am aware that there is a difference between statistics for *drill-down
> > and data processing* purposes and statistics for *telemetry eyeball viewing
> > only* purposes, but the line is blurry, and I see a big risk of setting a
> > path that leads to JSON being used in places where it shouldn't.
> > >
> > > Here is another reason why I dislike JSON for this: JSON is fine for the
> > LAMP stack with REST protocols. But other systems use other protocols with
> > other formats, e.g. the TICK stack uses an even simpler text based format.
> > So DPDK based systems supporting the TICK stack will need to convert to
> > first JSON format (in the DPDK libraries), and then from JSON format to
> > InfluxDB format (in the DPDK application).
> > >
> > > I think that type conversion does not belong inside deep inside the DPDK
> > libraries, but is a job for the DPDK application. However, DPDK could
> > provide libraries for efficient bulk conversion to popular formats like
> > JSON. And other formats, if they are relevant, e.g. ASN.1 used by old
> > school SNMP.
> >
> > I believe JSON has it place in this library and in DPDK as it is a good
> > conversion tool and easy to utilize with a huge number of tools/languages.
>
> JSON is extremely heavy compared to a raw binary format.
>
> It makes sense for low volume, hierarchical structured data, but not for large tables or arrays of counters.
>
> > Binary output gets into endianness issues and a number of other problems,
> > so I would not want all of the data exported from DPDK to be in binary
> > format.
>
> Endianness considerations are only relevant for data exchanged across the network; not data exchanged across processes inside the same machine.
>
> And if you are exchanging data across the network, you would usually implement one or more well known protocols for that, e.g. JSON over HTTPS, or ASN.1 over SNMP, or InfluxDB over UDP. This means that the application needs to implement a protocol handler, which - in my opinion - should handle the relevant data type conversions from the raw format provided by DPDK.
>
> I think it would be silly for DPDK core libraries to provide counters in JSON format, so an SNMP Agent would need to convert them from JSON back to binary and then to ASN.1.
>
> > If the layout of the structure changes then the code would need to
> > know that on both side to be able to convert the data into the correct
> > values.
>
> I may be exaggerating here, but trying to prove a point: This is what we have ABI stability for. Structures should be designed cleverly and future proof, e.g. like the ethdev xstats. Using text based APIs is a circumvention of ABI stability.
>
> >
> > With that stated, the new telemetry code allows the application to add new
> > commands and with that you can create a binary set of commands along side
> > the JSON or any other output format. With the new register command we can
> > create say a ‘/ethdevraw/stats,X’ set of commands that can emit binary
> > format.
>
> That would be silly. The protocol handler should make the protocol specific conversion, not the driver! Again, going to the extreme to prove a point: If I understand you correctly, this would mean that PMDs would have provide counters in ASN.1 format for SNMP.
>
> Our application provides a HTTPS/REST based communication interface for multiple purposes, e.g. getting tables of data. And if you want to get a table of some data via this interface, you can specify the output format in the request, so you can get it in e.g. TSV format (tabulator separated with a headline) for scripts, HTML format for human eyeballs. This data conversion happens at a common location, so we can easily add other output formats. You don't want to push this all the way down to the originator of the data.
>
> >
> > Using this method we get the best of both worlds and when using languages
> > like Go or Python to collect these stats we have a standard format for
> > conversion. In Go it is pretty hard to do binary conversion and JSON
> > conversion is just a few lines.
>
> I don't think DPDK should provide preferential treatment to Go or Python. DPDK is based on C, and should mainly cater for C.
>
> > JSON may not be the fastest, but if you are
> > requesting stats faster than a second then use the raw commands to get the
> > data, which anyone can add to its application or we can add them to DPDK as
> > a standard command set.
>
> APIs in the libraries are currently available to get data in raw format. My main concern is that libraries in the future will not provide functions to get raw data, like they do now, but only JSON formatted data for the telemetry library. This is what I want to avoid.
>
Hi Morten,
thanks for all the feedback.
Firstly on the performance side, we did some basic benchmarking of the
output capabilities of the current proposal. Using a dummy client that had
two queries constantly outstanding (to avoid dead time between one response
and next request), we measured the number of replies per second from the
ethdev xstats call.
* with a 2.3 GHz Xeon system, we got 3,500 responses per second, with 146
stats per response, giving a total of >500k stats per second encoded and
transmitted.
* for those 500k stats, looking at the cpu time on the core doing the
telemetry work, ~80% of CPU time was spent inside the ixgbe driver
getting the stats from the NIC card itself.
* replacing the ixgbe NIC with a ring vdev increased the responses per
second to >100k, though with only 13 stats per response this time, giving
1.3M stats per second.
* Splitting the existing xstats call in this RFC into separate xstat
names and xstat values calls (something I think is a good idea to do
generally), and only calling the xstat values call each time, gives
further perf increases to 163k responses per second.
Overall so, at least on the json generation side, it appears we can do
things rather quickly, though I admit that we did not look into the parsing
cost on the other side.
All that being said, however, I do understand your point about having
everything work internally in json - something that ties in with Thomas
concern about having flexibility. Therefore, while we will upstream a v3
very shortly with the few incremental comments on v2, we can thereafter
look to switch the internal communication between callbacks and telemetry
library to use a regular data structure, and then leave the json encoding
to the library itself just before output. That would:
a) allow the addition of other output types in the future without needing
new callbacks.
b) allow more flexibility for integrating with a future one-IPC mechanism
for DPDK.
I hope this option will resolve most concerns and allow for a 20.05
integration.
Regards.
/Bruce
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v7 03/10] ring: introduce RTS ring mode
2020-04-20 12:28 3% ` [dpdk-dev] [PATCH v7 00/10] New sync modes for ring Konstantin Ananyev
2020-04-20 12:28 9% ` [dpdk-dev] [PATCH v7 02/10] ring: prepare ring to allow new sync schemes Konstantin Ananyev
@ 2020-04-20 12:28 1% ` Konstantin Ananyev
2020-04-21 11:31 0% ` [dpdk-dev] [PATCH v7 00/10] New sync modes for ring David Marchand
2 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-20 12:28 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
Introduce relaxed tail sync (RTS) mode for MT ring synchronization.
Aim to reduce stall times in case when ring is used on
overcommited cpus (multiple active threads on the same cpu).
The main difference from original MP/MC algorithm is that
tail value is increased not by every thread that finished enqueue/dequeue,
but only by the last one.
That allows threads to avoid spinning on ring tail value,
leaving actual tail value change to the last thread in the update queue.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
---
This patch depends on following patch:
"meson: add libatomic as a global dependency for i686 clang"
(http://patches.dpdk.org/patch/68876/)
check-abi.sh reports what I believe is a false-positive about
ring cons/prod changes. As a workaround, devtools/libabigail.abignore is
updated to suppress *struct ring* related errors.
devtools/libabigail.abignore | 7 +
doc/guides/rel_notes/release_20_05.rst | 7 +
lib/librte_ring/Makefile | 4 +-
lib/librte_ring/meson.build | 7 +-
lib/librte_ring/rte_ring.c | 100 +++++-
lib/librte_ring/rte_ring.h | 118 +++++--
lib/librte_ring/rte_ring_core.h | 36 +-
lib/librte_ring/rte_ring_elem.h | 114 ++++++-
lib/librte_ring/rte_ring_rts.h | 439 +++++++++++++++++++++++++
lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
10 files changed, 963 insertions(+), 48 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_rts.h
create mode 100644 lib/librte_ring/rte_ring_rts_c11_mem.h
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index a59df8f13..cd86d89ca 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -11,3 +11,10 @@
type_kind = enum
name = rte_crypto_asym_xform_type
changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
+; Ignore updates of ring prod/cons
+[suppress_type]
+ type_kind = struct
+ name = rte_ring
+[suppress_type]
+ type_kind = struct
+ name = rte_event_ring
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index 184967844..eedf960d0 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -81,6 +81,13 @@ New Features
by making use of the event device capabilities. The event mode currently supports
only inline IPsec protocol offload.
+* **New synchronization modes for rte_ring.**
+
+ Introduced new optional MT synchronization mode for rte_ring:
+ Relaxed Tail Sync (RTS). With this mode selected, rte_ring shows
+ significant improvements for average enqueue/dequeue times on
+ overcommitted systems.
+
Removed Items
-------------
diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile
index 6572768c9..04e446e37 100644
--- a/lib/librte_ring/Makefile
+++ b/lib/librte_ring/Makefile
@@ -19,6 +19,8 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
rte_ring_core.h \
rte_ring_elem.h \
rte_ring_generic.h \
- rte_ring_c11_mem.h
+ rte_ring_c11_mem.h \
+ rte_ring_rts.h \
+ rte_ring_rts_c11_mem.h
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build
index c656781da..a95598032 100644
--- a/lib/librte_ring/meson.build
+++ b/lib/librte_ring/meson.build
@@ -6,4 +6,9 @@ headers = files('rte_ring.h',
'rte_ring_core.h',
'rte_ring_elem.h',
'rte_ring_c11_mem.h',
- 'rte_ring_generic.h')
+ 'rte_ring_generic.h',
+ 'rte_ring_rts.h',
+ 'rte_ring_rts_c11_mem.h')
+
+# rte_ring_create_elem and rte_ring_get_memsize_elem are experimental
+allow_experimental_apis = true
diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
index fa5733907..222eec0fb 100644
--- a/lib/librte_ring/rte_ring.c
+++ b/lib/librte_ring/rte_ring.c
@@ -45,6 +45,9 @@ EAL_REGISTER_TAILQ(rte_ring_tailq)
/* true if x is a power of 2 */
#define POWEROF2(x) ((((x)-1) & (x)) == 0)
+/* by default set head/tail distance as 1/8 of ring capacity */
+#define HTD_MAX_DEF 8
+
/* return the size of memory occupied by a ring */
ssize_t
rte_ring_get_memsize_elem(unsigned int esize, unsigned int count)
@@ -79,11 +82,84 @@ rte_ring_get_memsize(unsigned int count)
return rte_ring_get_memsize_elem(sizeof(void *), count);
}
+/*
+ * internal helper function to reset prod/cons head-tail values.
+ */
+static void
+reset_headtail(void *p)
+{
+ struct rte_ring_headtail *ht;
+ struct rte_ring_rts_headtail *ht_rts;
+
+ ht = p;
+ ht_rts = p;
+
+ switch (ht->sync_type) {
+ case RTE_RING_SYNC_MT:
+ case RTE_RING_SYNC_ST:
+ ht->head = 0;
+ ht->tail = 0;
+ break;
+ case RTE_RING_SYNC_MT_RTS:
+ ht_rts->head.raw = 0;
+ ht_rts->tail.raw = 0;
+ break;
+ default:
+ /* unknown sync mode */
+ RTE_ASSERT(0);
+ }
+}
+
void
rte_ring_reset(struct rte_ring *r)
{
- r->prod.head = r->cons.head = 0;
- r->prod.tail = r->cons.tail = 0;
+ reset_headtail(&r->prod);
+ reset_headtail(&r->cons);
+}
+
+/*
+ * helper function, calculates sync_type values for prod and cons
+ * based on input flags. Returns zero at success or negative
+ * errno value otherwise.
+ */
+static int
+get_sync_type(uint32_t flags, enum rte_ring_sync_type *prod_st,
+ enum rte_ring_sync_type *cons_st)
+{
+ static const uint32_t prod_st_flags =
+ (RING_F_SP_ENQ | RING_F_MP_RTS_ENQ);
+ static const uint32_t cons_st_flags =
+ (RING_F_SC_DEQ | RING_F_MC_RTS_DEQ);
+
+ switch (flags & prod_st_flags) {
+ case 0:
+ *prod_st = RTE_RING_SYNC_MT;
+ break;
+ case RING_F_SP_ENQ:
+ *prod_st = RTE_RING_SYNC_ST;
+ break;
+ case RING_F_MP_RTS_ENQ:
+ *prod_st = RTE_RING_SYNC_MT_RTS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (flags & cons_st_flags) {
+ case 0:
+ *cons_st = RTE_RING_SYNC_MT;
+ break;
+ case RING_F_SC_DEQ:
+ *cons_st = RTE_RING_SYNC_ST;
+ break;
+ case RING_F_MC_RTS_DEQ:
+ *cons_st = RTE_RING_SYNC_MT_RTS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
}
int
@@ -100,16 +176,20 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
RTE_BUILD_BUG_ON((offsetof(struct rte_ring, prod) &
RTE_CACHE_LINE_MASK) != 0);
+ RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, sync_type) !=
+ offsetof(struct rte_ring_rts_headtail, sync_type));
+ RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, tail) !=
+ offsetof(struct rte_ring_rts_headtail, tail.val.pos));
+
/* init the ring structure */
memset(r, 0, sizeof(*r));
ret = strlcpy(r->name, name, sizeof(r->name));
if (ret < 0 || ret >= (int)sizeof(r->name))
return -ENAMETOOLONG;
r->flags = flags;
- r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
- RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
- r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
- RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
+ ret = get_sync_type(flags, &r->prod.sync_type, &r->cons.sync_type);
+ if (ret != 0)
+ return ret;
if (flags & RING_F_EXACT_SZ) {
r->size = rte_align32pow2(count + 1);
@@ -126,8 +206,12 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
r->mask = count - 1;
r->capacity = r->mask;
}
- r->prod.head = r->cons.head = 0;
- r->prod.tail = r->cons.tail = 0;
+
+ /* set default values for head-tail distance */
+ if (flags & RING_F_MP_RTS_ENQ)
+ rte_ring_set_prod_htd_max(r, r->capacity / HTD_MAX_DEF);
+ if (flags & RING_F_MC_RTS_DEQ)
+ rte_ring_set_cons_htd_max(r, r->capacity / HTD_MAX_DEF);
return 0;
}
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index 35ee4491c..c42e1cfc4 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright (c) 2010-2017 Intel Corporation
+ * Copyright (c) 2010-2020 Intel Corporation
* Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
* All rights reserved.
* Derived from FreeBSD's bufring.h
@@ -79,12 +79,24 @@ ssize_t rte_ring_get_memsize(unsigned count);
* The number of elements in the ring (must be a power of 2).
* @param flags
* An OR of the following:
- * - RING_F_SP_ENQ: If this flag is set, the default behavior when
- * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
- * is "single-producer". Otherwise, it is "multi-producers".
- * - RING_F_SC_DEQ: If this flag is set, the default behavior when
- * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
- * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - One of mutually exclusive flags that define producer behavior:
+ * - RING_F_SP_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "single-producer".
+ * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "multi-producer RTS mode".
+ * If none of these flags is set, then default "multi-producer"
+ * behavior is selected.
+ * - One of mutually exclusive flags that define consumer behavior:
+ * - RING_F_SC_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "multi-consumer RTS mode".
+ * If none of these flags is set, then default "multi-consumer"
+ * behavior is selected.
* @return
* 0 on success, or a negative value on error.
*/
@@ -114,12 +126,24 @@ int rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
* constraint for the reserved zone.
* @param flags
* An OR of the following:
- * - RING_F_SP_ENQ: If this flag is set, the default behavior when
- * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
- * is "single-producer". Otherwise, it is "multi-producers".
- * - RING_F_SC_DEQ: If this flag is set, the default behavior when
- * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
- * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - One of mutually exclusive flags that define producer behavior:
+ * - RING_F_SP_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "single-producer".
+ * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "multi-producer RTS mode".
+ * If none of these flags is set, then default "multi-producer"
+ * behavior is selected.
+ * - One of mutually exclusive flags that define consumer behavior:
+ * - RING_F_SC_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "multi-consumer RTS mode".
+ * If none of these flags is set, then default "multi-consumer"
+ * behavior is selected.
* @return
* On success, the pointer to the new allocated ring. NULL on error with
* rte_errno set appropriately. Possible errno values include:
@@ -389,8 +413,21 @@ static __rte_always_inline unsigned int
rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_bulk(r, obj_table, n, free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_bulk(r, obj_table, n, free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_bulk(r, obj_table, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -524,8 +561,20 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
unsigned int *available)
{
- return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_bulk(r, obj_table, n, available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_bulk(r, obj_table, n, available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_bulk(r, obj_table, n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -845,8 +894,21 @@ static __rte_always_inline unsigned
rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
- r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_burst(r, obj_table, n, free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_burst(r, obj_table, n, free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_burst(r, obj_table, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -925,9 +987,21 @@ static __rte_always_inline unsigned
rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_burst(r, obj_table, n, available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_burst(r, obj_table, n, available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_burst(r, obj_table, n,
+ available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
#ifdef __cplusplus
diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
index d9cef763f..bd21fa535 100644
--- a/lib/librte_ring/rte_ring_core.h
+++ b/lib/librte_ring/rte_ring_core.h
@@ -57,6 +57,9 @@ enum rte_ring_queue_behavior {
enum rte_ring_sync_type {
RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
RTE_RING_SYNC_ST, /**< single thread only */
+#ifdef ALLOW_EXPERIMENTAL_API
+ RTE_RING_SYNC_MT_RTS, /**< multi-thread relaxed tail sync */
+#endif
};
/**
@@ -76,6 +79,22 @@ struct rte_ring_headtail {
};
};
+union __rte_ring_rts_poscnt {
+ /** raw 8B value to read/write *cnt* and *pos* as one atomic op */
+ uint64_t raw __rte_aligned(8);
+ struct {
+ uint32_t cnt; /**< head/tail reference counter */
+ uint32_t pos; /**< head/tail position */
+ } val;
+};
+
+struct rte_ring_rts_headtail {
+ volatile union __rte_ring_rts_poscnt tail;
+ enum rte_ring_sync_type sync_type; /**< sync type of prod/cons */
+ uint32_t htd_max; /**< max allowed distance between head/tail */
+ volatile union __rte_ring_rts_poscnt head;
+};
+
/**
* An RTE ring structure.
*
@@ -104,11 +123,21 @@ struct rte_ring {
char pad0 __rte_cache_aligned; /**< empty cache line */
/** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail prod;
+ struct rte_ring_rts_headtail rts_prod;
+ } __rte_cache_aligned;
+
char pad1 __rte_cache_aligned; /**< empty cache line */
/** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail cons;
+ struct rte_ring_rts_headtail rts_cons;
+ } __rte_cache_aligned;
+
char pad2 __rte_cache_aligned; /**< empty cache line */
};
@@ -125,6 +154,9 @@ struct rte_ring {
#define RING_F_EXACT_SZ 0x0004
#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
+#define RING_F_MP_RTS_ENQ 0x0008 /**< The default enqueue is "MP RTS". */
+#define RING_F_MC_RTS_DEQ 0x0010 /**< The default dequeue is "MC RTS". */
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
index 7406c0b0f..4030753b6 100644
--- a/lib/librte_ring/rte_ring_elem.h
+++ b/lib/librte_ring/rte_ring_elem.h
@@ -74,12 +74,24 @@ ssize_t rte_ring_get_memsize_elem(unsigned int esize, unsigned int count);
* constraint for the reserved zone.
* @param flags
* An OR of the following:
- * - RING_F_SP_ENQ: If this flag is set, the default behavior when
- * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
- * is "single-producer". Otherwise, it is "multi-producers".
- * - RING_F_SC_DEQ: If this flag is set, the default behavior when
- * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
- * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - One of mutually exclusive flags that define producer behavior:
+ * - RING_F_SP_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "single-producer".
+ * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "multi-producer RTS mode".
+ * If none of these flags is set, then default "multi-producer"
+ * behavior is selected.
+ * - One of mutually exclusive flags that define consumer behavior:
+ * - RING_F_SC_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "multi-consumer RTS mode".
+ * If none of these flags is set, then default "multi-consumer"
+ * behavior is selected.
* @return
* On success, the pointer to the new allocated ring. NULL on error with
* rte_errno set appropriately. Possible errno values include:
@@ -528,6 +540,10 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
}
+#ifdef ALLOW_EXPERIMENTAL_API
+#include <rte_ring_rts.h>
+#endif
+
/**
* Enqueue several objects on a ring.
*
@@ -557,6 +573,26 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_FIXED, r->prod.sync_type, free_space);
+
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (free_space != NULL)
+ *free_space = 0;
+ return 0;
}
/**
@@ -661,7 +697,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
}
/**
@@ -719,8 +755,25 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
+ available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
+ available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize,
+ n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (available != NULL)
+ *available = 0;
+ return 0;
}
/**
@@ -887,8 +940,25 @@ static __rte_always_inline unsigned
rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n,
+ free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
+ free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize,
+ n, free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (free_space != NULL)
+ *free_space = 0;
+ return 0;
}
/**
@@ -979,9 +1049,25 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
+ available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
+ available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize,
+ n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (available != NULL)
+ *available = 0;
+ return 0;
}
#include <rte_ring.h>
diff --git a/lib/librte_ring/rte_ring_rts.h b/lib/librte_ring/rte_ring_rts.h
new file mode 100644
index 000000000..8ced07096
--- /dev/null
+++ b/lib/librte_ring/rte_ring_rts.h
@@ -0,0 +1,439 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_RTS_H_
+#define _RTE_RING_RTS_H_
+
+/**
+ * @file rte_ring_rts.h
+ * @b EXPERIMENTAL: this API may change without prior notice
+ * It is not recommended to include this file directly.
+ * Please include <rte_ring.h> instead.
+ *
+ * Contains functions for Relaxed Tail Sync (RTS) ring mode.
+ * The main idea remains the same as for our original MP/MC synchronization
+ * mechanism.
+ * The main difference is that tail value is increased not
+ * by every thread that finished enqueue/dequeue,
+ * but only by the current last one doing enqueue/dequeue.
+ * That allows threads to skip spinning on tail value,
+ * leaving actual tail value change to last thread at a given instance.
+ * RTS requires 2 64-bit CAS for each enqueue(/dequeue) operation:
+ * one for head update, second for tail update.
+ * As a gain it allows thread to avoid spinning/waiting on tail value.
+ * In comparision original MP/MC algorithm requires one 32-bit CAS
+ * for head update and waiting/spinning on tail value.
+ *
+ * Brief outline:
+ * - introduce update counter (cnt) for both head and tail.
+ * - increment head.cnt for each head.value update
+ * - write head.value and head.cnt atomically (64-bit CAS)
+ * - move tail.value ahead only when tail.cnt + 1 == head.cnt
+ * (indicating that this is the last thread updating the tail)
+ * - increment tail.cnt when each enqueue/dequeue op finishes
+ * (no matter if tail.value going to change or not)
+ * - write tail.value and tail.cnt atomically (64-bit CAS)
+ *
+ * To avoid producer/consumer starvation:
+ * - limit max allowed distance between head and tail value (HTD_MAX).
+ * I.E. thread is allowed to proceed with changing head.value,
+ * only when: head.value - tail.value <= HTD_MAX
+ * HTD_MAX is an optional parameter.
+ * With HTD_MAX == 0 we'll have fully serialized ring -
+ * i.e. only one thread at a time will be able to enqueue/dequeue
+ * to/from the ring.
+ * With HTD_MAX >= ring.capacity - no limitation.
+ * By default HTD_MAX == ring.capacity / 8.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_ring_rts_c11_mem.h>
+
+/**
+ * @internal Enqueue several objects on the RTS ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Enqueue as many items as possible from ring
+ * @param free_space
+ * returns the amount of space after the enqueue operation has finished
+ * @return
+ * Actual number of objects enqueued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_do_rts_enqueue_elem(struct rte_ring *r, const void *obj_table,
+ uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
+ uint32_t *free_space)
+{
+ uint32_t free, head;
+
+ n = __rte_ring_rts_move_prod_head(r, n, behavior, &head, &free);
+
+ if (n != 0) {
+ __rte_ring_enqueue_elems(r, head, obj_table, esize, n);
+ __rte_ring_rts_update_tail(&r->rts_prod);
+ }
+
+ if (free_space != NULL)
+ *free_space = free - n;
+ return n;
+}
+
+/**
+ * @internal Dequeue several objects from the RTS ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to pull from the ring.
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Dequeue as many items as possible from ring
+ * @param available
+ * returns the number of remaining ring entries after the dequeue has finished
+ * @return
+ * - Actual number of objects dequeued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_do_rts_dequeue_elem(struct rte_ring *r, void *obj_table,
+ uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
+ uint32_t *available)
+{
+ uint32_t entries, head;
+
+ n = __rte_ring_rts_move_cons_head(r, n, behavior, &head, &entries);
+
+ if (n != 0) {
+ __rte_ring_dequeue_elems(r, head, obj_table, esize, n);
+ __rte_ring_rts_update_tail(&r->rts_cons);
+ }
+
+ if (available != NULL)
+ *available = entries - n;
+ return n;
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * The number of objects enqueued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mp_rts_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *free_space)
+{
+ return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_FIXED, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects that will be filled.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * The number of objects dequeued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mc_rts_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *available)
+{
+ return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_FIXED, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * - n: Actual number of objects enqueued.
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mp_rts_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *free_space)
+{
+ return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_VARIABLE, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ * When the requested objects are more than the available objects,
+ * only dequeue the actual number of objects.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects that will be filled.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * - n: Actual number of objects dequeued, 0 if ring is empty
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mc_rts_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *available)
+{
+ return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_VARIABLE, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects).
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * The number of objects enqueued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mp_rts_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
+ unsigned int n, unsigned int *free_space)
+{
+ return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table,
+ sizeof(uintptr_t), n, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects) that will be filled.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * The number of objects dequeued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mc_rts_dequeue_bulk(struct rte_ring *r, void **obj_table,
+ unsigned int n, unsigned int *available)
+{
+ return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table,
+ sizeof(uintptr_t), n, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects).
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * - n: Actual number of objects enqueued.
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mp_rts_enqueue_burst(struct rte_ring *r, void * const *obj_table,
+ unsigned int n, unsigned int *free_space)
+{
+ return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table,
+ sizeof(uintptr_t), n, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ * When the requested objects are more than the available objects,
+ * only dequeue the actual number of objects.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects) that will be filled.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * - n: Actual number of objects dequeued, 0 if ring is empty
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mc_rts_dequeue_burst(struct rte_ring *r, void **obj_table,
+ unsigned int n, unsigned int *available)
+{
+ return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table,
+ sizeof(uintptr_t), n, available);
+}
+
+/**
+ * Return producer max Head-Tail-Distance (HTD).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Producer HTD value, if producer is set in appropriate sync mode,
+ * or UINT32_MAX otherwise.
+ */
+__rte_experimental
+static inline uint32_t
+rte_ring_get_prod_htd_max(const struct rte_ring *r)
+{
+ if (r->prod.sync_type == RTE_RING_SYNC_MT_RTS)
+ return r->rts_prod.htd_max;
+ return UINT32_MAX;
+}
+
+/**
+ * Set producer max Head-Tail-Distance (HTD).
+ * Note that producer has to use appropriate sync mode (RTS).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param v
+ * new HTD value to setup.
+ * @return
+ * Zero on success, or negative error code otherwise.
+ */
+__rte_experimental
+static inline int
+rte_ring_set_prod_htd_max(struct rte_ring *r, uint32_t v)
+{
+ if (r->prod.sync_type != RTE_RING_SYNC_MT_RTS)
+ return -ENOTSUP;
+
+ r->rts_prod.htd_max = v;
+ return 0;
+}
+
+/**
+ * Return consumer max Head-Tail-Distance (HTD).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Consumer HTD value, if consumer is set in appropriate sync mode,
+ * or UINT32_MAX otherwise.
+ */
+__rte_experimental
+static inline uint32_t
+rte_ring_get_cons_htd_max(const struct rte_ring *r)
+{
+ if (r->cons.sync_type == RTE_RING_SYNC_MT_RTS)
+ return r->rts_cons.htd_max;
+ return UINT32_MAX;
+}
+
+/**
+ * Set consumer max Head-Tail-Distance (HTD).
+ * Note that consumer has to use appropriate sync mode (RTS).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param v
+ * new HTD value to setup.
+ * @return
+ * Zero on success, or negative error code otherwise.
+ */
+__rte_experimental
+static inline int
+rte_ring_set_cons_htd_max(struct rte_ring *r, uint32_t v)
+{
+ if (r->cons.sync_type != RTE_RING_SYNC_MT_RTS)
+ return -ENOTSUP;
+
+ r->rts_cons.htd_max = v;
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RING_RTS_H_ */
diff --git a/lib/librte_ring/rte_ring_rts_c11_mem.h b/lib/librte_ring/rte_ring_rts_c11_mem.h
new file mode 100644
index 000000000..327f22796
--- /dev/null
+++ b/lib/librte_ring/rte_ring_rts_c11_mem.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_RTS_C11_MEM_H_
+#define _RTE_RING_RTS_C11_MEM_H_
+
+/**
+ * @file rte_ring_rts_c11_mem.h
+ * It is not recommended to include this file directly,
+ * include <rte_ring.h> instead.
+ * Contains internal helper functions for Relaxed Tail Sync (RTS) ring mode.
+ * For more information please refer to <rte_ring_rts.h>.
+ */
+
+/**
+ * @internal This function updates tail values.
+ */
+static __rte_always_inline void
+__rte_ring_rts_update_tail(struct rte_ring_rts_headtail *ht)
+{
+ union __rte_ring_rts_poscnt h, ot, nt;
+
+ /*
+ * If there are other enqueues/dequeues in progress that
+ * might preceded us, then don't update tail with new value.
+ */
+
+ ot.raw = __atomic_load_n(&ht->tail.raw, __ATOMIC_ACQUIRE);
+
+ do {
+ /* on 32-bit systems we have to do atomic read here */
+ h.raw = __atomic_load_n(&ht->head.raw, __ATOMIC_RELAXED);
+
+ nt.raw = ot.raw;
+ if (++nt.val.cnt == h.val.cnt)
+ nt.val.pos = h.val.pos;
+
+ } while (__atomic_compare_exchange_n(&ht->tail.raw, &ot.raw, nt.raw,
+ 0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE) == 0);
+}
+
+/**
+ * @internal This function waits till head/tail distance wouldn't
+ * exceed pre-defined max value.
+ */
+static __rte_always_inline void
+__rte_ring_rts_head_wait(const struct rte_ring_rts_headtail *ht,
+ union __rte_ring_rts_poscnt *h)
+{
+ uint32_t max;
+
+ max = ht->htd_max;
+
+ while (h->val.pos - ht->tail.val.pos > max) {
+ rte_pause();
+ h->raw = __atomic_load_n(&ht->head.raw, __ATOMIC_ACQUIRE);
+ }
+}
+
+/**
+ * @internal This function updates the producer head for enqueue.
+ */
+static __rte_always_inline uint32_t
+__rte_ring_rts_move_prod_head(struct rte_ring *r, uint32_t num,
+ enum rte_ring_queue_behavior behavior, uint32_t *old_head,
+ uint32_t *free_entries)
+{
+ uint32_t n;
+ union __rte_ring_rts_poscnt nh, oh;
+
+ const uint32_t capacity = r->capacity;
+
+ oh.raw = __atomic_load_n(&r->rts_prod.head.raw, __ATOMIC_ACQUIRE);
+
+ do {
+ /* Reset n to the initial burst count */
+ n = num;
+
+ /*
+ * wait for prod head/tail distance,
+ * make sure that we read prod head *before*
+ * reading cons tail.
+ */
+ __rte_ring_rts_head_wait(&r->rts_prod, &oh);
+
+ /*
+ * The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * *old_head > cons_tail). So 'free_entries' is always between 0
+ * and capacity (which is < size).
+ */
+ *free_entries = capacity + r->cons.tail - oh.val.pos;
+
+ /* check that we have enough room in ring */
+ if (unlikely(n > *free_entries))
+ n = (behavior == RTE_RING_QUEUE_FIXED) ?
+ 0 : *free_entries;
+
+ if (n == 0)
+ break;
+
+ nh.val.pos = oh.val.pos + n;
+ nh.val.cnt = oh.val.cnt + 1;
+
+ /*
+ * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
+ * - OOO reads of cons tail value
+ * - OOO copy of elems to the ring
+ */
+ } while (__atomic_compare_exchange_n(&r->rts_prod.head.raw,
+ &oh.raw, nh.raw,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
+
+ *old_head = oh.val.pos;
+ return n;
+}
+
+/**
+ * @internal This function updates the consumer head for dequeue
+ */
+static __rte_always_inline unsigned int
+__rte_ring_rts_move_cons_head(struct rte_ring *r, uint32_t num,
+ enum rte_ring_queue_behavior behavior, uint32_t *old_head,
+ uint32_t *entries)
+{
+ uint32_t n;
+ union __rte_ring_rts_poscnt nh, oh;
+
+ oh.raw = __atomic_load_n(&r->rts_cons.head.raw, __ATOMIC_ACQUIRE);
+
+ /* move cons.head atomically */
+ do {
+ /* Restore n as it may change every loop */
+ n = num;
+
+ /*
+ * wait for cons head/tail distance,
+ * make sure that we read cons head *before*
+ * reading prod tail.
+ */
+ __rte_ring_rts_head_wait(&r->rts_cons, &oh);
+
+ /* The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * cons_head > prod_tail). So 'entries' is always between 0
+ * and size(ring)-1.
+ */
+ *entries = r->prod.tail - oh.val.pos;
+
+ /* Set the actual entries for dequeue */
+ if (n > *entries)
+ n = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : *entries;
+
+ if (unlikely(n == 0))
+ break;
+
+ nh.val.pos = oh.val.pos + n;
+ nh.val.cnt = oh.val.cnt + 1;
+
+ /*
+ * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
+ * - OOO reads of prod tail value
+ * - OOO copy of elems from the ring
+ */
+ } while (__atomic_compare_exchange_n(&r->rts_cons.head.raw,
+ &oh.raw, nh.raw,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
+
+ *old_head = oh.val.pos;
+ return n;
+}
+
+#endif /* _RTE_RING_RTS_C11_MEM_H_ */
--
2.17.1
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v7 02/10] ring: prepare ring to allow new sync schemes
2020-04-20 12:28 3% ` [dpdk-dev] [PATCH v7 00/10] New sync modes for ring Konstantin Ananyev
@ 2020-04-20 12:28 9% ` Konstantin Ananyev
2020-04-20 12:28 1% ` [dpdk-dev] [PATCH v7 03/10] ring: introduce RTS ring mode Konstantin Ananyev
2020-04-21 11:31 0% ` [dpdk-dev] [PATCH v7 00/10] New sync modes for ring David Marchand
2 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-20 12:28 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
To make these preparations two main things are done:
- Change from *single* to *sync_type* to allow different
synchronisation schemes to be applied.
Mark *single* as deprecated in comments.
Add new functions to allow user to query ring sync types.
Replace direct access to *single* with appropriate function call.
- Move actual rte_ring and related structures definitions into a
separate file: <rte_ring_core.h>. It allows to refer contents
of <rte_ring_elem.h> from <rte_ring.h> without introducing a
circular dependency.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
---
app/test/test_pdump.c | 6 +-
lib/librte_pdump/rte_pdump.c | 2 +-
lib/librte_port/rte_port_ring.c | 12 +--
lib/librte_ring/Makefile | 1 +
lib/librte_ring/meson.build | 1 +
lib/librte_ring/rte_ring.c | 6 +-
lib/librte_ring/rte_ring.h | 170 ++++++++++++++------------------
lib/librte_ring/rte_ring_core.h | 132 +++++++++++++++++++++++++
lib/librte_ring/rte_ring_elem.h | 42 +++-----
9 files changed, 234 insertions(+), 138 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_core.h
diff --git a/app/test/test_pdump.c b/app/test/test_pdump.c
index ad183184c..6a1180bcb 100644
--- a/app/test/test_pdump.c
+++ b/app/test/test_pdump.c
@@ -57,8 +57,7 @@ run_pdump_client_tests(void)
if (ret < 0)
return -1;
mp->flags = 0x0000;
- ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
+ ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(), 0);
if (ring_client == NULL) {
printf("rte_ring_create SR0 failed");
return -1;
@@ -71,9 +70,6 @@ run_pdump_client_tests(void)
}
rte_eth_dev_probing_finish(eth_dev);
- ring_client->prod.single = 0;
- ring_client->cons.single = 0;
-
printf("\n***** flags = RTE_PDUMP_FLAG_TX *****\n");
for (itr = 0; itr < NUM_ITR; itr++) {
diff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c
index 8a01ac510..f96709f95 100644
--- a/lib/librte_pdump/rte_pdump.c
+++ b/lib/librte_pdump/rte_pdump.c
@@ -380,7 +380,7 @@ pdump_validate_ring_mp(struct rte_ring *ring, struct rte_mempool *mp)
rte_errno = EINVAL;
return -1;
}
- if (ring->prod.single || ring->cons.single) {
+ if (rte_ring_is_prod_single(ring) || rte_ring_is_cons_single(ring)) {
PDUMP_LOG(ERR, "ring with either SP or SC settings"
" is not valid for pdump, should have MP and MC settings\n");
rte_errno = EINVAL;
diff --git a/lib/librte_port/rte_port_ring.c b/lib/librte_port/rte_port_ring.c
index 47fcdd06a..52b2d8e55 100644
--- a/lib/librte_port/rte_port_ring.c
+++ b/lib/librte_port/rte_port_ring.c
@@ -44,8 +44,8 @@ rte_port_ring_reader_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->cons.single && is_multi) ||
- (!(conf->ring->cons.single) && !is_multi)) {
+ (rte_ring_is_cons_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
}
@@ -171,8 +171,8 @@ rte_port_ring_writer_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->prod.single && is_multi) ||
- (!(conf->ring->prod.single) && !is_multi) ||
+ (rte_ring_is_prod_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
(conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
@@ -440,8 +440,8 @@ rte_port_ring_writer_nodrop_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->prod.single && is_multi) ||
- (!(conf->ring->prod.single) && !is_multi) ||
+ (rte_ring_is_prod_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
(conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile
index 28368e6d1..6572768c9 100644
--- a/lib/librte_ring/Makefile
+++ b/lib/librte_ring/Makefile
@@ -16,6 +16,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_RING) := rte_ring.c
# install includes
SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
+ rte_ring_core.h \
rte_ring_elem.h \
rte_ring_generic.h \
rte_ring_c11_mem.h
diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build
index 05402e4f0..c656781da 100644
--- a/lib/librte_ring/meson.build
+++ b/lib/librte_ring/meson.build
@@ -3,6 +3,7 @@
sources = files('rte_ring.c')
headers = files('rte_ring.h',
+ 'rte_ring_core.h',
'rte_ring_elem.h',
'rte_ring_c11_mem.h',
'rte_ring_generic.h')
diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
index 77e5de099..fa5733907 100644
--- a/lib/librte_ring/rte_ring.c
+++ b/lib/librte_ring/rte_ring.c
@@ -106,8 +106,10 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
if (ret < 0 || ret >= (int)sizeof(r->name))
return -ENAMETOOLONG;
r->flags = flags;
- r->prod.single = (flags & RING_F_SP_ENQ) ? __IS_SP : __IS_MP;
- r->cons.single = (flags & RING_F_SC_DEQ) ? __IS_SC : __IS_MC;
+ r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
+ RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
+ r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
+ RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
if (flags & RING_F_EXACT_SZ) {
r->size = rte_align32pow2(count + 1);
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index 18fc5d845..35ee4491c 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -36,91 +36,7 @@
extern "C" {
#endif
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/queue.h>
-#include <errno.h>
-#include <rte_common.h>
-#include <rte_config.h>
-#include <rte_memory.h>
-#include <rte_lcore.h>
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_memzone.h>
-#include <rte_pause.h>
-
-#define RTE_TAILQ_RING_NAME "RTE_RING"
-
-enum rte_ring_queue_behavior {
- RTE_RING_QUEUE_FIXED = 0, /* Enq/Deq a fixed number of items from a ring */
- RTE_RING_QUEUE_VARIABLE /* Enq/Deq as many items as possible from ring */
-};
-
-#define RTE_RING_MZ_PREFIX "RG_"
-/** The maximum length of a ring name. */
-#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
- sizeof(RTE_RING_MZ_PREFIX) + 1)
-
-/* structure to hold a pair of head/tail values and other metadata */
-struct rte_ring_headtail {
- volatile uint32_t head; /**< Prod/consumer head. */
- volatile uint32_t tail; /**< Prod/consumer tail. */
- uint32_t single; /**< True if single prod/cons */
-};
-
-/**
- * An RTE ring structure.
- *
- * The producer and the consumer have a head and a tail index. The particularity
- * of these index is that they are not between 0 and size(ring). These indexes
- * are between 0 and 2^32, and we mask their value when we access the ring[]
- * field. Thanks to this assumption, we can do subtractions between 2 index
- * values in a modulo-32bit base: that's why the overflow of the indexes is not
- * a problem.
- */
-struct rte_ring {
- /*
- * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
- * compatibility requirements, it could be changed to RTE_RING_NAMESIZE
- * next time the ABI changes
- */
- char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned; /**< Name of the ring. */
- int flags; /**< Flags supplied at creation. */
- const struct rte_memzone *memzone;
- /**< Memzone, if any, containing the rte_ring */
- uint32_t size; /**< Size of ring. */
- uint32_t mask; /**< Mask (size-1) of ring. */
- uint32_t capacity; /**< Usable size of ring */
-
- char pad0 __rte_cache_aligned; /**< empty cache line */
-
- /** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
- char pad1 __rte_cache_aligned; /**< empty cache line */
-
- /** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
- char pad2 __rte_cache_aligned; /**< empty cache line */
-};
-
-#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
-#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
-/**
- * Ring is to hold exactly requested number of entries.
- * Without this flag set, the ring size requested must be a power of 2, and the
- * usable space will be that size - 1. With the flag, the requested size will
- * be rounded up to the next power of two, but the usable space will be exactly
- * that requested. Worst case, if a power-of-2 size is requested, half the
- * ring space will be wasted.
- */
-#define RING_F_EXACT_SZ 0x0004
-#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
-
-/* @internal defines for passing to the enqueue dequeue worker functions */
-#define __IS_SP 1
-#define __IS_MP 0
-#define __IS_SC 1
-#define __IS_MC 0
+#include <rte_ring_core.h>
/**
* Calculate the memory size needed for a ring
@@ -420,7 +336,7 @@ rte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_MP, free_space);
+ RTE_RING_SYNC_MT, free_space);
}
/**
@@ -443,9 +359,13 @@ rte_ring_sp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_SP, free_space);
+ RTE_RING_SYNC_ST, free_space);
}
+#ifdef ALLOW_EXPERIMENTAL_API
+#include <rte_ring_elem.h>
+#endif
+
/**
* Enqueue several objects on a ring.
*
@@ -470,7 +390,7 @@ rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->prod.single, free_space);
+ r->prod.sync_type, free_space);
}
/**
@@ -554,7 +474,7 @@ rte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_MC, available);
+ RTE_RING_SYNC_MT, available);
}
/**
@@ -578,7 +498,7 @@ rte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_SC, available);
+ RTE_RING_SYNC_ST, available);
}
/**
@@ -605,7 +525,7 @@ rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
/**
@@ -777,6 +697,62 @@ rte_ring_get_capacity(const struct rte_ring *r)
return r->capacity;
}
+/**
+ * Return sync type used by producer in the ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Producer sync type value.
+ */
+static inline enum rte_ring_sync_type
+rte_ring_get_prod_sync_type(const struct rte_ring *r)
+{
+ return r->prod.sync_type;
+}
+
+/**
+ * Check is the ring for single producer.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * true if ring is SP, zero otherwise.
+ */
+static inline int
+rte_ring_is_prod_single(const struct rte_ring *r)
+{
+ return (rte_ring_get_prod_sync_type(r) == RTE_RING_SYNC_ST);
+}
+
+/**
+ * Return sync type used by consumer in the ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Consumer sync type value.
+ */
+static inline enum rte_ring_sync_type
+rte_ring_get_cons_sync_type(const struct rte_ring *r)
+{
+ return r->cons.sync_type;
+}
+
+/**
+ * Check is the ring for single consumer.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * true if ring is SC, zero otherwise.
+ */
+static inline int
+rte_ring_is_cons_single(const struct rte_ring *r)
+{
+ return (rte_ring_get_cons_sync_type(r) == RTE_RING_SYNC_ST);
+}
+
/**
* Dump the status of all rings on the console
*
@@ -820,7 +796,7 @@ rte_ring_mp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -843,7 +819,7 @@ rte_ring_sp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -870,7 +846,7 @@ rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
- r->prod.single, free_space);
+ r->prod.sync_type, free_space);
}
/**
@@ -898,7 +874,7 @@ rte_ring_mc_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
}
/**
@@ -923,7 +899,7 @@ rte_ring_sc_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
}
/**
@@ -951,7 +927,7 @@ rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
{
return __rte_ring_do_dequeue(r, obj_table, n,
RTE_RING_QUEUE_VARIABLE,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
#ifdef __cplusplus
diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
new file mode 100644
index 000000000..d9cef763f
--- /dev/null
+++ b/lib/librte_ring/rte_ring_core.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_CORE_H_
+#define _RTE_RING_CORE_H_
+
+/**
+ * @file
+ * This file contains definion of RTE ring structure itself,
+ * init flags and some related macros.
+ * For majority of DPDK entities, it is not recommended to include
+ * this file directly, use include <rte_ring.h> or <rte_ring_elem.h>
+ * instead.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/queue.h>
+#include <errno.h>
+#include <rte_common.h>
+#include <rte_config.h>
+#include <rte_memory.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_memzone.h>
+#include <rte_pause.h>
+#include <rte_debug.h>
+
+#define RTE_TAILQ_RING_NAME "RTE_RING"
+
+/** enqueue/dequeue behavior types */
+enum rte_ring_queue_behavior {
+ /** Enq/Deq a fixed number of items from a ring */
+ RTE_RING_QUEUE_FIXED = 0,
+ /** Enq/Deq as many items as possible from ring */
+ RTE_RING_QUEUE_VARIABLE
+};
+
+#define RTE_RING_MZ_PREFIX "RG_"
+/** The maximum length of a ring name. */
+#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
+ sizeof(RTE_RING_MZ_PREFIX) + 1)
+
+/** prod/cons sync types */
+enum rte_ring_sync_type {
+ RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
+ RTE_RING_SYNC_ST, /**< single thread only */
+};
+
+/**
+ * structures to hold a pair of head/tail values and other metadata.
+ * Depending on sync_type format of that structure might be different,
+ * but offset for *sync_type* and *tail* values should remain the same.
+ */
+struct rte_ring_headtail {
+ volatile uint32_t head; /**< prod/consumer head. */
+ volatile uint32_t tail; /**< prod/consumer tail. */
+ RTE_STD_C11
+ union {
+ /** sync type of prod/cons */
+ enum rte_ring_sync_type sync_type;
+ /** deprecated - True if single prod/cons */
+ uint32_t single;
+ };
+};
+
+/**
+ * An RTE ring structure.
+ *
+ * The producer and the consumer have a head and a tail index. The particularity
+ * of these index is that they are not between 0 and size(ring). These indexes
+ * are between 0 and 2^32, and we mask their value when we access the ring[]
+ * field. Thanks to this assumption, we can do subtractions between 2 index
+ * values in a modulo-32bit base: that's why the overflow of the indexes is not
+ * a problem.
+ */
+struct rte_ring {
+ /*
+ * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
+ * compatibility requirements, it could be changed to RTE_RING_NAMESIZE
+ * next time the ABI changes
+ */
+ char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned;
+ /**< Name of the ring. */
+ int flags; /**< Flags supplied at creation. */
+ const struct rte_memzone *memzone;
+ /**< Memzone, if any, containing the rte_ring */
+ uint32_t size; /**< Size of ring. */
+ uint32_t mask; /**< Mask (size-1) of ring. */
+ uint32_t capacity; /**< Usable size of ring */
+
+ char pad0 __rte_cache_aligned; /**< empty cache line */
+
+ /** Ring producer status. */
+ struct rte_ring_headtail prod __rte_cache_aligned;
+ char pad1 __rte_cache_aligned; /**< empty cache line */
+
+ /** Ring consumer status. */
+ struct rte_ring_headtail cons __rte_cache_aligned;
+ char pad2 __rte_cache_aligned; /**< empty cache line */
+};
+
+#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
+#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
+/**
+ * Ring is to hold exactly requested number of entries.
+ * Without this flag set, the ring size requested must be a power of 2, and the
+ * usable space will be that size - 1. With the flag, the requested size will
+ * be rounded up to the next power of two, but the usable space will be exactly
+ * that requested. Worst case, if a power-of-2 size is requested, half the
+ * ring space will be wasted.
+ */
+#define RING_F_EXACT_SZ 0x0004
+#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RING_CORE_H_ */
diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
index 663addc73..7406c0b0f 100644
--- a/lib/librte_ring/rte_ring_elem.h
+++ b/lib/librte_ring/rte_ring_elem.h
@@ -20,21 +20,7 @@
extern "C" {
#endif
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <errno.h>
-#include <rte_common.h>
-#include <rte_config.h>
-#include <rte_memory.h>
-#include <rte_lcore.h>
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_memzone.h>
-#include <rte_pause.h>
-
-#include "rte_ring.h"
+#include <rte_ring_core.h>
/**
* @warning
@@ -510,7 +496,7 @@ rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_MP, free_space);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -539,7 +525,7 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_SP, free_space);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -570,7 +556,7 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->prod.single, free_space);
+ RTE_RING_QUEUE_FIXED, r->prod.sync_type, free_space);
}
/**
@@ -675,7 +661,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_MC, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
}
/**
@@ -703,7 +689,7 @@ rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_SC, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
}
/**
@@ -734,7 +720,7 @@ rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->cons.single, available);
+ RTE_RING_QUEUE_FIXED, r->cons.sync_type, available);
}
/**
@@ -842,7 +828,7 @@ rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -871,7 +857,7 @@ rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -902,7 +888,7 @@ rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, r->prod.single, free_space);
+ RTE_RING_QUEUE_VARIABLE, r->prod.sync_type, free_space);
}
/**
@@ -934,7 +920,7 @@ rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
}
/**
@@ -963,7 +949,7 @@ rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
}
/**
@@ -995,9 +981,11 @@ rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_VARIABLE,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
+#include <rte_ring.h>
+
#ifdef __cplusplus
}
#endif
--
2.17.1
^ permalink raw reply [relevance 9%]
* [dpdk-dev] [PATCH v7 00/10] New sync modes for ring
2020-04-20 12:11 3% ` [dpdk-dev] [PATCH v6 00/10] " Konstantin Ananyev
2020-04-20 12:11 9% ` [dpdk-dev] [PATCH v6 02/10] ring: prepare ring to allow new sync schemes Konstantin Ananyev
2020-04-20 12:11 1% ` [dpdk-dev] [PATCH v6 03/10] ring: introduce RTS ring mode Konstantin Ananyev
@ 2020-04-20 12:28 3% ` Konstantin Ananyev
2020-04-20 12:28 9% ` [dpdk-dev] [PATCH v7 02/10] ring: prepare ring to allow new sync schemes Konstantin Ananyev
` (2 more replies)
2 siblings, 3 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-20 12:28 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
This patch series depends on following patch:
"meson: add libatomic as a global dependency for i686 clang"
(http://patches.dpdk.org/patch/68876/)
V6 - V7:
1. fix checkpatch issues
V5 - V6:
1. add dependency on the external patch (-latomic for i686 clang)
2. remove unneeded code from rte_ring_generic (Honnappa)
3. extra comments for ring init/create API (Honnappa)
4. __rte prefix for internal structs (Honnappa)
5. update docs (rel notes and prog guide)
V4 - V5:
1. fix i686 clang build problem
2. fix formal API comments
V3 - V4 changes:
Address comments from Honnappa:
1. for new sync modes make legacy API wrappers around _elem_ calls
2. remove rte_ring_(hts|rts)_generic.h
3. few changes in C11 version
4. peek API - add missing functions for _elem_
5. remove _IS_SP/_IS_MP, etc. internal macros
6. fix param types (obj_table) for _elem_functions
7. fix formal API comments
8. deduplicate code for test_ring_stress
9. added functional tests for new sync modes
V2 - V3 changes:
1. few more compilation fixes (for gcc 4.8.X)
2. extra update devtools/libabigail.abignore (workaround)
V1 - V2 changes:
1. fix compilation issues
2. add C11 atomics support
3. updates devtools/libabigail.abignore (workaround)
RFC - V1 changes:
1. remove ABI brekage (at least I hope I did)
2. Add support for ring_elem
3. rework peek related API a bit
4. rework test to make it less verbose and unite all test-cases
in one command
5. add new test-case for MT peek API
These days more and more customers use(/try to use) DPDK based apps within
overcommitted systems (multiple acttive threads over same pysical cores):
VM, container deployments, etc.
One quite common problem they hit:
Lock-Holder-Preemption/Lock-Waiter-Preemption with rte_ring.
LHP is quite a common problem for spin-based sync primitives
(spin-locks, etc.) on overcommitted systems.
The situation gets much worse when some sort of
fair-locking technique is used (ticket-lock, etc.).
As now not only lock-owner but also lock-waiters scheduling
order matters a lot (LWP).
These two problems are well-known for kernel within VMs:
http://www-archive.xenproject.org/files/xensummitboston08/LHP.pdf
https://www.cs.hs-rm.de/~kaiser/events/wamos2017/Slides/selcuk.pdf
The problem with rte_ring is that while head accusion is sort of
un-fair locking, waiting on tail is very similar to ticket lock schema -
tail has to be updated in particular order.
That makes current rte_ring implementation to perform
really pure on some overcommited scenarios.
It is probably not possible to completely resolve LHP problem in
userspace only (without some kernel communication/intervention).
But removing fairness at tail update helps to avoid LWP and
can mitigate the situation significantly.
This patch proposes two new optional ring synchronization modes:
1) Head/Tail Sync (HTS) mode
In that mode enqueue/dequeue operation is fully serialized:
only one thread at a time is allowed to perform given op.
As another enhancement provide ability to split enqueue/dequeue
operation into two phases:
- enqueue/dequeue start
- enqueue/dequeue finish
That allows user to inspect objects in the ring without removing
them from it (aka MT safe peek).
2) Relaxed Tail Sync (RTS)
The main difference from original MP/MC algorithm is that
tail value is increased not by every thread that finished enqueue/dequeue,
but only by the last one.
That allows threads to avoid spinning on ring tail value,
leaving actual tail value change to the last thread in the update queue.
Note that these new sync modes are optional.
For current rte_ring users nothing should change
(both in terms of API/ABI and performance).
Existing sync modes MP/MC,SP/SC kept untouched, set up in the same
way (via flags and _init_), and MP/MC remains as default one.
The only thing that changed:
Format of prod/cons now could differ depending on mode selected at _init_.
So user has to stick with one sync model through whole ring lifetime.
In other words, user can't create a ring for let say SP mode and then
in the middle of data-path change his mind and start using MP_RTS mode.
For existing modes (SP/MP, SC/MC) format remains the same and
user can still use them interchangeably, though of course it is an
error prone practice.
Test results on IA (see below) show significant improvements
for average enqueue/dequeue op times on overcommitted systems.
For 'classic' DPDK deployments (one thread per core) original MP/MC
algorithm still shows best numbers, though for 64-bit target
RTS numbers are not that far away.
Numbers were produced by new UT test-case: ring_stress_autotest, i.e.:
echo ring_stress_autotest | ./dpdk-test -n 4 --lcores='...'
X86_64 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
DEQ+ENQ average cycles/obj
MP/MC HTS RTS
1thread@1core(--lcores=6-7) 8.00 8.15 8.99
2thread@2core(--lcores=6-8) 19.14 19.61 20.35
4thread@4core(--lcores=6-10) 29.43 29.79 31.82
8thread@8core(--lcores=6-14) 110.59 192.81 119.50
16thread@16core(--lcores=6-22) 461.03 813.12 495.59
32thread/@32core(--lcores='6-22,55-70') 982.90 1972.38 1160.51
2thread@1core(--lcores='6,(10-11)@7' 20140.50 23.58 25.14
4thread@2core(--lcores='6,(10-11)@7,(20-21)@8' 153680.60 76.88 80.05
8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 280314.32 294.72 318.79
16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 643176.59 1144.02 1175.14
32thread@2core(--lcores='6,(10-25)@7,(30-45)@8' 4264238.80 4627.48 4892.68
8thread@2core(--lcores='6,(10-17)@(7,8))' 321085.98 298.59 307.47
16thread@4core(--lcores='6,(20-35)@(7-10))' 1900705.61 575.35 678.29
32thread@4core(--lcores='6,(20-51)@(7-10))' 5510445.85 2164.36 2714.12
i686 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
DEQ+ENQ average cycles/obj
MP/MC HTS RTS
1thread@1core(--lcores=6-7) 7.85 12.13 11.31
2thread@2core(--lcores=6-8) 17.89 24.52 21.86
8thread@8core(--lcores=6-14) 32.58 354.20 54.58
32thread/@32core(--lcores='6-22,55-70') 813.77 6072.41 2169.91
2thread@1core(--lcores='6,(10-11)@7' 16095.00 36.06 34.74
8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 1140354.54 346.61 361.57
16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 1920417.86 1314.90 1416.65
8thread@2core(--lcores='6,(10-17)@(7,8))' 594358.61 332.70 357.74
32thread@4core(--lcores='6,(20-51)@(7-10))' 5319896.86 2836.44 3028.87
Konstantin Ananyev (10):
test/ring: add contention stress test
ring: prepare ring to allow new sync schemes
ring: introduce RTS ring mode
test/ring: add contention stress test for RTS ring
ring: introduce HTS ring mode
test/ring: add contention stress test for HTS ring
ring: introduce peek style API
test/ring: add stress test for MT peek API
test/ring: add functional tests for new sync modes
doc: update ring guide
app/test/Makefile | 5 +
app/test/meson.build | 5 +
app/test/test_pdump.c | 6 +-
app/test/test_ring.c | 93 +++--
app/test/test_ring_hts_stress.c | 32 ++
app/test/test_ring_mpmc_stress.c | 31 ++
app/test/test_ring_peek_stress.c | 43 +++
app/test/test_ring_rts_stress.c | 32 ++
app/test/test_ring_stress.c | 57 +++
app/test/test_ring_stress.h | 38 ++
app/test/test_ring_stress_impl.h | 396 +++++++++++++++++++++
devtools/libabigail.abignore | 7 +
doc/guides/prog_guide/ring_lib.rst | 95 +++++
doc/guides/rel_notes/release_20_05.rst | 16 +
lib/librte_pdump/rte_pdump.c | 2 +-
lib/librte_port/rte_port_ring.c | 12 +-
lib/librte_ring/Makefile | 9 +-
lib/librte_ring/meson.build | 12 +-
lib/librte_ring/rte_ring.c | 114 +++++-
lib/librte_ring/rte_ring.h | 306 ++++++++++------
lib/librte_ring/rte_ring_core.h | 184 ++++++++++
lib/librte_ring/rte_ring_elem.h | 171 +++++++--
lib/librte_ring/rte_ring_hts.h | 332 ++++++++++++++++++
lib/librte_ring/rte_ring_hts_c11_mem.h | 164 +++++++++
lib/librte_ring/rte_ring_peek.h | 444 ++++++++++++++++++++++++
lib/librte_ring/rte_ring_peek_c11_mem.h | 110 ++++++
lib/librte_ring/rte_ring_rts.h | 439 +++++++++++++++++++++++
lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
28 files changed, 3142 insertions(+), 192 deletions(-)
create mode 100644 app/test/test_ring_hts_stress.c
create mode 100644 app/test/test_ring_mpmc_stress.c
create mode 100644 app/test/test_ring_peek_stress.c
create mode 100644 app/test/test_ring_rts_stress.c
create mode 100644 app/test/test_ring_stress.c
create mode 100644 app/test/test_ring_stress.h
create mode 100644 app/test/test_ring_stress_impl.h
create mode 100644 lib/librte_ring/rte_ring_core.h
create mode 100644 lib/librte_ring/rte_ring_hts.h
create mode 100644 lib/librte_ring/rte_ring_hts_c11_mem.h
create mode 100644 lib/librte_ring/rte_ring_peek.h
create mode 100644 lib/librte_ring/rte_ring_peek_c11_mem.h
create mode 100644 lib/librte_ring/rte_ring_rts.h
create mode 100644 lib/librte_ring/rte_ring_rts_c11_mem.h
--
2.17.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21
2020-04-20 11:57 9% ` Ray Kinsella
@ 2020-04-20 12:20 9% ` David Marchand
2020-04-20 15:25 9% ` Ray Kinsella
2020-04-22 8:07 6% ` Ray Kinsella
0 siblings, 2 replies; 200+ results
From: David Marchand @ 2020-04-20 12:20 UTC (permalink / raw)
To: Ray Kinsella
Cc: dev, Wang, Haiyue, Matan Azrad, Anoob Joseph, Yigit, Ferruh,
Mahipal Challa, Eelco Chaudron, Cristian Dumitrescu,
Thomas Monjalon, Jingjing Wu, Wenzhuo Lu, Shahaf Shuler,
Viacheslav Ovsiienko, Jerin Jacob Kollanukkaran,
Nithin Dabilpuram, Alfredo Cardigliano, Neil Horman
On Mon, Apr 20, 2020 at 1:57 PM Ray Kinsella <mdr@ashroe.eu> wrote:
>
> Travis ABI check warnings, can be safely ignored in this case, I think.
>
> https://travis-ci.com/github/ovsrobot/dpdk/builds/161009923
How about comparing to 19.11 ABI then?
--- a/.travis.yml
+++ b/.travis.yml
@@ -36,7 +36,7 @@ script: ./.ci/${TRAVIS_OS_NAME}-build.sh
env:
global:
- - REF_GIT_TAG=v20.02
+ - REF_GIT_TAG=v19.11
jobs:
include:
--
David Marchand
^ permalink raw reply [relevance 9%]
* [dpdk-dev] [PATCH v6 03/10] ring: introduce RTS ring mode
2020-04-20 12:11 3% ` [dpdk-dev] [PATCH v6 00/10] " Konstantin Ananyev
2020-04-20 12:11 9% ` [dpdk-dev] [PATCH v6 02/10] ring: prepare ring to allow new sync schemes Konstantin Ananyev
@ 2020-04-20 12:11 1% ` Konstantin Ananyev
2020-04-20 12:28 3% ` [dpdk-dev] [PATCH v7 00/10] New sync modes for ring Konstantin Ananyev
2 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-20 12:11 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
Introduce relaxed tail sync (RTS) mode for MT ring synchronization.
Aim to reduce stall times in case when ring is used on
overcommited cpus (multiple active threads on the same cpu).
The main difference from original MP/MC algorithm is that
tail value is increased not by every thread that finished enqueue/dequeue,
but only by the last one.
That allows threads to avoid spinning on ring tail value,
leaving actual tail value change to the last thread in the update queue.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
---
check-abi.sh reports what I believe is a false-positive about
ring cons/prod changes. As a workaround, devtools/libabigail.abignore is
updated to suppress *struct ring* related errors.
This patch depends on following patch:
"meson: add libatomic as a global dependency for i686 clang"
(http://patches.dpdk.org/patch/68876/)
devtools/libabigail.abignore | 7 +
doc/guides/rel_notes/release_20_05.rst | 7 +
lib/librte_ring/Makefile | 4 +-
lib/librte_ring/meson.build | 7 +-
lib/librte_ring/rte_ring.c | 100 +++++-
lib/librte_ring/rte_ring.h | 118 +++++--
lib/librte_ring/rte_ring_core.h | 36 +-
lib/librte_ring/rte_ring_elem.h | 114 ++++++-
lib/librte_ring/rte_ring_rts.h | 439 +++++++++++++++++++++++++
lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
10 files changed, 963 insertions(+), 48 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_rts.h
create mode 100644 lib/librte_ring/rte_ring_rts_c11_mem.h
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index a59df8f13..cd86d89ca 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -11,3 +11,10 @@
type_kind = enum
name = rte_crypto_asym_xform_type
changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
+; Ignore updates of ring prod/cons
+[suppress_type]
+ type_kind = struct
+ name = rte_ring
+[suppress_type]
+ type_kind = struct
+ name = rte_event_ring
diff --git a/doc/guides/rel_notes/release_20_05.rst b/doc/guides/rel_notes/release_20_05.rst
index 184967844..eedf960d0 100644
--- a/doc/guides/rel_notes/release_20_05.rst
+++ b/doc/guides/rel_notes/release_20_05.rst
@@ -81,6 +81,13 @@ New Features
by making use of the event device capabilities. The event mode currently supports
only inline IPsec protocol offload.
+* **New synchronization modes for rte_ring.**
+
+ Introduced new optional MT synchronization mode for rte_ring:
+ Relaxed Tail Sync (RTS). With this mode selected, rte_ring shows
+ significant improvements for average enqueue/dequeue times on
+ overcommitted systems.
+
Removed Items
-------------
diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile
index 6572768c9..04e446e37 100644
--- a/lib/librte_ring/Makefile
+++ b/lib/librte_ring/Makefile
@@ -19,6 +19,8 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
rte_ring_core.h \
rte_ring_elem.h \
rte_ring_generic.h \
- rte_ring_c11_mem.h
+ rte_ring_c11_mem.h \
+ rte_ring_rts.h \
+ rte_ring_rts_c11_mem.h
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build
index c656781da..a95598032 100644
--- a/lib/librte_ring/meson.build
+++ b/lib/librte_ring/meson.build
@@ -6,4 +6,9 @@ headers = files('rte_ring.h',
'rte_ring_core.h',
'rte_ring_elem.h',
'rte_ring_c11_mem.h',
- 'rte_ring_generic.h')
+ 'rte_ring_generic.h',
+ 'rte_ring_rts.h',
+ 'rte_ring_rts_c11_mem.h')
+
+# rte_ring_create_elem and rte_ring_get_memsize_elem are experimental
+allow_experimental_apis = true
diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
index fa5733907..222eec0fb 100644
--- a/lib/librte_ring/rte_ring.c
+++ b/lib/librte_ring/rte_ring.c
@@ -45,6 +45,9 @@ EAL_REGISTER_TAILQ(rte_ring_tailq)
/* true if x is a power of 2 */
#define POWEROF2(x) ((((x)-1) & (x)) == 0)
+/* by default set head/tail distance as 1/8 of ring capacity */
+#define HTD_MAX_DEF 8
+
/* return the size of memory occupied by a ring */
ssize_t
rte_ring_get_memsize_elem(unsigned int esize, unsigned int count)
@@ -79,11 +82,84 @@ rte_ring_get_memsize(unsigned int count)
return rte_ring_get_memsize_elem(sizeof(void *), count);
}
+/*
+ * internal helper function to reset prod/cons head-tail values.
+ */
+static void
+reset_headtail(void *p)
+{
+ struct rte_ring_headtail *ht;
+ struct rte_ring_rts_headtail *ht_rts;
+
+ ht = p;
+ ht_rts = p;
+
+ switch (ht->sync_type) {
+ case RTE_RING_SYNC_MT:
+ case RTE_RING_SYNC_ST:
+ ht->head = 0;
+ ht->tail = 0;
+ break;
+ case RTE_RING_SYNC_MT_RTS:
+ ht_rts->head.raw = 0;
+ ht_rts->tail.raw = 0;
+ break;
+ default:
+ /* unknown sync mode */
+ RTE_ASSERT(0);
+ }
+}
+
void
rte_ring_reset(struct rte_ring *r)
{
- r->prod.head = r->cons.head = 0;
- r->prod.tail = r->cons.tail = 0;
+ reset_headtail(&r->prod);
+ reset_headtail(&r->cons);
+}
+
+/*
+ * helper function, calculates sync_type values for prod and cons
+ * based on input flags. Returns zero at success or negative
+ * errno value otherwise.
+ */
+static int
+get_sync_type(uint32_t flags, enum rte_ring_sync_type *prod_st,
+ enum rte_ring_sync_type *cons_st)
+{
+ static const uint32_t prod_st_flags =
+ (RING_F_SP_ENQ | RING_F_MP_RTS_ENQ);
+ static const uint32_t cons_st_flags =
+ (RING_F_SC_DEQ | RING_F_MC_RTS_DEQ);
+
+ switch (flags & prod_st_flags) {
+ case 0:
+ *prod_st = RTE_RING_SYNC_MT;
+ break;
+ case RING_F_SP_ENQ:
+ *prod_st = RTE_RING_SYNC_ST;
+ break;
+ case RING_F_MP_RTS_ENQ:
+ *prod_st = RTE_RING_SYNC_MT_RTS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (flags & cons_st_flags) {
+ case 0:
+ *cons_st = RTE_RING_SYNC_MT;
+ break;
+ case RING_F_SC_DEQ:
+ *cons_st = RTE_RING_SYNC_ST;
+ break;
+ case RING_F_MC_RTS_DEQ:
+ *cons_st = RTE_RING_SYNC_MT_RTS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
}
int
@@ -100,16 +176,20 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
RTE_BUILD_BUG_ON((offsetof(struct rte_ring, prod) &
RTE_CACHE_LINE_MASK) != 0);
+ RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, sync_type) !=
+ offsetof(struct rte_ring_rts_headtail, sync_type));
+ RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, tail) !=
+ offsetof(struct rte_ring_rts_headtail, tail.val.pos));
+
/* init the ring structure */
memset(r, 0, sizeof(*r));
ret = strlcpy(r->name, name, sizeof(r->name));
if (ret < 0 || ret >= (int)sizeof(r->name))
return -ENAMETOOLONG;
r->flags = flags;
- r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
- RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
- r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
- RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
+ ret = get_sync_type(flags, &r->prod.sync_type, &r->cons.sync_type);
+ if (ret != 0)
+ return ret;
if (flags & RING_F_EXACT_SZ) {
r->size = rte_align32pow2(count + 1);
@@ -126,8 +206,12 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
r->mask = count - 1;
r->capacity = r->mask;
}
- r->prod.head = r->cons.head = 0;
- r->prod.tail = r->cons.tail = 0;
+
+ /* set default values for head-tail distance */
+ if (flags & RING_F_MP_RTS_ENQ)
+ rte_ring_set_prod_htd_max(r, r->capacity / HTD_MAX_DEF);
+ if (flags & RING_F_MC_RTS_DEQ)
+ rte_ring_set_cons_htd_max(r, r->capacity / HTD_MAX_DEF);
return 0;
}
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index 35ee4491c..c42e1cfc4 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright (c) 2010-2017 Intel Corporation
+ * Copyright (c) 2010-2020 Intel Corporation
* Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
* All rights reserved.
* Derived from FreeBSD's bufring.h
@@ -79,12 +79,24 @@ ssize_t rte_ring_get_memsize(unsigned count);
* The number of elements in the ring (must be a power of 2).
* @param flags
* An OR of the following:
- * - RING_F_SP_ENQ: If this flag is set, the default behavior when
- * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
- * is "single-producer". Otherwise, it is "multi-producers".
- * - RING_F_SC_DEQ: If this flag is set, the default behavior when
- * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
- * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - One of mutually exclusive flags that define producer behavior:
+ * - RING_F_SP_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "single-producer".
+ * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "multi-producer RTS mode".
+ * If none of these flags is set, then default "multi-producer"
+ * behavior is selected.
+ * - One of mutually exclusive flags that define consumer behavior:
+ * - RING_F_SC_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "multi-consumer RTS mode".
+ * If none of these flags is set, then default "multi-consumer"
+ * behavior is selected.
* @return
* 0 on success, or a negative value on error.
*/
@@ -114,12 +126,24 @@ int rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
* constraint for the reserved zone.
* @param flags
* An OR of the following:
- * - RING_F_SP_ENQ: If this flag is set, the default behavior when
- * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
- * is "single-producer". Otherwise, it is "multi-producers".
- * - RING_F_SC_DEQ: If this flag is set, the default behavior when
- * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
- * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - One of mutually exclusive flags that define producer behavior:
+ * - RING_F_SP_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "single-producer".
+ * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "multi-producer RTS mode".
+ * If none of these flags is set, then default "multi-producer"
+ * behavior is selected.
+ * - One of mutually exclusive flags that define consumer behavior:
+ * - RING_F_SC_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "multi-consumer RTS mode".
+ * If none of these flags is set, then default "multi-consumer"
+ * behavior is selected.
* @return
* On success, the pointer to the new allocated ring. NULL on error with
* rte_errno set appropriately. Possible errno values include:
@@ -389,8 +413,21 @@ static __rte_always_inline unsigned int
rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_bulk(r, obj_table, n, free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_bulk(r, obj_table, n, free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_bulk(r, obj_table, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -524,8 +561,20 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
unsigned int *available)
{
- return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_bulk(r, obj_table, n, available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_bulk(r, obj_table, n, available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_bulk(r, obj_table, n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -845,8 +894,21 @@ static __rte_always_inline unsigned
rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
- r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_burst(r, obj_table, n, free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_burst(r, obj_table, n, free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_burst(r, obj_table, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -925,9 +987,21 @@ static __rte_always_inline unsigned
rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_burst(r, obj_table, n, available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_burst(r, obj_table, n, available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_burst(r, obj_table, n,
+ available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
#ifdef __cplusplus
diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
index d9cef763f..bd21fa535 100644
--- a/lib/librte_ring/rte_ring_core.h
+++ b/lib/librte_ring/rte_ring_core.h
@@ -57,6 +57,9 @@ enum rte_ring_queue_behavior {
enum rte_ring_sync_type {
RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
RTE_RING_SYNC_ST, /**< single thread only */
+#ifdef ALLOW_EXPERIMENTAL_API
+ RTE_RING_SYNC_MT_RTS, /**< multi-thread relaxed tail sync */
+#endif
};
/**
@@ -76,6 +79,22 @@ struct rte_ring_headtail {
};
};
+union __rte_ring_rts_poscnt {
+ /** raw 8B value to read/write *cnt* and *pos* as one atomic op */
+ uint64_t raw __rte_aligned(8);
+ struct {
+ uint32_t cnt; /**< head/tail reference counter */
+ uint32_t pos; /**< head/tail position */
+ } val;
+};
+
+struct rte_ring_rts_headtail {
+ volatile union __rte_ring_rts_poscnt tail;
+ enum rte_ring_sync_type sync_type; /**< sync type of prod/cons */
+ uint32_t htd_max; /**< max allowed distance between head/tail */
+ volatile union __rte_ring_rts_poscnt head;
+};
+
/**
* An RTE ring structure.
*
@@ -104,11 +123,21 @@ struct rte_ring {
char pad0 __rte_cache_aligned; /**< empty cache line */
/** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail prod;
+ struct rte_ring_rts_headtail rts_prod;
+ } __rte_cache_aligned;
+
char pad1 __rte_cache_aligned; /**< empty cache line */
/** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail cons;
+ struct rte_ring_rts_headtail rts_cons;
+ } __rte_cache_aligned;
+
char pad2 __rte_cache_aligned; /**< empty cache line */
};
@@ -125,6 +154,9 @@ struct rte_ring {
#define RING_F_EXACT_SZ 0x0004
#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
+#define RING_F_MP_RTS_ENQ 0x0008 /**< The default enqueue is "MP RTS". */
+#define RING_F_MC_RTS_DEQ 0x0010 /**< The default dequeue is "MC RTS". */
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
index 7406c0b0f..4030753b6 100644
--- a/lib/librte_ring/rte_ring_elem.h
+++ b/lib/librte_ring/rte_ring_elem.h
@@ -74,12 +74,24 @@ ssize_t rte_ring_get_memsize_elem(unsigned int esize, unsigned int count);
* constraint for the reserved zone.
* @param flags
* An OR of the following:
- * - RING_F_SP_ENQ: If this flag is set, the default behavior when
- * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
- * is "single-producer". Otherwise, it is "multi-producers".
- * - RING_F_SC_DEQ: If this flag is set, the default behavior when
- * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
- * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - One of mutually exclusive flags that define producer behavior:
+ * - RING_F_SP_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "single-producer".
+ * - RING_F_MP_RTS_ENQ: If this flag is set, the default behavior when
+ * using ``rte_ring_enqueue()`` or ``rte_ring_enqueue_bulk()``
+ * is "multi-producer RTS mode".
+ * If none of these flags is set, then default "multi-producer"
+ * behavior is selected.
+ * - One of mutually exclusive flags that define consumer behavior:
+ * - RING_F_SC_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "single-consumer". Otherwise, it is "multi-consumers".
+ * - RING_F_MC_RTS_DEQ: If this flag is set, the default behavior when
+ * using ``rte_ring_dequeue()`` or ``rte_ring_dequeue_bulk()``
+ * is "multi-consumer RTS mode".
+ * If none of these flags is set, then default "multi-consumer"
+ * behavior is selected.
* @return
* On success, the pointer to the new allocated ring. NULL on error with
* rte_errno set appropriately. Possible errno values include:
@@ -528,6 +540,10 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
}
+#ifdef ALLOW_EXPERIMENTAL_API
+#include <rte_ring_rts.h>
+#endif
+
/**
* Enqueue several objects on a ring.
*
@@ -557,6 +573,26 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_FIXED, r->prod.sync_type, free_space);
+
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (free_space != NULL)
+ *free_space = 0;
+ return 0;
}
/**
@@ -661,7 +697,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
}
/**
@@ -719,8 +755,25 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
+ available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
+ available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize,
+ n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (available != NULL)
+ *available = 0;
+ return 0;
}
/**
@@ -887,8 +940,25 @@ static __rte_always_inline unsigned
rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n,
+ free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
+ free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize,
+ n, free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (free_space != NULL)
+ *free_space = 0;
+ return 0;
}
/**
@@ -979,9 +1049,25 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
+ available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
+ available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize,
+ n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (available != NULL)
+ *available = 0;
+ return 0;
}
#include <rte_ring.h>
diff --git a/lib/librte_ring/rte_ring_rts.h b/lib/librte_ring/rte_ring_rts.h
new file mode 100644
index 000000000..8ced07096
--- /dev/null
+++ b/lib/librte_ring/rte_ring_rts.h
@@ -0,0 +1,439 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_RTS_H_
+#define _RTE_RING_RTS_H_
+
+/**
+ * @file rte_ring_rts.h
+ * @b EXPERIMENTAL: this API may change without prior notice
+ * It is not recommended to include this file directly.
+ * Please include <rte_ring.h> instead.
+ *
+ * Contains functions for Relaxed Tail Sync (RTS) ring mode.
+ * The main idea remains the same as for our original MP/MC synchronization
+ * mechanism.
+ * The main difference is that tail value is increased not
+ * by every thread that finished enqueue/dequeue,
+ * but only by the current last one doing enqueue/dequeue.
+ * That allows threads to skip spinning on tail value,
+ * leaving actual tail value change to last thread at a given instance.
+ * RTS requires 2 64-bit CAS for each enqueue(/dequeue) operation:
+ * one for head update, second for tail update.
+ * As a gain it allows thread to avoid spinning/waiting on tail value.
+ * In comparision original MP/MC algorithm requires one 32-bit CAS
+ * for head update and waiting/spinning on tail value.
+ *
+ * Brief outline:
+ * - introduce update counter (cnt) for both head and tail.
+ * - increment head.cnt for each head.value update
+ * - write head.value and head.cnt atomically (64-bit CAS)
+ * - move tail.value ahead only when tail.cnt + 1 == head.cnt
+ * (indicating that this is the last thread updating the tail)
+ * - increment tail.cnt when each enqueue/dequeue op finishes
+ * (no matter if tail.value going to change or not)
+ * - write tail.value and tail.cnt atomically (64-bit CAS)
+ *
+ * To avoid producer/consumer starvation:
+ * - limit max allowed distance between head and tail value (HTD_MAX).
+ * I.E. thread is allowed to proceed with changing head.value,
+ * only when: head.value - tail.value <= HTD_MAX
+ * HTD_MAX is an optional parameter.
+ * With HTD_MAX == 0 we'll have fully serialized ring -
+ * i.e. only one thread at a time will be able to enqueue/dequeue
+ * to/from the ring.
+ * With HTD_MAX >= ring.capacity - no limitation.
+ * By default HTD_MAX == ring.capacity / 8.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_ring_rts_c11_mem.h>
+
+/**
+ * @internal Enqueue several objects on the RTS ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Enqueue as many items as possible from ring
+ * @param free_space
+ * returns the amount of space after the enqueue operation has finished
+ * @return
+ * Actual number of objects enqueued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_do_rts_enqueue_elem(struct rte_ring *r, const void *obj_table,
+ uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
+ uint32_t *free_space)
+{
+ uint32_t free, head;
+
+ n = __rte_ring_rts_move_prod_head(r, n, behavior, &head, &free);
+
+ if (n != 0) {
+ __rte_ring_enqueue_elems(r, head, obj_table, esize, n);
+ __rte_ring_rts_update_tail(&r->rts_prod);
+ }
+
+ if (free_space != NULL)
+ *free_space = free - n;
+ return n;
+}
+
+/**
+ * @internal Dequeue several objects from the RTS ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to pull from the ring.
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Dequeue as many items as possible from ring
+ * @param available
+ * returns the number of remaining ring entries after the dequeue has finished
+ * @return
+ * - Actual number of objects dequeued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_do_rts_dequeue_elem(struct rte_ring *r, void *obj_table,
+ uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
+ uint32_t *available)
+{
+ uint32_t entries, head;
+
+ n = __rte_ring_rts_move_cons_head(r, n, behavior, &head, &entries);
+
+ if (n != 0) {
+ __rte_ring_dequeue_elems(r, head, obj_table, esize, n);
+ __rte_ring_rts_update_tail(&r->rts_cons);
+ }
+
+ if (available != NULL)
+ *available = entries - n;
+ return n;
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * The number of objects enqueued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mp_rts_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *free_space)
+{
+ return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_FIXED, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects that will be filled.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * The number of objects dequeued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mc_rts_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *available)
+{
+ return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_FIXED, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * - n: Actual number of objects enqueued.
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mp_rts_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *free_space)
+{
+ return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_VARIABLE, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ * When the requested objects are more than the available objects,
+ * only dequeue the actual number of objects.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects that will be filled.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * - n: Actual number of objects dequeued, 0 if ring is empty
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mc_rts_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *available)
+{
+ return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_VARIABLE, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects).
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * The number of objects enqueued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mp_rts_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
+ unsigned int n, unsigned int *free_space)
+{
+ return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table,
+ sizeof(uintptr_t), n, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects) that will be filled.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * The number of objects dequeued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mc_rts_dequeue_bulk(struct rte_ring *r, void **obj_table,
+ unsigned int n, unsigned int *available)
+{
+ return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table,
+ sizeof(uintptr_t), n, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects).
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * - n: Actual number of objects enqueued.
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mp_rts_enqueue_burst(struct rte_ring *r, void * const *obj_table,
+ unsigned int n, unsigned int *free_space)
+{
+ return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table,
+ sizeof(uintptr_t), n, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ * When the requested objects are more than the available objects,
+ * only dequeue the actual number of objects.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects) that will be filled.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * - n: Actual number of objects dequeued, 0 if ring is empty
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mc_rts_dequeue_burst(struct rte_ring *r, void **obj_table,
+ unsigned int n, unsigned int *available)
+{
+ return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table,
+ sizeof(uintptr_t), n, available);
+}
+
+/**
+ * Return producer max Head-Tail-Distance (HTD).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Producer HTD value, if producer is set in appropriate sync mode,
+ * or UINT32_MAX otherwise.
+ */
+__rte_experimental
+static inline uint32_t
+rte_ring_get_prod_htd_max(const struct rte_ring *r)
+{
+ if (r->prod.sync_type == RTE_RING_SYNC_MT_RTS)
+ return r->rts_prod.htd_max;
+ return UINT32_MAX;
+}
+
+/**
+ * Set producer max Head-Tail-Distance (HTD).
+ * Note that producer has to use appropriate sync mode (RTS).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param v
+ * new HTD value to setup.
+ * @return
+ * Zero on success, or negative error code otherwise.
+ */
+__rte_experimental
+static inline int
+rte_ring_set_prod_htd_max(struct rte_ring *r, uint32_t v)
+{
+ if (r->prod.sync_type != RTE_RING_SYNC_MT_RTS)
+ return -ENOTSUP;
+
+ r->rts_prod.htd_max = v;
+ return 0;
+}
+
+/**
+ * Return consumer max Head-Tail-Distance (HTD).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Consumer HTD value, if consumer is set in appropriate sync mode,
+ * or UINT32_MAX otherwise.
+ */
+__rte_experimental
+static inline uint32_t
+rte_ring_get_cons_htd_max(const struct rte_ring *r)
+{
+ if (r->cons.sync_type == RTE_RING_SYNC_MT_RTS)
+ return r->rts_cons.htd_max;
+ return UINT32_MAX;
+}
+
+/**
+ * Set consumer max Head-Tail-Distance (HTD).
+ * Note that consumer has to use appropriate sync mode (RTS).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param v
+ * new HTD value to setup.
+ * @return
+ * Zero on success, or negative error code otherwise.
+ */
+__rte_experimental
+static inline int
+rte_ring_set_cons_htd_max(struct rte_ring *r, uint32_t v)
+{
+ if (r->cons.sync_type != RTE_RING_SYNC_MT_RTS)
+ return -ENOTSUP;
+
+ r->rts_cons.htd_max = v;
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RING_RTS_H_ */
diff --git a/lib/librte_ring/rte_ring_rts_c11_mem.h b/lib/librte_ring/rte_ring_rts_c11_mem.h
new file mode 100644
index 000000000..327f22796
--- /dev/null
+++ b/lib/librte_ring/rte_ring_rts_c11_mem.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_RTS_C11_MEM_H_
+#define _RTE_RING_RTS_C11_MEM_H_
+
+/**
+ * @file rte_ring_rts_c11_mem.h
+ * It is not recommended to include this file directly,
+ * include <rte_ring.h> instead.
+ * Contains internal helper functions for Relaxed Tail Sync (RTS) ring mode.
+ * For more information please refer to <rte_ring_rts.h>.
+ */
+
+/**
+ * @internal This function updates tail values.
+ */
+static __rte_always_inline void
+__rte_ring_rts_update_tail(struct rte_ring_rts_headtail *ht)
+{
+ union __rte_ring_rts_poscnt h, ot, nt;
+
+ /*
+ * If there are other enqueues/dequeues in progress that
+ * might preceded us, then don't update tail with new value.
+ */
+
+ ot.raw = __atomic_load_n(&ht->tail.raw, __ATOMIC_ACQUIRE);
+
+ do {
+ /* on 32-bit systems we have to do atomic read here */
+ h.raw = __atomic_load_n(&ht->head.raw, __ATOMIC_RELAXED);
+
+ nt.raw = ot.raw;
+ if (++nt.val.cnt == h.val.cnt)
+ nt.val.pos = h.val.pos;
+
+ } while (__atomic_compare_exchange_n(&ht->tail.raw, &ot.raw, nt.raw,
+ 0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE) == 0);
+}
+
+/**
+ * @internal This function waits till head/tail distance wouldn't
+ * exceed pre-defined max value.
+ */
+static __rte_always_inline void
+__rte_ring_rts_head_wait(const struct rte_ring_rts_headtail *ht,
+ union __rte_ring_rts_poscnt *h)
+{
+ uint32_t max;
+
+ max = ht->htd_max;
+
+ while (h->val.pos - ht->tail.val.pos > max) {
+ rte_pause();
+ h->raw = __atomic_load_n(&ht->head.raw, __ATOMIC_ACQUIRE);
+ }
+}
+
+/**
+ * @internal This function updates the producer head for enqueue.
+ */
+static __rte_always_inline uint32_t
+__rte_ring_rts_move_prod_head(struct rte_ring *r, uint32_t num,
+ enum rte_ring_queue_behavior behavior, uint32_t *old_head,
+ uint32_t *free_entries)
+{
+ uint32_t n;
+ union __rte_ring_rts_poscnt nh, oh;
+
+ const uint32_t capacity = r->capacity;
+
+ oh.raw = __atomic_load_n(&r->rts_prod.head.raw, __ATOMIC_ACQUIRE);
+
+ do {
+ /* Reset n to the initial burst count */
+ n = num;
+
+ /*
+ * wait for prod head/tail distance,
+ * make sure that we read prod head *before*
+ * reading cons tail.
+ */
+ __rte_ring_rts_head_wait(&r->rts_prod, &oh);
+
+ /*
+ * The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * *old_head > cons_tail). So 'free_entries' is always between 0
+ * and capacity (which is < size).
+ */
+ *free_entries = capacity + r->cons.tail - oh.val.pos;
+
+ /* check that we have enough room in ring */
+ if (unlikely(n > *free_entries))
+ n = (behavior == RTE_RING_QUEUE_FIXED) ?
+ 0 : *free_entries;
+
+ if (n == 0)
+ break;
+
+ nh.val.pos = oh.val.pos + n;
+ nh.val.cnt = oh.val.cnt + 1;
+
+ /*
+ * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
+ * - OOO reads of cons tail value
+ * - OOO copy of elems to the ring
+ */
+ } while (__atomic_compare_exchange_n(&r->rts_prod.head.raw,
+ &oh.raw, nh.raw,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
+
+ *old_head = oh.val.pos;
+ return n;
+}
+
+/**
+ * @internal This function updates the consumer head for dequeue
+ */
+static __rte_always_inline unsigned int
+__rte_ring_rts_move_cons_head(struct rte_ring *r, uint32_t num,
+ enum rte_ring_queue_behavior behavior, uint32_t *old_head,
+ uint32_t *entries)
+{
+ uint32_t n;
+ union __rte_ring_rts_poscnt nh, oh;
+
+ oh.raw = __atomic_load_n(&r->rts_cons.head.raw, __ATOMIC_ACQUIRE);
+
+ /* move cons.head atomically */
+ do {
+ /* Restore n as it may change every loop */
+ n = num;
+
+ /*
+ * wait for cons head/tail distance,
+ * make sure that we read cons head *before*
+ * reading prod tail.
+ */
+ __rte_ring_rts_head_wait(&r->rts_cons, &oh);
+
+ /* The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * cons_head > prod_tail). So 'entries' is always between 0
+ * and size(ring)-1.
+ */
+ *entries = r->prod.tail - oh.val.pos;
+
+ /* Set the actual entries for dequeue */
+ if (n > *entries)
+ n = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : *entries;
+
+ if (unlikely(n == 0))
+ break;
+
+ nh.val.pos = oh.val.pos + n;
+ nh.val.cnt = oh.val.cnt + 1;
+
+ /*
+ * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
+ * - OOO reads of prod tail value
+ * - OOO copy of elems from the ring
+ */
+ } while (__atomic_compare_exchange_n(&r->rts_cons.head.raw,
+ &oh.raw, nh.raw,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
+
+ *old_head = oh.val.pos;
+ return n;
+}
+
+#endif /* _RTE_RING_RTS_C11_MEM_H_ */
--
2.17.1
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v6 02/10] ring: prepare ring to allow new sync schemes
2020-04-20 12:11 3% ` [dpdk-dev] [PATCH v6 00/10] " Konstantin Ananyev
@ 2020-04-20 12:11 9% ` Konstantin Ananyev
2020-04-20 12:11 1% ` [dpdk-dev] [PATCH v6 03/10] ring: introduce RTS ring mode Konstantin Ananyev
2020-04-20 12:28 3% ` [dpdk-dev] [PATCH v7 00/10] New sync modes for ring Konstantin Ananyev
2 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-20 12:11 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
To make these preparations two main things are done:
- Change from *single* to *sync_type* to allow different
synchronisation schemes to be applied.
Mark *single* as deprecated in comments.
Add new functions to allow user to query ring sync types.
Replace direct access to *single* with appropriate function call.
- Move actual rte_ring and related structures definitions into a
separate file: <rte_ring_core.h>. It allows to refer contents
of <rte_ring_elem.h> from <rte_ring.h> without introducing a
circular dependency.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Acked-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
---
app/test/test_pdump.c | 6 +-
lib/librte_pdump/rte_pdump.c | 2 +-
lib/librte_port/rte_port_ring.c | 12 +--
lib/librte_ring/Makefile | 1 +
lib/librte_ring/meson.build | 1 +
lib/librte_ring/rte_ring.c | 6 +-
lib/librte_ring/rte_ring.h | 170 ++++++++++++++------------------
lib/librte_ring/rte_ring_core.h | 132 +++++++++++++++++++++++++
lib/librte_ring/rte_ring_elem.h | 42 +++-----
9 files changed, 234 insertions(+), 138 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_core.h
diff --git a/app/test/test_pdump.c b/app/test/test_pdump.c
index ad183184c..6a1180bcb 100644
--- a/app/test/test_pdump.c
+++ b/app/test/test_pdump.c
@@ -57,8 +57,7 @@ run_pdump_client_tests(void)
if (ret < 0)
return -1;
mp->flags = 0x0000;
- ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
+ ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(), 0);
if (ring_client == NULL) {
printf("rte_ring_create SR0 failed");
return -1;
@@ -71,9 +70,6 @@ run_pdump_client_tests(void)
}
rte_eth_dev_probing_finish(eth_dev);
- ring_client->prod.single = 0;
- ring_client->cons.single = 0;
-
printf("\n***** flags = RTE_PDUMP_FLAG_TX *****\n");
for (itr = 0; itr < NUM_ITR; itr++) {
diff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c
index 8a01ac510..f96709f95 100644
--- a/lib/librte_pdump/rte_pdump.c
+++ b/lib/librte_pdump/rte_pdump.c
@@ -380,7 +380,7 @@ pdump_validate_ring_mp(struct rte_ring *ring, struct rte_mempool *mp)
rte_errno = EINVAL;
return -1;
}
- if (ring->prod.single || ring->cons.single) {
+ if (rte_ring_is_prod_single(ring) || rte_ring_is_cons_single(ring)) {
PDUMP_LOG(ERR, "ring with either SP or SC settings"
" is not valid for pdump, should have MP and MC settings\n");
rte_errno = EINVAL;
diff --git a/lib/librte_port/rte_port_ring.c b/lib/librte_port/rte_port_ring.c
index 47fcdd06a..52b2d8e55 100644
--- a/lib/librte_port/rte_port_ring.c
+++ b/lib/librte_port/rte_port_ring.c
@@ -44,8 +44,8 @@ rte_port_ring_reader_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->cons.single && is_multi) ||
- (!(conf->ring->cons.single) && !is_multi)) {
+ (rte_ring_is_cons_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
}
@@ -171,8 +171,8 @@ rte_port_ring_writer_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->prod.single && is_multi) ||
- (!(conf->ring->prod.single) && !is_multi) ||
+ (rte_ring_is_prod_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
(conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
@@ -440,8 +440,8 @@ rte_port_ring_writer_nodrop_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->prod.single && is_multi) ||
- (!(conf->ring->prod.single) && !is_multi) ||
+ (rte_ring_is_prod_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
(conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile
index 28368e6d1..6572768c9 100644
--- a/lib/librte_ring/Makefile
+++ b/lib/librte_ring/Makefile
@@ -16,6 +16,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_RING) := rte_ring.c
# install includes
SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
+ rte_ring_core.h \
rte_ring_elem.h \
rte_ring_generic.h \
rte_ring_c11_mem.h
diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build
index 05402e4f0..c656781da 100644
--- a/lib/librte_ring/meson.build
+++ b/lib/librte_ring/meson.build
@@ -3,6 +3,7 @@
sources = files('rte_ring.c')
headers = files('rte_ring.h',
+ 'rte_ring_core.h',
'rte_ring_elem.h',
'rte_ring_c11_mem.h',
'rte_ring_generic.h')
diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
index 77e5de099..fa5733907 100644
--- a/lib/librte_ring/rte_ring.c
+++ b/lib/librte_ring/rte_ring.c
@@ -106,8 +106,10 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
if (ret < 0 || ret >= (int)sizeof(r->name))
return -ENAMETOOLONG;
r->flags = flags;
- r->prod.single = (flags & RING_F_SP_ENQ) ? __IS_SP : __IS_MP;
- r->cons.single = (flags & RING_F_SC_DEQ) ? __IS_SC : __IS_MC;
+ r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
+ RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
+ r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
+ RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
if (flags & RING_F_EXACT_SZ) {
r->size = rte_align32pow2(count + 1);
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index 18fc5d845..35ee4491c 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -36,91 +36,7 @@
extern "C" {
#endif
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/queue.h>
-#include <errno.h>
-#include <rte_common.h>
-#include <rte_config.h>
-#include <rte_memory.h>
-#include <rte_lcore.h>
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_memzone.h>
-#include <rte_pause.h>
-
-#define RTE_TAILQ_RING_NAME "RTE_RING"
-
-enum rte_ring_queue_behavior {
- RTE_RING_QUEUE_FIXED = 0, /* Enq/Deq a fixed number of items from a ring */
- RTE_RING_QUEUE_VARIABLE /* Enq/Deq as many items as possible from ring */
-};
-
-#define RTE_RING_MZ_PREFIX "RG_"
-/** The maximum length of a ring name. */
-#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
- sizeof(RTE_RING_MZ_PREFIX) + 1)
-
-/* structure to hold a pair of head/tail values and other metadata */
-struct rte_ring_headtail {
- volatile uint32_t head; /**< Prod/consumer head. */
- volatile uint32_t tail; /**< Prod/consumer tail. */
- uint32_t single; /**< True if single prod/cons */
-};
-
-/**
- * An RTE ring structure.
- *
- * The producer and the consumer have a head and a tail index. The particularity
- * of these index is that they are not between 0 and size(ring). These indexes
- * are between 0 and 2^32, and we mask their value when we access the ring[]
- * field. Thanks to this assumption, we can do subtractions between 2 index
- * values in a modulo-32bit base: that's why the overflow of the indexes is not
- * a problem.
- */
-struct rte_ring {
- /*
- * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
- * compatibility requirements, it could be changed to RTE_RING_NAMESIZE
- * next time the ABI changes
- */
- char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned; /**< Name of the ring. */
- int flags; /**< Flags supplied at creation. */
- const struct rte_memzone *memzone;
- /**< Memzone, if any, containing the rte_ring */
- uint32_t size; /**< Size of ring. */
- uint32_t mask; /**< Mask (size-1) of ring. */
- uint32_t capacity; /**< Usable size of ring */
-
- char pad0 __rte_cache_aligned; /**< empty cache line */
-
- /** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
- char pad1 __rte_cache_aligned; /**< empty cache line */
-
- /** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
- char pad2 __rte_cache_aligned; /**< empty cache line */
-};
-
-#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
-#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
-/**
- * Ring is to hold exactly requested number of entries.
- * Without this flag set, the ring size requested must be a power of 2, and the
- * usable space will be that size - 1. With the flag, the requested size will
- * be rounded up to the next power of two, but the usable space will be exactly
- * that requested. Worst case, if a power-of-2 size is requested, half the
- * ring space will be wasted.
- */
-#define RING_F_EXACT_SZ 0x0004
-#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
-
-/* @internal defines for passing to the enqueue dequeue worker functions */
-#define __IS_SP 1
-#define __IS_MP 0
-#define __IS_SC 1
-#define __IS_MC 0
+#include <rte_ring_core.h>
/**
* Calculate the memory size needed for a ring
@@ -420,7 +336,7 @@ rte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_MP, free_space);
+ RTE_RING_SYNC_MT, free_space);
}
/**
@@ -443,9 +359,13 @@ rte_ring_sp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_SP, free_space);
+ RTE_RING_SYNC_ST, free_space);
}
+#ifdef ALLOW_EXPERIMENTAL_API
+#include <rte_ring_elem.h>
+#endif
+
/**
* Enqueue several objects on a ring.
*
@@ -470,7 +390,7 @@ rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->prod.single, free_space);
+ r->prod.sync_type, free_space);
}
/**
@@ -554,7 +474,7 @@ rte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_MC, available);
+ RTE_RING_SYNC_MT, available);
}
/**
@@ -578,7 +498,7 @@ rte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_SC, available);
+ RTE_RING_SYNC_ST, available);
}
/**
@@ -605,7 +525,7 @@ rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
/**
@@ -777,6 +697,62 @@ rte_ring_get_capacity(const struct rte_ring *r)
return r->capacity;
}
+/**
+ * Return sync type used by producer in the ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Producer sync type value.
+ */
+static inline enum rte_ring_sync_type
+rte_ring_get_prod_sync_type(const struct rte_ring *r)
+{
+ return r->prod.sync_type;
+}
+
+/**
+ * Check is the ring for single producer.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * true if ring is SP, zero otherwise.
+ */
+static inline int
+rte_ring_is_prod_single(const struct rte_ring *r)
+{
+ return (rte_ring_get_prod_sync_type(r) == RTE_RING_SYNC_ST);
+}
+
+/**
+ * Return sync type used by consumer in the ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Consumer sync type value.
+ */
+static inline enum rte_ring_sync_type
+rte_ring_get_cons_sync_type(const struct rte_ring *r)
+{
+ return r->cons.sync_type;
+}
+
+/**
+ * Check is the ring for single consumer.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * true if ring is SC, zero otherwise.
+ */
+static inline int
+rte_ring_is_cons_single(const struct rte_ring *r)
+{
+ return (rte_ring_get_cons_sync_type(r) == RTE_RING_SYNC_ST);
+}
+
/**
* Dump the status of all rings on the console
*
@@ -820,7 +796,7 @@ rte_ring_mp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -843,7 +819,7 @@ rte_ring_sp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -870,7 +846,7 @@ rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
- r->prod.single, free_space);
+ r->prod.sync_type, free_space);
}
/**
@@ -898,7 +874,7 @@ rte_ring_mc_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
}
/**
@@ -923,7 +899,7 @@ rte_ring_sc_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
}
/**
@@ -951,7 +927,7 @@ rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
{
return __rte_ring_do_dequeue(r, obj_table, n,
RTE_RING_QUEUE_VARIABLE,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
#ifdef __cplusplus
diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
new file mode 100644
index 000000000..d9cef763f
--- /dev/null
+++ b/lib/librte_ring/rte_ring_core.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_CORE_H_
+#define _RTE_RING_CORE_H_
+
+/**
+ * @file
+ * This file contains definion of RTE ring structure itself,
+ * init flags and some related macros.
+ * For majority of DPDK entities, it is not recommended to include
+ * this file directly, use include <rte_ring.h> or <rte_ring_elem.h>
+ * instead.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/queue.h>
+#include <errno.h>
+#include <rte_common.h>
+#include <rte_config.h>
+#include <rte_memory.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_memzone.h>
+#include <rte_pause.h>
+#include <rte_debug.h>
+
+#define RTE_TAILQ_RING_NAME "RTE_RING"
+
+/** enqueue/dequeue behavior types */
+enum rte_ring_queue_behavior {
+ /** Enq/Deq a fixed number of items from a ring */
+ RTE_RING_QUEUE_FIXED = 0,
+ /** Enq/Deq as many items as possible from ring */
+ RTE_RING_QUEUE_VARIABLE
+};
+
+#define RTE_RING_MZ_PREFIX "RG_"
+/** The maximum length of a ring name. */
+#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
+ sizeof(RTE_RING_MZ_PREFIX) + 1)
+
+/** prod/cons sync types */
+enum rte_ring_sync_type {
+ RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
+ RTE_RING_SYNC_ST, /**< single thread only */
+};
+
+/**
+ * structures to hold a pair of head/tail values and other metadata.
+ * Depending on sync_type format of that structure might be different,
+ * but offset for *sync_type* and *tail* values should remain the same.
+ */
+struct rte_ring_headtail {
+ volatile uint32_t head; /**< prod/consumer head. */
+ volatile uint32_t tail; /**< prod/consumer tail. */
+ RTE_STD_C11
+ union {
+ /** sync type of prod/cons */
+ enum rte_ring_sync_type sync_type;
+ /** deprecated - True if single prod/cons */
+ uint32_t single;
+ };
+};
+
+/**
+ * An RTE ring structure.
+ *
+ * The producer and the consumer have a head and a tail index. The particularity
+ * of these index is that they are not between 0 and size(ring). These indexes
+ * are between 0 and 2^32, and we mask their value when we access the ring[]
+ * field. Thanks to this assumption, we can do subtractions between 2 index
+ * values in a modulo-32bit base: that's why the overflow of the indexes is not
+ * a problem.
+ */
+struct rte_ring {
+ /*
+ * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
+ * compatibility requirements, it could be changed to RTE_RING_NAMESIZE
+ * next time the ABI changes
+ */
+ char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned;
+ /**< Name of the ring. */
+ int flags; /**< Flags supplied at creation. */
+ const struct rte_memzone *memzone;
+ /**< Memzone, if any, containing the rte_ring */
+ uint32_t size; /**< Size of ring. */
+ uint32_t mask; /**< Mask (size-1) of ring. */
+ uint32_t capacity; /**< Usable size of ring */
+
+ char pad0 __rte_cache_aligned; /**< empty cache line */
+
+ /** Ring producer status. */
+ struct rte_ring_headtail prod __rte_cache_aligned;
+ char pad1 __rte_cache_aligned; /**< empty cache line */
+
+ /** Ring consumer status. */
+ struct rte_ring_headtail cons __rte_cache_aligned;
+ char pad2 __rte_cache_aligned; /**< empty cache line */
+};
+
+#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
+#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
+/**
+ * Ring is to hold exactly requested number of entries.
+ * Without this flag set, the ring size requested must be a power of 2, and the
+ * usable space will be that size - 1. With the flag, the requested size will
+ * be rounded up to the next power of two, but the usable space will be exactly
+ * that requested. Worst case, if a power-of-2 size is requested, half the
+ * ring space will be wasted.
+ */
+#define RING_F_EXACT_SZ 0x0004
+#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RING_CORE_H_ */
diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
index 663addc73..7406c0b0f 100644
--- a/lib/librte_ring/rte_ring_elem.h
+++ b/lib/librte_ring/rte_ring_elem.h
@@ -20,21 +20,7 @@
extern "C" {
#endif
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <errno.h>
-#include <rte_common.h>
-#include <rte_config.h>
-#include <rte_memory.h>
-#include <rte_lcore.h>
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_memzone.h>
-#include <rte_pause.h>
-
-#include "rte_ring.h"
+#include <rte_ring_core.h>
/**
* @warning
@@ -510,7 +496,7 @@ rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_MP, free_space);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -539,7 +525,7 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_SP, free_space);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -570,7 +556,7 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->prod.single, free_space);
+ RTE_RING_QUEUE_FIXED, r->prod.sync_type, free_space);
}
/**
@@ -675,7 +661,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_MC, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
}
/**
@@ -703,7 +689,7 @@ rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_SC, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
}
/**
@@ -734,7 +720,7 @@ rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->cons.single, available);
+ RTE_RING_QUEUE_FIXED, r->cons.sync_type, available);
}
/**
@@ -842,7 +828,7 @@ rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -871,7 +857,7 @@ rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -902,7 +888,7 @@ rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, r->prod.single, free_space);
+ RTE_RING_QUEUE_VARIABLE, r->prod.sync_type, free_space);
}
/**
@@ -934,7 +920,7 @@ rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
}
/**
@@ -963,7 +949,7 @@ rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
}
/**
@@ -995,9 +981,11 @@ rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_VARIABLE,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
+#include <rte_ring.h>
+
#ifdef __cplusplus
}
#endif
--
2.17.1
^ permalink raw reply [relevance 9%]
* [dpdk-dev] [PATCH v6 00/10] New sync modes for ring
2020-04-18 16:32 3% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Konstantin Ananyev
` (2 preceding siblings ...)
2020-04-19 2:32 0% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Honnappa Nagarahalli
@ 2020-04-20 12:11 3% ` Konstantin Ananyev
2020-04-20 12:11 9% ` [dpdk-dev] [PATCH v6 02/10] ring: prepare ring to allow new sync schemes Konstantin Ananyev
` (2 more replies)
3 siblings, 3 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-20 12:11 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
This patch series depends on following patch:
"meson: add libatomic as a global dependency for i686 clang"
(http://patches.dpdk.org/patch/68876/)
V5 - V6:
1. add dependency on the external patch (-latomic for i686 clang)
2. remove unneeded code from rte_ring_generic (Honnappa)
3. extra comments for ring init/create API (Honnappa)
4. __rte prefix for internal structs (Honnappa)
5. update docs (rel notes and prog guide)
V4 - V5:
1. fix i686 clang build problem
2. fix formal API comments
V3 - V4 changes:
Address comments from Honnappa:
1. for new sync modes make legacy API wrappers around _elem_ calls
2. remove rte_ring_(hts|rts)_generic.h
3. few changes in C11 version
4. peek API - add missing functions for _elem_
5. remove _IS_SP/_IS_MP, etc. internal macros
6. fix param types (obj_table) for _elem_functions
7. fix formal API comments
8. deduplicate code for test_ring_stress
9. added functional tests for new sync modes
V2 - V3 changes:
1. few more compilation fixes (for gcc 4.8.X)
2. extra update devtools/libabigail.abignore (workaround)
V1 - V2 changes:
1. fix compilation issues
2. add C11 atomics support
3. updates devtools/libabigail.abignore (workaround)
RFC - V1 changes:
1. remove ABI brekage (at least I hope I did)
2. Add support for ring_elem
3. rework peek related API a bit
4. rework test to make it less verbose and unite all test-cases
in one command
5. add new test-case for MT peek API
These days more and more customers use(/try to use) DPDK based apps within
overcommitted systems (multiple acttive threads over same pysical cores):
VM, container deployments, etc.
One quite common problem they hit:
Lock-Holder-Preemption/Lock-Waiter-Preemption with rte_ring.
LHP is quite a common problem for spin-based sync primitives
(spin-locks, etc.) on overcommitted systems.
The situation gets much worse when some sort of
fair-locking technique is used (ticket-lock, etc.).
As now not only lock-owner but also lock-waiters scheduling
order matters a lot (LWP).
These two problems are well-known for kernel within VMs:
http://www-archive.xenproject.org/files/xensummitboston08/LHP.pdf
https://www.cs.hs-rm.de/~kaiser/events/wamos2017/Slides/selcuk.pdf
The problem with rte_ring is that while head accusion is sort of
un-fair locking, waiting on tail is very similar to ticket lock schema -
tail has to be updated in particular order.
That makes current rte_ring implementation to perform
really pure on some overcommited scenarios.
It is probably not possible to completely resolve LHP problem in
userspace only (without some kernel communication/intervention).
But removing fairness at tail update helps to avoid LWP and
can mitigate the situation significantly.
This patch proposes two new optional ring synchronization modes:
1) Head/Tail Sync (HTS) mode
In that mode enqueue/dequeue operation is fully serialized:
only one thread at a time is allowed to perform given op.
As another enhancement provide ability to split enqueue/dequeue
operation into two phases:
- enqueue/dequeue start
- enqueue/dequeue finish
That allows user to inspect objects in the ring without removing
them from it (aka MT safe peek).
2) Relaxed Tail Sync (RTS)
The main difference from original MP/MC algorithm is that
tail value is increased not by every thread that finished enqueue/dequeue,
but only by the last one.
That allows threads to avoid spinning on ring tail value,
leaving actual tail value change to the last thread in the update queue.
Note that these new sync modes are optional.
For current rte_ring users nothing should change
(both in terms of API/ABI and performance).
Existing sync modes MP/MC,SP/SC kept untouched, set up in the same
way (via flags and _init_), and MP/MC remains as default one.
The only thing that changed:
Format of prod/cons now could differ depending on mode selected at _init_.
So user has to stick with one sync model through whole ring lifetime.
In other words, user can't create a ring for let say SP mode and then
in the middle of data-path change his mind and start using MP_RTS mode.
For existing modes (SP/MP, SC/MC) format remains the same and
user can still use them interchangeably, though of course it is an
error prone practice.
Test results on IA (see below) show significant improvements
for average enqueue/dequeue op times on overcommitted systems.
For 'classic' DPDK deployments (one thread per core) original MP/MC
algorithm still shows best numbers, though for 64-bit target
RTS numbers are not that far away.
Numbers were produced by new UT test-case: ring_stress_autotest, i.e.:
echo ring_stress_autotest | ./dpdk-test -n 4 --lcores='...'
X86_64 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
DEQ+ENQ average cycles/obj
MP/MC HTS RTS
1thread@1core(--lcores=6-7) 8.00 8.15 8.99
2thread@2core(--lcores=6-8) 19.14 19.61 20.35
4thread@4core(--lcores=6-10) 29.43 29.79 31.82
8thread@8core(--lcores=6-14) 110.59 192.81 119.50
16thread@16core(--lcores=6-22) 461.03 813.12 495.59
32thread/@32core(--lcores='6-22,55-70') 982.90 1972.38 1160.51
2thread@1core(--lcores='6,(10-11)@7' 20140.50 23.58 25.14
4thread@2core(--lcores='6,(10-11)@7,(20-21)@8' 153680.60 76.88 80.05
8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 280314.32 294.72 318.79
16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 643176.59 1144.02 1175.14
32thread@2core(--lcores='6,(10-25)@7,(30-45)@8' 4264238.80 4627.48 4892.68
8thread@2core(--lcores='6,(10-17)@(7,8))' 321085.98 298.59 307.47
16thread@4core(--lcores='6,(20-35)@(7-10))' 1900705.61 575.35 678.29
32thread@4core(--lcores='6,(20-51)@(7-10))' 5510445.85 2164.36 2714.12
i686 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
DEQ+ENQ average cycles/obj
MP/MC HTS RTS
1thread@1core(--lcores=6-7) 7.85 12.13 11.31
2thread@2core(--lcores=6-8) 17.89 24.52 21.86
8thread@8core(--lcores=6-14) 32.58 354.20 54.58
32thread/@32core(--lcores='6-22,55-70') 813.77 6072.41 2169.91
2thread@1core(--lcores='6,(10-11)@7' 16095.00 36.06 34.74
8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 1140354.54 346.61 361.57
16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 1920417.86 1314.90 1416.65
8thread@2core(--lcores='6,(10-17)@(7,8))' 594358.61 332.70 357.74
32thread@4core(--lcores='6,(20-51)@(7-10))' 5319896.86 2836.44 3028.87
Konstantin Ananyev (10):
test/ring: add contention stress test
ring: prepare ring to allow new sync schemes
ring: introduce RTS ring mode
test/ring: add contention stress test for RTS ring
ring: introduce HTS ring mode
test/ring: add contention stress test for HTS ring
ring: introduce peek style API
test/ring: add stress test for MT peek API
test/ring: add functional tests for new sync modes
doc: update ring guide
app/test/Makefile | 5 +
app/test/meson.build | 5 +
app/test/test_pdump.c | 6 +-
app/test/test_ring.c | 93 +++--
app/test/test_ring_hts_stress.c | 32 ++
app/test/test_ring_mpmc_stress.c | 31 ++
app/test/test_ring_peek_stress.c | 43 +++
app/test/test_ring_rts_stress.c | 32 ++
app/test/test_ring_stress.c | 57 +++
app/test/test_ring_stress.h | 38 ++
app/test/test_ring_stress_impl.h | 396 +++++++++++++++++++++
devtools/libabigail.abignore | 7 +
doc/guides/prog_guide/ring_lib.rst | 95 +++++
doc/guides/rel_notes/release_20_05.rst | 16 +
lib/librte_pdump/rte_pdump.c | 2 +-
lib/librte_port/rte_port_ring.c | 12 +-
lib/librte_ring/Makefile | 9 +-
lib/librte_ring/meson.build | 12 +-
lib/librte_ring/rte_ring.c | 114 +++++-
lib/librte_ring/rte_ring.h | 306 ++++++++++------
lib/librte_ring/rte_ring_core.h | 184 ++++++++++
lib/librte_ring/rte_ring_elem.h | 171 +++++++--
lib/librte_ring/rte_ring_hts.h | 332 ++++++++++++++++++
lib/librte_ring/rte_ring_hts_c11_mem.h | 164 +++++++++
lib/librte_ring/rte_ring_peek.h | 444 ++++++++++++++++++++++++
lib/librte_ring/rte_ring_peek_c11_mem.h | 110 ++++++
lib/librte_ring/rte_ring_rts.h | 439 +++++++++++++++++++++++
lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
28 files changed, 3142 insertions(+), 192 deletions(-)
create mode 100644 app/test/test_ring_hts_stress.c
create mode 100644 app/test/test_ring_mpmc_stress.c
create mode 100644 app/test/test_ring_peek_stress.c
create mode 100644 app/test/test_ring_rts_stress.c
create mode 100644 app/test/test_ring_stress.c
create mode 100644 app/test/test_ring_stress.h
create mode 100644 app/test/test_ring_stress_impl.h
create mode 100644 lib/librte_ring/rte_ring_core.h
create mode 100644 lib/librte_ring/rte_ring_hts.h
create mode 100644 lib/librte_ring/rte_ring_hts_c11_mem.h
create mode 100644 lib/librte_ring/rte_ring_peek.h
create mode 100644 lib/librte_ring/rte_ring_peek_c11_mem.h
create mode 100644 lib/librte_ring/rte_ring_rts.h
create mode 100644 lib/librte_ring/rte_ring_rts_c11_mem.h
--
2.17.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21
2020-04-20 9:34 15% [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21 Ray Kinsella
@ 2020-04-20 11:57 9% ` Ray Kinsella
2020-04-20 12:20 9% ` David Marchand
2020-04-23 6:41 21% ` [dpdk-dev] [PATCH v2] " Ray Kinsella
` (2 subsequent siblings)
3 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-20 11:57 UTC (permalink / raw)
To: dev
Cc: haiyue.wang, matan, anoobj, ferruh.yigit, david.marchand,
mchalla, echaudro, cristian.dumitrescu, thomas, jingjing.wu,
wenzhuo.lu, shahafs, viacheslavo, jerinj, ndabilpuram,
cardigliano, Neil Horman
Travis ABI check warnings, can be safely ignored in this case, I think.
https://travis-ci.com/github/ovsrobot/dpdk/builds/161009923
Ray K
On 20/04/2020 10:34, Ray Kinsella wrote:
> Change references to abi 20.0.1 to use abi v21.0, add myself as the map
> file maintainer to more closely monitor future abi changes.
>
> Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
> ---
> MAINTAINERS | 2 ++
> drivers/common/iavf/rte_common_iavf_version.map | 2 +-
> drivers/common/mlx5/rte_common_mlx5_version.map | 2 +-
> drivers/common/octeontx2/rte_common_octeontx2_version.map | 2 +-
> drivers/net/ionic/rte_pmd_ionic_version.map | 2 +-
> drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map | 2 +-
> drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map | 2 +-
> lib/librte_meter/rte_meter_version.map | 2 +-
> 8 files changed, 9 insertions(+), 7 deletions(-)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 1bf00d7e5..c352e7815 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -86,6 +86,8 @@ F: doc/
> ABI Policy
> M: Ray Kinsella <mdr@ashroe.eu>
> F: doc/guides/contributing/abi_*.rst
> +F: drivers/*/*/*.map
> +F: lib/*/*.map
>
> Developers and Maintainers Tools
> M: Thomas Monjalon <thomas@monjalon.net>
> diff --git a/drivers/common/iavf/rte_common_iavf_version.map b/drivers/common/iavf/rte_common_iavf_version.map
> index 2f11d67c0..b9ca81aea 100644
> --- a/drivers/common/iavf/rte_common_iavf_version.map
> +++ b/drivers/common/iavf/rte_common_iavf_version.map
> @@ -1,4 +1,4 @@
> -DPDK_20.0.1 {
> +DPDK_21.0 {
> global:
>
> iavf_init_adminq;
> diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map
> index aede2a0a5..7bfea95fb 100644
> --- a/drivers/common/mlx5/rte_common_mlx5_version.map
> +++ b/drivers/common/mlx5/rte_common_mlx5_version.map
> @@ -1,4 +1,4 @@
> -DPDK_20.0.1 {
> +DPDK_21.0 {
> global:
>
> mlx5_class_get;
> diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
> index 8f2404bd9..68392ff79 100644
> --- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
> +++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
> @@ -34,7 +34,7 @@ DPDK_20.0 {
> local: *;
> };
>
> -DPDK_20.0.1 {
> +DPDK_21.0 {
> global:
>
> otx2_eth_dev_is_sec_capable;
> diff --git a/drivers/net/ionic/rte_pmd_ionic_version.map b/drivers/net/ionic/rte_pmd_ionic_version.map
> index bc8fd6d4d..cd8100ee4 100644
> --- a/drivers/net/ionic/rte_pmd_ionic_version.map
> +++ b/drivers/net/ionic/rte_pmd_ionic_version.map
> @@ -1,4 +1,4 @@
> -DPDK_20.0.1 {
> +DPDK_21.0 {
>
> local: *;
> };
> diff --git a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
> index bc8fd6d4d..cd8100ee4 100644
> --- a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
> +++ b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
> @@ -1,4 +1,4 @@
> -DPDK_20.0.1 {
> +DPDK_21.0 {
>
> local: *;
> };
> diff --git a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
> index 179f7f1ae..299ae632d 100644
> --- a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
> +++ b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
> @@ -1,3 +1,3 @@
> -DPDK_20.0.1 {
> +DPDK_21.0 {
> local: *;
> };
> diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
> index fc12cc0bf..10c56756c 100644
> --- a/lib/librte_meter/rte_meter_version.map
> +++ b/lib/librte_meter/rte_meter_version.map
> @@ -13,7 +13,7 @@ DPDK_20.0 {
> local: *;
> };
>
> -DPDK_20.0.1 {
> +DPDK_21.0 {
> global:
>
> rte_meter_trtcm_rfc4115_color_aware_check;
>
^ permalink raw reply [relevance 9%]
* [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21
@ 2020-04-20 9:34 15% Ray Kinsella
2020-04-20 11:57 9% ` Ray Kinsella
` (3 more replies)
0 siblings, 4 replies; 200+ results
From: Ray Kinsella @ 2020-04-20 9:34 UTC (permalink / raw)
To: dev
Cc: haiyue.wang, matan, anoobj, ferruh.yigit, david.marchand,
mchalla, echaudro, cristian.dumitrescu, thomas, jingjing.wu,
wenzhuo.lu, shahafs, viacheslavo, jerinj, ndabilpuram,
cardigliano, Ray Kinsella
Change references to abi 20.0.1 to use abi v21.0, add myself as the map
file maintainer to more closely monitor future abi changes.
Signed-off-by: Ray Kinsella <mdr@ashroe.eu>
---
MAINTAINERS | 2 ++
drivers/common/iavf/rte_common_iavf_version.map | 2 +-
drivers/common/mlx5/rte_common_mlx5_version.map | 2 +-
drivers/common/octeontx2/rte_common_octeontx2_version.map | 2 +-
drivers/net/ionic/rte_pmd_ionic_version.map | 2 +-
drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map | 2 +-
drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map | 2 +-
lib/librte_meter/rte_meter_version.map | 2 +-
8 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index 1bf00d7e5..c352e7815 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -86,6 +86,8 @@ F: doc/
ABI Policy
M: Ray Kinsella <mdr@ashroe.eu>
F: doc/guides/contributing/abi_*.rst
+F: drivers/*/*/*.map
+F: lib/*/*.map
Developers and Maintainers Tools
M: Thomas Monjalon <thomas@monjalon.net>
diff --git a/drivers/common/iavf/rte_common_iavf_version.map b/drivers/common/iavf/rte_common_iavf_version.map
index 2f11d67c0..b9ca81aea 100644
--- a/drivers/common/iavf/rte_common_iavf_version.map
+++ b/drivers/common/iavf/rte_common_iavf_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21.0 {
global:
iavf_init_adminq;
diff --git a/drivers/common/mlx5/rte_common_mlx5_version.map b/drivers/common/mlx5/rte_common_mlx5_version.map
index aede2a0a5..7bfea95fb 100644
--- a/drivers/common/mlx5/rte_common_mlx5_version.map
+++ b/drivers/common/mlx5/rte_common_mlx5_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21.0 {
global:
mlx5_class_get;
diff --git a/drivers/common/octeontx2/rte_common_octeontx2_version.map b/drivers/common/octeontx2/rte_common_octeontx2_version.map
index 8f2404bd9..68392ff79 100644
--- a/drivers/common/octeontx2/rte_common_octeontx2_version.map
+++ b/drivers/common/octeontx2/rte_common_octeontx2_version.map
@@ -34,7 +34,7 @@ DPDK_20.0 {
local: *;
};
-DPDK_20.0.1 {
+DPDK_21.0 {
global:
otx2_eth_dev_is_sec_capable;
diff --git a/drivers/net/ionic/rte_pmd_ionic_version.map b/drivers/net/ionic/rte_pmd_ionic_version.map
index bc8fd6d4d..cd8100ee4 100644
--- a/drivers/net/ionic/rte_pmd_ionic_version.map
+++ b/drivers/net/ionic/rte_pmd_ionic_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21.0 {
local: *;
};
diff --git a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
index bc8fd6d4d..cd8100ee4 100644
--- a/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
+++ b/drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map
@@ -1,4 +1,4 @@
-DPDK_20.0.1 {
+DPDK_21.0 {
local: *;
};
diff --git a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
index 179f7f1ae..299ae632d 100644
--- a/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
+++ b/drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map
@@ -1,3 +1,3 @@
-DPDK_20.0.1 {
+DPDK_21.0 {
local: *;
};
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index fc12cc0bf..10c56756c 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -13,7 +13,7 @@ DPDK_20.0 {
local: *;
};
-DPDK_20.0.1 {
+DPDK_21.0 {
global:
rte_meter_trtcm_rfc4115_color_aware_check;
--
2.17.1
^ permalink raw reply [relevance 15%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-17 16:10 4% ` Thomas Monjalon
@ 2020-04-20 8:43 8% ` Ray Kinsella
0 siblings, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-20 8:43 UTC (permalink / raw)
To: Thomas Monjalon, Neil Horman; +Cc: dev, david.marchand
On 17/04/2020 17:10, Thomas Monjalon wrote:
> 17/04/2020 17:42, Ray Kinsella:
>> On 17/04/2020 13:10, Thomas Monjalon wrote:
>>> 17/04/2020 13:47, Ray Kinsella:
>>>> On 17/04/2020 11:20, Thomas Monjalon wrote:
>>>>> 17/04/2020 12:11, Ray Kinsella:
>>>>>> check-abi.sh appears to be backward step in terms of usability.
>>>>>
>>>>> No, check-abi.sh benefits from a nice integration in build scripts.
>>>>> See below.
>>>>>
>>>>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
>>>>>> And it will do the build, install, dump and comparison for me.
>>>>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
>>>>>>
>>>>>> With check-abi on the other hand, I need to the build and install myself.
>>>>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
>>>>>> It silently fails when it doesn't find any ...
>>>>>>
>>>>>> Do I run abi-dumper on the so's myself, or how does it work?
>>>>>
>>>>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
>>>>> Probably we should document usage in these scripts.
>>>>
>>>> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
>>>> Any tips or tricks would be welcome.
>>>
>>> export DPDK_ABI_REF_VERSION=v20.02
>>> or
>>> export DPDK_ABI_REF_VERSION=v19.11
>>>
>>> Depends on which compatibility you want to test...
>>>
>>
>> Few things ...
>>
>> 1. test-meson-build.sh keep barfing complaining about reference paths.
>> ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
>>
>> Under the hood, ninja install is failing complaining that it needs an absolute path.
>> I fixed this in test_meson_build.sh and will send a patch in a minute.
>> Though it's strange no-one else has seen it?
>
> I set an absolute path in DPDK_ABI_REF_DIR.
> Not sure you can really fix it. What would be the root dir?
Figure it out at runtime, check with realpath, if DPDK_ABI_REF_DIR is not set?
Or at the very least test_meson_build.sh should barf, if DPDK_ABI_REF_DIR is not set when $DPDK_ABI_REF_VERSION is set.
root@silpixa00395806:/build/dpdk# git diff devtools/test-meson-builds.sh
diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh
index c1ff2bb50..f24cc104d 100755
--- a/devtools/test-meson-builds.sh
+++ b/devtools/test-meson-builds.sh
@@ -103,13 +103,15 @@ compile () # <builddir>
install_target () # <builddir> <installdir>
{
+ destdir_fp=$(realpath $2)
+
rm -rf $2
if [ -n "$TEST_MESON_BUILD_VERY_VERBOSE$TEST_MESON_BUILD_VERBOSE" ]; then
echo "DESTDIR=$2 $ninja_cmd -C $1 install"
- DESTDIR=$2 $ninja_cmd -C $1 install
+ DESTDIR=$destdir_fp $ninja_cmd -C $1 install
else
echo "DESTDIR=$2 $ninja_cmd -C $1 install >/dev/null"
- DESTDIR=$2 $ninja_cmd -C $1 install >/dev/null
+ DESTDIR=$destdir_fp $ninja_cmd -C $1 install >/dev/null
fi
}
@@ -147,7 +149,7 @@ build () # <directory> <target compiler> <meson options>
$srcdir/devtools/gen-abi.sh \
$(readlink -f $builds_dir/$targetdir/install)
$srcdir/devtools/check-abi.sh $abirefdir/$targetdir \
- $(readlink -f $builds_dir/$targetdir/install)
+ $(readlink -f $builds_dir/$targetdir/install) || :
fi
}
>
>> 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
>
> Yes
>
>> 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
>> In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
>> I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
>
> Why is it a common case? You want to compare with a tag. Why something else?
>
I disagree, perhaps it's just me as a contributor.
My first action is to check that _my_ submission has done no harm.
Assuming that the origin's HEAD is more than likely good, I check my changes against it.
I assume that anything else that has changed between the origin's HEAD and v19.11, someone somewhere else has approved.
So why would I compare against v19.11, when I only want to check that the changes I have made have caused no harm.
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH 1/4] vhost: inroduce operation to get vDPA queue stats
2020-04-19 6:18 0% ` Shahaf Shuler
@ 2020-04-20 7:13 0% ` Maxime Coquelin
2020-04-20 15:57 0% ` Shahaf Shuler
0 siblings, 1 reply; 200+ results
From: Maxime Coquelin @ 2020-04-20 7:13 UTC (permalink / raw)
To: Shahaf Shuler, Matan Azrad, dev, Xiao Wang; +Cc: Slava Ovsiienko
Hi Shahaf,
On 4/19/20 8:18 AM, Shahaf Shuler wrote:
> Thursday, April 16, 2020 4:20 PM, Maxime Coquelin:
>> Subject: Re: [PATCH 1/4] vhost: inroduce operation to get vDPA queue stats
>>
>> Hi Matan,
>>
>> On 4/16/20 11:06 AM, Matan Azrad wrote:
>>> Hi Maxime
>>>
>>> Can you point on specific vendor specific counter I suggested?
>>
>> No, I can't, but I think we can expect that other vendors may have other
>> counters they would be interested to dump.
>>
>> Maybe Intel has some counters in the IFC that they could dump.
>> Xiao, any thoughts?
>>
>>> I think all of them come directly from virtio protocols.
>>
>> exceed_max_chain, for example. Doesn't the spec specify that a descriptors
>> chain can be as long as the size of the virtqueue?
>>
>> Here it seems to indicate the device could support less.
>
> Spec allows device to limit the max supported chain (see [1]).
Ha ok, I missed that. Please note that this is only allowed for packed
ring, it is not in the split ring part.
>>
>> Also, as the spec evolves, we may have new counters that comes up, so
>> better to have something flexible from the start IMHO to avoid ABI
>> breakages.
>
> I think there are better ways to address that, e.g.:
> 1. have some reserved fields for future
> 2. have the option to point to next item, and by that link chain of stat structures
>
>>
>> Maybe we can have some common xstats names for the Virtio related
>> counters define in vdpa lib, and then the vendors can specify more vendor-
>> specific counters if they wish?
>
> xstats are good, and we should have it to expose the vendor specific counters. The basic counters though, should be simple and vendor agnostic so that any SW/scripting layer on top of the DPDK can easily use and expose it.
> Hence I think it will be good to have the basic counters with well-defined stats structure as part of the vdpa stats API. Is the exceed_max_chain is the only counter you find odd or there are more?
Problem is that not all the vDPA NIC will implement these counters, so
with only proposed implementation, the user cannot know whether counter
value is 0 or counter is just not implemented. For example, the Virtio
specification does not specify counters, so a full Virtio HW offload
device won't have them.
So I think the xstat is the right thing to do, with standardized names
for the standard counters.
Regards,
Maxime
>>
>> Thanks,
>> Maxime
>
> [1]
> https://github.com/oasis-tcs/virtio-spec/blob/master/packed-ring.tex#L498
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
2020-04-19 7:35 0% ` David Marchand
@ 2020-04-19 16:17 0% ` Chautru, Nicolas
0 siblings, 0 replies; 200+ results
From: Chautru, Nicolas @ 2020-04-19 16:17 UTC (permalink / raw)
To: David Marchand
Cc: Trahe, Fiona, Akhil Goyal, dev, Jerin Jacob, Pavan Nikhilesh,
Richardson, Bruce, Thomas Monjalon, Yigit, Ferruh,
Hemant Agrawal
Hi David,
I will double check internally then as it may be something just that I miss on my end right now given you cannot reproduce it.
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Sunday, April 19, 2020 12:35 AM
> To: Chautru, Nicolas <nicolas.chautru@intel.com>
> Cc: Trahe, Fiona <fiona.trahe@intel.com>; Akhil Goyal <akhil.goyal@nxp.com>;
> dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan Nikhilesh
> <pbhagavatula@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Thomas Monjalon <thomas@monjalon.net>;
> Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>
> Subject: Re: [dpdk-dev] [PATCH v5] build: disable experimental API check
> internally
>
> On Sat, Apr 18, 2020 at 9:46 PM Chautru, Nicolas <nicolas.chautru@intel.com>
> wrote:
> > It is probably just me but I having issue with this new patch.
> > I typically rebuild the PMD libraries directly when doing incremental changes
> from the Makefile in the PMD directory (ie. not rebuilding full DPDK each time,
> which still work okay obviously).
> > With this new change it doesn't seem to work any longer with the updated
> Makefiles without the ALLOW_EXPERIMENTAL_API:
> > Symbol is not yet part of stable ABI
> > [-Werror=deprecated-declarations] I would need to have a further look but
> checking whether it is just me.
>
> Can you give details?
>
> I just tried with fpga_lte_fec:
> $ make O=$HOME/builds/x86_64-native-linux-gcc+shared+kmods
> drivers/baseband/fpga_lte_fec_sub
> drivers/baseband/fpga_lte_fec_sub
> == Build drivers/baseband/fpga_lte_fec
> CC fpga_lte_fec.o
> PMDINFO fpga_lte_fec.o.pmd.c
> CC fpga_lte_fec.o.pmd.o
> LD fpga_lte_fec.o
> LD librte_pmd_bbdev_fpga_lte_fec.so.20.0.2
> INSTALL-LIB librte_pmd_bbdev_fpga_lte_fec.so.20.0.2
>
>
> --
> David Marchand
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v6 00/33] DPDK Trace support
@ 2020-04-19 10:01 1% ` jerinj
2020-04-22 19:03 1% ` [dpdk-dev] [PATCH v7 00/32] DPDK Trace support jerinj
0 siblings, 2 replies; 200+ results
From: jerinj @ 2020-04-19 10:01 UTC (permalink / raw)
Cc: dev, thomas, bruce.richardson, david.marchand, mattias.ronnblom,
skori, Jerin Jacob
From: Jerin Jacob <jerinj@marvell.com>
v6
~~
Following changes are based on David's feedback.
1) Changed rte_trace_t to rte_trace_point_t
2) Reworked the header file to have following API name and filename changes
rte_trace.h has following trace control APIs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a) rte_trace_is_enabled()
b) rte_trace_mode_set()
c) rte_trace_mode_get()
d) rte_trace_pattern()
e) rte_trace_regexp()
f) rte_trace_save()
g) rte_trace_metadata_dump()
h) rte_trace_dump()
rte_trace_point.h has following tracepoint related APIs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
a) rte_trace_point_enable()
b) rte_trace_point_disable()
c) rte_trace_point_is_enabled()
d) rte_trace_point_lookup()
e) rte_trace_point_emit_*()
f) RTE_TRACE_POINT_* macros
3) made rte_trace_fp_enabled() as internal.
4) Added common macros to have rte_trace_point_emit_* definition at
single place a.k.a more common code now.
5) git grep -l rte_trace_ctf |xargs sed -i -e
's/rte_trace_ctf_/rte_tracepoint_emit_/g'.
6) Added the reason new section for tracepoint in git commit log
7) Sorted symbols alphabetic order in rte_eal_version.map file.
8) Fix snprint return handling bug in __rte_trace_point_emit_field() function.
9) Doc: added newline for section titles.
10) ctf_field and ctf_count made it as static.
v5
~~
Following API rework based David and Thomas feedback.
1) Rename - "Shell pattern" to "Globbing pattern"
2) Remove the log "level" notion from trace library.
3) Remove rte_trace_global_[level/mode]* API from trace library.
4) EAL command line arg to --trace=regex/globing from --trace-level=regex/globing:level
5) Remove "@b EXPERIMENTAL: this API may change without prior notice" from each functions.
6) Use FP instead of DP for fastpath reference.
7) Updated documentation to reflect the above rework.
8) Updated UT to to reflect the above rework.
8) Updated UT for a FP trace point emit.
9) Updated performance test case for a FP trace point emission.
10) Updated git commit comments to reflect the above rework.
v4:
~~
1) Rebased to master.
2) Adapted to latest EAL directory structure change.
3) Fix possible build issue with out of tree application wherein
it does not define -DALLOW_EXPERIMENTAL_API. Fixed by making
fast path trace functions as NOP as it was getting included
in the inline functions of ethdev,mempool, cryptodev, etc(David)
4) Removed DALLOW_EXPERIMENTAL_API definition from individual driver files.
Now it set as global using http://patches.dpdk.org/patch/67758/ patch (David)
5) Added new meson option(-Denable_trace_dp=true)for enabling the datapath trace point (David, Bruce)
6) Changed the authorship and Rewrote the programmer's guide based on the below feedback(Thomas)
http://patches.dpdk.org/patch/67352/
v3:
~~
1) Fix the following build issues reported by CI
http://mails.dpdk.org/archives/test-report/2020-March/122060.html
a) clang + i686 meson build issue(Fixed in the the patch meson: add libatomic as a global dependency for i686 clang)
b) fixed build issue with FreeBSD with top of tree change.
c) fixed missing experimental API for iavf and ice with meson build in avx512 files.
v2:
~~
Addressed the following review comments from Mattias Rönnblom:
1) Changed
from:
typedef uint64_t* rte_trace_t;
to
typedef uint64_t rte_trace_t;
Initially thought to make the handle as
struct rte_trace {
uint64_t val;
}
but changed to uint64_t for the following reasons
a) It is opaque to the application and it will fix the compile-time type
check as well.
b) The handle has an index that will point to an internal slow-path
structure so no ABI change required in the future.
c) RTE_TRACE_POINT_DEFINE need to expose trace object. So it is better
to keep as uint64_t and avoid one more indirection for no use.
2)
Changed:
from:
enum rte_trace_mode_e {
to:
enum rte_trace_mode {
3) removed [out] "found" param from rte_trace_pattern() and
rte_trace_regexp()
4) Changed rte_trace_from_name to rte_trace_by_name
5) rte_trace_is_dp_enabled() return bool now
6) in __rte_trace_point_register() the argument fn change to register_fn
7) removed !! from rte_trace_is_enabled()
8) Remove uninitialized "rc warning" from rte_trace_pattern() and
rte_trace_regexp()
9) fixup bool return type for trace_entry_compare()
10) fixup calloc casting in trace_mkdir()
11) check fclose() return in trace_meta_save() and trace_mem_save()
12) rte_trace_ctf_* macro cleanup
13) added release notes
14) fix build issues reported by CI
http://mails.dpdk.org/archives/test-report/2020-March/121235.html
This patch set contains
~~~~~~~~~~~~~~~~~~~~~~~~
# The native implementation of common trace format(CTF)[1] based tracer
# Public API to create the trace points.
# Add tracepoints to eal, ethdev, mempool, eventdev and cryptodev
library for tracing support
# A unit test case
# Performance test case to measure the trace overhead. (See eal/trace:
# add trace performance test cases, patch)
# Programmers guide for Trace support(See doc: add trace library guide,
# patch)
# Tested OS:
~~~~~~~~~~~
- Linux
- FreeBSD
# Tested open source CTF trace viewers
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- Babeltrace
- Tracecompass
# Trace overhead comparison with LTTng
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
trace overhead data on x86:[2]
# 236 cycles with LTTng(>100ns)
# 18 cycles(7ns) with Native DPDK CTF emitter.(See eal/trace: add trace
# performance test cases patch)
trace overhead data on arm64:
# 312 cycles to 1100 cycles with LTTng based on the class of arm64 CPU.
# 11 cycles to 13 cycles with Native DPDK CTF emitter based on the
class of arm64 CPU.
18 cycles(on x86) vs 11 cycles(on arm64) is due to rdtsc() overhead in
x86. It seems rdtsc takes around 15cycles in x86.
More details:
~~~~~~~~~~~~~
# The Native DPDK CTF trace support does not have any dependency on
third-party library.
The generated output file is compatible with LTTng as both are using
CTF trace format.
The performance gain comes from:
1) exploit dpdk worker thread usage model to avoid atomics and use per
core variables
2) use hugepage,
3) avoid a lot function pointers in fast-path etc
4) avoid unaligned store for arm64 etc
Features:
~~~~~~~~~
- No specific limit on the events. A string-based event like rte_log
for pattern matching
- Dynamic enable/disable support.
- Instructmention overhead is ~1 cycle. i.e cost of adding the code
wth out using trace feature.
- Timestamp support for all the events using DPDK rte_rtdsc
- No dependency on another library. Clean room native implementation of CTF.
Functional test case:
a) echo "trace_autotest" | sudo ./build/app/test/dpdk-test -c 0x3 --trace=.*
The above command emits the following trace events
<code>
uint8_t i;
rte_trace_lib_eal_generic_void();
rte_trace_lib_eal_generic_u64(0x10000000000000);
rte_trace_lib_eal_generic_u32(0x10000000);
rte_trace_lib_eal_generic_u16(0xffee);
rte_trace_lib_eal_generic_u8(0xc);
rte_trace_lib_eal_generic_i64(-1234);
rte_trace_lib_eal_generic_i32(-1234567);
rte_trace_lib_eal_generic_i16(12);
rte_trace_lib_eal_generic_i8(-3);
rte_trace_lib_eal_generic_string("my string");
rte_trace_lib_eal_generic_function(__func__);
</code>
Install babeltrace package in Linux and point the generated trace file
to babel trace. By default trace file created under
<user>/dpdk-traces/time_stamp/
example:
# babeltrace /root/dpdk-traces/rte-2020-02-15-PM-02-56-51 | more
[13:27:36.138468807] (+?.?????????) lib.eal.generic.void: { cpu_id =0, name = "dpdk-test" }, { }
[13:27:36.138468851] (+0.000000044) lib.eal.generic.u64: { cpu_id = 0, name = "dpdk-test" }, { in = 4503599627370496 }
[13:27:36.138468860] (+0.000000009) lib.eal.generic.u32: { cpu_id = 0, name = "dpdk-test" }, { in = 268435456 }
[13:27:36.138468934] (+0.000000074) lib.eal.generic.u16: { cpu_id = 0, name = "dpdk-test" }, { in = 65518 }
[13:27:36.138468949] (+0.000000015) lib.eal.generic.u8: { cpu_id = 0, name = "dpdk-test" }, { in = 12 }
[13:27:36.138468956] (+0.000000007) lib.eal.generic.i64: { cpu_id = 0, name = "dpdk-test" }, { in = -1234 }
[13:27:36.138468963] (+0.000000007) lib.eal.generic.i32: { cpu_id = 0, name = "dpdk-test" }, { in = -1234567 }
[13:27:36.138469024] (+0.000000061) lib.eal.generic.i16: { cpu_id = 0, name = "dpdk-test" }, { in = 12 }
[13:27:36.138469044] (+0.000000020) lib.eal.generic.i8: { cpu_id = 0, name = "dpdk-test" }, { in = -3 }
[13:27:36.138469051] (+0.000000007) lib.eal.generic.string: { cpu_id = 0, name = "dpdk-test" }, { str = "my string" }
[13:27:36.138469203] (+0.000000152) lib.eal.generic.func: { cpu_id = 0, name = "dpdk-test" }, { func = "test_trace_points" }
# There is a GUI based trace viewer available in Windows, Linux and Mac.
It is called as tracecompass.(https://www.eclipse.org/tracecompass/)
The example screenshot and Histogram of above DPDK trace using
Tracecompass.
https://github.com/jerinjacobk/share/blob/master/dpdk_trace.JPG
File walk through:
~~~~~~~~~~~~~~~~~~
lib/librte_eal/common/include/rte_trace.h - Public API for Trace
provider and Trace control
lib/librte_eal/common/eal_common_trace.c - main trace implementation
lib/librte_eal/common/eal_common_trace_ctf.c - CTF metadata spec
implementation
lib/librte_eal/common/eal_common_trace_utils.c - command line utils
and filesystem operations.
lib/librte_eal/common/eal_common_trace_points.c - trace points for EAL
library
lib/librte_eal/common/include/rte_trace_eal.h - EAL tracepoint public
API.
lib/librte_eal/common/eal_trace.h - Private trace header file.
[1] https://diamon.org/ctf/
[2] The above test is ported to LTTng for finding the LTTng trace
overhead. It available at
https://github.com/jerinjacobk/lttng-overhead
https://github.com/jerinjacobk/lttng-overhead/blob/master/README
Jerin Jacob (22):
eal: introduce API for getting thread name
eal/trace: define the public API for trace support
eal/trace: implement trace register API
eal/trace: implement trace operation APIs
eal/trace: add internal trace init and fini interface
eal/trace: get bootup timestamp for trace
eal/trace: create CTF TDSL metadata in memory
eal/trace: implement trace memory allocation
eal/trace: implement debug dump function
eal/trace: implement trace save
eal/trace: implement registration payload
eal/trace: implement provider payload
eal/trace: hook internal trace APIs to Linux
eal/trace: hook internal trace APIs to FreeBSD
eal/trace: add generic tracepoints
eal/trace: add alarm tracepoints
eal/trace: add memory tracepoints
eal/trace: add memzone tracepoints
eal/trace: add thread tracepoints
eal/trace: add interrupt tracepoints
eal/trace: add trace performance test cases
doc: add trace library guide
Pavan Nikhilesh (1):
meson: add libatomic as a global dependency for i686 clang
Sunil Kumar Kori (10):
eal/trace: handle CTF keyword collision
eal/trace: add trace configuration parameter
eal/trace: add trace dir configuration parameter
eal/trace: add trace bufsize configuration parameter
eal/trace: add trace mode configuration parameter
eal/trace: add unit test cases
ethdev: add tracepoints
eventdev: add tracepoints
cryptodev: add tracepoints
mempool: add tracepoints
MAINTAINERS | 8 +
app/test/Makefile | 4 +-
app/test/meson.build | 3 +
app/test/test_trace.c | 223 ++++++++
app/test/test_trace.h | 15 +
app/test/test_trace_perf.c | 183 +++++++
app/test/test_trace_register.c | 17 +
config/common_base | 1 +
config/meson.build | 9 +
doc/api/doxy-api-index.md | 4 +-
doc/guides/linux_gsg/eal_args.include.rst | 52 ++
doc/guides/prog_guide/build-sdk-meson.rst | 5 +
doc/guides/prog_guide/index.rst | 1 +
doc/guides/prog_guide/trace_lib.rst | 346 ++++++++++++
doc/guides/rel_notes/release_20_05.rst | 9 +
drivers/event/octeontx/meson.build | 5 -
drivers/event/octeontx2/meson.build | 5 -
drivers/event/opdl/meson.build | 5 -
examples/cmdline/Makefile | 1 +
examples/cmdline/meson.build | 1 +
examples/distributor/Makefile | 1 +
examples/distributor/meson.build | 1 +
examples/ethtool/ethtool-app/Makefile | 1 +
examples/eventdev_pipeline/meson.build | 1 +
examples/flow_filtering/Makefile | 1 +
examples/flow_filtering/meson.build | 1 +
examples/helloworld/Makefile | 1 +
examples/helloworld/meson.build | 1 +
examples/ioat/Makefile | 1 +
examples/ioat/meson.build | 1 +
examples/ip_fragmentation/Makefile | 2 +
examples/ip_fragmentation/meson.build | 1 +
examples/ip_reassembly/Makefile | 1 +
examples/ip_reassembly/meson.build | 1 +
examples/ipv4_multicast/Makefile | 1 +
examples/ipv4_multicast/meson.build | 1 +
examples/l2fwd-cat/Makefile | 1 +
examples/l2fwd-cat/meson.build | 1 +
examples/l2fwd-event/Makefile | 1 +
examples/l2fwd-event/meson.build | 6 +-
examples/l2fwd-jobstats/Makefile | 1 +
examples/l2fwd-jobstats/meson.build | 1 +
examples/l2fwd-keepalive/Makefile | 1 +
examples/l2fwd-keepalive/ka-agent/Makefile | 1 +
examples/l2fwd-keepalive/meson.build | 1 +
examples/l3fwd-acl/Makefile | 1 +
examples/l3fwd-acl/meson.build | 1 +
examples/l3fwd/Makefile | 1 +
examples/l3fwd/meson.build | 1 +
examples/link_status_interrupt/Makefile | 1 +
examples/link_status_interrupt/meson.build | 1 +
.../client_server_mp/mp_client/Makefile | 1 +
.../client_server_mp/mp_client/meson.build | 1 +
.../client_server_mp/mp_server/meson.build | 1 +
examples/multi_process/hotplug_mp/Makefile | 1 +
examples/multi_process/hotplug_mp/meson.build | 1 +
examples/multi_process/simple_mp/Makefile | 1 +
examples/multi_process/simple_mp/meson.build | 1 +
examples/multi_process/symmetric_mp/Makefile | 1 +
.../multi_process/symmetric_mp/meson.build | 1 +
examples/ntb/Makefile | 1 +
examples/ntb/meson.build | 1 +
examples/packet_ordering/Makefile | 1 +
examples/packet_ordering/meson.build | 1 +
.../performance-thread/l3fwd-thread/Makefile | 1 +
.../l3fwd-thread/meson.build | 1 +
.../performance-thread/pthread_shim/Makefile | 1 +
.../pthread_shim/meson.build | 1 +
examples/ptpclient/Makefile | 1 +
examples/ptpclient/meson.build | 1 +
examples/qos_meter/Makefile | 1 +
examples/qos_meter/meson.build | 1 +
examples/qos_sched/Makefile | 1 +
examples/qos_sched/meson.build | 1 +
examples/server_node_efd/node/Makefile | 1 +
examples/server_node_efd/node/meson.build | 1 +
examples/server_node_efd/server/Makefile | 1 +
examples/server_node_efd/server/meson.build | 1 +
examples/service_cores/Makefile | 1 +
examples/service_cores/meson.build | 1 +
examples/skeleton/Makefile | 1 +
examples/skeleton/meson.build | 1 +
examples/timer/Makefile | 1 +
examples/timer/meson.build | 1 +
examples/vm_power_manager/Makefile | 1 +
examples/vm_power_manager/meson.build | 1 +
examples/vmdq/Makefile | 1 +
examples/vmdq/meson.build | 1 +
examples/vmdq_dcb/Makefile | 1 +
examples/vmdq_dcb/meson.build | 1 +
lib/librte_cryptodev/Makefile | 4 +-
lib/librte_cryptodev/cryptodev_trace_points.c | 70 +++
lib/librte_cryptodev/meson.build | 6 +-
lib/librte_cryptodev/rte_cryptodev.c | 18 +
lib/librte_cryptodev/rte_cryptodev.h | 6 +
.../rte_cryptodev_version.map | 18 +
lib/librte_cryptodev/rte_trace_cryptodev.h | 148 ++++++
lib/librte_cryptodev/rte_trace_cryptodev_fp.h | 38 ++
lib/librte_distributor/meson.build | 5 -
lib/librte_eal/common/eal_common_memzone.c | 9 +
lib/librte_eal/common/eal_common_options.c | 65 +++
lib/librte_eal/common/eal_common_thread.c | 4 +-
lib/librte_eal/common/eal_common_trace.c | 500 ++++++++++++++++++
lib/librte_eal/common/eal_common_trace_ctf.c | 488 +++++++++++++++++
.../common/eal_common_trace_points.c | 115 ++++
.../common/eal_common_trace_utils.c | 478 +++++++++++++++++
lib/librte_eal/common/eal_options.h | 8 +
lib/librte_eal/common/eal_private.h | 5 +
lib/librte_eal/common/eal_trace.h | 122 +++++
lib/librte_eal/common/meson.build | 4 +
lib/librte_eal/common/rte_malloc.c | 60 ++-
lib/librte_eal/freebsd/Makefile | 4 +
lib/librte_eal/freebsd/eal.c | 10 +
lib/librte_eal/freebsd/eal_alarm.c | 3 +
lib/librte_eal/freebsd/eal_interrupts.c | 54 +-
lib/librte_eal/freebsd/eal_thread.c | 21 +-
lib/librte_eal/include/meson.build | 5 +
lib/librte_eal/include/rte_lcore.h | 17 +
lib/librte_eal/include/rte_trace.h | 141 +++++
lib/librte_eal/include/rte_trace_eal.h | 278 ++++++++++
lib/librte_eal/include/rte_trace_point.h | 306 +++++++++++
.../include/rte_trace_point_provider.h | 131 +++++
.../include/rte_trace_point_register.h | 39 ++
lib/librte_eal/linux/Makefile | 4 +
lib/librte_eal/linux/eal.c | 9 +
lib/librte_eal/linux/eal_alarm.c | 4 +
lib/librte_eal/linux/eal_interrupts.c | 84 +--
lib/librte_eal/linux/eal_thread.c | 27 +-
lib/librte_eal/rte_eal_version.map | 50 ++
lib/librte_ethdev/Makefile | 3 +
lib/librte_ethdev/ethdev_trace_points.c | 43 ++
lib/librte_ethdev/meson.build | 5 +-
lib/librte_ethdev/rte_ethdev.c | 12 +
lib/librte_ethdev/rte_ethdev.h | 5 +
lib/librte_ethdev/rte_ethdev_version.map | 10 +
lib/librte_ethdev/rte_trace_ethdev.h | 97 ++++
lib/librte_ethdev/rte_trace_ethdev_fp.h | 44 ++
lib/librte_eventdev/Makefile | 3 +
lib/librte_eventdev/eventdev_trace_points.c | 173 ++++++
lib/librte_eventdev/meson.build | 3 +
.../rte_event_crypto_adapter.c | 10 +
.../rte_event_eth_rx_adapter.c | 11 +
.../rte_event_eth_tx_adapter.c | 13 +-
.../rte_event_eth_tx_adapter.h | 2 +
lib/librte_eventdev/rte_event_timer_adapter.c | 8 +-
lib/librte_eventdev/rte_event_timer_adapter.h | 8 +
lib/librte_eventdev/rte_eventdev.c | 9 +
lib/librte_eventdev/rte_eventdev.h | 5 +-
lib/librte_eventdev/rte_eventdev_version.map | 42 ++
lib/librte_eventdev/rte_trace_eventdev.h | 311 +++++++++++
lib/librte_eventdev/rte_trace_eventdev_fp.h | 85 +++
lib/librte_mempool/Makefile | 3 +
lib/librte_mempool/mempool_trace_points.c | 108 ++++
lib/librte_mempool/meson.build | 5 +-
lib/librte_mempool/rte_mempool.c | 16 +
lib/librte_mempool/rte_mempool.h | 13 +
lib/librte_mempool/rte_mempool_ops.c | 7 +
lib/librte_mempool/rte_mempool_version.map | 26 +
lib/librte_mempool/rte_trace_mempool.h | 178 +++++++
lib/librte_mempool/rte_trace_mempool_fp.h | 116 ++++
lib/librte_rcu/meson.build | 5 -
meson_options.txt | 2 +
162 files changed, 5607 insertions(+), 105 deletions(-)
create mode 100644 app/test/test_trace.c
create mode 100644 app/test/test_trace.h
create mode 100644 app/test/test_trace_perf.c
create mode 100644 app/test/test_trace_register.c
create mode 100644 doc/guides/prog_guide/trace_lib.rst
create mode 100644 lib/librte_cryptodev/cryptodev_trace_points.c
create mode 100644 lib/librte_cryptodev/rte_trace_cryptodev.h
create mode 100644 lib/librte_cryptodev/rte_trace_cryptodev_fp.h
create mode 100644 lib/librte_eal/common/eal_common_trace.c
create mode 100644 lib/librte_eal/common/eal_common_trace_ctf.c
create mode 100644 lib/librte_eal/common/eal_common_trace_points.c
create mode 100644 lib/librte_eal/common/eal_common_trace_utils.c
create mode 100644 lib/librte_eal/common/eal_trace.h
create mode 100644 lib/librte_eal/include/rte_trace.h
create mode 100644 lib/librte_eal/include/rte_trace_eal.h
create mode 100644 lib/librte_eal/include/rte_trace_point.h
create mode 100644 lib/librte_eal/include/rte_trace_point_provider.h
create mode 100644 lib/librte_eal/include/rte_trace_point_register.h
create mode 100644 lib/librte_ethdev/ethdev_trace_points.c
create mode 100644 lib/librte_ethdev/rte_trace_ethdev.h
create mode 100644 lib/librte_ethdev/rte_trace_ethdev_fp.h
create mode 100644 lib/librte_eventdev/eventdev_trace_points.c
create mode 100644 lib/librte_eventdev/rte_trace_eventdev.h
create mode 100644 lib/librte_eventdev/rte_trace_eventdev_fp.h
create mode 100644 lib/librte_mempool/mempool_trace_points.c
create mode 100644 lib/librte_mempool/rte_trace_mempool.h
create mode 100644 lib/librte_mempool/rte_trace_mempool_fp.h
--
2.25.1
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
2020-04-18 19:43 3% ` Chautru, Nicolas
@ 2020-04-19 7:35 0% ` David Marchand
2020-04-19 16:17 0% ` Chautru, Nicolas
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2020-04-19 7:35 UTC (permalink / raw)
To: Chautru, Nicolas
Cc: Trahe, Fiona, Akhil Goyal, dev, Jerin Jacob, Pavan Nikhilesh,
Richardson, Bruce, Thomas Monjalon, Yigit, Ferruh,
Hemant Agrawal
On Sat, Apr 18, 2020 at 9:46 PM Chautru, Nicolas
<nicolas.chautru@intel.com> wrote:
> It is probably just me but I having issue with this new patch.
> I typically rebuild the PMD libraries directly when doing incremental changes from the Makefile in the PMD directory (ie. not rebuilding full DPDK each time, which still work okay obviously).
> With this new change it doesn't seem to work any longer with the updated Makefiles without the ALLOW_EXPERIMENTAL_API:
> Symbol is not yet part of stable ABI [-Werror=deprecated-declarations]
> I would need to have a further look but checking whether it is just me.
Can you give details?
I just tried with fpga_lte_fec:
$ make O=$HOME/builds/x86_64-native-linux-gcc+shared+kmods
drivers/baseband/fpga_lte_fec_sub
drivers/baseband/fpga_lte_fec_sub
== Build drivers/baseband/fpga_lte_fec
CC fpga_lte_fec.o
PMDINFO fpga_lte_fec.o.pmd.c
CC fpga_lte_fec.o.pmd.o
LD fpga_lte_fec.o
LD librte_pmd_bbdev_fpga_lte_fec.so.20.0.2
INSTALL-LIB librte_pmd_bbdev_fpga_lte_fec.so.20.0.2
--
David Marchand
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/4] vhost: inroduce operation to get vDPA queue stats
@ 2020-04-19 6:18 0% ` Shahaf Shuler
2020-04-20 7:13 0% ` Maxime Coquelin
0 siblings, 1 reply; 200+ results
From: Shahaf Shuler @ 2020-04-19 6:18 UTC (permalink / raw)
To: Maxime Coquelin, Matan Azrad, dev, Xiao Wang; +Cc: Slava Ovsiienko
Thursday, April 16, 2020 4:20 PM, Maxime Coquelin:
> Subject: Re: [PATCH 1/4] vhost: inroduce operation to get vDPA queue stats
>
> Hi Matan,
>
> On 4/16/20 11:06 AM, Matan Azrad wrote:
> > Hi Maxime
> >
> > Can you point on specific vendor specific counter I suggested?
>
> No, I can't, but I think we can expect that other vendors may have other
> counters they would be interested to dump.
>
> Maybe Intel has some counters in the IFC that they could dump.
> Xiao, any thoughts?
>
> > I think all of them come directly from virtio protocols.
>
> exceed_max_chain, for example. Doesn't the spec specify that a descriptors
> chain can be as long as the size of the virtqueue?
>
> Here it seems to indicate the device could support less.
Spec allows device to limit the max supported chain (see [1]).
>
> Also, as the spec evolves, we may have new counters that comes up, so
> better to have something flexible from the start IMHO to avoid ABI
> breakages.
I think there are better ways to address that, e.g.:
1. have some reserved fields for future
2. have the option to point to next item, and by that link chain of stat structures
>
> Maybe we can have some common xstats names for the Virtio related
> counters define in vdpa lib, and then the vendors can specify more vendor-
> specific counters if they wish?
xstats are good, and we should have it to expose the vendor specific counters. The basic counters though, should be simple and vendor agnostic so that any SW/scripting layer on top of the DPDK can easily use and expose it.
Hence I think it will be good to have the basic counters with well-defined stats structure as part of the vdpa stats API. Is the exceed_max_chain is the only counter you find odd or there are more?
>
> Thanks,
> Maxime
[1]
https://github.com/oasis-tcs/virtio-spec/blob/master/packed-ring.tex#L498
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v5 0/9] New sync modes for ring
2020-04-18 16:32 3% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Konstantin Ananyev
2020-04-18 16:32 9% ` [dpdk-dev] [PATCH v5 2/9] ring: prepare ring to allow new sync schemes Konstantin Ananyev
2020-04-18 16:32 1% ` [dpdk-dev] [PATCH v5 3/9] ring: introduce RTS ring mode Konstantin Ananyev
@ 2020-04-19 2:32 0% ` Honnappa Nagarahalli
2020-04-20 12:11 3% ` [dpdk-dev] [PATCH v6 00/10] " Konstantin Ananyev
3 siblings, 0 replies; 200+ results
From: Honnappa Nagarahalli @ 2020-04-19 2:32 UTC (permalink / raw)
To: Konstantin Ananyev, dev
Cc: david.marchand, jielong.zjl, nd, Honnappa Nagarahalli, nd
Hi Konstantin,
Changes look good overall, I have integrated RCU defer APIs patch as well. Please consider adding the following (in another patch?)
1) Release notes
2) Updates to programmer guide for RTS and HTS modes
Thank you,
Honnappa
> -----Original Message-----
> From: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Sent: Saturday, April 18, 2020 11:32 AM
> To: dev@dpdk.org
> Cc: Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>;
> david.marchand@redhat.com; jielong.zjl@antfin.com; Konstantin Ananyev
> <konstantin.ananyev@intel.com>
> Subject: [PATCH v5 0/9] New sync modes for ring
>
> V4 - V5:
> 1. fix i686 clang build problem
> 2. fix formal API comments
>
> V3 - V4 changes:
> Address comments from Honnappa:
> 1. for new sync modes make legacy API wrappers around _elem_ calls 2.
> remove rte_ring_(hts|rts)_generic.h 3. few changes in C11 version 4. peek API
> - add missing functions for _elem_ 5. remove _IS_SP/_IS_MP, etc. internal
> macros 6. fix param types (obj_table) for _elem_functions 7. fix formal API
> comments 8. deduplicate code for test_ring_stress 9. added functional tests
> for new sync modes
>
> V2 - V3 changes:
> 1. few more compilation fixes (for gcc 4.8.X) 2. extra update
> devtools/libabigail.abignore (workaround)
>
> V1 - V2 changes:
> 1. fix compilation issues
> 2. add C11 atomics support
> 3. updates devtools/libabigail.abignore (workaround)
>
> RFC - V1 changes:
> 1. remove ABI brekage (at least I hope I did) 2. Add support for ring_elem 3.
> rework peek related API a bit 4. rework test to make it less verbose and unite
> all test-cases
> in one command
> 5. add new test-case for MT peek API
>
> TODO list:
> 1. Update docs
>
> These days more and more customers use(/try to use) DPDK based apps
> within overcommitted systems (multiple acttive threads over same pysical
> cores):
> VM, container deployments, etc.
> One quite common problem they hit:
> Lock-Holder-Preemption/Lock-Waiter-Preemption with rte_ring.
> LHP is quite a common problem for spin-based sync primitives (spin-locks, etc.)
> on overcommitted systems.
> The situation gets much worse when some sort of fair-locking technique is
> used (ticket-lock, etc.).
> As now not only lock-owner but also lock-waiters scheduling order matters a
> lot (LWP).
> These two problems are well-known for kernel within VMs:
> http://www-archive.xenproject.org/files/xensummitboston08/LHP.pdf
> https://www.cs.hs-rm.de/~kaiser/events/wamos2017/Slides/selcuk.pdf
> The problem with rte_ring is that while head accusion is sort of un-fair locking,
> waiting on tail is very similar to ticket lock schema - tail has to be updated in
> particular order.
> That makes current rte_ring implementation to perform really pure on some
> overcommited scenarios.
> It is probably not possible to completely resolve LHP problem in userspace
> only (without some kernel communication/intervention).
> But removing fairness at tail update helps to avoid LWP and can mitigate the
> situation significantly.
> This patch proposes two new optional ring synchronization modes:
> 1) Head/Tail Sync (HTS) mode
> In that mode enqueue/dequeue operation is fully serialized:
> only one thread at a time is allowed to perform given op.
> As another enhancement provide ability to split enqueue/dequeue
> operation into two phases:
> - enqueue/dequeue start
> - enqueue/dequeue finish
> That allows user to inspect objects in the ring without removing
> them from it (aka MT safe peek).
> 2) Relaxed Tail Sync (RTS)
> The main difference from original MP/MC algorithm is that tail value is
> increased not by every thread that finished enqueue/dequeue, but only by the
> last one.
> That allows threads to avoid spinning on ring tail value, leaving actual tail
> value change to the last thread in the update queue.
>
> Note that these new sync modes are optional.
> For current rte_ring users nothing should change (both in terms of API/ABI
> and performance).
> Existing sync modes MP/MC,SP/SC kept untouched, set up in the same way
> (via flags and _init_), and MP/MC remains as default one.
> The only thing that changed:
> Format of prod/cons now could differ depending on mode selected at _init_.
> So user has to stick with one sync model through whole ring lifetime.
> In other words, user can't create a ring for let say SP mode and then in the
> middle of data-path change his mind and start using MP_RTS mode.
> For existing modes (SP/MP, SC/MC) format remains the same and user can
> still use them interchangeably, though of course it is an error prone practice.
>
> Test results on IA (see below) show significant improvements for average
> enqueue/dequeue op times on overcommitted systems.
> For 'classic' DPDK deployments (one thread per core) original MP/MC
> algorithm still shows best numbers, though for 64-bit target RTS numbers are
> not that far away.
> Numbers were produced by new UT test-case: ring_stress_autotest, i.e.:
> echo ring_stress_autotest | ./dpdk-test -n 4 --lcores='...'
>
> X86_64 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
> DEQ+ENQ average cycles/obj
> MP/MC HTS RTS
> 1thread@1core(--lcores=6-7) 8.00 8.15 8.99
> 2thread@2core(--lcores=6-8) 19.14 19.61 20.35
> 4thread@4core(--lcores=6-10) 29.43 29.79 31.82
> 8thread@8core(--lcores=6-14) 110.59 192.81 119.50
> 16thread@16core(--lcores=6-22) 461.03 813.12 495.59
> 32thread/@32core(--lcores='6-22,55-70') 982.90 1972.38 1160.51
>
> 2thread@1core(--lcores='6,(10-11)@7' 20140.50 23.58 25.14
> 4thread@2core(--lcores='6,(10-11)@7,(20-21)@8' 153680.60 76.88 80.05
> 8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 280314.32 294.72
> 318.79 16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 643176.59
> 1144.02 1175.14 32thread@2core(--lcores='6,(10-25)@7,(30-45)@8'
> 4264238.80 4627.48 4892.68
>
> 8thread@2core(--lcores='6,(10-17)@(7,8))' 321085.98 298.59 307.47
> 16thread@4core(--lcores='6,(20-35)@(7-10))' 1900705.61 575.35 678.29
> 32thread@4core(--lcores='6,(20-51)@(7-10))' 5510445.85 2164.36
> 2714.12
>
> i686 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
> DEQ+ENQ average cycles/obj
> MP/MC HTS RTS
> 1thread@1core(--lcores=6-7) 7.85 12.13 11.31
> 2thread@2core(--lcores=6-8) 17.89 24.52 21.86
> 8thread@8core(--lcores=6-14) 32.58 354.20 54.58
> 32thread/@32core(--lcores='6-22,55-70') 813.77 6072.41 2169.91
>
> 2thread@1core(--lcores='6,(10-11)@7' 16095.00 36.06 34.74
> 8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 1140354.54 346.61
> 361.57 16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 1920417.86
> 1314.90 1416.65
>
> 8thread@2core(--lcores='6,(10-17)@(7,8))' 594358.61 332.70 357.74
> 32thread@4core(--lcores='6,(20-51)@(7-10))' 5319896.86 2836.44
> 3028.87
>
> Konstantin Ananyev (9):
> test/ring: add contention stress test
> ring: prepare ring to allow new sync schemes
> ring: introduce RTS ring mode
> test/ring: add contention stress test for RTS ring
> ring: introduce HTS ring mode
> test/ring: add contention stress test for HTS ring
> ring: introduce peek style API
> test/ring: add stress test for MT peek API
> test/ring: add functional tests for new sync modes
>
> app/test/Makefile | 5 +
> app/test/meson.build | 5 +
> app/test/test_pdump.c | 6 +-
> app/test/test_ring.c | 93 ++++--
> app/test/test_ring_hts_stress.c | 32 ++
> app/test/test_ring_mpmc_stress.c | 31 ++
> app/test/test_ring_peek_stress.c | 43 +++
> app/test/test_ring_rts_stress.c | 32 ++
> app/test/test_ring_stress.c | 57 ++++
> app/test/test_ring_stress.h | 38 +++
> app/test/test_ring_stress_impl.h | 396 ++++++++++++++++++++++
> devtools/libabigail.abignore | 7 +
> lib/librte_pdump/rte_pdump.c | 2 +-
> lib/librte_port/rte_port_ring.c | 12 +-
> lib/librte_ring/Makefile | 8 +-
> lib/librte_ring/meson.build | 11 +-
> lib/librte_ring/rte_ring.c | 114 ++++++-
> lib/librte_ring/rte_ring.h | 243 ++++++++------
> lib/librte_ring/rte_ring_c11_mem.h | 44 +++
> lib/librte_ring/rte_ring_core.h | 184 ++++++++++
> lib/librte_ring/rte_ring_elem.h | 141 ++++++--
> lib/librte_ring/rte_ring_generic.h | 48 +++
> lib/librte_ring/rte_ring_hts.h | 332 +++++++++++++++++++
> lib/librte_ring/rte_ring_hts_c11_mem.h | 207 ++++++++++++
> lib/librte_ring/rte_ring_peek.h | 442 +++++++++++++++++++++++++
> lib/librte_ring/rte_ring_rts.h | 439 ++++++++++++++++++++++++
> lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
> 27 files changed, 2977 insertions(+), 174 deletions(-) create mode 100644
> app/test/test_ring_hts_stress.c create mode 100644
> app/test/test_ring_mpmc_stress.c create mode 100644
> app/test/test_ring_peek_stress.c create mode 100644
> app/test/test_ring_rts_stress.c create mode 100644
> app/test/test_ring_stress.c create mode 100644 app/test/test_ring_stress.h
> create mode 100644 app/test/test_ring_stress_impl.h create mode 100644
> lib/librte_ring/rte_ring_core.h create mode 100644
> lib/librte_ring/rte_ring_hts.h create mode 100644
> lib/librte_ring/rte_ring_hts_c11_mem.h
> create mode 100644 lib/librte_ring/rte_ring_peek.h create mode 100644
> lib/librte_ring/rte_ring_rts.h create mode 100644
> lib/librte_ring/rte_ring_rts_c11_mem.h
>
> --
> 2.17.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v5 3/9] ring: introduce RTS ring mode
2020-04-18 16:32 1% ` [dpdk-dev] [PATCH v5 3/9] ring: introduce RTS ring mode Konstantin Ananyev
@ 2020-04-19 2:31 0% ` Honnappa Nagarahalli
0 siblings, 0 replies; 200+ results
From: Honnappa Nagarahalli @ 2020-04-19 2:31 UTC (permalink / raw)
To: Konstantin Ananyev, dev; +Cc: david.marchand, jielong.zjl, nd
<snip>
>
> Introduce relaxed tail sync (RTS) mode for MT ring synchronization.
> Aim to reduce stall times in case when ring is used on overcommited cpus
> (multiple active threads on the same cpu).
> The main difference from original MP/MC algorithm is that tail value is
> increased not by every thread that finished enqueue/dequeue, but only by the
> last one.
> That allows threads to avoid spinning on ring tail value, leaving actual tail
> value change to the last thread in the update queue.
>
> Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
Few nits, otherwise
Acked-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> ---
>
> check-abi.sh reports what I believe is a false-positive about ring cons/prod
> changes. As a workaround, devtools/libabigail.abignore is updated to
> suppress *struct ring* related errors.
>
> devtools/libabigail.abignore | 7 +
> lib/librte_ring/Makefile | 4 +-
> lib/librte_ring/meson.build | 7 +-
> lib/librte_ring/rte_ring.c | 100 +++++-
> lib/librte_ring/rte_ring.h | 70 +++-
> lib/librte_ring/rte_ring_core.h | 36 +-
> lib/librte_ring/rte_ring_elem.h | 90 ++++-
> lib/librte_ring/rte_ring_rts.h | 439 +++++++++++++++++++++++++
> lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
> 9 files changed, 902 insertions(+), 30 deletions(-) create mode 100644
> lib/librte_ring/rte_ring_rts.h create mode 100644
> lib/librte_ring/rte_ring_rts_c11_mem.h
>
> diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore index
> a59df8f13..cd86d89ca 100644
> --- a/devtools/libabigail.abignore
> +++ b/devtools/libabigail.abignore
> @@ -11,3 +11,10 @@
> type_kind = enum
> name = rte_crypto_asym_xform_type
> changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
> +; Ignore updates of ring prod/cons
> +[suppress_type]
> + type_kind = struct
> + name = rte_ring
> +[suppress_type]
> + type_kind = struct
> + name = rte_event_ring
> diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile index
> 6572768c9..04e446e37 100644
> --- a/lib/librte_ring/Makefile
> +++ b/lib/librte_ring/Makefile
> @@ -19,6 +19,8 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include :=
> rte_ring.h \
> rte_ring_core.h \
> rte_ring_elem.h \
> rte_ring_generic.h \
> - rte_ring_c11_mem.h
> + rte_ring_c11_mem.h \
> + rte_ring_rts.h \
> + rte_ring_rts_c11_mem.h
>
> include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build index
> c656781da..a95598032 100644
> --- a/lib/librte_ring/meson.build
> +++ b/lib/librte_ring/meson.build
> @@ -6,4 +6,9 @@ headers = files('rte_ring.h',
> 'rte_ring_core.h',
> 'rte_ring_elem.h',
> 'rte_ring_c11_mem.h',
> - 'rte_ring_generic.h')
> + 'rte_ring_generic.h',
> + 'rte_ring_rts.h',
> + 'rte_ring_rts_c11_mem.h')
> +
> +# rte_ring_create_elem and rte_ring_get_memsize_elem are experimental
> +allow_experimental_apis = true
> diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c index
> fa5733907..222eec0fb 100644
> --- a/lib/librte_ring/rte_ring.c
> +++ b/lib/librte_ring/rte_ring.c
> @@ -45,6 +45,9 @@ EAL_REGISTER_TAILQ(rte_ring_tailq)
> /* true if x is a power of 2 */
> #define POWEROF2(x) ((((x)-1) & (x)) == 0)
>
> +/* by default set head/tail distance as 1/8 of ring capacity */
> +#define HTD_MAX_DEF 8
> +
> /* return the size of memory occupied by a ring */ ssize_t
> rte_ring_get_memsize_elem(unsigned int esize, unsigned int count) @@ -
> 79,11 +82,84 @@ rte_ring_get_memsize(unsigned int count)
> return rte_ring_get_memsize_elem(sizeof(void *), count); }
>
> +/*
> + * internal helper function to reset prod/cons head-tail values.
> + */
> +static void
> +reset_headtail(void *p)
The internal functions have used __rte prefix in ring library. I think we should follow the same here.
> +{
> + struct rte_ring_headtail *ht;
> + struct rte_ring_rts_headtail *ht_rts;
> +
> + ht = p;
> + ht_rts = p;
> +
> + switch (ht->sync_type) {
> + case RTE_RING_SYNC_MT:
> + case RTE_RING_SYNC_ST:
> + ht->head = 0;
> + ht->tail = 0;
> + break;
> + case RTE_RING_SYNC_MT_RTS:
> + ht_rts->head.raw = 0;
> + ht_rts->tail.raw = 0;
> + break;
> + default:
> + /* unknown sync mode */
> + RTE_ASSERT(0);
> + }
> +}
> +
> void
> rte_ring_reset(struct rte_ring *r)
> {
> - r->prod.head = r->cons.head = 0;
> - r->prod.tail = r->cons.tail = 0;
> + reset_headtail(&r->prod);
> + reset_headtail(&r->cons);
> +}
> +
> +/*
> + * helper function, calculates sync_type values for prod and cons
> + * based on input flags. Returns zero at success or negative
> + * errno value otherwise.
> + */
> +static int
> +get_sync_type(uint32_t flags, enum rte_ring_sync_type *prod_st,
> + enum rte_ring_sync_type *cons_st)
The internal functions have used __rte prefix in ring library. I think we should follow the same here.
Also, it will help avoid symbol clashes.
> +{
> + static const uint32_t prod_st_flags =
> + (RING_F_SP_ENQ | RING_F_MP_RTS_ENQ);
> + static const uint32_t cons_st_flags =
> + (RING_F_SC_DEQ | RING_F_MC_RTS_DEQ);
> +
> + switch (flags & prod_st_flags) {
> + case 0:
> + *prod_st = RTE_RING_SYNC_MT;
> + break;
> + case RING_F_SP_ENQ:
> + *prod_st = RTE_RING_SYNC_ST;
> + break;
> + case RING_F_MP_RTS_ENQ:
> + *prod_st = RTE_RING_SYNC_MT_RTS;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + switch (flags & cons_st_flags) {
> + case 0:
> + *cons_st = RTE_RING_SYNC_MT;
> + break;
> + case RING_F_SC_DEQ:
> + *cons_st = RTE_RING_SYNC_ST;
> + break;
> + case RING_F_MC_RTS_DEQ:
> + *cons_st = RTE_RING_SYNC_MT_RTS;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + return 0;
> }
>
> int
> @@ -100,16 +176,20 @@ rte_ring_init(struct rte_ring *r, const char *name,
> unsigned count,
> RTE_BUILD_BUG_ON((offsetof(struct rte_ring, prod) &
> RTE_CACHE_LINE_MASK) != 0);
>
> + RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, sync_type) !=
> + offsetof(struct rte_ring_rts_headtail, sync_type));
> + RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, tail) !=
> + offsetof(struct rte_ring_rts_headtail, tail.val.pos));
> +
> /* init the ring structure */
> memset(r, 0, sizeof(*r));
> ret = strlcpy(r->name, name, sizeof(r->name));
> if (ret < 0 || ret >= (int)sizeof(r->name))
> return -ENAMETOOLONG;
> r->flags = flags;
> - r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
> - RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
> - r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
> - RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
> + ret = get_sync_type(flags, &r->prod.sync_type, &r->cons.sync_type);
> + if (ret != 0)
> + return ret;
>
> if (flags & RING_F_EXACT_SZ) {
> r->size = rte_align32pow2(count + 1); @@ -126,8 +206,12
> @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
> r->mask = count - 1;
> r->capacity = r->mask;
> }
> - r->prod.head = r->cons.head = 0;
> - r->prod.tail = r->cons.tail = 0;
> +
> + /* set default values for head-tail distance */
> + if (flags & RING_F_MP_RTS_ENQ)
> + rte_ring_set_prod_htd_max(r, r->capacity / HTD_MAX_DEF);
> + if (flags & RING_F_MC_RTS_DEQ)
> + rte_ring_set_cons_htd_max(r, r->capacity / HTD_MAX_DEF);
>
> return 0;
> }
> diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h index
> 35ee4491c..77f206ca7 100644
> --- a/lib/librte_ring/rte_ring.h
> +++ b/lib/librte_ring/rte_ring.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: BSD-3-Clause
> *
> - * Copyright (c) 2010-2017 Intel Corporation
> + * Copyright (c) 2010-2020 Intel Corporation
> * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
> * All rights reserved.
> * Derived from FreeBSD's bufring.h
> @@ -389,8 +389,21 @@ static __rte_always_inline unsigned int
> rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
> unsigned int n, unsigned int *free_space) {
> - return __rte_ring_do_enqueue(r, obj_table, n,
> RTE_RING_QUEUE_FIXED,
> - r->prod.sync_type, free_space);
> + switch (r->prod.sync_type) {
> + case RTE_RING_SYNC_MT:
> + return rte_ring_mp_enqueue_bulk(r, obj_table, n, free_space);
> + case RTE_RING_SYNC_ST:
> + return rte_ring_sp_enqueue_bulk(r, obj_table, n, free_space);
> #ifdef
> +ALLOW_EXPERIMENTAL_API
> + case RTE_RING_SYNC_MT_RTS:
> + return rte_ring_mp_rts_enqueue_bulk(r, obj_table, n,
> + free_space);
> +#endif
> + }
> +
> + /* valid ring should never reach this point */
> + RTE_ASSERT(0);
> + return 0;
> }
>
> /**
> @@ -524,8 +537,20 @@ static __rte_always_inline unsigned int
> rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
> unsigned int *available)
> {
> - return __rte_ring_do_dequeue(r, obj_table, n,
> RTE_RING_QUEUE_FIXED,
> - r->cons.sync_type, available);
> + switch (r->cons.sync_type) {
> + case RTE_RING_SYNC_MT:
> + return rte_ring_mc_dequeue_bulk(r, obj_table, n, available);
> + case RTE_RING_SYNC_ST:
> + return rte_ring_sc_dequeue_bulk(r, obj_table, n, available);
> #ifdef
> +ALLOW_EXPERIMENTAL_API
> + case RTE_RING_SYNC_MT_RTS:
> + return rte_ring_mc_rts_dequeue_bulk(r, obj_table, n,
> available);
> +#endif
> + }
> +
> + /* valid ring should never reach this point */
> + RTE_ASSERT(0);
> + return 0;
> }
>
> /**
> @@ -845,8 +870,21 @@ static __rte_always_inline unsigned
> rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
> unsigned int n, unsigned int *free_space) {
> - return __rte_ring_do_enqueue(r, obj_table, n,
> RTE_RING_QUEUE_VARIABLE,
> - r->prod.sync_type, free_space);
> + switch (r->prod.sync_type) {
> + case RTE_RING_SYNC_MT:
> + return rte_ring_mp_enqueue_burst(r, obj_table, n,
> free_space);
> + case RTE_RING_SYNC_ST:
> + return rte_ring_sp_enqueue_burst(r, obj_table, n, free_space);
> #ifdef
> +ALLOW_EXPERIMENTAL_API
> + case RTE_RING_SYNC_MT_RTS:
> + return rte_ring_mp_rts_enqueue_burst(r, obj_table, n,
> + free_space);
> +#endif
> + }
> +
> + /* valid ring should never reach this point */
> + RTE_ASSERT(0);
> + return 0;
> }
>
> /**
> @@ -925,9 +963,21 @@ static __rte_always_inline unsigned
> rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
> unsigned int n, unsigned int *available) {
> - return __rte_ring_do_dequeue(r, obj_table, n,
> - RTE_RING_QUEUE_VARIABLE,
> - r->cons.sync_type, available);
> + switch (r->cons.sync_type) {
> + case RTE_RING_SYNC_MT:
> + return rte_ring_mc_dequeue_burst(r, obj_table, n, available);
> + case RTE_RING_SYNC_ST:
> + return rte_ring_sc_dequeue_burst(r, obj_table, n, available);
> #ifdef
> +ALLOW_EXPERIMENTAL_API
> + case RTE_RING_SYNC_MT_RTS:
> + return rte_ring_mc_rts_dequeue_burst(r, obj_table, n,
> + available);
> +#endif
> + }
> +
> + /* valid ring should never reach this point */
> + RTE_ASSERT(0);
> + return 0;
> }
>
> #ifdef __cplusplus
> diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
> index d9cef763f..ded0fa0b7 100644
> --- a/lib/librte_ring/rte_ring_core.h
> +++ b/lib/librte_ring/rte_ring_core.h
> @@ -57,6 +57,9 @@ enum rte_ring_queue_behavior { enum
> rte_ring_sync_type {
> RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
> RTE_RING_SYNC_ST, /**< single thread only */
> +#ifdef ALLOW_EXPERIMENTAL_API
> + RTE_RING_SYNC_MT_RTS, /**< multi-thread relaxed tail sync */
These need to be documented in rte_ring_init, rte_ring_create, rte_ring_create_elem API comments.
Also, please check if you want to update the file description in rte_ring.h in brief to capture the new features.
> #endif
> };
>
> /**
> @@ -76,6 +79,22 @@ struct rte_ring_headtail {
> };
> };
>
> +union rte_ring_rts_poscnt {
I think this is internal structure, prefix can be __rte
> + /** raw 8B value to read/write *cnt* and *pos* as one atomic op */
> + uint64_t raw __rte_aligned(8);
> + struct {
> + uint32_t cnt; /**< head/tail reference counter */
> + uint32_t pos; /**< head/tail position */
> + } val;
> +};
> +
> +struct rte_ring_rts_headtail {
Same here, the prefix can be __rte
> + volatile union rte_ring_rts_poscnt tail;
> + enum rte_ring_sync_type sync_type; /**< sync type of prod/cons */
> + uint32_t htd_max; /**< max allowed distance between head/tail */
> + volatile union rte_ring_rts_poscnt head; };
> +
> /**
> * An RTE ring structure.
> *
> @@ -104,11 +123,21 @@ struct rte_ring {
> char pad0 __rte_cache_aligned; /**< empty cache line */
>
> /** Ring producer status. */
> - struct rte_ring_headtail prod __rte_cache_aligned;
> + RTE_STD_C11
> + union {
> + struct rte_ring_headtail prod;
> + struct rte_ring_rts_headtail rts_prod;
> + } __rte_cache_aligned;
> +
> char pad1 __rte_cache_aligned; /**< empty cache line */
>
> /** Ring consumer status. */
> - struct rte_ring_headtail cons __rte_cache_aligned;
> + RTE_STD_C11
> + union {
> + struct rte_ring_headtail cons;
> + struct rte_ring_rts_headtail rts_cons;
> + } __rte_cache_aligned;
> +
> char pad2 __rte_cache_aligned; /**< empty cache line */ };
>
> @@ -125,6 +154,9 @@ struct rte_ring {
> #define RING_F_EXACT_SZ 0x0004
> #define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
>
> +#define RING_F_MP_RTS_ENQ 0x0008 /**< The default enqueue is "MP
> RTS".
> +*/ #define RING_F_MC_RTS_DEQ 0x0010 /**< The default dequeue is "MC
> +RTS". */
> +
> #ifdef __cplusplus
> }
> #endif
> diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
> index 7406c0b0f..6da0a917b 100644
> --- a/lib/librte_ring/rte_ring_elem.h
> +++ b/lib/librte_ring/rte_ring_elem.h
> @@ -528,6 +528,10 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r,
> const void *obj_table,
> RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST,
> free_space); }
>
> +#ifdef ALLOW_EXPERIMENTAL_API
> +#include <rte_ring_rts.h>
> +#endif
> +
> /**
> * Enqueue several objects on a ring.
> *
> @@ -557,6 +561,26 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r,
> const void *obj_table, {
> return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
> RTE_RING_QUEUE_FIXED, r->prod.sync_type,
> free_space);
> +
> + switch (r->prod.sync_type) {
> + case RTE_RING_SYNC_MT:
> + return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
> + free_space);
> + case RTE_RING_SYNC_ST:
> + return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
> + free_space);
> +#ifdef ALLOW_EXPERIMENTAL_API
> + case RTE_RING_SYNC_MT_RTS:
> + return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table,
> esize, n,
> + free_space);
> +#endif
> + }
> +
> + /* valid ring should never reach this point */
> + RTE_ASSERT(0);
> + if (free_space != NULL)
> + *free_space = 0;
> + return 0;
> }
>
> /**
> @@ -661,7 +685,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r,
> void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_FIXED,
> RTE_RING_SYNC_MT, available);
> + RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT,
> available);
> }
>
> /**
> @@ -719,8 +743,25 @@ static __rte_always_inline unsigned int
> rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *available) {
> - return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_FIXED, r->cons.sync_type,
> available);
> + switch (r->cons.sync_type) {
> + case RTE_RING_SYNC_MT:
> + return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
> + available);
> + case RTE_RING_SYNC_ST:
> + return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
> + available);
> +#ifdef ALLOW_EXPERIMENTAL_API
> + case RTE_RING_SYNC_MT_RTS:
> + return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table,
> esize,
> + n, available);
> +#endif
> + }
> +
> + /* valid ring should never reach this point */
> + RTE_ASSERT(0);
> + if (available != NULL)
> + *available = 0;
> + return 0;
> }
>
> /**
> @@ -887,8 +928,25 @@ static __rte_always_inline unsigned
> rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *free_space) {
> - return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_VARIABLE, r->prod.sync_type,
> free_space);
> + switch (r->prod.sync_type) {
> + case RTE_RING_SYNC_MT:
> + return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize,
> n,
> + free_space);
> + case RTE_RING_SYNC_ST:
> + return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
> + free_space);
> +#ifdef ALLOW_EXPERIMENTAL_API
> + case RTE_RING_SYNC_MT_RTS:
> + return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table,
> esize,
> + n, free_space);
> +#endif
> + }
> +
> + /* valid ring should never reach this point */
> + RTE_ASSERT(0);
> + if (free_space != NULL)
> + *free_space = 0;
> + return 0;
> }
>
> /**
> @@ -979,9 +1037,25 @@ static __rte_always_inline unsigned int
> rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *available) {
> - return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_VARIABLE,
> - r->cons.sync_type, available);
> + switch (r->cons.sync_type) {
> + case RTE_RING_SYNC_MT:
> + return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
> + available);
> + case RTE_RING_SYNC_ST:
> + return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
> + available);
> +#ifdef ALLOW_EXPERIMENTAL_API
> + case RTE_RING_SYNC_MT_RTS:
> + return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table,
> esize,
> + n, available);
> +#endif
> + }
> +
> + /* valid ring should never reach this point */
> + RTE_ASSERT(0);
> + if (available != NULL)
> + *available = 0;
> + return 0;
> }
>
> #include <rte_ring.h>
> diff --git a/lib/librte_ring/rte_ring_rts.h b/lib/librte_ring/rte_ring_rts.h new
> file mode 100644 index 000000000..8ced07096
> --- /dev/null
> +++ b/lib/librte_ring/rte_ring_rts.h
> @@ -0,0 +1,439 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Copyright (c) 2010-2020 Intel Corporation
> + * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
> + * All rights reserved.
> + * Derived from FreeBSD's bufring.h
> + * Used as BSD-3 Licensed with permission from Kip Macy.
> + */
> +
> +#ifndef _RTE_RING_RTS_H_
> +#define _RTE_RING_RTS_H_
> +
> +/**
> + * @file rte_ring_rts.h
> + * @b EXPERIMENTAL: this API may change without prior notice
> + * It is not recommended to include this file directly.
> + * Please include <rte_ring.h> instead.
> + *
> + * Contains functions for Relaxed Tail Sync (RTS) ring mode.
> + * The main idea remains the same as for our original MP/MC
> +synchronization
> + * mechanism.
> + * The main difference is that tail value is increased not
> + * by every thread that finished enqueue/dequeue,
> + * but only by the current last one doing enqueue/dequeue.
> + * That allows threads to skip spinning on tail value,
> + * leaving actual tail value change to last thread at a given instance.
> + * RTS requires 2 64-bit CAS for each enqueue(/dequeue) operation:
> + * one for head update, second for tail update.
> + * As a gain it allows thread to avoid spinning/waiting on tail value.
> + * In comparision original MP/MC algorithm requires one 32-bit CAS
> + * for head update and waiting/spinning on tail value.
> + *
> + * Brief outline:
> + * - introduce update counter (cnt) for both head and tail.
> + * - increment head.cnt for each head.value update
> + * - write head.value and head.cnt atomically (64-bit CAS)
> + * - move tail.value ahead only when tail.cnt + 1 == head.cnt
> + * (indicating that this is the last thread updating the tail)
> + * - increment tail.cnt when each enqueue/dequeue op finishes
> + * (no matter if tail.value going to change or not)
> + * - write tail.value and tail.cnt atomically (64-bit CAS)
> + *
> + * To avoid producer/consumer starvation:
> + * - limit max allowed distance between head and tail value (HTD_MAX).
> + * I.E. thread is allowed to proceed with changing head.value,
> + * only when: head.value - tail.value <= HTD_MAX
> + * HTD_MAX is an optional parameter.
> + * With HTD_MAX == 0 we'll have fully serialized ring -
> + * i.e. only one thread at a time will be able to enqueue/dequeue
> + * to/from the ring.
> + * With HTD_MAX >= ring.capacity - no limitation.
> + * By default HTD_MAX == ring.capacity / 8.
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <rte_ring_rts_c11_mem.h>
> +
> +/**
> + * @internal Enqueue several objects on the RTS ring.
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of objects.
> + * @param esize
> + * The size of ring element, in bytes. It must be a multiple of 4.
> + * This must be the same value used while creating the ring. Otherwise
> + * the results are undefined.
> + * @param n
> + * The number of objects to add in the ring from the obj_table.
> + * @param behavior
> + * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring
> + * RTE_RING_QUEUE_VARIABLE: Enqueue as many items as possible from
> ring
> + * @param free_space
> + * returns the amount of space after the enqueue operation has finished
> + * @return
> + * Actual number of objects enqueued.
> + * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
> + */
> +static __rte_always_inline unsigned int
> +__rte_ring_do_rts_enqueue_elem(struct rte_ring *r, const void *obj_table,
> + uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
> + uint32_t *free_space)
> +{
> + uint32_t free, head;
> +
> + n = __rte_ring_rts_move_prod_head(r, n, behavior, &head, &free);
> +
> + if (n != 0) {
> + __rte_ring_enqueue_elems(r, head, obj_table, esize, n);
> + __rte_ring_rts_update_tail(&r->rts_prod);
> + }
> +
> + if (free_space != NULL)
> + *free_space = free - n;
> + return n;
> +}
> +
> +/**
> + * @internal Dequeue several objects from the RTS ring.
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of objects.
> + * @param esize
> + * The size of ring element, in bytes. It must be a multiple of 4.
> + * This must be the same value used while creating the ring. Otherwise
> + * the results are undefined.
> + * @param n
> + * The number of objects to pull from the ring.
> + * @param behavior
> + * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a
> ring
> + * RTE_RING_QUEUE_VARIABLE: Dequeue as many items as possible from
> ring
> + * @param available
> + * returns the number of remaining ring entries after the dequeue has
> finished
> + * @return
> + * - Actual number of objects dequeued.
> + * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
> + */
> +static __rte_always_inline unsigned int
> +__rte_ring_do_rts_dequeue_elem(struct rte_ring *r, void *obj_table,
> + uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
> + uint32_t *available)
> +{
> + uint32_t entries, head;
> +
> + n = __rte_ring_rts_move_cons_head(r, n, behavior, &head, &entries);
> +
> + if (n != 0) {
> + __rte_ring_dequeue_elems(r, head, obj_table, esize, n);
> + __rte_ring_rts_update_tail(&r->rts_cons);
> + }
> +
> + if (available != NULL)
> + *available = entries - n;
> + return n;
> +}
> +
> +/**
> + * Enqueue several objects on the RTS ring (multi-producers safe).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of objects.
> + * @param esize
> + * The size of ring element, in bytes. It must be a multiple of 4.
> + * This must be the same value used while creating the ring. Otherwise
> + * the results are undefined.
> + * @param n
> + * The number of objects to add in the ring from the obj_table.
> + * @param free_space
> + * if non-NULL, returns the amount of space in the ring after the
> + * enqueue operation has finished.
> + * @return
> + * The number of objects enqueued, either 0 or n
> + */
> +__rte_experimental
> +static __rte_always_inline unsigned int
> +rte_ring_mp_rts_enqueue_bulk_elem(struct rte_ring *r, const void
> *obj_table,
> + unsigned int esize, unsigned int n, unsigned int *free_space) {
> + return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
> + RTE_RING_QUEUE_FIXED, free_space);
> +}
> +
> +/**
> + * Dequeue several objects from an RTS ring (multi-consumers safe).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of objects that will be filled.
> + * @param esize
> + * The size of ring element, in bytes. It must be a multiple of 4.
> + * This must be the same value used while creating the ring. Otherwise
> + * the results are undefined.
> + * @param n
> + * The number of objects to dequeue from the ring to the obj_table.
> + * @param available
> + * If non-NULL, returns the number of remaining ring entries after the
> + * dequeue has finished.
> + * @return
> + * The number of objects dequeued, either 0 or n
> + */
> +__rte_experimental
> +static __rte_always_inline unsigned int
> +rte_ring_mc_rts_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
> + unsigned int esize, unsigned int n, unsigned int *available) {
> + return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
> + RTE_RING_QUEUE_FIXED, available);
> +}
> +
> +/**
> + * Enqueue several objects on the RTS ring (multi-producers safe).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of objects.
> + * @param esize
> + * The size of ring element, in bytes. It must be a multiple of 4.
> + * This must be the same value used while creating the ring. Otherwise
> + * the results are undefined.
> + * @param n
> + * The number of objects to add in the ring from the obj_table.
> + * @param free_space
> + * if non-NULL, returns the amount of space in the ring after the
> + * enqueue operation has finished.
> + * @return
> + * - n: Actual number of objects enqueued.
> + */
> +__rte_experimental
> +static __rte_always_inline unsigned
> +rte_ring_mp_rts_enqueue_burst_elem(struct rte_ring *r, const void
> *obj_table,
> + unsigned int esize, unsigned int n, unsigned int *free_space) {
> + return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
> + RTE_RING_QUEUE_VARIABLE, free_space); }
> +
> +/**
> + * Dequeue several objects from an RTS ring (multi-consumers safe).
> + * When the requested objects are more than the available objects,
> + * only dequeue the actual number of objects.
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of objects that will be filled.
> + * @param esize
> + * The size of ring element, in bytes. It must be a multiple of 4.
> + * This must be the same value used while creating the ring. Otherwise
> + * the results are undefined.
> + * @param n
> + * The number of objects to dequeue from the ring to the obj_table.
> + * @param available
> + * If non-NULL, returns the number of remaining ring entries after the
> + * dequeue has finished.
> + * @return
> + * - n: Actual number of objects dequeued, 0 if ring is empty
> + */
> +__rte_experimental
> +static __rte_always_inline unsigned
> +rte_ring_mc_rts_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
> + unsigned int esize, unsigned int n, unsigned int *available) {
> + return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
> + RTE_RING_QUEUE_VARIABLE, available); }
> +
> +/**
> + * Enqueue several objects on the RTS ring (multi-producers safe).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of void * pointers (objects).
> + * @param n
> + * The number of objects to add in the ring from the obj_table.
> + * @param free_space
> + * if non-NULL, returns the amount of space in the ring after the
> + * enqueue operation has finished.
> + * @return
> + * The number of objects enqueued, either 0 or n
> + */
> +__rte_experimental
> +static __rte_always_inline unsigned int
> +rte_ring_mp_rts_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
> + unsigned int n, unsigned int *free_space) {
> + return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table,
> + sizeof(uintptr_t), n, free_space);
> +}
> +
> +/**
> + * Dequeue several objects from an RTS ring (multi-consumers safe).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of void * pointers (objects) that will be filled.
> + * @param n
> + * The number of objects to dequeue from the ring to the obj_table.
> + * @param available
> + * If non-NULL, returns the number of remaining ring entries after the
> + * dequeue has finished.
> + * @return
> + * The number of objects dequeued, either 0 or n
> + */
> +__rte_experimental
> +static __rte_always_inline unsigned int
> +rte_ring_mc_rts_dequeue_bulk(struct rte_ring *r, void **obj_table,
> + unsigned int n, unsigned int *available) {
> + return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table,
> + sizeof(uintptr_t), n, available);
> +}
> +
> +/**
> + * Enqueue several objects on the RTS ring (multi-producers safe).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of void * pointers (objects).
> + * @param n
> + * The number of objects to add in the ring from the obj_table.
> + * @param free_space
> + * if non-NULL, returns the amount of space in the ring after the
> + * enqueue operation has finished.
> + * @return
> + * - n: Actual number of objects enqueued.
> + */
> +__rte_experimental
> +static __rte_always_inline unsigned
> +rte_ring_mp_rts_enqueue_burst(struct rte_ring *r, void * const *obj_table,
> + unsigned int n, unsigned int *free_space) {
> + return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table,
> + sizeof(uintptr_t), n, free_space);
> +}
> +
> +/**
> + * Dequeue several objects from an RTS ring (multi-consumers safe).
> + * When the requested objects are more than the available objects,
> + * only dequeue the actual number of objects.
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param obj_table
> + * A pointer to a table of void * pointers (objects) that will be filled.
> + * @param n
> + * The number of objects to dequeue from the ring to the obj_table.
> + * @param available
> + * If non-NULL, returns the number of remaining ring entries after the
> + * dequeue has finished.
> + * @return
> + * - n: Actual number of objects dequeued, 0 if ring is empty
> + */
> +__rte_experimental
> +static __rte_always_inline unsigned
> +rte_ring_mc_rts_dequeue_burst(struct rte_ring *r, void **obj_table,
> + unsigned int n, unsigned int *available) {
> + return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table,
> + sizeof(uintptr_t), n, available);
> +}
> +
> +/**
> + * Return producer max Head-Tail-Distance (HTD).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @return
> + * Producer HTD value, if producer is set in appropriate sync mode,
> + * or UINT32_MAX otherwise.
> + */
> +__rte_experimental
> +static inline uint32_t
> +rte_ring_get_prod_htd_max(const struct rte_ring *r) {
> + if (r->prod.sync_type == RTE_RING_SYNC_MT_RTS)
> + return r->rts_prod.htd_max;
> + return UINT32_MAX;
> +}
> +
> +/**
> + * Set producer max Head-Tail-Distance (HTD).
> + * Note that producer has to use appropriate sync mode (RTS).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param v
> + * new HTD value to setup.
> + * @return
> + * Zero on success, or negative error code otherwise.
> + */
> +__rte_experimental
> +static inline int
> +rte_ring_set_prod_htd_max(struct rte_ring *r, uint32_t v) {
> + if (r->prod.sync_type != RTE_RING_SYNC_MT_RTS)
> + return -ENOTSUP;
> +
> + r->rts_prod.htd_max = v;
> + return 0;
> +}
> +
> +/**
> + * Return consumer max Head-Tail-Distance (HTD).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @return
> + * Consumer HTD value, if consumer is set in appropriate sync mode,
> + * or UINT32_MAX otherwise.
> + */
> +__rte_experimental
> +static inline uint32_t
> +rte_ring_get_cons_htd_max(const struct rte_ring *r) {
> + if (r->cons.sync_type == RTE_RING_SYNC_MT_RTS)
> + return r->rts_cons.htd_max;
> + return UINT32_MAX;
> +}
> +
> +/**
> + * Set consumer max Head-Tail-Distance (HTD).
> + * Note that consumer has to use appropriate sync mode (RTS).
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @param v
> + * new HTD value to setup.
> + * @return
> + * Zero on success, or negative error code otherwise.
> + */
> +__rte_experimental
> +static inline int
> +rte_ring_set_cons_htd_max(struct rte_ring *r, uint32_t v) {
> + if (r->cons.sync_type != RTE_RING_SYNC_MT_RTS)
> + return -ENOTSUP;
> +
> + r->rts_cons.htd_max = v;
> + return 0;
> +}
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_RING_RTS_H_ */
> diff --git a/lib/librte_ring/rte_ring_rts_c11_mem.h
> b/lib/librte_ring/rte_ring_rts_c11_mem.h
> new file mode 100644
> index 000000000..9f26817c0
> --- /dev/null
> +++ b/lib/librte_ring/rte_ring_rts_c11_mem.h
> @@ -0,0 +1,179 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Copyright (c) 2010-2020 Intel Corporation
> + * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
> + * All rights reserved.
> + * Derived from FreeBSD's bufring.h
> + * Used as BSD-3 Licensed with permission from Kip Macy.
> + */
> +
> +#ifndef _RTE_RING_RTS_C11_MEM_H_
> +#define _RTE_RING_RTS_C11_MEM_H_
> +
> +/**
> + * @file rte_ring_rts_c11_mem.h
> + * It is not recommended to include this file directly,
> + * include <rte_ring.h> instead.
> + * Contains internal helper functions for Relaxed Tail Sync (RTS) ring mode.
> + * For more information please refer to <rte_ring_rts.h>.
> + */
> +
> +/**
> + * @internal This function updates tail values.
> + */
> +static __rte_always_inline void
> +__rte_ring_rts_update_tail(struct rte_ring_rts_headtail *ht) {
> + union rte_ring_rts_poscnt h, ot, nt;
> +
> + /*
> + * If there are other enqueues/dequeues in progress that
> + * might preceded us, then don't update tail with new value.
> + */
> +
> + ot.raw = __atomic_load_n(&ht->tail.raw, __ATOMIC_ACQUIRE);
> +
> + do {
> + /* on 32-bit systems we have to do atomic read here */
> + h.raw = __atomic_load_n(&ht->head.raw,
> __ATOMIC_RELAXED);
> +
> + nt.raw = ot.raw;
> + if (++nt.val.cnt == h.val.cnt)
> + nt.val.pos = h.val.pos;
> +
> + } while (__atomic_compare_exchange_n(&ht->tail.raw, &ot.raw,
> nt.raw,
> + 0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE) == 0); }
> +
> +/**
> + * @internal This function waits till head/tail distance wouldn't
> + * exceed pre-defined max value.
> + */
> +static __rte_always_inline void
> +__rte_ring_rts_head_wait(const struct rte_ring_rts_headtail *ht,
> + union rte_ring_rts_poscnt *h)
> +{
> + uint32_t max;
> +
> + max = ht->htd_max;
> +
> + while (h->val.pos - ht->tail.val.pos > max) {
> + rte_pause();
> + h->raw = __atomic_load_n(&ht->head.raw,
> __ATOMIC_ACQUIRE);
> + }
> +}
> +
> +/**
> + * @internal This function updates the producer head for enqueue.
> + */
> +static __rte_always_inline uint32_t
> +__rte_ring_rts_move_prod_head(struct rte_ring *r, uint32_t num,
> + enum rte_ring_queue_behavior behavior, uint32_t *old_head,
> + uint32_t *free_entries)
> +{
> + uint32_t n;
> + union rte_ring_rts_poscnt nh, oh;
> +
> + const uint32_t capacity = r->capacity;
> +
> + oh.raw = __atomic_load_n(&r->rts_prod.head.raw,
> __ATOMIC_ACQUIRE);
> +
> + do {
> + /* Reset n to the initial burst count */
> + n = num;
> +
> + /*
> + * wait for prod head/tail distance,
> + * make sure that we read prod head *before*
> + * reading cons tail.
> + */
> + __rte_ring_rts_head_wait(&r->rts_prod, &oh);
> +
> + /*
> + * The subtraction is done between two unsigned 32bits
> value
> + * (the result is always modulo 32 bits even if we have
> + * *old_head > cons_tail). So 'free_entries' is always between
> 0
> + * and capacity (which is < size).
> + */
> + *free_entries = capacity + r->cons.tail - oh.val.pos;
> +
> + /* check that we have enough room in ring */
> + if (unlikely(n > *free_entries))
> + n = (behavior == RTE_RING_QUEUE_FIXED) ?
> + 0 : *free_entries;
> +
> + if (n == 0)
> + break;
> +
> + nh.val.pos = oh.val.pos + n;
> + nh.val.cnt = oh.val.cnt + 1;
> +
> + /*
> + * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
> + * - OOO reads of cons tail value
> + * - OOO copy of elems to the ring
> + */
> + } while (__atomic_compare_exchange_n(&r->rts_prod.head.raw,
> + &oh.raw, nh.raw,
> + 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
> +
> + *old_head = oh.val.pos;
> + return n;
> +}
> +
> +/**
> + * @internal This function updates the consumer head for dequeue */
> +static __rte_always_inline unsigned int
> +__rte_ring_rts_move_cons_head(struct rte_ring *r, uint32_t num,
> + enum rte_ring_queue_behavior behavior, uint32_t *old_head,
> + uint32_t *entries)
> +{
> + uint32_t n;
> + union rte_ring_rts_poscnt nh, oh;
> +
> + oh.raw = __atomic_load_n(&r->rts_cons.head.raw,
> __ATOMIC_ACQUIRE);
> +
> + /* move cons.head atomically */
> + do {
> + /* Restore n as it may change every loop */
> + n = num;
> +
> + /*
> + * wait for cons head/tail distance,
> + * make sure that we read cons head *before*
> + * reading prod tail.
> + */
> + __rte_ring_rts_head_wait(&r->rts_cons, &oh);
> +
> + /* The subtraction is done between two unsigned 32bits value
> + * (the result is always modulo 32 bits even if we have
> + * cons_head > prod_tail). So 'entries' is always between 0
> + * and size(ring)-1.
> + */
> + *entries = r->prod.tail - oh.val.pos;
> +
> + /* Set the actual entries for dequeue */
> + if (n > *entries)
> + n = (behavior == RTE_RING_QUEUE_FIXED) ? 0 :
> *entries;
> +
> + if (unlikely(n == 0))
> + break;
> +
> + nh.val.pos = oh.val.pos + n;
> + nh.val.cnt = oh.val.cnt + 1;
> +
> + /*
> + * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
> + * - OOO reads of prod tail value
> + * - OOO copy of elems from the ring
> + */
> + } while (__atomic_compare_exchange_n(&r->rts_cons.head.raw,
> + &oh.raw, nh.raw,
> + 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
> +
> + *old_head = oh.val.pos;
> + return n;
> +}
> +
> +#endif /* _RTE_RING_RTS_C11_MEM_H_ */
> --
> 2.17.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v5 2/9] ring: prepare ring to allow new sync schemes
2020-04-18 16:32 9% ` [dpdk-dev] [PATCH v5 2/9] ring: prepare ring to allow new sync schemes Konstantin Ananyev
@ 2020-04-19 2:31 0% ` Honnappa Nagarahalli
0 siblings, 0 replies; 200+ results
From: Honnappa Nagarahalli @ 2020-04-19 2:31 UTC (permalink / raw)
To: Konstantin Ananyev, dev
Cc: david.marchand, jielong.zjl, nd, Honnappa Nagarahalli, nd
<snip>
>
> To make these preparations two main things are done:
> - Change from *single* to *sync_type* to allow different
> synchronisation schemes to be applied.
> Mark *single* as deprecated in comments.
> Add new functions to allow user to query ring sync types.
> Replace direct access to *single* with appropriate function call.
> - Move actual rte_ring and related structures definitions into a
> separate file: <rte_ring_core.h>. It allows to refer contents
> of <rte_ring_elem.h> from <rte_ring.h> without introducing a
> circular dependency.
>
> Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
few nits inline, otherwise
Acked-by: Honnappa Nagarahalli <honnappa.nagarahalli@arm.com>
> ---
> app/test/test_pdump.c | 6 +-
> lib/librte_pdump/rte_pdump.c | 2 +-
> lib/librte_port/rte_port_ring.c | 12 +--
> lib/librte_ring/Makefile | 1 +
> lib/librte_ring/meson.build | 1 +
> lib/librte_ring/rte_ring.c | 6 +-
> lib/librte_ring/rte_ring.h | 170 ++++++++++++++------------------
> lib/librte_ring/rte_ring_core.h | 132 +++++++++++++++++++++++++
> lib/librte_ring/rte_ring_elem.h | 42 +++-----
> 9 files changed, 234 insertions(+), 138 deletions(-) create mode 100644
> lib/librte_ring/rte_ring_core.h
>
> diff --git a/app/test/test_pdump.c b/app/test/test_pdump.c index
> ad183184c..6a1180bcb 100644
> --- a/app/test/test_pdump.c
> +++ b/app/test/test_pdump.c
> @@ -57,8 +57,7 @@ run_pdump_client_tests(void)
> if (ret < 0)
> return -1;
> mp->flags = 0x0000;
> - ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(),
> - RING_F_SP_ENQ | RING_F_SC_DEQ);
> + ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(), 0);
> if (ring_client == NULL) {
> printf("rte_ring_create SR0 failed");
> return -1;
> @@ -71,9 +70,6 @@ run_pdump_client_tests(void)
> }
> rte_eth_dev_probing_finish(eth_dev);
>
> - ring_client->prod.single = 0;
> - ring_client->cons.single = 0;
> -
> printf("\n***** flags = RTE_PDUMP_FLAG_TX *****\n");
>
> for (itr = 0; itr < NUM_ITR; itr++) {
> diff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c
> index 8a01ac510..f96709f95 100644
> --- a/lib/librte_pdump/rte_pdump.c
> +++ b/lib/librte_pdump/rte_pdump.c
> @@ -380,7 +380,7 @@ pdump_validate_ring_mp(struct rte_ring *ring, struct
> rte_mempool *mp)
> rte_errno = EINVAL;
> return -1;
> }
> - if (ring->prod.single || ring->cons.single) {
> + if (rte_ring_is_prod_single(ring) || rte_ring_is_cons_single(ring)) {
> PDUMP_LOG(ERR, "ring with either SP or SC settings"
> " is not valid for pdump, should have MP and MC settings\n");
> rte_errno = EINVAL;
> diff --git a/lib/librte_port/rte_port_ring.c b/lib/librte_port/rte_port_ring.c
> index 47fcdd06a..52b2d8e55 100644
> --- a/lib/librte_port/rte_port_ring.c
> +++ b/lib/librte_port/rte_port_ring.c
> @@ -44,8 +44,8 @@ rte_port_ring_reader_create_internal(void *params, int
> socket_id,
> /* Check input parameters */
> if ((conf == NULL) ||
> (conf->ring == NULL) ||
> - (conf->ring->cons.single && is_multi) ||
> - (!(conf->ring->cons.single) && !is_multi)) {
> + (rte_ring_is_cons_single(conf->ring) && is_multi) ||
> + (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
> RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
> return NULL;
> }
> @@ -171,8 +171,8 @@ rte_port_ring_writer_create_internal(void *params,
> int socket_id,
> /* Check input parameters */
> if ((conf == NULL) ||
> (conf->ring == NULL) ||
> - (conf->ring->prod.single && is_multi) ||
> - (!(conf->ring->prod.single) && !is_multi) ||
> + (rte_ring_is_prod_single(conf->ring) && is_multi) ||
> + (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
> (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
> RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
> return NULL;
> @@ -440,8 +440,8 @@ rte_port_ring_writer_nodrop_create_internal(void
> *params, int socket_id,
> /* Check input parameters */
> if ((conf == NULL) ||
> (conf->ring == NULL) ||
> - (conf->ring->prod.single && is_multi) ||
> - (!(conf->ring->prod.single) && !is_multi) ||
> + (rte_ring_is_prod_single(conf->ring) && is_multi) ||
> + (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
> (conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
> RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
> return NULL;
> diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile index
> 28368e6d1..6572768c9 100644
> --- a/lib/librte_ring/Makefile
> +++ b/lib/librte_ring/Makefile
> @@ -16,6 +16,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_RING) := rte_ring.c
>
> # install includes
> SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
> + rte_ring_core.h \
> rte_ring_elem.h \
> rte_ring_generic.h \
> rte_ring_c11_mem.h
> diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build index
> 05402e4f0..c656781da 100644
> --- a/lib/librte_ring/meson.build
> +++ b/lib/librte_ring/meson.build
> @@ -3,6 +3,7 @@
>
> sources = files('rte_ring.c')
> headers = files('rte_ring.h',
> + 'rte_ring_core.h',
> 'rte_ring_elem.h',
> 'rte_ring_c11_mem.h',
> 'rte_ring_generic.h')
> diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c index
> 77e5de099..fa5733907 100644
> --- a/lib/librte_ring/rte_ring.c
> +++ b/lib/librte_ring/rte_ring.c
> @@ -106,8 +106,10 @@ rte_ring_init(struct rte_ring *r, const char *name,
> unsigned count,
> if (ret < 0 || ret >= (int)sizeof(r->name))
> return -ENAMETOOLONG;
> r->flags = flags;
> - r->prod.single = (flags & RING_F_SP_ENQ) ? __IS_SP : __IS_MP;
> - r->cons.single = (flags & RING_F_SC_DEQ) ? __IS_SC : __IS_MC;
> + r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
> + RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
> + r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
> + RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
>
> if (flags & RING_F_EXACT_SZ) {
> r->size = rte_align32pow2(count + 1); diff --git
> a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h index
> 18fc5d845..35ee4491c 100644
> --- a/lib/librte_ring/rte_ring.h
> +++ b/lib/librte_ring/rte_ring.h
> @@ -36,91 +36,7 @@
> extern "C" {
> #endif
>
> -#include <stdio.h>
> -#include <stdint.h>
> -#include <sys/queue.h>
> -#include <errno.h>
> -#include <rte_common.h>
> -#include <rte_config.h>
> -#include <rte_memory.h>
> -#include <rte_lcore.h>
> -#include <rte_atomic.h>
> -#include <rte_branch_prediction.h>
> -#include <rte_memzone.h>
> -#include <rte_pause.h>
> -
> -#define RTE_TAILQ_RING_NAME "RTE_RING"
> -
> -enum rte_ring_queue_behavior {
> - RTE_RING_QUEUE_FIXED = 0, /* Enq/Deq a fixed number of items
> from a ring */
> - RTE_RING_QUEUE_VARIABLE /* Enq/Deq as many items as possible
> from ring */
> -};
> -
> -#define RTE_RING_MZ_PREFIX "RG_"
> -/** The maximum length of a ring name. */ -#define RTE_RING_NAMESIZE
> (RTE_MEMZONE_NAMESIZE - \
> - sizeof(RTE_RING_MZ_PREFIX) + 1)
> -
> -/* structure to hold a pair of head/tail values and other metadata */ -struct
> rte_ring_headtail {
> - volatile uint32_t head; /**< Prod/consumer head. */
> - volatile uint32_t tail; /**< Prod/consumer tail. */
> - uint32_t single; /**< True if single prod/cons */
> -};
> -
> -/**
> - * An RTE ring structure.
> - *
> - * The producer and the consumer have a head and a tail index. The
> particularity
> - * of these index is that they are not between 0 and size(ring). These indexes
> - * are between 0 and 2^32, and we mask their value when we access the
> ring[]
> - * field. Thanks to this assumption, we can do subtractions between 2 index
> - * values in a modulo-32bit base: that's why the overflow of the indexes is
> not
> - * a problem.
> - */
> -struct rte_ring {
> - /*
> - * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
> - * compatibility requirements, it could be changed to
> RTE_RING_NAMESIZE
> - * next time the ABI changes
> - */
> - char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned; /**<
> Name of the ring. */
> - int flags; /**< Flags supplied at creation. */
> - const struct rte_memzone *memzone;
> - /**< Memzone, if any, containing the rte_ring */
> - uint32_t size; /**< Size of ring. */
> - uint32_t mask; /**< Mask (size-1) of ring. */
> - uint32_t capacity; /**< Usable size of ring */
> -
> - char pad0 __rte_cache_aligned; /**< empty cache line */
> -
> - /** Ring producer status. */
> - struct rte_ring_headtail prod __rte_cache_aligned;
> - char pad1 __rte_cache_aligned; /**< empty cache line */
> -
> - /** Ring consumer status. */
> - struct rte_ring_headtail cons __rte_cache_aligned;
> - char pad2 __rte_cache_aligned; /**< empty cache line */
> -};
> -
> -#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-
> producer". */ -#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is
> "single-consumer". */
These do not appear in the API document anymore
> -/**
> - * Ring is to hold exactly requested number of entries.
> - * Without this flag set, the ring size requested must be a power of 2, and the
> - * usable space will be that size - 1. With the flag, the requested size will
> - * be rounded up to the next power of two, but the usable space will be
> exactly
> - * that requested. Worst case, if a power-of-2 size is requested, half the
> - * ring space will be wasted.
> - */
> -#define RING_F_EXACT_SZ 0x0004
> -#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
> -
> -/* @internal defines for passing to the enqueue dequeue worker functions */
> -#define __IS_SP 1 -#define __IS_MP 0 -#define __IS_SC 1 -#define __IS_MC 0
> +#include <rte_ring_core.h>
>
> /**
> * Calculate the memory size needed for a ring @@ -420,7 +336,7 @@
> rte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
> unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue(r, obj_table, n,
> RTE_RING_QUEUE_FIXED,
> - __IS_MP, free_space);
> + RTE_RING_SYNC_MT, free_space);
> }
>
> /**
> @@ -443,9 +359,13 @@ rte_ring_sp_enqueue_bulk(struct rte_ring *r, void *
> const *obj_table,
> unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue(r, obj_table, n,
> RTE_RING_QUEUE_FIXED,
> - __IS_SP, free_space);
> + RTE_RING_SYNC_ST, free_space);
> }
>
> +#ifdef ALLOW_EXPERIMENTAL_API
> +#include <rte_ring_elem.h>
> +#endif
> +
> /**
> * Enqueue several objects on a ring.
> *
> @@ -470,7 +390,7 @@ rte_ring_enqueue_bulk(struct rte_ring *r, void *
> const *obj_table,
> unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue(r, obj_table, n,
> RTE_RING_QUEUE_FIXED,
> - r->prod.single, free_space);
> + r->prod.sync_type, free_space);
> }
>
> /**
> @@ -554,7 +474,7 @@ rte_ring_mc_dequeue_bulk(struct rte_ring *r, void
> **obj_table,
> unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue(r, obj_table, n,
> RTE_RING_QUEUE_FIXED,
> - __IS_MC, available);
> + RTE_RING_SYNC_MT, available);
> }
>
> /**
> @@ -578,7 +498,7 @@ rte_ring_sc_dequeue_bulk(struct rte_ring *r, void
> **obj_table,
> unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue(r, obj_table, n,
> RTE_RING_QUEUE_FIXED,
> - __IS_SC, available);
> + RTE_RING_SYNC_ST, available);
> }
>
> /**
> @@ -605,7 +525,7 @@ rte_ring_dequeue_bulk(struct rte_ring *r, void
> **obj_table, unsigned int n,
> unsigned int *available)
> {
> return __rte_ring_do_dequeue(r, obj_table, n,
> RTE_RING_QUEUE_FIXED,
> - r->cons.single, available);
> + r->cons.sync_type, available);
> }
>
> /**
> @@ -777,6 +697,62 @@ rte_ring_get_capacity(const struct rte_ring *r)
> return r->capacity;
> }
>
> +/**
> + * Return sync type used by producer in the ring.
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @return
> + * Producer sync type value.
> + */
> +static inline enum rte_ring_sync_type
> +rte_ring_get_prod_sync_type(const struct rte_ring *r) {
> + return r->prod.sync_type;
> +}
> +
> +/**
> + * Check is the ring for single producer.
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @return
> + * true if ring is SP, zero otherwise.
> + */
> +static inline int
> +rte_ring_is_prod_single(const struct rte_ring *r) {
> + return (rte_ring_get_prod_sync_type(r) == RTE_RING_SYNC_ST); }
> +
> +/**
> + * Return sync type used by consumer in the ring.
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @return
> + * Consumer sync type value.
> + */
> +static inline enum rte_ring_sync_type
> +rte_ring_get_cons_sync_type(const struct rte_ring *r) {
> + return r->cons.sync_type;
> +}
> +
> +/**
> + * Check is the ring for single consumer.
> + *
> + * @param r
> + * A pointer to the ring structure.
> + * @return
> + * true if ring is SC, zero otherwise.
> + */
> +static inline int
> +rte_ring_is_cons_single(const struct rte_ring *r) {
> + return (rte_ring_get_cons_sync_type(r) == RTE_RING_SYNC_ST); }
> +
> /**
> * Dump the status of all rings on the console
> *
> @@ -820,7 +796,7 @@ rte_ring_mp_enqueue_burst(struct rte_ring *r, void *
> const *obj_table,
> unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue(r, obj_table, n,
> - RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
> + RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT,
> free_space);
> }
>
> /**
> @@ -843,7 +819,7 @@ rte_ring_sp_enqueue_burst(struct rte_ring *r, void *
> const *obj_table,
> unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue(r, obj_table, n,
> - RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
> + RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST,
> free_space);
> }
>
> /**
> @@ -870,7 +846,7 @@ rte_ring_enqueue_burst(struct rte_ring *r, void *
> const *obj_table,
> unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue(r, obj_table, n,
> RTE_RING_QUEUE_VARIABLE,
> - r->prod.single, free_space);
> + r->prod.sync_type, free_space);
> }
>
> /**
> @@ -898,7 +874,7 @@ rte_ring_mc_dequeue_burst(struct rte_ring *r, void
> **obj_table,
> unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue(r, obj_table, n,
> - RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
> + RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT,
> available);
> }
>
> /**
> @@ -923,7 +899,7 @@ rte_ring_sc_dequeue_burst(struct rte_ring *r, void
> **obj_table,
> unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue(r, obj_table, n,
> - RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
> + RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST,
> available);
> }
>
> /**
> @@ -951,7 +927,7 @@ rte_ring_dequeue_burst(struct rte_ring *r, void
> **obj_table, {
> return __rte_ring_do_dequeue(r, obj_table, n,
> RTE_RING_QUEUE_VARIABLE,
> - r->cons.single, available);
> + r->cons.sync_type, available);
> }
>
> #ifdef __cplusplus
> diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
I like this separation, thanks.
> new file mode 100644 index 000000000..d9cef763f
> --- /dev/null
> +++ b/lib/librte_ring/rte_ring_core.h
> @@ -0,0 +1,132 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + *
> + * Copyright (c) 2010-2020 Intel Corporation
> + * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
> + * All rights reserved.
> + * Derived from FreeBSD's bufring.h
> + * Used as BSD-3 Licensed with permission from Kip Macy.
> + */
> +
> +#ifndef _RTE_RING_CORE_H_
> +#define _RTE_RING_CORE_H_
> +
> +/**
> + * @file
> + * This file contains definion of RTE ring structure itself,
^^^^^^^ definition
> + * init flags and some related macros.
> + * For majority of DPDK entities, it is not recommended to include
> + * this file directly, use include <rte_ring.h> or <rte_ring_elem.h>
> + * instead.
> + */
> +
> +#ifdef __cplusplus
> +extern "C" {
> +#endif
> +
> +#include <stdio.h>
> +#include <stdint.h>
> +#include <string.h>
> +#include <sys/queue.h>
> +#include <errno.h>
> +#include <rte_common.h>
> +#include <rte_config.h>
> +#include <rte_memory.h>
> +#include <rte_lcore.h>
> +#include <rte_atomic.h>
> +#include <rte_branch_prediction.h>
> +#include <rte_memzone.h>
> +#include <rte_pause.h>
> +#include <rte_debug.h>
> +
> +#define RTE_TAILQ_RING_NAME "RTE_RING"
> +
> +/** enqueue/dequeue behavior types */
> +enum rte_ring_queue_behavior {
> + /** Enq/Deq a fixed number of items from a ring */
> + RTE_RING_QUEUE_FIXED = 0,
> + /** Enq/Deq as many items as possible from ring */
> + RTE_RING_QUEUE_VARIABLE
> +};
> +
> +#define RTE_RING_MZ_PREFIX "RG_"
> +/** The maximum length of a ring name. */ #define RTE_RING_NAMESIZE
> +(RTE_MEMZONE_NAMESIZE - \
> + sizeof(RTE_RING_MZ_PREFIX) + 1)
> +
> +/** prod/cons sync types */
> +enum rte_ring_sync_type {
> + RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
> + RTE_RING_SYNC_ST, /**< single thread only */
> +};
> +
> +/**
> + * structures to hold a pair of head/tail values and other metadata.
> + * Depending on sync_type format of that structure might be different,
> + * but offset for *sync_type* and *tail* values should remain the same.
> + */
> +struct rte_ring_headtail {
> + volatile uint32_t head; /**< prod/consumer head. */
> + volatile uint32_t tail; /**< prod/consumer tail. */
> + RTE_STD_C11
> + union {
> + /** sync type of prod/cons */
> + enum rte_ring_sync_type sync_type;
> + /** deprecated - True if single prod/cons */
> + uint32_t single;
> + };
> +};
> +
> +/**
> + * An RTE ring structure.
> + *
> + * The producer and the consumer have a head and a tail index. The
> +particularity
> + * of these index is that they are not between 0 and size(ring). These
> +indexes
> + * are between 0 and 2^32, and we mask their value when we access the
> +ring[]
> + * field. Thanks to this assumption, we can do subtractions between 2
> +index
> + * values in a modulo-32bit base: that's why the overflow of the
> +indexes is not
> + * a problem.
> + */
> +struct rte_ring {
> + /*
> + * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
> + * compatibility requirements, it could be changed to
> RTE_RING_NAMESIZE
> + * next time the ABI changes
> + */
> + char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned;
> + /**< Name of the ring. */
> + int flags; /**< Flags supplied at creation. */
> + const struct rte_memzone *memzone;
> + /**< Memzone, if any, containing the rte_ring */
> + uint32_t size; /**< Size of ring. */
> + uint32_t mask; /**< Mask (size-1) of ring. */
> + uint32_t capacity; /**< Usable size of ring */
> +
> + char pad0 __rte_cache_aligned; /**< empty cache line */
> +
> + /** Ring producer status. */
> + struct rte_ring_headtail prod __rte_cache_aligned;
> + char pad1 __rte_cache_aligned; /**< empty cache line */
> +
> + /** Ring consumer status. */
> + struct rte_ring_headtail cons __rte_cache_aligned;
> + char pad2 __rte_cache_aligned; /**< empty cache line */ };
> +
> +#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is
> +"single-producer". */ #define RING_F_SC_DEQ 0x0002 /**< The default
> +dequeue is "single-consumer". */
> +/**
> + * Ring is to hold exactly requested number of entries.
> + * Without this flag set, the ring size requested must be a power of 2,
> +and the
> + * usable space will be that size - 1. With the flag, the requested
> +size will
> + * be rounded up to the next power of two, but the usable space will be
> +exactly
> + * that requested. Worst case, if a power-of-2 size is requested, half
> +the
> + * ring space will be wasted.
> + */
> +#define RING_F_EXACT_SZ 0x0004
> +#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
> +
> +#ifdef __cplusplus
> +}
> +#endif
> +
> +#endif /* _RTE_RING_CORE_H_ */
> diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
> index 663addc73..7406c0b0f 100644
> --- a/lib/librte_ring/rte_ring_elem.h
> +++ b/lib/librte_ring/rte_ring_elem.h
> @@ -20,21 +20,7 @@
> extern "C" {
> #endif
>
> -#include <stdio.h>
> -#include <stdint.h>
> -#include <string.h>
> -#include <sys/queue.h>
> -#include <errno.h>
> -#include <rte_common.h>
> -#include <rte_config.h>
> -#include <rte_memory.h>
> -#include <rte_lcore.h>
> -#include <rte_atomic.h>
> -#include <rte_branch_prediction.h>
> -#include <rte_memzone.h>
> -#include <rte_pause.h>
> -
> -#include "rte_ring.h"
> +#include <rte_ring_core.h>
>
> /**
> * @warning
> @@ -510,7 +496,7 @@ rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r,
> const void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_FIXED, __IS_MP, free_space);
> + RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT,
> free_space);
> }
>
> /**
> @@ -539,7 +525,7 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r,
> const void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_FIXED, __IS_SP, free_space);
> + RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST,
> free_space);
> }
>
> /**
> @@ -570,7 +556,7 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r, const
> void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_FIXED, r->prod.single, free_space);
> + RTE_RING_QUEUE_FIXED, r->prod.sync_type,
> free_space);
> }
>
> /**
> @@ -675,7 +661,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r,
> void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_FIXED, __IS_MC, available);
> + RTE_RING_QUEUE_FIXED,
> RTE_RING_SYNC_MT, available);
> }
>
> /**
> @@ -703,7 +689,7 @@ rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r,
> void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_FIXED, __IS_SC, available);
> + RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST,
> available);
> }
>
> /**
> @@ -734,7 +720,7 @@ rte_ring_dequeue_bulk_elem(struct rte_ring *r, void
> *obj_table,
> unsigned int esize, unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_FIXED, r->cons.single, available);
> + RTE_RING_QUEUE_FIXED, r->cons.sync_type,
> available);
> }
>
> /**
> @@ -842,7 +828,7 @@ rte_ring_mp_enqueue_burst_elem(struct rte_ring *r,
> const void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
> + RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT,
> free_space);
> }
>
> /**
> @@ -871,7 +857,7 @@ rte_ring_sp_enqueue_burst_elem(struct rte_ring *r,
> const void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
> + RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST,
> free_space);
> }
>
> /**
> @@ -902,7 +888,7 @@ rte_ring_enqueue_burst_elem(struct rte_ring *r,
> const void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *free_space) {
> return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_VARIABLE, r->prod.single,
> free_space);
> + RTE_RING_QUEUE_VARIABLE, r->prod.sync_type,
> free_space);
> }
>
> /**
> @@ -934,7 +920,7 @@ rte_ring_mc_dequeue_burst_elem(struct rte_ring *r,
> void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
> + RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT,
> available);
> }
>
> /**
> @@ -963,7 +949,7 @@ rte_ring_sc_dequeue_burst_elem(struct rte_ring *r,
> void *obj_table,
> unsigned int esize, unsigned int n, unsigned int *available) {
> return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
> - RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
> + RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST,
> available);
> }
>
> /**
> @@ -995,9 +981,11 @@ rte_ring_dequeue_burst_elem(struct rte_ring *r,
> void *obj_table, {
> return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
> RTE_RING_QUEUE_VARIABLE,
> - r->cons.single, available);
> + r->cons.sync_type, available);
> }
>
> +#include <rte_ring.h>
> +
> #ifdef __cplusplus
> }
> #endif
> --
> 2.17.1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
2020-04-17 15:52 0% ` Trahe, Fiona
@ 2020-04-18 19:43 3% ` Chautru, Nicolas
2020-04-19 7:35 0% ` David Marchand
0 siblings, 1 reply; 200+ results
From: Chautru, Nicolas @ 2020-04-18 19:43 UTC (permalink / raw)
To: Trahe, Fiona, David Marchand, Akhil Goyal
Cc: dev, Jerin Jacob, Pavan Nikhilesh, Richardson, Bruce,
Thomas Monjalon, Yigit, Ferruh, Hemant Agrawal, Trahe, Fiona
Hi,
It is probably just me but I having issue with this new patch.
I typically rebuild the PMD libraries directly when doing incremental changes from the Makefile in the PMD directory (ie. not rebuilding full DPDK each time, which still work okay obviously).
With this new change it doesn't seem to work any longer with the updated Makefiles without the ALLOW_EXPERIMENTAL_API:
Symbol is not yet part of stable ABI [-Werror=deprecated-declarations]
I would need to have a further look but checking whether it is just me.
Thanks
Nic
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Trahe, Fiona
> Sent: Friday, April 17, 2020 8:52 AM
> To: David Marchand <david.marchand@redhat.com>
> Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan
> Nikhilesh <pbhagavatula@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Thomas Monjalon <thomas@monjalon.net>;
> Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>; Trahe, Fiona <fiona.trahe@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v5] build: disable experimental API check
> internally
>
> Hi David,
>
> > -----Original Message-----
> > From: Trahe, Fiona <fiona.trahe@intel.com>
> > Sent: Friday, April 17, 2020 4:05 PM
> > To: David Marchand <david.marchand@redhat.com>
> > Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan
> > Nikhilesh <pbhagavatula@marvell.com>; Richardson, Bruce
> > <bruce.richardson@intel.com>; Thomas Monjalon <thomas@monjalon.net>;
> > Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> > <hemant.agrawal@nxp.com>; Trahe, Fiona <fiona.trahe@intel.com>
> > Subject: RE: [dpdk-dev] [PATCH v5] build: disable experimental API
> > check internally
> >
> > Hi Davd,
> >
> > > -----Original Message-----
> > > From: David Marchand <david.marchand@redhat.com>
> > > Sent: Friday, April 17, 2020 2:56 PM
> > > To: Trahe, Fiona <fiona.trahe@intel.com>
> > > Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan
> > > Nikhilesh <pbhagavatula@marvell.com>; Richardson, Bruce
> > > <bruce.richardson@intel.com>; Thomas
> > Monjalon
> > > <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> > > Hemant Agrawal <hemant.agrawal@nxp.com>
> > > Subject: Re: [dpdk-dev] [PATCH v5] build: disable experimental API
> > > check internally
> > >
> > > On Fri, Apr 17, 2020 at 3:44 PM Trahe, Fiona <fiona.trahe@intel.com>
> wrote:
> > > >
> > > > Hi David,
> > > >
> > > > > -----Original Message-----
> > > > > From: David Marchand <david.marchand@redhat.com>
> > > > > Sent: Friday, April 17, 2020 2:23 PM
> > > > > To: Trahe, Fiona <fiona.trahe@intel.com>
> > > > > Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>;
> > > > > Pavan Nikhilesh <pbhagavatula@marvell.com>; Richardson, Bruce
> > > > > <bruce.richardson@intel.com>; Thomas
> > > Monjalon
> > > > > <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>;
> > > > > Hemant Agrawal <hemant.agrawal@nxp.com>
> > > > > Subject: Re: [dpdk-dev] [PATCH v5] build: disable experimental
> > > > > API check internally
> > > > >
> > > > > On Fri, Apr 17, 2020 at 12:21 PM Trahe, Fiona <fiona.trahe@intel.com>
> wrote:
> > > > > > I see this is already applied.
> > > > > >
> > > > > > However,
> > > > > > rte_cryptodev_queue_pair_setup() calls
> > > > > > rte_cryptodev_sym_get_existing_header_session_size()
> > > > > > The former is a stable API, the latter is experimental.
> > > > > > So I expect the build to break when ALLOW_EXPERIMENTAL_API is
> disabled.
> > > > [Fiona] Thanks for confirming where the flag is.
> > > > But I think you've missed my point.
> > > > What about this problem?
> > >
> > > - dpdk-test-crypto-perf is built as part of the dpdk compilation itself.
> > > There is no user to be made aware of its use of experimental API.
> > >
> > > Now if you are talking about how the crypto API is bent in that it
> > > exposes a stable ABI with an underlying experimental ABI, this has
> > > nothing to do with the flag change.
> > [Fiona] Before this if an application didn't set
> > ALLOW_EXPERIMENTAL_API (which I expect is the default for many apps)
> > then the build worked fine as long as the app didn't directly call an
> > experimental API. The crypto lib still built ok as its own Makefile had the flag.
> > I just tried this with dpdk-test-crypto-perf. I had to remove one
> > direct call, without that it built ok. When I remove the flag from the
> > crypto lib Makefile, the build breaks as expected due to the above issue.
> >
> > So, yes, cryptodev lib should be fixed.
> > However this patch just applied will potentially break builds for many apps!
> > It could expose many other issues of internal dependencies on experimental
> APIs.
>
> [Fiona] Ok, I get it now, there's no issue.
> I see now why the patch name was changed from "global" to "internal"!
> I had understood that the flag the application set or didn't set would ripple
> down through the whole build. Instead the flag is set (or not set) once by the
> application only affecting direct API calls and once for the rest of the build,
> which includes apps in the app folder, but not apps in the examples folder.
> So allowing experimental APIs internally, while disallowing them externally.
> A bit confusing, but ok, doesn't break anything and definitely better than having
> flags in every Make/meson file.
>
> Fiona
>
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v8 0/2] support for VFIO-PCI VF token interface
2020-04-18 11:16 4% ` [dpdk-dev] [PATCH v7 0/2] support for VFIO-PCI VF token interface Haiyue Wang
@ 2020-04-18 17:30 4% ` Haiyue Wang
2020-04-20 16:53 3% ` David Marchand
2020-04-22 5:08 4% ` [dpdk-dev] [PATCH v9 " Haiyue Wang
2020-04-26 1:55 4% ` [dpdk-dev] [PATCH v10 0/2] support for VFIO-PCI VF token interface Haiyue Wang
3 siblings, 1 reply; 200+ results
From: Haiyue Wang @ 2020-04-18 17:30 UTC (permalink / raw)
To: dev, anatoly.burakov, thomas, vattunuru, jerinj, alex.williamson,
david.marchand
Cc: Haiyue Wang
v8: Update the document.
v7: Add the Fixes tag in uuid, the release note and help
document.
https://patchwork.dpdk.org/cover/68845/
v6: Drop the Fixes tag in uuid, since the file has been
moved to another place, not suitable to apply on stable.
And this is not a bug, just some kind of enhancement.
https://patchwork.dpdk.org/cover/68367/
v5: 1. Add the VF token parse error handling.
2. Split into two patches for different logic module.
3. Add more comments into the code for explaining the design.
4. Drop the ABI change workaround, this patch set focuses on code review.
https://patchwork.dpdk.org/cover/68364/
v4: 1. Ignore rte_vfio_setup_device ABI check since it is
for Linux driver use.
https://patchwork.dpdk.org/patch/68255/
v3: Fix the Travis build failed:
(1). rte_uuid.h:97:55: error: unknown type name ‘size_t’
(2). rte_uuid.h:58:2: error: implicit declaration of function ‘memcpy’
https://patchwork.dpdk.org/patch/68254/
v2: Fix the FreeBSD build error.
https://patchwork.dpdk.org/patch/68240/
v1: Update the commit message.
https://patchwork.dpdk.org/patch/68237/
RFC v2: https://patchwork.dpdk.org/patch/68114/
Based on Vamsi's RFC v1, and Alex's patch for Qemu
[https://lore.kernel.org/lkml/20200204161737.34696b91@w520.home/]:
Use the devarg to pass-down the VF token.
RFC v1: https://patchwork.dpdk.org/patch/66281/ by Vamsi.
Haiyue Wang (2):
eal: add uuid dependent header files explicitly
eal: support for VFIO-PCI VF token
doc/guides/linux_gsg/linux_drivers.rst | 38 ++++++++++++-
doc/guides/rel_notes/release_20_05.rst | 5 ++
drivers/bus/pci/linux/pci_vfio.c | 74 +++++++++++++++++++++++++-
lib/librte_eal/freebsd/eal.c | 3 +-
lib/librte_eal/include/rte_uuid.h | 2 +
lib/librte_eal/include/rte_vfio.h | 21 +++++++-
lib/librte_eal/linux/eal_vfio.c | 20 +++++--
7 files changed, 155 insertions(+), 8 deletions(-)
--
2.26.1
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v5 3/9] ring: introduce RTS ring mode
2020-04-18 16:32 3% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Konstantin Ananyev
2020-04-18 16:32 9% ` [dpdk-dev] [PATCH v5 2/9] ring: prepare ring to allow new sync schemes Konstantin Ananyev
@ 2020-04-18 16:32 1% ` Konstantin Ananyev
2020-04-19 2:31 0% ` Honnappa Nagarahalli
2020-04-19 2:32 0% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Honnappa Nagarahalli
2020-04-20 12:11 3% ` [dpdk-dev] [PATCH v6 00/10] " Konstantin Ananyev
3 siblings, 1 reply; 200+ results
From: Konstantin Ananyev @ 2020-04-18 16:32 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
Introduce relaxed tail sync (RTS) mode for MT ring synchronization.
Aim to reduce stall times in case when ring is used on
overcommited cpus (multiple active threads on the same cpu).
The main difference from original MP/MC algorithm is that
tail value is increased not by every thread that finished enqueue/dequeue,
but only by the last one.
That allows threads to avoid spinning on ring tail value,
leaving actual tail value change to the last thread in the update queue.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
check-abi.sh reports what I believe is a false-positive about
ring cons/prod changes. As a workaround, devtools/libabigail.abignore is
updated to suppress *struct ring* related errors.
devtools/libabigail.abignore | 7 +
lib/librte_ring/Makefile | 4 +-
lib/librte_ring/meson.build | 7 +-
lib/librte_ring/rte_ring.c | 100 +++++-
lib/librte_ring/rte_ring.h | 70 +++-
lib/librte_ring/rte_ring_core.h | 36 +-
lib/librte_ring/rte_ring_elem.h | 90 ++++-
lib/librte_ring/rte_ring_rts.h | 439 +++++++++++++++++++++++++
lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
9 files changed, 902 insertions(+), 30 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_rts.h
create mode 100644 lib/librte_ring/rte_ring_rts_c11_mem.h
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index a59df8f13..cd86d89ca 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -11,3 +11,10 @@
type_kind = enum
name = rte_crypto_asym_xform_type
changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
+; Ignore updates of ring prod/cons
+[suppress_type]
+ type_kind = struct
+ name = rte_ring
+[suppress_type]
+ type_kind = struct
+ name = rte_event_ring
diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile
index 6572768c9..04e446e37 100644
--- a/lib/librte_ring/Makefile
+++ b/lib/librte_ring/Makefile
@@ -19,6 +19,8 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
rte_ring_core.h \
rte_ring_elem.h \
rte_ring_generic.h \
- rte_ring_c11_mem.h
+ rte_ring_c11_mem.h \
+ rte_ring_rts.h \
+ rte_ring_rts_c11_mem.h
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build
index c656781da..a95598032 100644
--- a/lib/librte_ring/meson.build
+++ b/lib/librte_ring/meson.build
@@ -6,4 +6,9 @@ headers = files('rte_ring.h',
'rte_ring_core.h',
'rte_ring_elem.h',
'rte_ring_c11_mem.h',
- 'rte_ring_generic.h')
+ 'rte_ring_generic.h',
+ 'rte_ring_rts.h',
+ 'rte_ring_rts_c11_mem.h')
+
+# rte_ring_create_elem and rte_ring_get_memsize_elem are experimental
+allow_experimental_apis = true
diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
index fa5733907..222eec0fb 100644
--- a/lib/librte_ring/rte_ring.c
+++ b/lib/librte_ring/rte_ring.c
@@ -45,6 +45,9 @@ EAL_REGISTER_TAILQ(rte_ring_tailq)
/* true if x is a power of 2 */
#define POWEROF2(x) ((((x)-1) & (x)) == 0)
+/* by default set head/tail distance as 1/8 of ring capacity */
+#define HTD_MAX_DEF 8
+
/* return the size of memory occupied by a ring */
ssize_t
rte_ring_get_memsize_elem(unsigned int esize, unsigned int count)
@@ -79,11 +82,84 @@ rte_ring_get_memsize(unsigned int count)
return rte_ring_get_memsize_elem(sizeof(void *), count);
}
+/*
+ * internal helper function to reset prod/cons head-tail values.
+ */
+static void
+reset_headtail(void *p)
+{
+ struct rte_ring_headtail *ht;
+ struct rte_ring_rts_headtail *ht_rts;
+
+ ht = p;
+ ht_rts = p;
+
+ switch (ht->sync_type) {
+ case RTE_RING_SYNC_MT:
+ case RTE_RING_SYNC_ST:
+ ht->head = 0;
+ ht->tail = 0;
+ break;
+ case RTE_RING_SYNC_MT_RTS:
+ ht_rts->head.raw = 0;
+ ht_rts->tail.raw = 0;
+ break;
+ default:
+ /* unknown sync mode */
+ RTE_ASSERT(0);
+ }
+}
+
void
rte_ring_reset(struct rte_ring *r)
{
- r->prod.head = r->cons.head = 0;
- r->prod.tail = r->cons.tail = 0;
+ reset_headtail(&r->prod);
+ reset_headtail(&r->cons);
+}
+
+/*
+ * helper function, calculates sync_type values for prod and cons
+ * based on input flags. Returns zero at success or negative
+ * errno value otherwise.
+ */
+static int
+get_sync_type(uint32_t flags, enum rte_ring_sync_type *prod_st,
+ enum rte_ring_sync_type *cons_st)
+{
+ static const uint32_t prod_st_flags =
+ (RING_F_SP_ENQ | RING_F_MP_RTS_ENQ);
+ static const uint32_t cons_st_flags =
+ (RING_F_SC_DEQ | RING_F_MC_RTS_DEQ);
+
+ switch (flags & prod_st_flags) {
+ case 0:
+ *prod_st = RTE_RING_SYNC_MT;
+ break;
+ case RING_F_SP_ENQ:
+ *prod_st = RTE_RING_SYNC_ST;
+ break;
+ case RING_F_MP_RTS_ENQ:
+ *prod_st = RTE_RING_SYNC_MT_RTS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (flags & cons_st_flags) {
+ case 0:
+ *cons_st = RTE_RING_SYNC_MT;
+ break;
+ case RING_F_SC_DEQ:
+ *cons_st = RTE_RING_SYNC_ST;
+ break;
+ case RING_F_MC_RTS_DEQ:
+ *cons_st = RTE_RING_SYNC_MT_RTS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
}
int
@@ -100,16 +176,20 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
RTE_BUILD_BUG_ON((offsetof(struct rte_ring, prod) &
RTE_CACHE_LINE_MASK) != 0);
+ RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, sync_type) !=
+ offsetof(struct rte_ring_rts_headtail, sync_type));
+ RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, tail) !=
+ offsetof(struct rte_ring_rts_headtail, tail.val.pos));
+
/* init the ring structure */
memset(r, 0, sizeof(*r));
ret = strlcpy(r->name, name, sizeof(r->name));
if (ret < 0 || ret >= (int)sizeof(r->name))
return -ENAMETOOLONG;
r->flags = flags;
- r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
- RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
- r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
- RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
+ ret = get_sync_type(flags, &r->prod.sync_type, &r->cons.sync_type);
+ if (ret != 0)
+ return ret;
if (flags & RING_F_EXACT_SZ) {
r->size = rte_align32pow2(count + 1);
@@ -126,8 +206,12 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
r->mask = count - 1;
r->capacity = r->mask;
}
- r->prod.head = r->cons.head = 0;
- r->prod.tail = r->cons.tail = 0;
+
+ /* set default values for head-tail distance */
+ if (flags & RING_F_MP_RTS_ENQ)
+ rte_ring_set_prod_htd_max(r, r->capacity / HTD_MAX_DEF);
+ if (flags & RING_F_MC_RTS_DEQ)
+ rte_ring_set_cons_htd_max(r, r->capacity / HTD_MAX_DEF);
return 0;
}
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index 35ee4491c..77f206ca7 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright (c) 2010-2017 Intel Corporation
+ * Copyright (c) 2010-2020 Intel Corporation
* Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
* All rights reserved.
* Derived from FreeBSD's bufring.h
@@ -389,8 +389,21 @@ static __rte_always_inline unsigned int
rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_bulk(r, obj_table, n, free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_bulk(r, obj_table, n, free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_bulk(r, obj_table, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -524,8 +537,20 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
unsigned int *available)
{
- return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_bulk(r, obj_table, n, available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_bulk(r, obj_table, n, available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_bulk(r, obj_table, n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -845,8 +870,21 @@ static __rte_always_inline unsigned
rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
- r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_burst(r, obj_table, n, free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_burst(r, obj_table, n, free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_burst(r, obj_table, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -925,9 +963,21 @@ static __rte_always_inline unsigned
rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_burst(r, obj_table, n, available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_burst(r, obj_table, n, available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_burst(r, obj_table, n,
+ available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
#ifdef __cplusplus
diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
index d9cef763f..ded0fa0b7 100644
--- a/lib/librte_ring/rte_ring_core.h
+++ b/lib/librte_ring/rte_ring_core.h
@@ -57,6 +57,9 @@ enum rte_ring_queue_behavior {
enum rte_ring_sync_type {
RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
RTE_RING_SYNC_ST, /**< single thread only */
+#ifdef ALLOW_EXPERIMENTAL_API
+ RTE_RING_SYNC_MT_RTS, /**< multi-thread relaxed tail sync */
+#endif
};
/**
@@ -76,6 +79,22 @@ struct rte_ring_headtail {
};
};
+union rte_ring_rts_poscnt {
+ /** raw 8B value to read/write *cnt* and *pos* as one atomic op */
+ uint64_t raw __rte_aligned(8);
+ struct {
+ uint32_t cnt; /**< head/tail reference counter */
+ uint32_t pos; /**< head/tail position */
+ } val;
+};
+
+struct rte_ring_rts_headtail {
+ volatile union rte_ring_rts_poscnt tail;
+ enum rte_ring_sync_type sync_type; /**< sync type of prod/cons */
+ uint32_t htd_max; /**< max allowed distance between head/tail */
+ volatile union rte_ring_rts_poscnt head;
+};
+
/**
* An RTE ring structure.
*
@@ -104,11 +123,21 @@ struct rte_ring {
char pad0 __rte_cache_aligned; /**< empty cache line */
/** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail prod;
+ struct rte_ring_rts_headtail rts_prod;
+ } __rte_cache_aligned;
+
char pad1 __rte_cache_aligned; /**< empty cache line */
/** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail cons;
+ struct rte_ring_rts_headtail rts_cons;
+ } __rte_cache_aligned;
+
char pad2 __rte_cache_aligned; /**< empty cache line */
};
@@ -125,6 +154,9 @@ struct rte_ring {
#define RING_F_EXACT_SZ 0x0004
#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
+#define RING_F_MP_RTS_ENQ 0x0008 /**< The default enqueue is "MP RTS". */
+#define RING_F_MC_RTS_DEQ 0x0010 /**< The default dequeue is "MC RTS". */
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
index 7406c0b0f..6da0a917b 100644
--- a/lib/librte_ring/rte_ring_elem.h
+++ b/lib/librte_ring/rte_ring_elem.h
@@ -528,6 +528,10 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
}
+#ifdef ALLOW_EXPERIMENTAL_API
+#include <rte_ring_rts.h>
+#endif
+
/**
* Enqueue several objects on a ring.
*
@@ -557,6 +561,26 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_FIXED, r->prod.sync_type, free_space);
+
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (free_space != NULL)
+ *free_space = 0;
+ return 0;
}
/**
@@ -661,7 +685,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
}
/**
@@ -719,8 +743,25 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
+ available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
+ available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize,
+ n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (available != NULL)
+ *available = 0;
+ return 0;
}
/**
@@ -887,8 +928,25 @@ static __rte_always_inline unsigned
rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n,
+ free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
+ free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize,
+ n, free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (free_space != NULL)
+ *free_space = 0;
+ return 0;
}
/**
@@ -979,9 +1037,25 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
+ available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
+ available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize,
+ n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (available != NULL)
+ *available = 0;
+ return 0;
}
#include <rte_ring.h>
diff --git a/lib/librte_ring/rte_ring_rts.h b/lib/librte_ring/rte_ring_rts.h
new file mode 100644
index 000000000..8ced07096
--- /dev/null
+++ b/lib/librte_ring/rte_ring_rts.h
@@ -0,0 +1,439 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_RTS_H_
+#define _RTE_RING_RTS_H_
+
+/**
+ * @file rte_ring_rts.h
+ * @b EXPERIMENTAL: this API may change without prior notice
+ * It is not recommended to include this file directly.
+ * Please include <rte_ring.h> instead.
+ *
+ * Contains functions for Relaxed Tail Sync (RTS) ring mode.
+ * The main idea remains the same as for our original MP/MC synchronization
+ * mechanism.
+ * The main difference is that tail value is increased not
+ * by every thread that finished enqueue/dequeue,
+ * but only by the current last one doing enqueue/dequeue.
+ * That allows threads to skip spinning on tail value,
+ * leaving actual tail value change to last thread at a given instance.
+ * RTS requires 2 64-bit CAS for each enqueue(/dequeue) operation:
+ * one for head update, second for tail update.
+ * As a gain it allows thread to avoid spinning/waiting on tail value.
+ * In comparision original MP/MC algorithm requires one 32-bit CAS
+ * for head update and waiting/spinning on tail value.
+ *
+ * Brief outline:
+ * - introduce update counter (cnt) for both head and tail.
+ * - increment head.cnt for each head.value update
+ * - write head.value and head.cnt atomically (64-bit CAS)
+ * - move tail.value ahead only when tail.cnt + 1 == head.cnt
+ * (indicating that this is the last thread updating the tail)
+ * - increment tail.cnt when each enqueue/dequeue op finishes
+ * (no matter if tail.value going to change or not)
+ * - write tail.value and tail.cnt atomically (64-bit CAS)
+ *
+ * To avoid producer/consumer starvation:
+ * - limit max allowed distance between head and tail value (HTD_MAX).
+ * I.E. thread is allowed to proceed with changing head.value,
+ * only when: head.value - tail.value <= HTD_MAX
+ * HTD_MAX is an optional parameter.
+ * With HTD_MAX == 0 we'll have fully serialized ring -
+ * i.e. only one thread at a time will be able to enqueue/dequeue
+ * to/from the ring.
+ * With HTD_MAX >= ring.capacity - no limitation.
+ * By default HTD_MAX == ring.capacity / 8.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_ring_rts_c11_mem.h>
+
+/**
+ * @internal Enqueue several objects on the RTS ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Enqueue as many items as possible from ring
+ * @param free_space
+ * returns the amount of space after the enqueue operation has finished
+ * @return
+ * Actual number of objects enqueued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_do_rts_enqueue_elem(struct rte_ring *r, const void *obj_table,
+ uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
+ uint32_t *free_space)
+{
+ uint32_t free, head;
+
+ n = __rte_ring_rts_move_prod_head(r, n, behavior, &head, &free);
+
+ if (n != 0) {
+ __rte_ring_enqueue_elems(r, head, obj_table, esize, n);
+ __rte_ring_rts_update_tail(&r->rts_prod);
+ }
+
+ if (free_space != NULL)
+ *free_space = free - n;
+ return n;
+}
+
+/**
+ * @internal Dequeue several objects from the RTS ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to pull from the ring.
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Dequeue as many items as possible from ring
+ * @param available
+ * returns the number of remaining ring entries after the dequeue has finished
+ * @return
+ * - Actual number of objects dequeued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_do_rts_dequeue_elem(struct rte_ring *r, void *obj_table,
+ uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
+ uint32_t *available)
+{
+ uint32_t entries, head;
+
+ n = __rte_ring_rts_move_cons_head(r, n, behavior, &head, &entries);
+
+ if (n != 0) {
+ __rte_ring_dequeue_elems(r, head, obj_table, esize, n);
+ __rte_ring_rts_update_tail(&r->rts_cons);
+ }
+
+ if (available != NULL)
+ *available = entries - n;
+ return n;
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * The number of objects enqueued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mp_rts_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *free_space)
+{
+ return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_FIXED, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects that will be filled.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * The number of objects dequeued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mc_rts_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *available)
+{
+ return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_FIXED, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * - n: Actual number of objects enqueued.
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mp_rts_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *free_space)
+{
+ return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_VARIABLE, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ * When the requested objects are more than the available objects,
+ * only dequeue the actual number of objects.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects that will be filled.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * - n: Actual number of objects dequeued, 0 if ring is empty
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mc_rts_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *available)
+{
+ return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_VARIABLE, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects).
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * The number of objects enqueued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mp_rts_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
+ unsigned int n, unsigned int *free_space)
+{
+ return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table,
+ sizeof(uintptr_t), n, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects) that will be filled.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * The number of objects dequeued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mc_rts_dequeue_bulk(struct rte_ring *r, void **obj_table,
+ unsigned int n, unsigned int *available)
+{
+ return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table,
+ sizeof(uintptr_t), n, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects).
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * - n: Actual number of objects enqueued.
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mp_rts_enqueue_burst(struct rte_ring *r, void * const *obj_table,
+ unsigned int n, unsigned int *free_space)
+{
+ return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table,
+ sizeof(uintptr_t), n, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ * When the requested objects are more than the available objects,
+ * only dequeue the actual number of objects.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects) that will be filled.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * - n: Actual number of objects dequeued, 0 if ring is empty
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mc_rts_dequeue_burst(struct rte_ring *r, void **obj_table,
+ unsigned int n, unsigned int *available)
+{
+ return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table,
+ sizeof(uintptr_t), n, available);
+}
+
+/**
+ * Return producer max Head-Tail-Distance (HTD).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Producer HTD value, if producer is set in appropriate sync mode,
+ * or UINT32_MAX otherwise.
+ */
+__rte_experimental
+static inline uint32_t
+rte_ring_get_prod_htd_max(const struct rte_ring *r)
+{
+ if (r->prod.sync_type == RTE_RING_SYNC_MT_RTS)
+ return r->rts_prod.htd_max;
+ return UINT32_MAX;
+}
+
+/**
+ * Set producer max Head-Tail-Distance (HTD).
+ * Note that producer has to use appropriate sync mode (RTS).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param v
+ * new HTD value to setup.
+ * @return
+ * Zero on success, or negative error code otherwise.
+ */
+__rte_experimental
+static inline int
+rte_ring_set_prod_htd_max(struct rte_ring *r, uint32_t v)
+{
+ if (r->prod.sync_type != RTE_RING_SYNC_MT_RTS)
+ return -ENOTSUP;
+
+ r->rts_prod.htd_max = v;
+ return 0;
+}
+
+/**
+ * Return consumer max Head-Tail-Distance (HTD).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Consumer HTD value, if consumer is set in appropriate sync mode,
+ * or UINT32_MAX otherwise.
+ */
+__rte_experimental
+static inline uint32_t
+rte_ring_get_cons_htd_max(const struct rte_ring *r)
+{
+ if (r->cons.sync_type == RTE_RING_SYNC_MT_RTS)
+ return r->rts_cons.htd_max;
+ return UINT32_MAX;
+}
+
+/**
+ * Set consumer max Head-Tail-Distance (HTD).
+ * Note that consumer has to use appropriate sync mode (RTS).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param v
+ * new HTD value to setup.
+ * @return
+ * Zero on success, or negative error code otherwise.
+ */
+__rte_experimental
+static inline int
+rte_ring_set_cons_htd_max(struct rte_ring *r, uint32_t v)
+{
+ if (r->cons.sync_type != RTE_RING_SYNC_MT_RTS)
+ return -ENOTSUP;
+
+ r->rts_cons.htd_max = v;
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RING_RTS_H_ */
diff --git a/lib/librte_ring/rte_ring_rts_c11_mem.h b/lib/librte_ring/rte_ring_rts_c11_mem.h
new file mode 100644
index 000000000..9f26817c0
--- /dev/null
+++ b/lib/librte_ring/rte_ring_rts_c11_mem.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_RTS_C11_MEM_H_
+#define _RTE_RING_RTS_C11_MEM_H_
+
+/**
+ * @file rte_ring_rts_c11_mem.h
+ * It is not recommended to include this file directly,
+ * include <rte_ring.h> instead.
+ * Contains internal helper functions for Relaxed Tail Sync (RTS) ring mode.
+ * For more information please refer to <rte_ring_rts.h>.
+ */
+
+/**
+ * @internal This function updates tail values.
+ */
+static __rte_always_inline void
+__rte_ring_rts_update_tail(struct rte_ring_rts_headtail *ht)
+{
+ union rte_ring_rts_poscnt h, ot, nt;
+
+ /*
+ * If there are other enqueues/dequeues in progress that
+ * might preceded us, then don't update tail with new value.
+ */
+
+ ot.raw = __atomic_load_n(&ht->tail.raw, __ATOMIC_ACQUIRE);
+
+ do {
+ /* on 32-bit systems we have to do atomic read here */
+ h.raw = __atomic_load_n(&ht->head.raw, __ATOMIC_RELAXED);
+
+ nt.raw = ot.raw;
+ if (++nt.val.cnt == h.val.cnt)
+ nt.val.pos = h.val.pos;
+
+ } while (__atomic_compare_exchange_n(&ht->tail.raw, &ot.raw, nt.raw,
+ 0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE) == 0);
+}
+
+/**
+ * @internal This function waits till head/tail distance wouldn't
+ * exceed pre-defined max value.
+ */
+static __rte_always_inline void
+__rte_ring_rts_head_wait(const struct rte_ring_rts_headtail *ht,
+ union rte_ring_rts_poscnt *h)
+{
+ uint32_t max;
+
+ max = ht->htd_max;
+
+ while (h->val.pos - ht->tail.val.pos > max) {
+ rte_pause();
+ h->raw = __atomic_load_n(&ht->head.raw, __ATOMIC_ACQUIRE);
+ }
+}
+
+/**
+ * @internal This function updates the producer head for enqueue.
+ */
+static __rte_always_inline uint32_t
+__rte_ring_rts_move_prod_head(struct rte_ring *r, uint32_t num,
+ enum rte_ring_queue_behavior behavior, uint32_t *old_head,
+ uint32_t *free_entries)
+{
+ uint32_t n;
+ union rte_ring_rts_poscnt nh, oh;
+
+ const uint32_t capacity = r->capacity;
+
+ oh.raw = __atomic_load_n(&r->rts_prod.head.raw, __ATOMIC_ACQUIRE);
+
+ do {
+ /* Reset n to the initial burst count */
+ n = num;
+
+ /*
+ * wait for prod head/tail distance,
+ * make sure that we read prod head *before*
+ * reading cons tail.
+ */
+ __rte_ring_rts_head_wait(&r->rts_prod, &oh);
+
+ /*
+ * The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * *old_head > cons_tail). So 'free_entries' is always between 0
+ * and capacity (which is < size).
+ */
+ *free_entries = capacity + r->cons.tail - oh.val.pos;
+
+ /* check that we have enough room in ring */
+ if (unlikely(n > *free_entries))
+ n = (behavior == RTE_RING_QUEUE_FIXED) ?
+ 0 : *free_entries;
+
+ if (n == 0)
+ break;
+
+ nh.val.pos = oh.val.pos + n;
+ nh.val.cnt = oh.val.cnt + 1;
+
+ /*
+ * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
+ * - OOO reads of cons tail value
+ * - OOO copy of elems to the ring
+ */
+ } while (__atomic_compare_exchange_n(&r->rts_prod.head.raw,
+ &oh.raw, nh.raw,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
+
+ *old_head = oh.val.pos;
+ return n;
+}
+
+/**
+ * @internal This function updates the consumer head for dequeue
+ */
+static __rte_always_inline unsigned int
+__rte_ring_rts_move_cons_head(struct rte_ring *r, uint32_t num,
+ enum rte_ring_queue_behavior behavior, uint32_t *old_head,
+ uint32_t *entries)
+{
+ uint32_t n;
+ union rte_ring_rts_poscnt nh, oh;
+
+ oh.raw = __atomic_load_n(&r->rts_cons.head.raw, __ATOMIC_ACQUIRE);
+
+ /* move cons.head atomically */
+ do {
+ /* Restore n as it may change every loop */
+ n = num;
+
+ /*
+ * wait for cons head/tail distance,
+ * make sure that we read cons head *before*
+ * reading prod tail.
+ */
+ __rte_ring_rts_head_wait(&r->rts_cons, &oh);
+
+ /* The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * cons_head > prod_tail). So 'entries' is always between 0
+ * and size(ring)-1.
+ */
+ *entries = r->prod.tail - oh.val.pos;
+
+ /* Set the actual entries for dequeue */
+ if (n > *entries)
+ n = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : *entries;
+
+ if (unlikely(n == 0))
+ break;
+
+ nh.val.pos = oh.val.pos + n;
+ nh.val.cnt = oh.val.cnt + 1;
+
+ /*
+ * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
+ * - OOO reads of prod tail value
+ * - OOO copy of elems from the ring
+ */
+ } while (__atomic_compare_exchange_n(&r->rts_cons.head.raw,
+ &oh.raw, nh.raw,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
+
+ *old_head = oh.val.pos;
+ return n;
+}
+
+#endif /* _RTE_RING_RTS_C11_MEM_H_ */
--
2.17.1
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v5 2/9] ring: prepare ring to allow new sync schemes
2020-04-18 16:32 3% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Konstantin Ananyev
@ 2020-04-18 16:32 9% ` Konstantin Ananyev
2020-04-19 2:31 0% ` Honnappa Nagarahalli
2020-04-18 16:32 1% ` [dpdk-dev] [PATCH v5 3/9] ring: introduce RTS ring mode Konstantin Ananyev
` (2 subsequent siblings)
3 siblings, 1 reply; 200+ results
From: Konstantin Ananyev @ 2020-04-18 16:32 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
To make these preparations two main things are done:
- Change from *single* to *sync_type* to allow different
synchronisation schemes to be applied.
Mark *single* as deprecated in comments.
Add new functions to allow user to query ring sync types.
Replace direct access to *single* with appropriate function call.
- Move actual rte_ring and related structures definitions into a
separate file: <rte_ring_core.h>. It allows to refer contents
of <rte_ring_elem.h> from <rte_ring.h> without introducing a
circular dependency.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
app/test/test_pdump.c | 6 +-
lib/librte_pdump/rte_pdump.c | 2 +-
lib/librte_port/rte_port_ring.c | 12 +--
lib/librte_ring/Makefile | 1 +
lib/librte_ring/meson.build | 1 +
lib/librte_ring/rte_ring.c | 6 +-
lib/librte_ring/rte_ring.h | 170 ++++++++++++++------------------
lib/librte_ring/rte_ring_core.h | 132 +++++++++++++++++++++++++
lib/librte_ring/rte_ring_elem.h | 42 +++-----
9 files changed, 234 insertions(+), 138 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_core.h
diff --git a/app/test/test_pdump.c b/app/test/test_pdump.c
index ad183184c..6a1180bcb 100644
--- a/app/test/test_pdump.c
+++ b/app/test/test_pdump.c
@@ -57,8 +57,7 @@ run_pdump_client_tests(void)
if (ret < 0)
return -1;
mp->flags = 0x0000;
- ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
+ ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(), 0);
if (ring_client == NULL) {
printf("rte_ring_create SR0 failed");
return -1;
@@ -71,9 +70,6 @@ run_pdump_client_tests(void)
}
rte_eth_dev_probing_finish(eth_dev);
- ring_client->prod.single = 0;
- ring_client->cons.single = 0;
-
printf("\n***** flags = RTE_PDUMP_FLAG_TX *****\n");
for (itr = 0; itr < NUM_ITR; itr++) {
diff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c
index 8a01ac510..f96709f95 100644
--- a/lib/librte_pdump/rte_pdump.c
+++ b/lib/librte_pdump/rte_pdump.c
@@ -380,7 +380,7 @@ pdump_validate_ring_mp(struct rte_ring *ring, struct rte_mempool *mp)
rte_errno = EINVAL;
return -1;
}
- if (ring->prod.single || ring->cons.single) {
+ if (rte_ring_is_prod_single(ring) || rte_ring_is_cons_single(ring)) {
PDUMP_LOG(ERR, "ring with either SP or SC settings"
" is not valid for pdump, should have MP and MC settings\n");
rte_errno = EINVAL;
diff --git a/lib/librte_port/rte_port_ring.c b/lib/librte_port/rte_port_ring.c
index 47fcdd06a..52b2d8e55 100644
--- a/lib/librte_port/rte_port_ring.c
+++ b/lib/librte_port/rte_port_ring.c
@@ -44,8 +44,8 @@ rte_port_ring_reader_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->cons.single && is_multi) ||
- (!(conf->ring->cons.single) && !is_multi)) {
+ (rte_ring_is_cons_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
}
@@ -171,8 +171,8 @@ rte_port_ring_writer_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->prod.single && is_multi) ||
- (!(conf->ring->prod.single) && !is_multi) ||
+ (rte_ring_is_prod_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
(conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
@@ -440,8 +440,8 @@ rte_port_ring_writer_nodrop_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->prod.single && is_multi) ||
- (!(conf->ring->prod.single) && !is_multi) ||
+ (rte_ring_is_prod_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
(conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile
index 28368e6d1..6572768c9 100644
--- a/lib/librte_ring/Makefile
+++ b/lib/librte_ring/Makefile
@@ -16,6 +16,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_RING) := rte_ring.c
# install includes
SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
+ rte_ring_core.h \
rte_ring_elem.h \
rte_ring_generic.h \
rte_ring_c11_mem.h
diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build
index 05402e4f0..c656781da 100644
--- a/lib/librte_ring/meson.build
+++ b/lib/librte_ring/meson.build
@@ -3,6 +3,7 @@
sources = files('rte_ring.c')
headers = files('rte_ring.h',
+ 'rte_ring_core.h',
'rte_ring_elem.h',
'rte_ring_c11_mem.h',
'rte_ring_generic.h')
diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
index 77e5de099..fa5733907 100644
--- a/lib/librte_ring/rte_ring.c
+++ b/lib/librte_ring/rte_ring.c
@@ -106,8 +106,10 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
if (ret < 0 || ret >= (int)sizeof(r->name))
return -ENAMETOOLONG;
r->flags = flags;
- r->prod.single = (flags & RING_F_SP_ENQ) ? __IS_SP : __IS_MP;
- r->cons.single = (flags & RING_F_SC_DEQ) ? __IS_SC : __IS_MC;
+ r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
+ RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
+ r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
+ RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
if (flags & RING_F_EXACT_SZ) {
r->size = rte_align32pow2(count + 1);
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index 18fc5d845..35ee4491c 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -36,91 +36,7 @@
extern "C" {
#endif
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/queue.h>
-#include <errno.h>
-#include <rte_common.h>
-#include <rte_config.h>
-#include <rte_memory.h>
-#include <rte_lcore.h>
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_memzone.h>
-#include <rte_pause.h>
-
-#define RTE_TAILQ_RING_NAME "RTE_RING"
-
-enum rte_ring_queue_behavior {
- RTE_RING_QUEUE_FIXED = 0, /* Enq/Deq a fixed number of items from a ring */
- RTE_RING_QUEUE_VARIABLE /* Enq/Deq as many items as possible from ring */
-};
-
-#define RTE_RING_MZ_PREFIX "RG_"
-/** The maximum length of a ring name. */
-#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
- sizeof(RTE_RING_MZ_PREFIX) + 1)
-
-/* structure to hold a pair of head/tail values and other metadata */
-struct rte_ring_headtail {
- volatile uint32_t head; /**< Prod/consumer head. */
- volatile uint32_t tail; /**< Prod/consumer tail. */
- uint32_t single; /**< True if single prod/cons */
-};
-
-/**
- * An RTE ring structure.
- *
- * The producer and the consumer have a head and a tail index. The particularity
- * of these index is that they are not between 0 and size(ring). These indexes
- * are between 0 and 2^32, and we mask their value when we access the ring[]
- * field. Thanks to this assumption, we can do subtractions between 2 index
- * values in a modulo-32bit base: that's why the overflow of the indexes is not
- * a problem.
- */
-struct rte_ring {
- /*
- * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
- * compatibility requirements, it could be changed to RTE_RING_NAMESIZE
- * next time the ABI changes
- */
- char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned; /**< Name of the ring. */
- int flags; /**< Flags supplied at creation. */
- const struct rte_memzone *memzone;
- /**< Memzone, if any, containing the rte_ring */
- uint32_t size; /**< Size of ring. */
- uint32_t mask; /**< Mask (size-1) of ring. */
- uint32_t capacity; /**< Usable size of ring */
-
- char pad0 __rte_cache_aligned; /**< empty cache line */
-
- /** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
- char pad1 __rte_cache_aligned; /**< empty cache line */
-
- /** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
- char pad2 __rte_cache_aligned; /**< empty cache line */
-};
-
-#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
-#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
-/**
- * Ring is to hold exactly requested number of entries.
- * Without this flag set, the ring size requested must be a power of 2, and the
- * usable space will be that size - 1. With the flag, the requested size will
- * be rounded up to the next power of two, but the usable space will be exactly
- * that requested. Worst case, if a power-of-2 size is requested, half the
- * ring space will be wasted.
- */
-#define RING_F_EXACT_SZ 0x0004
-#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
-
-/* @internal defines for passing to the enqueue dequeue worker functions */
-#define __IS_SP 1
-#define __IS_MP 0
-#define __IS_SC 1
-#define __IS_MC 0
+#include <rte_ring_core.h>
/**
* Calculate the memory size needed for a ring
@@ -420,7 +336,7 @@ rte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_MP, free_space);
+ RTE_RING_SYNC_MT, free_space);
}
/**
@@ -443,9 +359,13 @@ rte_ring_sp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_SP, free_space);
+ RTE_RING_SYNC_ST, free_space);
}
+#ifdef ALLOW_EXPERIMENTAL_API
+#include <rte_ring_elem.h>
+#endif
+
/**
* Enqueue several objects on a ring.
*
@@ -470,7 +390,7 @@ rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->prod.single, free_space);
+ r->prod.sync_type, free_space);
}
/**
@@ -554,7 +474,7 @@ rte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_MC, available);
+ RTE_RING_SYNC_MT, available);
}
/**
@@ -578,7 +498,7 @@ rte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_SC, available);
+ RTE_RING_SYNC_ST, available);
}
/**
@@ -605,7 +525,7 @@ rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
/**
@@ -777,6 +697,62 @@ rte_ring_get_capacity(const struct rte_ring *r)
return r->capacity;
}
+/**
+ * Return sync type used by producer in the ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Producer sync type value.
+ */
+static inline enum rte_ring_sync_type
+rte_ring_get_prod_sync_type(const struct rte_ring *r)
+{
+ return r->prod.sync_type;
+}
+
+/**
+ * Check is the ring for single producer.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * true if ring is SP, zero otherwise.
+ */
+static inline int
+rte_ring_is_prod_single(const struct rte_ring *r)
+{
+ return (rte_ring_get_prod_sync_type(r) == RTE_RING_SYNC_ST);
+}
+
+/**
+ * Return sync type used by consumer in the ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Consumer sync type value.
+ */
+static inline enum rte_ring_sync_type
+rte_ring_get_cons_sync_type(const struct rte_ring *r)
+{
+ return r->cons.sync_type;
+}
+
+/**
+ * Check is the ring for single consumer.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * true if ring is SC, zero otherwise.
+ */
+static inline int
+rte_ring_is_cons_single(const struct rte_ring *r)
+{
+ return (rte_ring_get_cons_sync_type(r) == RTE_RING_SYNC_ST);
+}
+
/**
* Dump the status of all rings on the console
*
@@ -820,7 +796,7 @@ rte_ring_mp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -843,7 +819,7 @@ rte_ring_sp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -870,7 +846,7 @@ rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
- r->prod.single, free_space);
+ r->prod.sync_type, free_space);
}
/**
@@ -898,7 +874,7 @@ rte_ring_mc_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
}
/**
@@ -923,7 +899,7 @@ rte_ring_sc_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
}
/**
@@ -951,7 +927,7 @@ rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
{
return __rte_ring_do_dequeue(r, obj_table, n,
RTE_RING_QUEUE_VARIABLE,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
#ifdef __cplusplus
diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
new file mode 100644
index 000000000..d9cef763f
--- /dev/null
+++ b/lib/librte_ring/rte_ring_core.h
@@ -0,0 +1,132 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_CORE_H_
+#define _RTE_RING_CORE_H_
+
+/**
+ * @file
+ * This file contains definion of RTE ring structure itself,
+ * init flags and some related macros.
+ * For majority of DPDK entities, it is not recommended to include
+ * this file directly, use include <rte_ring.h> or <rte_ring_elem.h>
+ * instead.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/queue.h>
+#include <errno.h>
+#include <rte_common.h>
+#include <rte_config.h>
+#include <rte_memory.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_memzone.h>
+#include <rte_pause.h>
+#include <rte_debug.h>
+
+#define RTE_TAILQ_RING_NAME "RTE_RING"
+
+/** enqueue/dequeue behavior types */
+enum rte_ring_queue_behavior {
+ /** Enq/Deq a fixed number of items from a ring */
+ RTE_RING_QUEUE_FIXED = 0,
+ /** Enq/Deq as many items as possible from ring */
+ RTE_RING_QUEUE_VARIABLE
+};
+
+#define RTE_RING_MZ_PREFIX "RG_"
+/** The maximum length of a ring name. */
+#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
+ sizeof(RTE_RING_MZ_PREFIX) + 1)
+
+/** prod/cons sync types */
+enum rte_ring_sync_type {
+ RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
+ RTE_RING_SYNC_ST, /**< single thread only */
+};
+
+/**
+ * structures to hold a pair of head/tail values and other metadata.
+ * Depending on sync_type format of that structure might be different,
+ * but offset for *sync_type* and *tail* values should remain the same.
+ */
+struct rte_ring_headtail {
+ volatile uint32_t head; /**< prod/consumer head. */
+ volatile uint32_t tail; /**< prod/consumer tail. */
+ RTE_STD_C11
+ union {
+ /** sync type of prod/cons */
+ enum rte_ring_sync_type sync_type;
+ /** deprecated - True if single prod/cons */
+ uint32_t single;
+ };
+};
+
+/**
+ * An RTE ring structure.
+ *
+ * The producer and the consumer have a head and a tail index. The particularity
+ * of these index is that they are not between 0 and size(ring). These indexes
+ * are between 0 and 2^32, and we mask their value when we access the ring[]
+ * field. Thanks to this assumption, we can do subtractions between 2 index
+ * values in a modulo-32bit base: that's why the overflow of the indexes is not
+ * a problem.
+ */
+struct rte_ring {
+ /*
+ * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
+ * compatibility requirements, it could be changed to RTE_RING_NAMESIZE
+ * next time the ABI changes
+ */
+ char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned;
+ /**< Name of the ring. */
+ int flags; /**< Flags supplied at creation. */
+ const struct rte_memzone *memzone;
+ /**< Memzone, if any, containing the rte_ring */
+ uint32_t size; /**< Size of ring. */
+ uint32_t mask; /**< Mask (size-1) of ring. */
+ uint32_t capacity; /**< Usable size of ring */
+
+ char pad0 __rte_cache_aligned; /**< empty cache line */
+
+ /** Ring producer status. */
+ struct rte_ring_headtail prod __rte_cache_aligned;
+ char pad1 __rte_cache_aligned; /**< empty cache line */
+
+ /** Ring consumer status. */
+ struct rte_ring_headtail cons __rte_cache_aligned;
+ char pad2 __rte_cache_aligned; /**< empty cache line */
+};
+
+#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
+#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
+/**
+ * Ring is to hold exactly requested number of entries.
+ * Without this flag set, the ring size requested must be a power of 2, and the
+ * usable space will be that size - 1. With the flag, the requested size will
+ * be rounded up to the next power of two, but the usable space will be exactly
+ * that requested. Worst case, if a power-of-2 size is requested, half the
+ * ring space will be wasted.
+ */
+#define RING_F_EXACT_SZ 0x0004
+#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RING_CORE_H_ */
diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
index 663addc73..7406c0b0f 100644
--- a/lib/librte_ring/rte_ring_elem.h
+++ b/lib/librte_ring/rte_ring_elem.h
@@ -20,21 +20,7 @@
extern "C" {
#endif
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <errno.h>
-#include <rte_common.h>
-#include <rte_config.h>
-#include <rte_memory.h>
-#include <rte_lcore.h>
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_memzone.h>
-#include <rte_pause.h>
-
-#include "rte_ring.h"
+#include <rte_ring_core.h>
/**
* @warning
@@ -510,7 +496,7 @@ rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_MP, free_space);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -539,7 +525,7 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_SP, free_space);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -570,7 +556,7 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->prod.single, free_space);
+ RTE_RING_QUEUE_FIXED, r->prod.sync_type, free_space);
}
/**
@@ -675,7 +661,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_MC, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
}
/**
@@ -703,7 +689,7 @@ rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_SC, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
}
/**
@@ -734,7 +720,7 @@ rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->cons.single, available);
+ RTE_RING_QUEUE_FIXED, r->cons.sync_type, available);
}
/**
@@ -842,7 +828,7 @@ rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -871,7 +857,7 @@ rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -902,7 +888,7 @@ rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, r->prod.single, free_space);
+ RTE_RING_QUEUE_VARIABLE, r->prod.sync_type, free_space);
}
/**
@@ -934,7 +920,7 @@ rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
}
/**
@@ -963,7 +949,7 @@ rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
}
/**
@@ -995,9 +981,11 @@ rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_VARIABLE,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
+#include <rte_ring.h>
+
#ifdef __cplusplus
}
#endif
--
2.17.1
^ permalink raw reply [relevance 9%]
* [dpdk-dev] [PATCH v5 0/9] New sync modes for ring
2020-04-17 13:36 3% ` [dpdk-dev] [PATCH v4 " Konstantin Ananyev
2020-04-17 13:36 9% ` [dpdk-dev] [PATCH v4 2/9] ring: prepare ring to allow new sync schemes Konstantin Ananyev
2020-04-17 13:36 1% ` [dpdk-dev] [PATCH v4 3/9] ring: introduce RTS ring mode Konstantin Ananyev
@ 2020-04-18 16:32 3% ` Konstantin Ananyev
2020-04-18 16:32 9% ` [dpdk-dev] [PATCH v5 2/9] ring: prepare ring to allow new sync schemes Konstantin Ananyev
` (3 more replies)
2 siblings, 4 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-18 16:32 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
V4 - V5:
1. fix i686 clang build problem
2. fix formal API comments
V3 - V4 changes:
Address comments from Honnappa:
1. for new sync modes make legacy API wrappers around _elem_ calls
2. remove rte_ring_(hts|rts)_generic.h
3. few changes in C11 version
4. peek API - add missing functions for _elem_
5. remove _IS_SP/_IS_MP, etc. internal macros
6. fix param types (obj_table) for _elem_functions
7. fix formal API comments
8. deduplicate code for test_ring_stress
9. added functional tests for new sync modes
V2 - V3 changes:
1. few more compilation fixes (for gcc 4.8.X)
2. extra update devtools/libabigail.abignore (workaround)
V1 - V2 changes:
1. fix compilation issues
2. add C11 atomics support
3. updates devtools/libabigail.abignore (workaround)
RFC - V1 changes:
1. remove ABI brekage (at least I hope I did)
2. Add support for ring_elem
3. rework peek related API a bit
4. rework test to make it less verbose and unite all test-cases
in one command
5. add new test-case for MT peek API
TODO list:
1. Update docs
These days more and more customers use(/try to use) DPDK based apps within
overcommitted systems (multiple acttive threads over same pysical cores):
VM, container deployments, etc.
One quite common problem they hit:
Lock-Holder-Preemption/Lock-Waiter-Preemption with rte_ring.
LHP is quite a common problem for spin-based sync primitives
(spin-locks, etc.) on overcommitted systems.
The situation gets much worse when some sort of
fair-locking technique is used (ticket-lock, etc.).
As now not only lock-owner but also lock-waiters scheduling
order matters a lot (LWP).
These two problems are well-known for kernel within VMs:
http://www-archive.xenproject.org/files/xensummitboston08/LHP.pdf
https://www.cs.hs-rm.de/~kaiser/events/wamos2017/Slides/selcuk.pdf
The problem with rte_ring is that while head accusion is sort of
un-fair locking, waiting on tail is very similar to ticket lock schema -
tail has to be updated in particular order.
That makes current rte_ring implementation to perform
really pure on some overcommited scenarios.
It is probably not possible to completely resolve LHP problem in
userspace only (without some kernel communication/intervention).
But removing fairness at tail update helps to avoid LWP and
can mitigate the situation significantly.
This patch proposes two new optional ring synchronization modes:
1) Head/Tail Sync (HTS) mode
In that mode enqueue/dequeue operation is fully serialized:
only one thread at a time is allowed to perform given op.
As another enhancement provide ability to split enqueue/dequeue
operation into two phases:
- enqueue/dequeue start
- enqueue/dequeue finish
That allows user to inspect objects in the ring without removing
them from it (aka MT safe peek).
2) Relaxed Tail Sync (RTS)
The main difference from original MP/MC algorithm is that
tail value is increased not by every thread that finished enqueue/dequeue,
but only by the last one.
That allows threads to avoid spinning on ring tail value,
leaving actual tail value change to the last thread in the update queue.
Note that these new sync modes are optional.
For current rte_ring users nothing should change
(both in terms of API/ABI and performance).
Existing sync modes MP/MC,SP/SC kept untouched, set up in the same
way (via flags and _init_), and MP/MC remains as default one.
The only thing that changed:
Format of prod/cons now could differ depending on mode selected at _init_.
So user has to stick with one sync model through whole ring lifetime.
In other words, user can't create a ring for let say SP mode and then
in the middle of data-path change his mind and start using MP_RTS mode.
For existing modes (SP/MP, SC/MC) format remains the same and
user can still use them interchangeably, though of course it is an
error prone practice.
Test results on IA (see below) show significant improvements
for average enqueue/dequeue op times on overcommitted systems.
For 'classic' DPDK deployments (one thread per core) original MP/MC
algorithm still shows best numbers, though for 64-bit target
RTS numbers are not that far away.
Numbers were produced by new UT test-case: ring_stress_autotest, i.e.:
echo ring_stress_autotest | ./dpdk-test -n 4 --lcores='...'
X86_64 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
DEQ+ENQ average cycles/obj
MP/MC HTS RTS
1thread@1core(--lcores=6-7) 8.00 8.15 8.99
2thread@2core(--lcores=6-8) 19.14 19.61 20.35
4thread@4core(--lcores=6-10) 29.43 29.79 31.82
8thread@8core(--lcores=6-14) 110.59 192.81 119.50
16thread@16core(--lcores=6-22) 461.03 813.12 495.59
32thread/@32core(--lcores='6-22,55-70') 982.90 1972.38 1160.51
2thread@1core(--lcores='6,(10-11)@7' 20140.50 23.58 25.14
4thread@2core(--lcores='6,(10-11)@7,(20-21)@8' 153680.60 76.88 80.05
8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 280314.32 294.72 318.79
16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 643176.59 1144.02 1175.14
32thread@2core(--lcores='6,(10-25)@7,(30-45)@8' 4264238.80 4627.48 4892.68
8thread@2core(--lcores='6,(10-17)@(7,8))' 321085.98 298.59 307.47
16thread@4core(--lcores='6,(20-35)@(7-10))' 1900705.61 575.35 678.29
32thread@4core(--lcores='6,(20-51)@(7-10))' 5510445.85 2164.36 2714.12
i686 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
DEQ+ENQ average cycles/obj
MP/MC HTS RTS
1thread@1core(--lcores=6-7) 7.85 12.13 11.31
2thread@2core(--lcores=6-8) 17.89 24.52 21.86
8thread@8core(--lcores=6-14) 32.58 354.20 54.58
32thread/@32core(--lcores='6-22,55-70') 813.77 6072.41 2169.91
2thread@1core(--lcores='6,(10-11)@7' 16095.00 36.06 34.74
8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 1140354.54 346.61 361.57
16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 1920417.86 1314.90 1416.65
8thread@2core(--lcores='6,(10-17)@(7,8))' 594358.61 332.70 357.74
32thread@4core(--lcores='6,(20-51)@(7-10))' 5319896.86 2836.44 3028.87
Konstantin Ananyev (9):
test/ring: add contention stress test
ring: prepare ring to allow new sync schemes
ring: introduce RTS ring mode
test/ring: add contention stress test for RTS ring
ring: introduce HTS ring mode
test/ring: add contention stress test for HTS ring
ring: introduce peek style API
test/ring: add stress test for MT peek API
test/ring: add functional tests for new sync modes
app/test/Makefile | 5 +
app/test/meson.build | 5 +
app/test/test_pdump.c | 6 +-
app/test/test_ring.c | 93 ++++--
app/test/test_ring_hts_stress.c | 32 ++
app/test/test_ring_mpmc_stress.c | 31 ++
app/test/test_ring_peek_stress.c | 43 +++
app/test/test_ring_rts_stress.c | 32 ++
app/test/test_ring_stress.c | 57 ++++
app/test/test_ring_stress.h | 38 +++
app/test/test_ring_stress_impl.h | 396 ++++++++++++++++++++++
devtools/libabigail.abignore | 7 +
lib/librte_pdump/rte_pdump.c | 2 +-
lib/librte_port/rte_port_ring.c | 12 +-
lib/librte_ring/Makefile | 8 +-
lib/librte_ring/meson.build | 11 +-
lib/librte_ring/rte_ring.c | 114 ++++++-
lib/librte_ring/rte_ring.h | 243 ++++++++------
lib/librte_ring/rte_ring_c11_mem.h | 44 +++
lib/librte_ring/rte_ring_core.h | 184 ++++++++++
lib/librte_ring/rte_ring_elem.h | 141 ++++++--
lib/librte_ring/rte_ring_generic.h | 48 +++
lib/librte_ring/rte_ring_hts.h | 332 +++++++++++++++++++
lib/librte_ring/rte_ring_hts_c11_mem.h | 207 ++++++++++++
lib/librte_ring/rte_ring_peek.h | 442 +++++++++++++++++++++++++
lib/librte_ring/rte_ring_rts.h | 439 ++++++++++++++++++++++++
lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
27 files changed, 2977 insertions(+), 174 deletions(-)
create mode 100644 app/test/test_ring_hts_stress.c
create mode 100644 app/test/test_ring_mpmc_stress.c
create mode 100644 app/test/test_ring_peek_stress.c
create mode 100644 app/test/test_ring_rts_stress.c
create mode 100644 app/test/test_ring_stress.c
create mode 100644 app/test/test_ring_stress.h
create mode 100644 app/test/test_ring_stress_impl.h
create mode 100644 lib/librte_ring/rte_ring_core.h
create mode 100644 lib/librte_ring/rte_ring_hts.h
create mode 100644 lib/librte_ring/rte_ring_hts_c11_mem.h
create mode 100644 lib/librte_ring/rte_ring_peek.h
create mode 100644 lib/librte_ring/rte_ring_rts.h
create mode 100644 lib/librte_ring/rte_ring_rts_c11_mem.h
--
2.17.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v7 0/2] support for VFIO-PCI VF token interface
@ 2020-04-18 11:16 4% ` Haiyue Wang
2020-04-18 17:30 4% ` [dpdk-dev] [PATCH v8 " Haiyue Wang
` (2 subsequent siblings)
3 siblings, 0 replies; 200+ results
From: Haiyue Wang @ 2020-04-18 11:16 UTC (permalink / raw)
To: dev, anatoly.burakov, thomas, vattunuru, jerinj, alex.williamson,
david.marchand
Cc: Haiyue Wang
v7: Add the Fixes tag in uuid, the release note and help
document.
v6: Drop the Fixes tag in uuid, since the file has been
moved to another place, not suitable to apply on stable.
And this is not a bug, just some kind of enhancement.
https://patchwork.dpdk.org/cover/68367/
v5: 1. Add the VF token parse error handling.
2. Split into two patches for different logic module.
3. Add more comments into the code for explaining the design.
4. Drop the ABI change workaround, this patch set focuses on code review.
https://patchwork.dpdk.org/cover/68364/
v4: 1. Ignore rte_vfio_setup_device ABI check since it is
for Linux driver use.
https://patchwork.dpdk.org/patch/68255/
v3: Fix the Travis build failed:
(1). rte_uuid.h:97:55: error: unknown type name ‘size_t’
(2). rte_uuid.h:58:2: error: implicit declaration of function ‘memcpy’
https://patchwork.dpdk.org/patch/68254/
v2: Fix the FreeBSD build error.
https://patchwork.dpdk.org/patch/68240/
v1: Update the commit message.
https://patchwork.dpdk.org/patch/68237/
RFC v2: https://patchwork.dpdk.org/patch/68114/
Based on Vamsi's RFC v1, and Alex's patch for Qemu
[https://lore.kernel.org/lkml/20200204161737.34696b91@w520.home/]:
Use the devarg to pass-down the VF token.
RFC v1: https://patchwork.dpdk.org/patch/66281/ by Vamsi.
Haiyue Wang (2):
eal: add uuid dependent header files explicitly
eal: support for VFIO-PCI VF token
doc/guides/linux_gsg/linux_drivers.rst | 23 +++++++-
doc/guides/rel_notes/release_20_05.rst | 5 ++
drivers/bus/pci/linux/pci_vfio.c | 74 +++++++++++++++++++++++++-
lib/librte_eal/freebsd/eal.c | 3 +-
lib/librte_eal/include/rte_uuid.h | 2 +
lib/librte_eal/include/rte_vfio.h | 21 +++++++-
lib/librte_eal/linux/eal_vfio.c | 20 +++++--
7 files changed, 140 insertions(+), 8 deletions(-)
--
2.26.1
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
2020-04-18 5:04 0% ` Bill Zhou
@ 2020-04-18 9:44 0% ` Thomas Monjalon
2020-04-20 14:06 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-18 9:44 UTC (permalink / raw)
To: Ferruh Yigit, Ori Kam, Matan Azrad, wenzhuo.lu, jingjing.wu,
bernard.iremonger, john.mcnamara, marko.kovacevic, arybchenko,
Bill Zhou
Cc: dev
18/04/2020 07:04, Bill Zhou:
> From: Ferruh Yigit <ferruh.yigit@intel.com>
> > On 4/14/2020 9:32 AM, Dong Zhou wrote:
> > > --- a/lib/librte_ethdev/rte_ethdev.h
> > > +++ b/lib/librte_ethdev/rte_ethdev.h
> > > @@ -3015,6 +3015,7 @@ enum rte_eth_event_type {
> > > RTE_ETH_EVENT_NEW, /**< port is probed */
> > > RTE_ETH_EVENT_DESTROY, /**< port is released */
> > > RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
> > > + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected
> > */
> > > RTE_ETH_EVENT_MAX /**< max value of this enum */
> > > };
> >
> >
> > Just recognized that this is failing in ABI check [1], as far as last time for a
> > similar enum warning a QAT patch has been dropped, should this need to
> > wait for
> > 20.11 too?
>
> This patch is commonly used for flow aging, there are 2 other patches have
> implement flow aging in mlx5 driver reply to this patch.
> In our schedule, this feature is merged in 20.05 for some customers. Can it
> be fixed?
These MAX values in enums are a pain.
We can try to think what can be done, waiting 20.11.
Not sure there is a solution, except hijacking an existing value
not used in the PMD, waiting the definitive value in 20.11...
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
2020-04-17 22:00 3% ` Ferruh Yigit
2020-04-17 22:07 0% ` Stephen Hemminger
@ 2020-04-18 5:04 0% ` Bill Zhou
2020-04-18 9:44 0% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Bill Zhou @ 2020-04-18 5:04 UTC (permalink / raw)
To: Ferruh Yigit, Ori Kam, Matan Azrad, wenzhuo.lu, jingjing.wu,
bernard.iremonger, john.mcnamara, marko.kovacevic,
Thomas Monjalon, arybchenko
Cc: dev
> -----Original Message-----
> From: Ferruh Yigit <ferruh.yigit@intel.com>
> Sent: Saturday, April 18, 2020 6:01 AM
> To: Bill Zhou <dongz@mellanox.com>; Ori Kam <orika@mellanox.com>;
> Matan Azrad <matan@mellanox.com>; wenzhuo.lu@intel.com;
> jingjing.wu@intel.com; bernard.iremonger@intel.com;
> john.mcnamara@intel.com; marko.kovacevic@intel.com; Thomas Monjalon
> <thomas@monjalon.net>; arybchenko@solarflare.com
> Cc: dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
>
> On 4/14/2020 9:32 AM, Dong Zhou wrote:
> > One of the reasons to destroy a flow is the fact that no packet
> > matches the flow for "timeout" time.
> > For example, when TCP\UDP sessions are suddenly closed.
> >
> > Currently, there is not any DPDK mechanism for flow aging and the
> > applications use their own ways to detect and destroy aged-out flows.
> >
> > The flow aging implementation need include:
> > - A new rte_flow action: RTE_FLOW_ACTION_TYPE_AGE to set the
> timeout and
> > the application flow context for each flow.
> > - A new ethdev event: RTE_ETH_EVENT_FLOW_AGED for the driver to
> report
> > that there are new aged-out flows.
> > - A new rte_flow API: rte_flow_get_aged_flows to get the aged-out flows
> > contexts from the port.
> > - Support input flow aging command line in Testpmd.
> >
> > Signed-off-by: Dong Zhou <dongz@mellanox.com>
>
> <...>
>
> > --- a/lib/librte_ethdev/rte_ethdev.h
> > +++ b/lib/librte_ethdev/rte_ethdev.h
> > @@ -3015,6 +3015,7 @@ enum rte_eth_event_type {
> > RTE_ETH_EVENT_NEW, /**< port is probed */
> > RTE_ETH_EVENT_DESTROY, /**< port is released */
> > RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
> > + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected
> */
> > RTE_ETH_EVENT_MAX /**< max value of this enum */
> > };
>
>
> Just recognized that this is failing in ABI check [1], as far as last time for a
> similar enum warning a QAT patch has been dropped, should this need to
> wait for
> 20.11 too?
This patch is commonly used for flow aging, there are 2 other patches have
implement flow aging in mlx5 driver reply to this patch.
In our schedule, this feature is merged in 20.05 for some customers. Can it
be fixed?
>
>
> [1]
> [C]'function int _rte_eth_dev_callback_process(rte_eth_dev*,
> rte_eth_event_type, void*)' at rte_ethdev.c:4063:1 has some indirect sub-
> type
> changes:
> parameter 2 of type 'enum rte_eth_event_type' has sub-type changes:
> type size hasn't changed
> 1 enumerator insertion:
> 'rte_eth_event_type::RTE_ETH_EVENT_FLOW_AGED' value '10'
> 1 enumerator change:
> 'rte_eth_event_type::RTE_ETH_EVENT_MAX' from value '10' to '11' at
> rte_ethdev.h:3008:1
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
2020-04-17 22:00 3% ` Ferruh Yigit
@ 2020-04-17 22:07 0% ` Stephen Hemminger
2020-04-18 5:04 0% ` Bill Zhou
1 sibling, 0 replies; 200+ results
From: Stephen Hemminger @ 2020-04-17 22:07 UTC (permalink / raw)
To: Ferruh Yigit
Cc: Dong Zhou, orika, matan, wenzhuo.lu, jingjing.wu,
bernard.iremonger, john.mcnamara, marko.kovacevic, thomas,
arybchenko, dev
On Fri, 17 Apr 2020 23:00:57 +0100
Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> On 4/14/2020 9:32 AM, Dong Zhou wrote:
> > One of the reasons to destroy a flow is the fact that no packet matches the
> > flow for "timeout" time.
> > For example, when TCP\UDP sessions are suddenly closed.
> >
> > Currently, there is not any DPDK mechanism for flow aging and the
> > applications use their own ways to detect and destroy aged-out flows.
> >
> > The flow aging implementation need include:
> > - A new rte_flow action: RTE_FLOW_ACTION_TYPE_AGE to set the timeout and
> > the application flow context for each flow.
> > - A new ethdev event: RTE_ETH_EVENT_FLOW_AGED for the driver to report
> > that there are new aged-out flows.
> > - A new rte_flow API: rte_flow_get_aged_flows to get the aged-out flows
> > contexts from the port.
> > - Support input flow aging command line in Testpmd.
> >
> > Signed-off-by: Dong Zhou <dongz@mellanox.com>
>
> <...>
>
> > --- a/lib/librte_ethdev/rte_ethdev.h
> > +++ b/lib/librte_ethdev/rte_ethdev.h
> > @@ -3015,6 +3015,7 @@ enum rte_eth_event_type {
> > RTE_ETH_EVENT_NEW, /**< port is probed */
> > RTE_ETH_EVENT_DESTROY, /**< port is released */
> > RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
> > + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected */
> > RTE_ETH_EVENT_MAX /**< max value of this enum */
> > };
>
>
> Just recognized that this is failing in ABI check [1], as far as last time for a
> similar enum warning a QAT patch has been dropped, should this need to wait for
> 20.11 too?
>
>
> [1]
> [C]'function int _rte_eth_dev_callback_process(rte_eth_dev*,
> rte_eth_event_type, void*)' at rte_ethdev.c:4063:1 has some indirect sub-type
> changes:
> parameter 2 of type 'enum rte_eth_event_type' has sub-type changes:
> type size hasn't changed
> 1 enumerator insertion:
> 'rte_eth_event_type::RTE_ETH_EVENT_FLOW_AGED' value '10'
> 1 enumerator change:
> 'rte_eth_event_type::RTE_ETH_EVENT_MAX' from value '10' to '11' at
> rte_ethdev.h:3008:1
>
For 20.11, those _MAX values need to be removed from enums
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] ethdev: support flow aging
@ 2020-04-17 22:00 3% ` Ferruh Yigit
2020-04-17 22:07 0% ` Stephen Hemminger
2020-04-18 5:04 0% ` Bill Zhou
0 siblings, 2 replies; 200+ results
From: Ferruh Yigit @ 2020-04-17 22:00 UTC (permalink / raw)
To: Dong Zhou, orika, matan, wenzhuo.lu, jingjing.wu,
bernard.iremonger, john.mcnamara, marko.kovacevic, thomas,
arybchenko
Cc: dev
On 4/14/2020 9:32 AM, Dong Zhou wrote:
> One of the reasons to destroy a flow is the fact that no packet matches the
> flow for "timeout" time.
> For example, when TCP\UDP sessions are suddenly closed.
>
> Currently, there is not any DPDK mechanism for flow aging and the
> applications use their own ways to detect and destroy aged-out flows.
>
> The flow aging implementation need include:
> - A new rte_flow action: RTE_FLOW_ACTION_TYPE_AGE to set the timeout and
> the application flow context for each flow.
> - A new ethdev event: RTE_ETH_EVENT_FLOW_AGED for the driver to report
> that there are new aged-out flows.
> - A new rte_flow API: rte_flow_get_aged_flows to get the aged-out flows
> contexts from the port.
> - Support input flow aging command line in Testpmd.
>
> Signed-off-by: Dong Zhou <dongz@mellanox.com>
<...>
> --- a/lib/librte_ethdev/rte_ethdev.h
> +++ b/lib/librte_ethdev/rte_ethdev.h
> @@ -3015,6 +3015,7 @@ enum rte_eth_event_type {
> RTE_ETH_EVENT_NEW, /**< port is probed */
> RTE_ETH_EVENT_DESTROY, /**< port is released */
> RTE_ETH_EVENT_IPSEC, /**< IPsec offload related event */
> + RTE_ETH_EVENT_FLOW_AGED,/**< New aged-out flows is detected */
> RTE_ETH_EVENT_MAX /**< max value of this enum */
> };
Just recognized that this is failing in ABI check [1], as far as last time for a
similar enum warning a QAT patch has been dropped, should this need to wait for
20.11 too?
[1]
[C]'function int _rte_eth_dev_callback_process(rte_eth_dev*,
rte_eth_event_type, void*)' at rte_ethdev.c:4063:1 has some indirect sub-type
changes:
parameter 2 of type 'enum rte_eth_event_type' has sub-type changes:
type size hasn't changed
1 enumerator insertion:
'rte_eth_event_type::RTE_ETH_EVENT_FLOW_AGED' value '10'
1 enumerator change:
'rte_eth_event_type::RTE_ETH_EVENT_MAX' from value '10' to '11' at
rte_ethdev.h:3008:1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v1] common/mlx5: remove devx depndency on ibv and dv
@ 2020-04-17 16:19 0% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2020-04-17 16:19 UTC (permalink / raw)
To: Thomas Monjalon
Cc: Matan Azrad, Raslan Darawsheh, Ophir Munk, David Marchand, dev,
Olga Shern, Asaf Penso, Kinsella, Ray, Neil Horman, Kevin Laatz,
hemant.agrawal, Haiyue Wang, Sunil Kumar Kori
On 4/16/2020 9:00 PM, Thomas Monjalon wrote:
> 16/04/2020 19:35, Ferruh Yigit:
>> On 4/9/2020 8:24 AM, David Marchand wrote:
>>> On Wed, Apr 8, 2020 at 7:12 PM Ferruh Yigit <ferruh.yigit@intel.com> wrote:
>>>> On 4/1/2020 10:59 AM, Raslan Darawsheh wrote:
>>>>> From: Ophir Munk <ophirmu@mellanox.com>
>>>>>>
>>>>>> File mlx5_devx_cmds.c should contain pure DevX calls. It must be OS
>>>>>> agnostic and not include any references to ibv or dv structs (defined in
>>>>>> ibverbs and rdma-core linux libraries). This commit replaces all ibv and
>>>>>> dv references with 'void *'. Specifically, the following struct were
>>>>>> replaced:
>>>>>> 1. struct ibv_context *
>>>>>> 2. struct ibv_qp *
>>>>>> 3. struct mlx5dv_devx_cmd_comp *
>>>>>>
>>>>>> Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
>>>>>
>>>>> Patch applied to next-net-mlx,
>>>>>
>>>>
>>>> Hi David,
>>>>
>>>> This patch is failing in the travis for ABI checks [1], since mlx has APIs now
>>>> [2], are they public APIs or internal ones, and are they part of the ABI policy,
>>>> can you please check this?
>>>
>>> - What I see on patchwork and test-report ml for this patch:
>>> http://patchwork.dpdk.org/patch/67367/
>>>
>>> Ophir proposed a patch on 03/30.
>>>
>>> The robot reported an issue on 03/30, and I suppose Ophir got a report.
>>> https://mails.dpdk.org/archives/test-report/2020-March/122623.html
>>> https://travis-ci.com/github/ovsrobot/dpdk/jobs/308057800#L2337
>>>
>>> Matan acked the patch on 03/31.
>>>
>>> Rasland merged the patch on 04/01.
>>>
>>> I understand that the abi checks are not perfect, and people need help
>>> with the new abi checks.
>>> Prove me wrong, but here, I get the feeling that it was just ignored
>>> by 3 people in a row.
>>>
>>> - On the question if these should be public API or internal, that is
>>> not for me to reply/investigate.
>>> This is a question for Mellanox.
>>>
>>
>> Hi Matan, Raslan, Ophir,
>>
>> First can you please clarify if these APIs are internal or public?
>
> As most of common drivers, some functions are exported to be
> used by some PMDs. So they are not part of the API/ABI and should be skipped
> by ABI checks.
>
>> And later if the ABI break issue is not clarified I may need to drop these
>> patches. Right now they fail in travis!
>
> Yes, it fails and could it be avoided with some libabigail config.
> But the real solution is to mark internal symbols, and we are waiting
> for rte_internal patchset to be completed and merged.
>
> Ferruh, please let's not bloat libabigail config,
> and reject any patch failing ABI checks.
>
> As a consequence, this patch must be dropped until it uses rte_internal.
> Thanks
>
>
dropped the patch from next-net and updated its patchwork status.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-17 15:42 9% ` Ray Kinsella
@ 2020-04-17 16:10 4% ` Thomas Monjalon
2020-04-20 8:43 8% ` Ray Kinsella
2020-04-21 11:12 4% ` Neil Horman
1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-17 16:10 UTC (permalink / raw)
To: Neil Horman, Ray Kinsella; +Cc: dev, david.marchand
17/04/2020 17:42, Ray Kinsella:
> On 17/04/2020 13:10, Thomas Monjalon wrote:
> > 17/04/2020 13:47, Ray Kinsella:
> >> On 17/04/2020 11:20, Thomas Monjalon wrote:
> >>> 17/04/2020 12:11, Ray Kinsella:
> >>>> check-abi.sh appears to be backward step in terms of usability.
> >>>
> >>> No, check-abi.sh benefits from a nice integration in build scripts.
> >>> See below.
> >>>
> >>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> >>>> And it will do the build, install, dump and comparison for me.
> >>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
> >>>>
> >>>> With check-abi on the other hand, I need to the build and install myself.
> >>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> >>>> It silently fails when it doesn't find any ...
> >>>>
> >>>> Do I run abi-dumper on the so's myself, or how does it work?
> >>>
> >>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> >>> Probably we should document usage in these scripts.
> >>
> >> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> >> Any tips or tricks would be welcome.
> >
> > export DPDK_ABI_REF_VERSION=v20.02
> > or
> > export DPDK_ABI_REF_VERSION=v19.11
> >
> > Depends on which compatibility you want to test...
> >
>
> Few things ...
>
> 1. test-meson-build.sh keep barfing complaining about reference paths.
> ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
>
> Under the hood, ninja install is failing complaining that it needs an absolute path.
> I fixed this in test_meson_build.sh and will send a patch in a minute.
> Though it's strange no-one else has seen it?
I set an absolute path in DPDK_ABI_REF_DIR.
Not sure you can really fix it. What would be the root dir?
> 2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
Yes
> 3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
> In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
> I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
Why is it a common case? You want to compare with a tag. Why something else?
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-17 11:46 5% ` Trahe, Fiona
@ 2020-04-17 16:01 0% ` Ray Kinsella
2020-04-20 16:59 3% ` Trahe, Fiona
1 sibling, 0 replies; 200+ results
From: Ray Kinsella @ 2020-04-17 16:01 UTC (permalink / raw)
To: Trahe, Fiona, Thomas Monjalon, Richardson, Bruce
Cc: dev, Kusztal, ArkadiuszX, Neil Horman, Luca Boccassi,
Kevin Traynor, Yigit, Ferruh
On 17/04/2020 12:46, Trahe, Fiona wrote:
> Hi all,
>
>> -----Original Message-----
>> From: Ray Kinsella <mdr@ashroe.eu>
>> Sent: Friday, April 17, 2020 11:34 AM
>> To: Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce <bruce.richardson@intel.com>
>> Cc: Trahe, Fiona <fiona.trahe@intel.com>; dev@dpdk.org; Kusztal, ArkadiuszX
>> <arkadiuszx.kusztal@intel.com>; Neil Horman <nhorman@tuxdriver.com>; Luca Boccassi
>> <bluca@debian.org>; Kevin Traynor <ktraynor@redhat.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
>> Subject: Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
>>
>>
>>
>> On 17/04/2020 11:17, Thomas Monjalon wrote:
>>> 17/04/2020 11:42, Ray Kinsella:
>>>> On 17/04/2020 10:31, Bruce Richardson wrote:
>>>>> On Fri, Apr 17, 2020 at 08:24:30AM +0100, Ray Kinsella wrote:
>>>>>> On 16/04/2020 11:01, Thomas Monjalon wrote:
>>>>>>> 16/04/2020 11:51, Bruce Richardson:
>>>>>>>> On Wed, Apr 15, 2020 at 06:24:19PM +0100, Trahe, Fiona wrote:
>>>>>>>>> 5a. If in 20.05 we add a version of a fn which breaks ABI 20.0, what should the name of the
>> original function be? fn_v20, or fn_v20.0
>>>>>>>>
>>>>>>>> In technical terms it really doesn't matter, it's just a name that will be
>>>>>>>> looked up in a table. I don't think we strictly enforce the naming, so
>>>>>>>> whatever is clearest is best. I'd suggest the former.
>>>>>>>
>>>>>>> Each release can have a new ABI.
>>>>>>
>>>>>> How many ABI's do we want to support?
>>>>>>
>>>>> It's not how many we want to support, but for me it's a matter of how many
>>>>> do we need to support. If an API is part of the stable set, it can't just
>>>>> drop to being experimental for one or two releases - it's always stable
>>>>> until deprecated. We also shouldn't have a situation where release 20.08 is
>>>>> ABI compatible with 19.11 but not 20.02 and 20.05.
>>>>
>>>> True. Let me say it differently.
>>>>
>>>> Our only commitment is to support v20 - 19.11
>>>> However you are correct, if something gets committed as v21 in 20.02, in practise should also be
>> there in 20.05+ also.
>>>> Because if it is committed as v21 and not as experimental, it should not be changing once
>> committed.
>>>>
>>>> In answering Thomas,
>>>> I was more commenting on the proliferation of ABI numbers & symbols we need to track in the
>> build.
>>>> With v20, v21 & Experimental we need to keep track of 3.
>>>> If we start allowing quarterly builds to have managed ABI's, it will get confusing.
>>>
>>> I don't remember why we are using intermediate ABI versions
>>> between v20 and v21.
>>> If we can use v21 for new ABI and make sure compatibility is maintained
>>> between all versions from 19.11 to 20.08, I'm fine.
> [Fiona] Here's a hypothetical case, but it illustrates why I don't think there
> should be an expectation to maintain ABI compatibility here.
> Example: in 20.05 add a new info_get_v21() which includes ChaChaPoly.
> In 20.08 add another new algorithm. info_get_v21() return now includes this.
> info_get_v21() will become stable in 20.11 and compatibility must be maintained from then on.
Yes, and the v20 version gets removed in 20.11.
> In the meantime, the fn is not experimental - that wouldn't be appropriate as it was a stable API.
Well it could be ... these are just labels after all.
So it entirely possible and permitted to have a info_get@DPDK_20.0 and info_get@EXPERIMENTAL simultaneously.
In fact, if it is your expectation that new version will change in successively quarterly releases.
That suggests it should be experimental.
There in a gap here, we appear to be missing the required MACROS to support a v20.0 + EXPERIMENTAL simultaneously.
As I remember this api was particularly sensitive to size of an enumeration?
Has that been resolved to make the api less brittle?
> But an app either wants stability and so should build against 19.11, or if prepared to move up to
> one non-stable-ABI quarterly release should be willing to rebuild for the next non-stable-ABI quarterly release.
> I think it's an unnecessary burden to require ABI compatibility across quarterly releases.
I generally agree with this point.
Our only cast iron solid commitment is compatibility with 19.11.
That said, once any API has dropped the EXPERIMENTAL label, it shouldn't be changing.
All things being equal quarterly releases should be compatible with each other, as v21 APIs should not be changing.
> And if required could end up with the version tracking hassle Ray referred to above with fn versions
> of 20.0.1, 20.0.2, 20.0.3, v21, and potentially several versions of same fn.
>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
2020-04-17 15:05 0% ` Trahe, Fiona
@ 2020-04-17 15:52 0% ` Trahe, Fiona
2020-04-18 19:43 3% ` Chautru, Nicolas
0 siblings, 1 reply; 200+ results
From: Trahe, Fiona @ 2020-04-17 15:52 UTC (permalink / raw)
To: David Marchand
Cc: dev, Jerin Jacob, Pavan Nikhilesh, Richardson, Bruce,
Thomas Monjalon, Yigit, Ferruh, Hemant Agrawal, Trahe, Fiona
Hi David,
> -----Original Message-----
> From: Trahe, Fiona <fiona.trahe@intel.com>
> Sent: Friday, April 17, 2020 4:05 PM
> To: David Marchand <david.marchand@redhat.com>
> Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan Nikhilesh
> <pbhagavatula@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>; Thomas Monjalon
> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>; Trahe, Fiona <fiona.trahe@intel.com>
> Subject: RE: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
>
> Hi Davd,
>
> > -----Original Message-----
> > From: David Marchand <david.marchand@redhat.com>
> > Sent: Friday, April 17, 2020 2:56 PM
> > To: Trahe, Fiona <fiona.trahe@intel.com>
> > Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan Nikhilesh
> > <pbhagavatula@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>; Thomas
> Monjalon
> > <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> > <hemant.agrawal@nxp.com>
> > Subject: Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
> >
> > On Fri, Apr 17, 2020 at 3:44 PM Trahe, Fiona <fiona.trahe@intel.com> wrote:
> > >
> > > Hi David,
> > >
> > > > -----Original Message-----
> > > > From: David Marchand <david.marchand@redhat.com>
> > > > Sent: Friday, April 17, 2020 2:23 PM
> > > > To: Trahe, Fiona <fiona.trahe@intel.com>
> > > > Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan Nikhilesh
> > > > <pbhagavatula@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>; Thomas
> > Monjalon
> > > > <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> > > > <hemant.agrawal@nxp.com>
> > > > Subject: Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
> > > >
> > > > On Fri, Apr 17, 2020 at 12:21 PM Trahe, Fiona <fiona.trahe@intel.com> wrote:
> > > > > I see this is already applied.
> > > > >
> > > > > However,
> > > > > rte_cryptodev_queue_pair_setup() calls
> > > > > rte_cryptodev_sym_get_existing_header_session_size()
> > > > > The former is a stable API, the latter is experimental.
> > > > > So I expect the build to break when ALLOW_EXPERIMENTAL_API is disabled.
> > > [Fiona] Thanks for confirming where the flag is.
> > > But I think you've missed my point.
> > > What about this problem?
> >
> > - dpdk-test-crypto-perf is built as part of the dpdk compilation itself.
> > There is no user to be made aware of its use of experimental API.
> >
> > Now if you are talking about how the crypto API is bent in that it
> > exposes a stable ABI with an underlying experimental ABI, this has
> > nothing to do with the flag change.
> [Fiona] Before this if an application didn't set ALLOW_EXPERIMENTAL_API
> (which I expect is the default for many apps) then the build worked fine
> as long as the app didn't directly call an experimental API. The crypto lib
> still built ok as its own Makefile had the flag.
> I just tried this with dpdk-test-crypto-perf. I had to remove one direct call,
> without that it built ok. When I remove the flag from the crypto lib Makefile, the
> build breaks as expected due to the above issue.
>
> So, yes, cryptodev lib should be fixed.
> However this patch just applied will potentially break builds for many apps!
> It could expose many other issues of internal dependencies on experimental APIs.
[Fiona] Ok, I get it now, there's no issue.
I see now why the patch name was changed from "global" to "internal"!
I had understood that the flag the application set or didn't set would ripple down
through the whole build. Instead the flag is set (or not set) once by the application
only affecting direct API calls and once for the rest of the build, which includes
apps in the app folder, but not apps in the examples folder.
So allowing experimental APIs internally, while disallowing them externally.
A bit confusing, but ok, doesn't break anything and definitely better than
having flags in every Make/meson file.
Fiona
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-17 12:10 4% ` Thomas Monjalon
@ 2020-04-17 15:42 9% ` Ray Kinsella
2020-04-17 16:10 4% ` Thomas Monjalon
2020-04-21 11:12 4% ` Neil Horman
0 siblings, 2 replies; 200+ results
From: Ray Kinsella @ 2020-04-17 15:42 UTC (permalink / raw)
To: Thomas Monjalon, Neil Horman; +Cc: dev, david.marchand
On 17/04/2020 13:10, Thomas Monjalon wrote:
> 17/04/2020 13:47, Ray Kinsella:
>> On 17/04/2020 11:20, Thomas Monjalon wrote:
>>> 17/04/2020 12:11, Ray Kinsella:
>>>> check-abi.sh appears to be backward step in terms of usability.
>>>
>>> No, check-abi.sh benefits from a nice integration in build scripts.
>>> See below.
>>>
>>>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
>>>> And it will do the build, install, dump and comparison for me.
>>>> And it picked up my 20.0.2 - > 21.0 changes no problem.
>>>>
>>>> With check-abi on the other hand, I need to the build and install myself.
>>>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
>>>> It silently fails when it doesn't find any ...
>>>>
>>>> Do I run abi-dumper on the so's myself, or how does it work?
>>>
>>> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
>>> Probably we should document usage in these scripts.
>>
>> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
>> Any tips or tricks would be welcome.
>
> export DPDK_ABI_REF_VERSION=v20.02
> or
> export DPDK_ABI_REF_VERSION=v19.11
>
> Depends on which compatibility you want to test...
>
Few things ...
1. test-meson-build.sh keep barfing complaining about reference paths.
ValueError: dst_dir must be absolute, got reference/v19.11/build-gcc-static/usr/local/share/dpdk/examples/bbdev_app
Under the hood, ninja install is failing complaining that it needs an absolute path.
I fixed this in test_meson_build.sh and will send a patch in a minute.
Though it's strange no-one else has seen it?
2. test-meson-build.sh compares the abi for the static builds, which doesn't make any sense.
3. test-meson-build.sh will only take a branch in DPDK_ABI_REF_VERSION that exists locally.
In order to get it to compare HEAD against HEAD~1, which you would imagine is a pretty common case.
I had a create a branch for HEAD~1, in validate-abi this a pretty simple `validate-abi HEAD~1 HEAD`
Thanks,
Ray K
Ray K
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
2020-04-17 13:56 4% ` David Marchand
@ 2020-04-17 15:05 0% ` Trahe, Fiona
2020-04-17 15:52 0% ` Trahe, Fiona
0 siblings, 1 reply; 200+ results
From: Trahe, Fiona @ 2020-04-17 15:05 UTC (permalink / raw)
To: David Marchand
Cc: dev, Jerin Jacob, Pavan Nikhilesh, Richardson, Bruce,
Thomas Monjalon, Yigit, Ferruh, Hemant Agrawal, Trahe, Fiona
Hi Davd,
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Friday, April 17, 2020 2:56 PM
> To: Trahe, Fiona <fiona.trahe@intel.com>
> Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan Nikhilesh
> <pbhagavatula@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>; Thomas Monjalon
> <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> <hemant.agrawal@nxp.com>
> Subject: Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
>
> On Fri, Apr 17, 2020 at 3:44 PM Trahe, Fiona <fiona.trahe@intel.com> wrote:
> >
> > Hi David,
> >
> > > -----Original Message-----
> > > From: David Marchand <david.marchand@redhat.com>
> > > Sent: Friday, April 17, 2020 2:23 PM
> > > To: Trahe, Fiona <fiona.trahe@intel.com>
> > > Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan Nikhilesh
> > > <pbhagavatula@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>; Thomas
> Monjalon
> > > <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> > > <hemant.agrawal@nxp.com>
> > > Subject: Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
> > >
> > > On Fri, Apr 17, 2020 at 12:21 PM Trahe, Fiona <fiona.trahe@intel.com> wrote:
> > > > I see this is already applied.
> > > >
> > > > However,
> > > > rte_cryptodev_queue_pair_setup() calls
> > > > rte_cryptodev_sym_get_existing_header_session_size()
> > > > The former is a stable API, the latter is experimental.
> > > > So I expect the build to break when ALLOW_EXPERIMENTAL_API is disabled.
> > [Fiona] Thanks for confirming where the flag is.
> > But I think you've missed my point.
> > What about this problem?
>
> - dpdk-test-crypto-perf is built as part of the dpdk compilation itself.
> There is no user to be made aware of its use of experimental API.
>
> Now if you are talking about how the crypto API is bent in that it
> exposes a stable ABI with an underlying experimental ABI, this has
> nothing to do with the flag change.
[Fiona] Before this if an application didn't set ALLOW_EXPERIMENTAL_API
(which I expect is the default for many apps) then the build worked fine
as long as the app didn't directly call an experimental API. The crypto lib
still built ok as its own Makefile had the flag.
I just tried this with dpdk-test-crypto-perf. I had to remove one direct call,
without that it built ok. When I remove the flag from the crypto lib Makefile, the
build breaks as expected due to the above issue.
So, yes, cryptodev lib should be fixed.
However this patch just applied will potentially break builds for many apps!
It could expose many other issues of internal dependencies on experimental APIs.
>
> - But if you want to check crypto experimental api, then try to
> disable the flag in examples making use of them.
>
>
> --
> David Marchand
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v3] cryptodev: version cryptodev info get function
@ 2020-04-17 14:59 11% Arek Kusztal
2020-04-20 14:22 3% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Arek Kusztal @ 2020-04-17 14:59 UTC (permalink / raw)
To: dev; +Cc: akhil.goyal, fiona.trahe, Arek Kusztal
This patch adds versioned function rte_cryptodev_info_get()
to prevent some issues with ABI policy.
Node v21 works in same way as before, returning driver capabilities
directly to the API caller. These capabilities may include new elements
not part of the v20 ABI.
Node v20 function maintains compatibility with v20 ABI releases
by stripping out elements not supported in v20 ABI. Because
rte_cryptodev_info_get is called by other API functions,
rte_cryptodev_sym_capability_get function is versioned the same way.
Signed-off-by: Arek Kusztal <arkadiuszx.kusztal@intel.com>
---
v2:
- changed version numbers of symbols to 20.0.2
v3:
- added v2/v3 informations
- changed version numbers of symbols to 21
- fixed checkpatch issues
This patch depends on following patches:
[1] - "[v3] cryptodev: add chacha20-poly1305 aead algorithm"
(http://patchwork.dpdk.org/patch/64549/)
lib/librte_cryptodev/rte_cryptodev.c | 143 ++++++++++++++++++++++++-
lib/librte_cryptodev/rte_cryptodev.h | 39 ++++++-
lib/librte_cryptodev/rte_cryptodev_version.map | 7 ++
3 files changed, 186 insertions(+), 3 deletions(-)
diff --git a/lib/librte_cryptodev/rte_cryptodev.c b/lib/librte_cryptodev/rte_cryptodev.c
index 6d1d0e9..b061447 100644
--- a/lib/librte_cryptodev/rte_cryptodev.c
+++ b/lib/librte_cryptodev/rte_cryptodev.c
@@ -41,6 +41,9 @@
#include "rte_cryptodev.h"
#include "rte_cryptodev_pmd.h"
+#include <rte_compat.h>
+#include <rte_function_versioning.h>
+
static uint8_t nb_drivers;
static struct rte_cryptodev rte_crypto_devices[RTE_CRYPTO_MAX_DEVS];
@@ -56,6 +59,14 @@ static struct rte_cryptodev_global cryptodev_globals = {
/* spinlock for crypto device callbacks */
static rte_spinlock_t rte_cryptodev_cb_lock = RTE_SPINLOCK_INITIALIZER;
+static const struct rte_cryptodev_capabilities
+ cryptodev_undefined_capabilities[] = {
+ RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
+};
+
+static struct rte_cryptodev_capabilities
+ *capability_copies[RTE_CRYPTO_MAX_DEVS];
+static uint8_t is_capability_checked[RTE_CRYPTO_MAX_DEVS];
/**
* The user application callback description.
@@ -280,7 +291,43 @@ rte_crypto_auth_operation_strings[] = {
};
const struct rte_cryptodev_symmetric_capability *
-rte_cryptodev_sym_capability_get(uint8_t dev_id,
+rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
+ const struct rte_cryptodev_sym_capability_idx *idx)
+{
+ const struct rte_cryptodev_capabilities *capability;
+ struct rte_cryptodev_info dev_info;
+ int i = 0;
+
+ rte_cryptodev_info_get_v20(dev_id, &dev_info);
+
+ while ((capability = &dev_info.capabilities[i++])->op !=
+ RTE_CRYPTO_OP_TYPE_UNDEFINED) {
+ if (capability->op != RTE_CRYPTO_OP_TYPE_SYMMETRIC)
+ continue;
+
+ if (capability->sym.xform_type != idx->type)
+ continue;
+
+ if (idx->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
+ capability->sym.auth.algo == idx->algo.auth)
+ return &capability->sym;
+
+ if (idx->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
+ capability->sym.cipher.algo == idx->algo.cipher)
+ return &capability->sym;
+
+ if (idx->type == RTE_CRYPTO_SYM_XFORM_AEAD &&
+ capability->sym.aead.algo == idx->algo.aead)
+ return &capability->sym;
+ }
+
+ return NULL;
+
+}
+VERSION_SYMBOL(rte_cryptodev_sym_capability_get, _v20, 20.0);
+
+const struct rte_cryptodev_symmetric_capability *
+rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
const struct rte_cryptodev_sym_capability_idx *idx)
{
const struct rte_cryptodev_capabilities *capability;
@@ -313,6 +360,10 @@ rte_cryptodev_sym_capability_get(uint8_t dev_id,
return NULL;
}
+MAP_STATIC_SYMBOL(const struct rte_cryptodev_symmetric_capability *
+ rte_cryptodev_sym_capability_get(uint8_t dev_id,
+ const struct rte_cryptodev_sym_capability_idx *idx),
+ rte_cryptodev_sym_capability_get_v21);
static int
param_range_check(uint16_t size, const struct rte_crypto_param_range *range)
@@ -999,6 +1050,13 @@ rte_cryptodev_close(uint8_t dev_id)
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->dev_close, -ENOTSUP);
retval = (*dev->dev_ops->dev_close)(dev);
+
+ if (capability_copies[dev_id]) {
+ free(capability_copies[dev_id]);
+ capability_copies[dev_id] = NULL;
+ }
+ is_capability_checked[dev_id] = 0;
+
if (retval < 0)
return retval;
@@ -1111,9 +1169,61 @@ rte_cryptodev_stats_reset(uint8_t dev_id)
(*dev->dev_ops->stats_reset)(dev);
}
+static void
+get_v20_capabilities(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
+{
+ const struct rte_cryptodev_capabilities *capability;
+ uint8_t found_invalid_capa = 0;
+ uint8_t counter = 0;
+
+ for (capability = dev_info->capabilities;
+ capability->op != RTE_CRYPTO_OP_TYPE_UNDEFINED;
+ ++capability, ++counter) {
+ if (capability->op == RTE_CRYPTO_OP_TYPE_SYMMETRIC &&
+ capability->sym.xform_type ==
+ RTE_CRYPTO_SYM_XFORM_AEAD
+ && capability->sym.aead.algo >=
+ RTE_CRYPTO_AEAD_CHACHA20_POLY1305) {
+ found_invalid_capa = 1;
+ counter--;
+ }
+ }
+ is_capability_checked[dev_id] = 1;
+ if (found_invalid_capa) {
+ capability_copies[dev_id] = malloc(counter *
+ sizeof(struct rte_cryptodev_capabilities));
+ if (capability_copies[dev_id] == NULL) {
+ /*
+ * error case - no memory to store the trimmed
+ * list, so have to return an empty list
+ */
+ dev_info->capabilities =
+ cryptodev_undefined_capabilities;
+ is_capability_checked[dev_id] = 0;
+ } else {
+ counter = 0;
+ for (capability = dev_info->capabilities;
+ capability->op !=
+ RTE_CRYPTO_OP_TYPE_UNDEFINED;
+ capability++) {
+ if (!(capability->op ==
+ RTE_CRYPTO_OP_TYPE_SYMMETRIC
+ && capability->sym.xform_type ==
+ RTE_CRYPTO_SYM_XFORM_AEAD
+ && capability->sym.aead.algo >=
+ RTE_CRYPTO_AEAD_CHACHA20_POLY1305)) {
+ capability_copies[dev_id][counter++] =
+ *capability;
+ }
+ }
+ dev_info->capabilities =
+ capability_copies[dev_id];
+ }
+ }
+}
void
-rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
+rte_cryptodev_info_get_v20(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
{
struct rte_cryptodev *dev;
@@ -1129,10 +1239,39 @@ rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
(*dev->dev_ops->dev_infos_get)(dev, dev_info);
+ if (capability_copies[dev_id] == NULL) {
+ if (!is_capability_checked[dev_id])
+ get_v20_capabilities(dev_id, dev_info);
+ } else
+ dev_info->capabilities = capability_copies[dev_id];
+
dev_info->driver_name = dev->device->driver->name;
dev_info->device = dev->device;
}
+VERSION_SYMBOL(rte_cryptodev_info_get, _v20, 20.0);
+
+void
+rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info *dev_info)
+{
+ struct rte_cryptodev *dev;
+
+ if (!rte_cryptodev_pmd_is_valid_dev(dev_id)) {
+ CDEV_LOG_ERR("Invalid dev_id=%d", dev_id);
+ return;
+ }
+
+ dev = &rte_crypto_devices[dev_id];
+ memset(dev_info, 0, sizeof(struct rte_cryptodev_info));
+
+ RTE_FUNC_PTR_OR_RET(*dev->dev_ops->dev_infos_get);
+ (*dev->dev_ops->dev_infos_get)(dev, dev_info);
+
+ dev_info->driver_name = dev->device->driver->name;
+ dev_info->device = dev->device;
+}
+MAP_STATIC_SYMBOL(void rte_cryptodev_info_get(uint8_t dev_id,
+ struct rte_cryptodev_info *dev_info), rte_cryptodev_info_get_v21);
int
rte_cryptodev_callback_register(uint8_t dev_id,
diff --git a/lib/librte_cryptodev/rte_cryptodev.h b/lib/librte_cryptodev/rte_cryptodev.h
index 437b8a9..7f1bc90 100644
--- a/lib/librte_cryptodev/rte_cryptodev.h
+++ b/lib/librte_cryptodev/rte_cryptodev.h
@@ -24,6 +24,9 @@ extern "C" {
#include <rte_common.h>
#include <rte_config.h>
+#include <rte_compat.h>
+#include <rte_function_versioning.h>
+
extern const char **rte_cyptodev_names;
/* Logging Macros */
@@ -217,6 +220,15 @@ struct rte_cryptodev_asym_capability_idx {
* - Return NULL if the capability not exist.
*/
const struct rte_cryptodev_symmetric_capability *
+rte_cryptodev_sym_capability_get_v20(uint8_t dev_id,
+ const struct rte_cryptodev_sym_capability_idx *idx);
+
+const struct rte_cryptodev_symmetric_capability *
+rte_cryptodev_sym_capability_get_v21(uint8_t dev_id,
+ const struct rte_cryptodev_sym_capability_idx *idx);
+BIND_DEFAULT_SYMBOL(rte_cryptodev_sym_capability_get, _v21, 21);
+
+const struct rte_cryptodev_symmetric_capability *
rte_cryptodev_sym_capability_get(uint8_t dev_id,
const struct rte_cryptodev_sym_capability_idx *idx);
@@ -758,9 +770,34 @@ rte_cryptodev_stats_reset(uint8_t dev_id);
* the last valid element has it's op field set to
* RTE_CRYPTO_OP_TYPE_UNDEFINED.
*/
-extern void
+
+void
rte_cryptodev_info_get(uint8_t dev_id, struct rte_cryptodev_info *dev_info);
+/* An extra element RTE_CRYPTO_AEAD_CHACHA20_POLY1305 is added
+ * to enum rte_crypto_aead_algorithm, also changing the value of
+ * RTE_CRYPTO_AEAD_LIST_END. To maintain ABI compatibility with applications
+ * which linked against earlier versions, preventing them, for example, from
+ * picking up the new value and using it to index into an array sized too small
+ * for it, it is necessary to have two versions of rte_cryptodev_info_get()
+ * The latest version just returns directly the capabilities retrieved from
+ * the device. The compatible version inspects the capabilities retrieved
+ * from the device, but only returns them directly if the new value
+ * is not included. If the new value is included, it allocates space
+ * for a copy of the device capabilities, trims the new value from this
+ * and returns this copy. It only needs to do this once per device.
+ * For the corner case of a corner case when the alloc may fail,
+ * an empty capability list is returned, as there is no mechanism to return
+ * an error and adding such a mechanism would itself be an ABI breakage.
+ * The compatible version can be removed after the next major ABI release.
+ */
+
+void
+rte_cryptodev_info_get_v20(uint8_t dev_id, struct rte_cryptodev_info *dev_info);
+
+void
+rte_cryptodev_info_get_v21(uint8_t dev_id, struct rte_cryptodev_info *dev_info);
+BIND_DEFAULT_SYMBOL(rte_cryptodev_info_get, _v21, 21);
/**
* Register a callback function for specific device id.
diff --git a/lib/librte_cryptodev/rte_cryptodev_version.map b/lib/librte_cryptodev/rte_cryptodev_version.map
index 6e41b4b..512a4a7 100644
--- a/lib/librte_cryptodev/rte_cryptodev_version.map
+++ b/lib/librte_cryptodev/rte_cryptodev_version.map
@@ -58,6 +58,13 @@ DPDK_20.0 {
local: *;
};
+DPDK_21 {
+ global:
+ rte_cryptodev_info_get;
+ rte_cryptodev_sym_capability_get;
+} DPDK_20.0;
+
+
EXPERIMENTAL {
global:
--
2.1.0
^ permalink raw reply [relevance 11%]
* Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
@ 2020-04-17 13:56 4% ` David Marchand
2020-04-17 15:05 0% ` Trahe, Fiona
0 siblings, 1 reply; 200+ results
From: David Marchand @ 2020-04-17 13:56 UTC (permalink / raw)
To: Trahe, Fiona
Cc: dev, Jerin Jacob, Pavan Nikhilesh, Richardson, Bruce,
Thomas Monjalon, Yigit, Ferruh, Hemant Agrawal
On Fri, Apr 17, 2020 at 3:44 PM Trahe, Fiona <fiona.trahe@intel.com> wrote:
>
> Hi David,
>
> > -----Original Message-----
> > From: David Marchand <david.marchand@redhat.com>
> > Sent: Friday, April 17, 2020 2:23 PM
> > To: Trahe, Fiona <fiona.trahe@intel.com>
> > Cc: dev <dev@dpdk.org>; Jerin Jacob <jerinjacobk@gmail.com>; Pavan Nikhilesh
> > <pbhagavatula@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>; Thomas Monjalon
> > <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Hemant Agrawal
> > <hemant.agrawal@nxp.com>
> > Subject: Re: [dpdk-dev] [PATCH v5] build: disable experimental API check internally
> >
> > On Fri, Apr 17, 2020 at 12:21 PM Trahe, Fiona <fiona.trahe@intel.com> wrote:
> > > I see this is already applied.
> > >
> > > However,
> > > rte_cryptodev_queue_pair_setup() calls
> > > rte_cryptodev_sym_get_existing_header_session_size()
> > > The former is a stable API, the latter is experimental.
> > > So I expect the build to break when ALLOW_EXPERIMENTAL_API is disabled.
> [Fiona] Thanks for confirming where the flag is.
> But I think you've missed my point.
> What about this problem?
- dpdk-test-crypto-perf is built as part of the dpdk compilation itself.
There is no user to be made aware of its use of experimental API.
Now if you are talking about how the crypto API is bent in that it
exposes a stable ABI with an underlying experimental ABI, this has
nothing to do with the flag change.
- But if you want to check crypto experimental api, then try to
disable the flag in examples making use of them.
--
David Marchand
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v4 3/9] ring: introduce RTS ring mode
2020-04-17 13:36 3% ` [dpdk-dev] [PATCH v4 " Konstantin Ananyev
2020-04-17 13:36 9% ` [dpdk-dev] [PATCH v4 2/9] ring: prepare ring to allow new sync schemes Konstantin Ananyev
@ 2020-04-17 13:36 1% ` Konstantin Ananyev
2020-04-18 16:32 3% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Konstantin Ananyev
2 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-17 13:36 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
Introduce relaxed tail sync (RTS) mode for MT ring synchronization.
Aim to reduce stall times in case when ring is used on
overcommited cpus (multiple active threads on the same cpu).
The main difference from original MP/MC algorithm is that
tail value is increased not by every thread that finished enqueue/dequeue,
but only by the last one.
That allows threads to avoid spinning on ring tail value,
leaving actual tail value change to the last thread in the update queue.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
check-abi.sh reports what I believe is a false-positive about
ring cons/prod changes. As a workaround, devtools/libabigail.abignore is
updated to suppress *struct ring* related errors.
devtools/libabigail.abignore | 7 +
lib/librte_ring/Makefile | 4 +-
lib/librte_ring/meson.build | 7 +-
lib/librte_ring/rte_ring.c | 100 +++++-
lib/librte_ring/rte_ring.h | 70 +++-
lib/librte_ring/rte_ring_core.h | 35 +-
lib/librte_ring/rte_ring_elem.h | 90 ++++-
lib/librte_ring/rte_ring_rts.h | 439 +++++++++++++++++++++++++
lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
9 files changed, 901 insertions(+), 30 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_rts.h
create mode 100644 lib/librte_ring/rte_ring_rts_c11_mem.h
diff --git a/devtools/libabigail.abignore b/devtools/libabigail.abignore
index a59df8f13..cd86d89ca 100644
--- a/devtools/libabigail.abignore
+++ b/devtools/libabigail.abignore
@@ -11,3 +11,10 @@
type_kind = enum
name = rte_crypto_asym_xform_type
changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
+; Ignore updates of ring prod/cons
+[suppress_type]
+ type_kind = struct
+ name = rte_ring
+[suppress_type]
+ type_kind = struct
+ name = rte_event_ring
diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile
index 6572768c9..04e446e37 100644
--- a/lib/librte_ring/Makefile
+++ b/lib/librte_ring/Makefile
@@ -19,6 +19,8 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
rte_ring_core.h \
rte_ring_elem.h \
rte_ring_generic.h \
- rte_ring_c11_mem.h
+ rte_ring_c11_mem.h \
+ rte_ring_rts.h \
+ rte_ring_rts_c11_mem.h
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build
index c656781da..a95598032 100644
--- a/lib/librte_ring/meson.build
+++ b/lib/librte_ring/meson.build
@@ -6,4 +6,9 @@ headers = files('rte_ring.h',
'rte_ring_core.h',
'rte_ring_elem.h',
'rte_ring_c11_mem.h',
- 'rte_ring_generic.h')
+ 'rte_ring_generic.h',
+ 'rte_ring_rts.h',
+ 'rte_ring_rts_c11_mem.h')
+
+# rte_ring_create_elem and rte_ring_get_memsize_elem are experimental
+allow_experimental_apis = true
diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
index fa5733907..222eec0fb 100644
--- a/lib/librte_ring/rte_ring.c
+++ b/lib/librte_ring/rte_ring.c
@@ -45,6 +45,9 @@ EAL_REGISTER_TAILQ(rte_ring_tailq)
/* true if x is a power of 2 */
#define POWEROF2(x) ((((x)-1) & (x)) == 0)
+/* by default set head/tail distance as 1/8 of ring capacity */
+#define HTD_MAX_DEF 8
+
/* return the size of memory occupied by a ring */
ssize_t
rte_ring_get_memsize_elem(unsigned int esize, unsigned int count)
@@ -79,11 +82,84 @@ rte_ring_get_memsize(unsigned int count)
return rte_ring_get_memsize_elem(sizeof(void *), count);
}
+/*
+ * internal helper function to reset prod/cons head-tail values.
+ */
+static void
+reset_headtail(void *p)
+{
+ struct rte_ring_headtail *ht;
+ struct rte_ring_rts_headtail *ht_rts;
+
+ ht = p;
+ ht_rts = p;
+
+ switch (ht->sync_type) {
+ case RTE_RING_SYNC_MT:
+ case RTE_RING_SYNC_ST:
+ ht->head = 0;
+ ht->tail = 0;
+ break;
+ case RTE_RING_SYNC_MT_RTS:
+ ht_rts->head.raw = 0;
+ ht_rts->tail.raw = 0;
+ break;
+ default:
+ /* unknown sync mode */
+ RTE_ASSERT(0);
+ }
+}
+
void
rte_ring_reset(struct rte_ring *r)
{
- r->prod.head = r->cons.head = 0;
- r->prod.tail = r->cons.tail = 0;
+ reset_headtail(&r->prod);
+ reset_headtail(&r->cons);
+}
+
+/*
+ * helper function, calculates sync_type values for prod and cons
+ * based on input flags. Returns zero at success or negative
+ * errno value otherwise.
+ */
+static int
+get_sync_type(uint32_t flags, enum rte_ring_sync_type *prod_st,
+ enum rte_ring_sync_type *cons_st)
+{
+ static const uint32_t prod_st_flags =
+ (RING_F_SP_ENQ | RING_F_MP_RTS_ENQ);
+ static const uint32_t cons_st_flags =
+ (RING_F_SC_DEQ | RING_F_MC_RTS_DEQ);
+
+ switch (flags & prod_st_flags) {
+ case 0:
+ *prod_st = RTE_RING_SYNC_MT;
+ break;
+ case RING_F_SP_ENQ:
+ *prod_st = RTE_RING_SYNC_ST;
+ break;
+ case RING_F_MP_RTS_ENQ:
+ *prod_st = RTE_RING_SYNC_MT_RTS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (flags & cons_st_flags) {
+ case 0:
+ *cons_st = RTE_RING_SYNC_MT;
+ break;
+ case RING_F_SC_DEQ:
+ *cons_st = RTE_RING_SYNC_ST;
+ break;
+ case RING_F_MC_RTS_DEQ:
+ *cons_st = RTE_RING_SYNC_MT_RTS;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return 0;
}
int
@@ -100,16 +176,20 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
RTE_BUILD_BUG_ON((offsetof(struct rte_ring, prod) &
RTE_CACHE_LINE_MASK) != 0);
+ RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, sync_type) !=
+ offsetof(struct rte_ring_rts_headtail, sync_type));
+ RTE_BUILD_BUG_ON(offsetof(struct rte_ring_headtail, tail) !=
+ offsetof(struct rte_ring_rts_headtail, tail.val.pos));
+
/* init the ring structure */
memset(r, 0, sizeof(*r));
ret = strlcpy(r->name, name, sizeof(r->name));
if (ret < 0 || ret >= (int)sizeof(r->name))
return -ENAMETOOLONG;
r->flags = flags;
- r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
- RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
- r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
- RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
+ ret = get_sync_type(flags, &r->prod.sync_type, &r->cons.sync_type);
+ if (ret != 0)
+ return ret;
if (flags & RING_F_EXACT_SZ) {
r->size = rte_align32pow2(count + 1);
@@ -126,8 +206,12 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
r->mask = count - 1;
r->capacity = r->mask;
}
- r->prod.head = r->cons.head = 0;
- r->prod.tail = r->cons.tail = 0;
+
+ /* set default values for head-tail distance */
+ if (flags & RING_F_MP_RTS_ENQ)
+ rte_ring_set_prod_htd_max(r, r->capacity / HTD_MAX_DEF);
+ if (flags & RING_F_MC_RTS_DEQ)
+ rte_ring_set_cons_htd_max(r, r->capacity / HTD_MAX_DEF);
return 0;
}
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index 35ee4491c..77f206ca7 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: BSD-3-Clause
*
- * Copyright (c) 2010-2017 Intel Corporation
+ * Copyright (c) 2010-2020 Intel Corporation
* Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
* All rights reserved.
* Derived from FreeBSD's bufring.h
@@ -389,8 +389,21 @@ static __rte_always_inline unsigned int
rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_bulk(r, obj_table, n, free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_bulk(r, obj_table, n, free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_bulk(r, obj_table, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -524,8 +537,20 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
unsigned int *available)
{
- return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_bulk(r, obj_table, n, available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_bulk(r, obj_table, n, available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_bulk(r, obj_table, n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -845,8 +870,21 @@ static __rte_always_inline unsigned
rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
- r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_burst(r, obj_table, n, free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_burst(r, obj_table, n, free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_burst(r, obj_table, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
/**
@@ -925,9 +963,21 @@ static __rte_always_inline unsigned
rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_burst(r, obj_table, n, available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_burst(r, obj_table, n, available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_burst(r, obj_table, n,
+ available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ return 0;
}
#ifdef __cplusplus
diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
index 459a0ffa1..173b5f68d 100644
--- a/lib/librte_ring/rte_ring_core.h
+++ b/lib/librte_ring/rte_ring_core.h
@@ -56,6 +56,9 @@ enum rte_ring_queue_behavior {
enum rte_ring_sync_type {
RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
RTE_RING_SYNC_ST, /**< single thread only */
+#ifdef ALLOW_EXPERIMENTAL_API
+ RTE_RING_SYNC_MT_RTS, /**< multi-thread relaxed tail sync */
+#endif
};
/**
@@ -75,6 +78,21 @@ struct rte_ring_headtail {
};
};
+union rte_ring_rts_poscnt {
+ uint64_t raw;
+ struct {
+ uint32_t cnt; /**< head/tail reference counter */
+ uint32_t pos; /**< head/tail position */
+ } val;
+};
+
+struct rte_ring_rts_headtail {
+ volatile union rte_ring_rts_poscnt tail;
+ enum rte_ring_sync_type sync_type; /**< sync type of prod/cons */
+ uint32_t htd_max; /**< max allowed distance between head/tail */
+ volatile union rte_ring_rts_poscnt head;
+};
+
/**
* An RTE ring structure.
*
@@ -103,11 +121,21 @@ struct rte_ring {
char pad0 __rte_cache_aligned; /**< empty cache line */
/** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail prod;
+ struct rte_ring_rts_headtail rts_prod;
+ } __rte_cache_aligned;
+
char pad1 __rte_cache_aligned; /**< empty cache line */
/** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
+ RTE_STD_C11
+ union {
+ struct rte_ring_headtail cons;
+ struct rte_ring_rts_headtail rts_cons;
+ } __rte_cache_aligned;
+
char pad2 __rte_cache_aligned; /**< empty cache line */
};
@@ -124,6 +152,9 @@ struct rte_ring {
#define RING_F_EXACT_SZ 0x0004
#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
+#define RING_F_MP_RTS_ENQ 0x0008 /**< The default enqueue is "MP RTS". */
+#define RING_F_MC_RTS_DEQ 0x0010 /**< The default dequeue is "MC RTS". */
+
#ifdef __cplusplus
}
#endif
diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
index 7406c0b0f..6da0a917b 100644
--- a/lib/librte_ring/rte_ring_elem.h
+++ b/lib/librte_ring/rte_ring_elem.h
@@ -528,6 +528,10 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
}
+#ifdef ALLOW_EXPERIMENTAL_API
+#include <rte_ring_rts.h>
+#endif
+
/**
* Enqueue several objects on a ring.
*
@@ -557,6 +561,26 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_FIXED, r->prod.sync_type, free_space);
+
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table, esize, n,
+ free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (free_space != NULL)
+ *free_space = 0;
+ return 0;
}
/**
@@ -661,7 +685,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
}
/**
@@ -719,8 +743,25 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_bulk_elem(r, obj_table, esize, n,
+ available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_bulk_elem(r, obj_table, esize, n,
+ available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table, esize,
+ n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (available != NULL)
+ *available = 0;
+ return 0;
}
/**
@@ -887,8 +928,25 @@ static __rte_always_inline unsigned
rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
- return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, r->prod.sync_type, free_space);
+ switch (r->prod.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mp_enqueue_burst_elem(r, obj_table, esize, n,
+ free_space);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sp_enqueue_burst_elem(r, obj_table, esize, n,
+ free_space);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table, esize,
+ n, free_space);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (free_space != NULL)
+ *free_space = 0;
+ return 0;
}
/**
@@ -979,9 +1037,25 @@ static __rte_always_inline unsigned int
rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
- return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE,
- r->cons.sync_type, available);
+ switch (r->cons.sync_type) {
+ case RTE_RING_SYNC_MT:
+ return rte_ring_mc_dequeue_burst_elem(r, obj_table, esize, n,
+ available);
+ case RTE_RING_SYNC_ST:
+ return rte_ring_sc_dequeue_burst_elem(r, obj_table, esize, n,
+ available);
+#ifdef ALLOW_EXPERIMENTAL_API
+ case RTE_RING_SYNC_MT_RTS:
+ return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table, esize,
+ n, available);
+#endif
+ }
+
+ /* valid ring should never reach this point */
+ RTE_ASSERT(0);
+ if (available != NULL)
+ *available = 0;
+ return 0;
}
#include <rte_ring.h>
diff --git a/lib/librte_ring/rte_ring_rts.h b/lib/librte_ring/rte_ring_rts.h
new file mode 100644
index 000000000..8ced07096
--- /dev/null
+++ b/lib/librte_ring/rte_ring_rts.h
@@ -0,0 +1,439 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_RTS_H_
+#define _RTE_RING_RTS_H_
+
+/**
+ * @file rte_ring_rts.h
+ * @b EXPERIMENTAL: this API may change without prior notice
+ * It is not recommended to include this file directly.
+ * Please include <rte_ring.h> instead.
+ *
+ * Contains functions for Relaxed Tail Sync (RTS) ring mode.
+ * The main idea remains the same as for our original MP/MC synchronization
+ * mechanism.
+ * The main difference is that tail value is increased not
+ * by every thread that finished enqueue/dequeue,
+ * but only by the current last one doing enqueue/dequeue.
+ * That allows threads to skip spinning on tail value,
+ * leaving actual tail value change to last thread at a given instance.
+ * RTS requires 2 64-bit CAS for each enqueue(/dequeue) operation:
+ * one for head update, second for tail update.
+ * As a gain it allows thread to avoid spinning/waiting on tail value.
+ * In comparision original MP/MC algorithm requires one 32-bit CAS
+ * for head update and waiting/spinning on tail value.
+ *
+ * Brief outline:
+ * - introduce update counter (cnt) for both head and tail.
+ * - increment head.cnt for each head.value update
+ * - write head.value and head.cnt atomically (64-bit CAS)
+ * - move tail.value ahead only when tail.cnt + 1 == head.cnt
+ * (indicating that this is the last thread updating the tail)
+ * - increment tail.cnt when each enqueue/dequeue op finishes
+ * (no matter if tail.value going to change or not)
+ * - write tail.value and tail.cnt atomically (64-bit CAS)
+ *
+ * To avoid producer/consumer starvation:
+ * - limit max allowed distance between head and tail value (HTD_MAX).
+ * I.E. thread is allowed to proceed with changing head.value,
+ * only when: head.value - tail.value <= HTD_MAX
+ * HTD_MAX is an optional parameter.
+ * With HTD_MAX == 0 we'll have fully serialized ring -
+ * i.e. only one thread at a time will be able to enqueue/dequeue
+ * to/from the ring.
+ * With HTD_MAX >= ring.capacity - no limitation.
+ * By default HTD_MAX == ring.capacity / 8.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <rte_ring_rts_c11_mem.h>
+
+/**
+ * @internal Enqueue several objects on the RTS ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Enqueue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Enqueue as many items as possible from ring
+ * @param free_space
+ * returns the amount of space after the enqueue operation has finished
+ * @return
+ * Actual number of objects enqueued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_do_rts_enqueue_elem(struct rte_ring *r, const void *obj_table,
+ uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
+ uint32_t *free_space)
+{
+ uint32_t free, head;
+
+ n = __rte_ring_rts_move_prod_head(r, n, behavior, &head, &free);
+
+ if (n != 0) {
+ __rte_ring_enqueue_elems(r, head, obj_table, esize, n);
+ __rte_ring_rts_update_tail(&r->rts_prod);
+ }
+
+ if (free_space != NULL)
+ *free_space = free - n;
+ return n;
+}
+
+/**
+ * @internal Dequeue several objects from the RTS ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to pull from the ring.
+ * @param behavior
+ * RTE_RING_QUEUE_FIXED: Dequeue a fixed number of items from a ring
+ * RTE_RING_QUEUE_VARIABLE: Dequeue as many items as possible from ring
+ * @param available
+ * returns the number of remaining ring entries after the dequeue has finished
+ * @return
+ * - Actual number of objects dequeued.
+ * If behavior == RTE_RING_QUEUE_FIXED, this will be 0 or n only.
+ */
+static __rte_always_inline unsigned int
+__rte_ring_do_rts_dequeue_elem(struct rte_ring *r, void *obj_table,
+ uint32_t esize, uint32_t n, enum rte_ring_queue_behavior behavior,
+ uint32_t *available)
+{
+ uint32_t entries, head;
+
+ n = __rte_ring_rts_move_cons_head(r, n, behavior, &head, &entries);
+
+ if (n != 0) {
+ __rte_ring_dequeue_elems(r, head, obj_table, esize, n);
+ __rte_ring_rts_update_tail(&r->rts_cons);
+ }
+
+ if (available != NULL)
+ *available = entries - n;
+ return n;
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * The number of objects enqueued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mp_rts_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *free_space)
+{
+ return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_FIXED, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects that will be filled.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * The number of objects dequeued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mc_rts_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *available)
+{
+ return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_FIXED, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * - n: Actual number of objects enqueued.
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mp_rts_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *free_space)
+{
+ return __rte_ring_do_rts_enqueue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_VARIABLE, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ * When the requested objects are more than the available objects,
+ * only dequeue the actual number of objects.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of objects that will be filled.
+ * @param esize
+ * The size of ring element, in bytes. It must be a multiple of 4.
+ * This must be the same value used while creating the ring. Otherwise
+ * the results are undefined.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * - n: Actual number of objects dequeued, 0 if ring is empty
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mc_rts_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
+ unsigned int esize, unsigned int n, unsigned int *available)
+{
+ return __rte_ring_do_rts_dequeue_elem(r, obj_table, esize, n,
+ RTE_RING_QUEUE_VARIABLE, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects).
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * The number of objects enqueued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mp_rts_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
+ unsigned int n, unsigned int *free_space)
+{
+ return rte_ring_mp_rts_enqueue_bulk_elem(r, obj_table,
+ sizeof(uintptr_t), n, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects) that will be filled.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * The number of objects dequeued, either 0 or n
+ */
+__rte_experimental
+static __rte_always_inline unsigned int
+rte_ring_mc_rts_dequeue_bulk(struct rte_ring *r, void **obj_table,
+ unsigned int n, unsigned int *available)
+{
+ return rte_ring_mc_rts_dequeue_bulk_elem(r, obj_table,
+ sizeof(uintptr_t), n, available);
+}
+
+/**
+ * Enqueue several objects on the RTS ring (multi-producers safe).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects).
+ * @param n
+ * The number of objects to add in the ring from the obj_table.
+ * @param free_space
+ * if non-NULL, returns the amount of space in the ring after the
+ * enqueue operation has finished.
+ * @return
+ * - n: Actual number of objects enqueued.
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mp_rts_enqueue_burst(struct rte_ring *r, void * const *obj_table,
+ unsigned int n, unsigned int *free_space)
+{
+ return rte_ring_mp_rts_enqueue_burst_elem(r, obj_table,
+ sizeof(uintptr_t), n, free_space);
+}
+
+/**
+ * Dequeue several objects from an RTS ring (multi-consumers safe).
+ * When the requested objects are more than the available objects,
+ * only dequeue the actual number of objects.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param obj_table
+ * A pointer to a table of void * pointers (objects) that will be filled.
+ * @param n
+ * The number of objects to dequeue from the ring to the obj_table.
+ * @param available
+ * If non-NULL, returns the number of remaining ring entries after the
+ * dequeue has finished.
+ * @return
+ * - n: Actual number of objects dequeued, 0 if ring is empty
+ */
+__rte_experimental
+static __rte_always_inline unsigned
+rte_ring_mc_rts_dequeue_burst(struct rte_ring *r, void **obj_table,
+ unsigned int n, unsigned int *available)
+{
+ return rte_ring_mc_rts_dequeue_burst_elem(r, obj_table,
+ sizeof(uintptr_t), n, available);
+}
+
+/**
+ * Return producer max Head-Tail-Distance (HTD).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Producer HTD value, if producer is set in appropriate sync mode,
+ * or UINT32_MAX otherwise.
+ */
+__rte_experimental
+static inline uint32_t
+rte_ring_get_prod_htd_max(const struct rte_ring *r)
+{
+ if (r->prod.sync_type == RTE_RING_SYNC_MT_RTS)
+ return r->rts_prod.htd_max;
+ return UINT32_MAX;
+}
+
+/**
+ * Set producer max Head-Tail-Distance (HTD).
+ * Note that producer has to use appropriate sync mode (RTS).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param v
+ * new HTD value to setup.
+ * @return
+ * Zero on success, or negative error code otherwise.
+ */
+__rte_experimental
+static inline int
+rte_ring_set_prod_htd_max(struct rte_ring *r, uint32_t v)
+{
+ if (r->prod.sync_type != RTE_RING_SYNC_MT_RTS)
+ return -ENOTSUP;
+
+ r->rts_prod.htd_max = v;
+ return 0;
+}
+
+/**
+ * Return consumer max Head-Tail-Distance (HTD).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Consumer HTD value, if consumer is set in appropriate sync mode,
+ * or UINT32_MAX otherwise.
+ */
+__rte_experimental
+static inline uint32_t
+rte_ring_get_cons_htd_max(const struct rte_ring *r)
+{
+ if (r->cons.sync_type == RTE_RING_SYNC_MT_RTS)
+ return r->rts_cons.htd_max;
+ return UINT32_MAX;
+}
+
+/**
+ * Set consumer max Head-Tail-Distance (HTD).
+ * Note that consumer has to use appropriate sync mode (RTS).
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @param v
+ * new HTD value to setup.
+ * @return
+ * Zero on success, or negative error code otherwise.
+ */
+__rte_experimental
+static inline int
+rte_ring_set_cons_htd_max(struct rte_ring *r, uint32_t v)
+{
+ if (r->cons.sync_type != RTE_RING_SYNC_MT_RTS)
+ return -ENOTSUP;
+
+ r->rts_cons.htd_max = v;
+ return 0;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RING_RTS_H_ */
diff --git a/lib/librte_ring/rte_ring_rts_c11_mem.h b/lib/librte_ring/rte_ring_rts_c11_mem.h
new file mode 100644
index 000000000..9f26817c0
--- /dev/null
+++ b/lib/librte_ring/rte_ring_rts_c11_mem.h
@@ -0,0 +1,179 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_RTS_C11_MEM_H_
+#define _RTE_RING_RTS_C11_MEM_H_
+
+/**
+ * @file rte_ring_rts_c11_mem.h
+ * It is not recommended to include this file directly,
+ * include <rte_ring.h> instead.
+ * Contains internal helper functions for Relaxed Tail Sync (RTS) ring mode.
+ * For more information please refer to <rte_ring_rts.h>.
+ */
+
+/**
+ * @internal This function updates tail values.
+ */
+static __rte_always_inline void
+__rte_ring_rts_update_tail(struct rte_ring_rts_headtail *ht)
+{
+ union rte_ring_rts_poscnt h, ot, nt;
+
+ /*
+ * If there are other enqueues/dequeues in progress that
+ * might preceded us, then don't update tail with new value.
+ */
+
+ ot.raw = __atomic_load_n(&ht->tail.raw, __ATOMIC_ACQUIRE);
+
+ do {
+ /* on 32-bit systems we have to do atomic read here */
+ h.raw = __atomic_load_n(&ht->head.raw, __ATOMIC_RELAXED);
+
+ nt.raw = ot.raw;
+ if (++nt.val.cnt == h.val.cnt)
+ nt.val.pos = h.val.pos;
+
+ } while (__atomic_compare_exchange_n(&ht->tail.raw, &ot.raw, nt.raw,
+ 0, __ATOMIC_RELEASE, __ATOMIC_ACQUIRE) == 0);
+}
+
+/**
+ * @internal This function waits till head/tail distance wouldn't
+ * exceed pre-defined max value.
+ */
+static __rte_always_inline void
+__rte_ring_rts_head_wait(const struct rte_ring_rts_headtail *ht,
+ union rte_ring_rts_poscnt *h)
+{
+ uint32_t max;
+
+ max = ht->htd_max;
+
+ while (h->val.pos - ht->tail.val.pos > max) {
+ rte_pause();
+ h->raw = __atomic_load_n(&ht->head.raw, __ATOMIC_ACQUIRE);
+ }
+}
+
+/**
+ * @internal This function updates the producer head for enqueue.
+ */
+static __rte_always_inline uint32_t
+__rte_ring_rts_move_prod_head(struct rte_ring *r, uint32_t num,
+ enum rte_ring_queue_behavior behavior, uint32_t *old_head,
+ uint32_t *free_entries)
+{
+ uint32_t n;
+ union rte_ring_rts_poscnt nh, oh;
+
+ const uint32_t capacity = r->capacity;
+
+ oh.raw = __atomic_load_n(&r->rts_prod.head.raw, __ATOMIC_ACQUIRE);
+
+ do {
+ /* Reset n to the initial burst count */
+ n = num;
+
+ /*
+ * wait for prod head/tail distance,
+ * make sure that we read prod head *before*
+ * reading cons tail.
+ */
+ __rte_ring_rts_head_wait(&r->rts_prod, &oh);
+
+ /*
+ * The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * *old_head > cons_tail). So 'free_entries' is always between 0
+ * and capacity (which is < size).
+ */
+ *free_entries = capacity + r->cons.tail - oh.val.pos;
+
+ /* check that we have enough room in ring */
+ if (unlikely(n > *free_entries))
+ n = (behavior == RTE_RING_QUEUE_FIXED) ?
+ 0 : *free_entries;
+
+ if (n == 0)
+ break;
+
+ nh.val.pos = oh.val.pos + n;
+ nh.val.cnt = oh.val.cnt + 1;
+
+ /*
+ * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
+ * - OOO reads of cons tail value
+ * - OOO copy of elems to the ring
+ */
+ } while (__atomic_compare_exchange_n(&r->rts_prod.head.raw,
+ &oh.raw, nh.raw,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
+
+ *old_head = oh.val.pos;
+ return n;
+}
+
+/**
+ * @internal This function updates the consumer head for dequeue
+ */
+static __rte_always_inline unsigned int
+__rte_ring_rts_move_cons_head(struct rte_ring *r, uint32_t num,
+ enum rte_ring_queue_behavior behavior, uint32_t *old_head,
+ uint32_t *entries)
+{
+ uint32_t n;
+ union rte_ring_rts_poscnt nh, oh;
+
+ oh.raw = __atomic_load_n(&r->rts_cons.head.raw, __ATOMIC_ACQUIRE);
+
+ /* move cons.head atomically */
+ do {
+ /* Restore n as it may change every loop */
+ n = num;
+
+ /*
+ * wait for cons head/tail distance,
+ * make sure that we read cons head *before*
+ * reading prod tail.
+ */
+ __rte_ring_rts_head_wait(&r->rts_cons, &oh);
+
+ /* The subtraction is done between two unsigned 32bits value
+ * (the result is always modulo 32 bits even if we have
+ * cons_head > prod_tail). So 'entries' is always between 0
+ * and size(ring)-1.
+ */
+ *entries = r->prod.tail - oh.val.pos;
+
+ /* Set the actual entries for dequeue */
+ if (n > *entries)
+ n = (behavior == RTE_RING_QUEUE_FIXED) ? 0 : *entries;
+
+ if (unlikely(n == 0))
+ break;
+
+ nh.val.pos = oh.val.pos + n;
+ nh.val.cnt = oh.val.cnt + 1;
+
+ /*
+ * this CAS(ACQUIRE, ACQUIRE) serves as a hoist barrier to prevent:
+ * - OOO reads of prod tail value
+ * - OOO copy of elems from the ring
+ */
+ } while (__atomic_compare_exchange_n(&r->rts_cons.head.raw,
+ &oh.raw, nh.raw,
+ 0, __ATOMIC_ACQUIRE, __ATOMIC_ACQUIRE) == 0);
+
+ *old_head = oh.val.pos;
+ return n;
+}
+
+#endif /* _RTE_RING_RTS_C11_MEM_H_ */
--
2.17.1
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v4 2/9] ring: prepare ring to allow new sync schemes
2020-04-17 13:36 3% ` [dpdk-dev] [PATCH v4 " Konstantin Ananyev
@ 2020-04-17 13:36 9% ` Konstantin Ananyev
2020-04-17 13:36 1% ` [dpdk-dev] [PATCH v4 3/9] ring: introduce RTS ring mode Konstantin Ananyev
2020-04-18 16:32 3% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Konstantin Ananyev
2 siblings, 0 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-17 13:36 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
To make these preparations two main things are done:
- Change from *single* to *sync_type* to allow different
synchronisation schemes to be applied.
Mark *single* as deprecated in comments.
Add new functions to allow user to query ring sync types.
Replace direct access to *single* with appropriate function call.
- Move actual rte_ring and related structures definitions into a
separate file: <rte_ring_core.h>. It allows to refer contents
of <rte_ring_elem.h> from <rte_ring.h> without introducing a
circular dependency.
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
app/test/test_pdump.c | 6 +-
lib/librte_pdump/rte_pdump.c | 2 +-
lib/librte_port/rte_port_ring.c | 12 +--
lib/librte_ring/Makefile | 1 +
lib/librte_ring/meson.build | 1 +
lib/librte_ring/rte_ring.c | 6 +-
lib/librte_ring/rte_ring.h | 170 ++++++++++++++------------------
lib/librte_ring/rte_ring_core.h | 131 ++++++++++++++++++++++++
lib/librte_ring/rte_ring_elem.h | 42 +++-----
9 files changed, 233 insertions(+), 138 deletions(-)
create mode 100644 lib/librte_ring/rte_ring_core.h
diff --git a/app/test/test_pdump.c b/app/test/test_pdump.c
index ad183184c..6a1180bcb 100644
--- a/app/test/test_pdump.c
+++ b/app/test/test_pdump.c
@@ -57,8 +57,7 @@ run_pdump_client_tests(void)
if (ret < 0)
return -1;
mp->flags = 0x0000;
- ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(),
- RING_F_SP_ENQ | RING_F_SC_DEQ);
+ ring_client = rte_ring_create("SR0", RING_SIZE, rte_socket_id(), 0);
if (ring_client == NULL) {
printf("rte_ring_create SR0 failed");
return -1;
@@ -71,9 +70,6 @@ run_pdump_client_tests(void)
}
rte_eth_dev_probing_finish(eth_dev);
- ring_client->prod.single = 0;
- ring_client->cons.single = 0;
-
printf("\n***** flags = RTE_PDUMP_FLAG_TX *****\n");
for (itr = 0; itr < NUM_ITR; itr++) {
diff --git a/lib/librte_pdump/rte_pdump.c b/lib/librte_pdump/rte_pdump.c
index 8a01ac510..f96709f95 100644
--- a/lib/librte_pdump/rte_pdump.c
+++ b/lib/librte_pdump/rte_pdump.c
@@ -380,7 +380,7 @@ pdump_validate_ring_mp(struct rte_ring *ring, struct rte_mempool *mp)
rte_errno = EINVAL;
return -1;
}
- if (ring->prod.single || ring->cons.single) {
+ if (rte_ring_is_prod_single(ring) || rte_ring_is_cons_single(ring)) {
PDUMP_LOG(ERR, "ring with either SP or SC settings"
" is not valid for pdump, should have MP and MC settings\n");
rte_errno = EINVAL;
diff --git a/lib/librte_port/rte_port_ring.c b/lib/librte_port/rte_port_ring.c
index 47fcdd06a..52b2d8e55 100644
--- a/lib/librte_port/rte_port_ring.c
+++ b/lib/librte_port/rte_port_ring.c
@@ -44,8 +44,8 @@ rte_port_ring_reader_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->cons.single && is_multi) ||
- (!(conf->ring->cons.single) && !is_multi)) {
+ (rte_ring_is_cons_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_cons_single(conf->ring) && !is_multi)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
}
@@ -171,8 +171,8 @@ rte_port_ring_writer_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->prod.single && is_multi) ||
- (!(conf->ring->prod.single) && !is_multi) ||
+ (rte_ring_is_prod_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
(conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
@@ -440,8 +440,8 @@ rte_port_ring_writer_nodrop_create_internal(void *params, int socket_id,
/* Check input parameters */
if ((conf == NULL) ||
(conf->ring == NULL) ||
- (conf->ring->prod.single && is_multi) ||
- (!(conf->ring->prod.single) && !is_multi) ||
+ (rte_ring_is_prod_single(conf->ring) && is_multi) ||
+ (!rte_ring_is_prod_single(conf->ring) && !is_multi) ||
(conf->tx_burst_sz > RTE_PORT_IN_BURST_SIZE_MAX)) {
RTE_LOG(ERR, PORT, "%s: Invalid Parameters\n", __func__);
return NULL;
diff --git a/lib/librte_ring/Makefile b/lib/librte_ring/Makefile
index 28368e6d1..6572768c9 100644
--- a/lib/librte_ring/Makefile
+++ b/lib/librte_ring/Makefile
@@ -16,6 +16,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_RING) := rte_ring.c
# install includes
SYMLINK-$(CONFIG_RTE_LIBRTE_RING)-include := rte_ring.h \
+ rte_ring_core.h \
rte_ring_elem.h \
rte_ring_generic.h \
rte_ring_c11_mem.h
diff --git a/lib/librte_ring/meson.build b/lib/librte_ring/meson.build
index 05402e4f0..c656781da 100644
--- a/lib/librte_ring/meson.build
+++ b/lib/librte_ring/meson.build
@@ -3,6 +3,7 @@
sources = files('rte_ring.c')
headers = files('rte_ring.h',
+ 'rte_ring_core.h',
'rte_ring_elem.h',
'rte_ring_c11_mem.h',
'rte_ring_generic.h')
diff --git a/lib/librte_ring/rte_ring.c b/lib/librte_ring/rte_ring.c
index 77e5de099..fa5733907 100644
--- a/lib/librte_ring/rte_ring.c
+++ b/lib/librte_ring/rte_ring.c
@@ -106,8 +106,10 @@ rte_ring_init(struct rte_ring *r, const char *name, unsigned count,
if (ret < 0 || ret >= (int)sizeof(r->name))
return -ENAMETOOLONG;
r->flags = flags;
- r->prod.single = (flags & RING_F_SP_ENQ) ? __IS_SP : __IS_MP;
- r->cons.single = (flags & RING_F_SC_DEQ) ? __IS_SC : __IS_MC;
+ r->prod.sync_type = (flags & RING_F_SP_ENQ) ?
+ RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
+ r->cons.sync_type = (flags & RING_F_SC_DEQ) ?
+ RTE_RING_SYNC_ST : RTE_RING_SYNC_MT;
if (flags & RING_F_EXACT_SZ) {
r->size = rte_align32pow2(count + 1);
diff --git a/lib/librte_ring/rte_ring.h b/lib/librte_ring/rte_ring.h
index 18fc5d845..35ee4491c 100644
--- a/lib/librte_ring/rte_ring.h
+++ b/lib/librte_ring/rte_ring.h
@@ -36,91 +36,7 @@
extern "C" {
#endif
-#include <stdio.h>
-#include <stdint.h>
-#include <sys/queue.h>
-#include <errno.h>
-#include <rte_common.h>
-#include <rte_config.h>
-#include <rte_memory.h>
-#include <rte_lcore.h>
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_memzone.h>
-#include <rte_pause.h>
-
-#define RTE_TAILQ_RING_NAME "RTE_RING"
-
-enum rte_ring_queue_behavior {
- RTE_RING_QUEUE_FIXED = 0, /* Enq/Deq a fixed number of items from a ring */
- RTE_RING_QUEUE_VARIABLE /* Enq/Deq as many items as possible from ring */
-};
-
-#define RTE_RING_MZ_PREFIX "RG_"
-/** The maximum length of a ring name. */
-#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
- sizeof(RTE_RING_MZ_PREFIX) + 1)
-
-/* structure to hold a pair of head/tail values and other metadata */
-struct rte_ring_headtail {
- volatile uint32_t head; /**< Prod/consumer head. */
- volatile uint32_t tail; /**< Prod/consumer tail. */
- uint32_t single; /**< True if single prod/cons */
-};
-
-/**
- * An RTE ring structure.
- *
- * The producer and the consumer have a head and a tail index. The particularity
- * of these index is that they are not between 0 and size(ring). These indexes
- * are between 0 and 2^32, and we mask their value when we access the ring[]
- * field. Thanks to this assumption, we can do subtractions between 2 index
- * values in a modulo-32bit base: that's why the overflow of the indexes is not
- * a problem.
- */
-struct rte_ring {
- /*
- * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
- * compatibility requirements, it could be changed to RTE_RING_NAMESIZE
- * next time the ABI changes
- */
- char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned; /**< Name of the ring. */
- int flags; /**< Flags supplied at creation. */
- const struct rte_memzone *memzone;
- /**< Memzone, if any, containing the rte_ring */
- uint32_t size; /**< Size of ring. */
- uint32_t mask; /**< Mask (size-1) of ring. */
- uint32_t capacity; /**< Usable size of ring */
-
- char pad0 __rte_cache_aligned; /**< empty cache line */
-
- /** Ring producer status. */
- struct rte_ring_headtail prod __rte_cache_aligned;
- char pad1 __rte_cache_aligned; /**< empty cache line */
-
- /** Ring consumer status. */
- struct rte_ring_headtail cons __rte_cache_aligned;
- char pad2 __rte_cache_aligned; /**< empty cache line */
-};
-
-#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
-#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
-/**
- * Ring is to hold exactly requested number of entries.
- * Without this flag set, the ring size requested must be a power of 2, and the
- * usable space will be that size - 1. With the flag, the requested size will
- * be rounded up to the next power of two, but the usable space will be exactly
- * that requested. Worst case, if a power-of-2 size is requested, half the
- * ring space will be wasted.
- */
-#define RING_F_EXACT_SZ 0x0004
-#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
-
-/* @internal defines for passing to the enqueue dequeue worker functions */
-#define __IS_SP 1
-#define __IS_MP 0
-#define __IS_SC 1
-#define __IS_MC 0
+#include <rte_ring_core.h>
/**
* Calculate the memory size needed for a ring
@@ -420,7 +336,7 @@ rte_ring_mp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_MP, free_space);
+ RTE_RING_SYNC_MT, free_space);
}
/**
@@ -443,9 +359,13 @@ rte_ring_sp_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_SP, free_space);
+ RTE_RING_SYNC_ST, free_space);
}
+#ifdef ALLOW_EXPERIMENTAL_API
+#include <rte_ring_elem.h>
+#endif
+
/**
* Enqueue several objects on a ring.
*
@@ -470,7 +390,7 @@ rte_ring_enqueue_bulk(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->prod.single, free_space);
+ r->prod.sync_type, free_space);
}
/**
@@ -554,7 +474,7 @@ rte_ring_mc_dequeue_bulk(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_MC, available);
+ RTE_RING_SYNC_MT, available);
}
/**
@@ -578,7 +498,7 @@ rte_ring_sc_dequeue_bulk(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- __IS_SC, available);
+ RTE_RING_SYNC_ST, available);
}
/**
@@ -605,7 +525,7 @@ rte_ring_dequeue_bulk(struct rte_ring *r, void **obj_table, unsigned int n,
unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n, RTE_RING_QUEUE_FIXED,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
/**
@@ -777,6 +697,62 @@ rte_ring_get_capacity(const struct rte_ring *r)
return r->capacity;
}
+/**
+ * Return sync type used by producer in the ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Producer sync type value.
+ */
+static inline enum rte_ring_sync_type
+rte_ring_get_prod_sync_type(const struct rte_ring *r)
+{
+ return r->prod.sync_type;
+}
+
+/**
+ * Check is the ring for single producer.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * true if ring is SP, zero otherwise.
+ */
+static inline int
+rte_ring_is_prod_single(const struct rte_ring *r)
+{
+ return (rte_ring_get_prod_sync_type(r) == RTE_RING_SYNC_ST);
+}
+
+/**
+ * Return sync type used by consumer in the ring.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * Consumer sync type value.
+ */
+static inline enum rte_ring_sync_type
+rte_ring_get_cons_sync_type(const struct rte_ring *r)
+{
+ return r->cons.sync_type;
+}
+
+/**
+ * Check is the ring for single consumer.
+ *
+ * @param r
+ * A pointer to the ring structure.
+ * @return
+ * true if ring is SC, zero otherwise.
+ */
+static inline int
+rte_ring_is_cons_single(const struct rte_ring *r)
+{
+ return (rte_ring_get_cons_sync_type(r) == RTE_RING_SYNC_ST);
+}
+
/**
* Dump the status of all rings on the console
*
@@ -820,7 +796,7 @@ rte_ring_mp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -843,7 +819,7 @@ rte_ring_sp_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -870,7 +846,7 @@ rte_ring_enqueue_burst(struct rte_ring *r, void * const *obj_table,
unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue(r, obj_table, n, RTE_RING_QUEUE_VARIABLE,
- r->prod.single, free_space);
+ r->prod.sync_type, free_space);
}
/**
@@ -898,7 +874,7 @@ rte_ring_mc_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
}
/**
@@ -923,7 +899,7 @@ rte_ring_sc_dequeue_burst(struct rte_ring *r, void **obj_table,
unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue(r, obj_table, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
}
/**
@@ -951,7 +927,7 @@ rte_ring_dequeue_burst(struct rte_ring *r, void **obj_table,
{
return __rte_ring_do_dequeue(r, obj_table, n,
RTE_RING_QUEUE_VARIABLE,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
#ifdef __cplusplus
diff --git a/lib/librte_ring/rte_ring_core.h b/lib/librte_ring/rte_ring_core.h
new file mode 100644
index 000000000..459a0ffa1
--- /dev/null
+++ b/lib/librte_ring/rte_ring_core.h
@@ -0,0 +1,131 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ *
+ * Copyright (c) 2010-2020 Intel Corporation
+ * Copyright (c) 2007-2009 Kip Macy kmacy@freebsd.org
+ * All rights reserved.
+ * Derived from FreeBSD's bufring.h
+ * Used as BSD-3 Licensed with permission from Kip Macy.
+ */
+
+#ifndef _RTE_RING_CORE_H_
+#define _RTE_RING_CORE_H_
+
+/**
+ * @file
+ * This file contains definion of RTE ring structure itself,
+ * init flags and some related macros.
+ * For majority of DPDK entities, it is not recommended to include
+ * this file directly, use include <rte_ring.h> or <rte_ring_elem.h>
+ * instead.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <sys/queue.h>
+#include <errno.h>
+#include <rte_common.h>
+#include <rte_config.h>
+#include <rte_memory.h>
+#include <rte_lcore.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_memzone.h>
+#include <rte_pause.h>
+#include <rte_debug.h>
+
+#define RTE_TAILQ_RING_NAME "RTE_RING"
+
+enum rte_ring_queue_behavior {
+ /** Enq/Deq a fixed number of items from a ring */
+ RTE_RING_QUEUE_FIXED = 0,
+ /** Enq/Deq as many items as possible from ring */
+ RTE_RING_QUEUE_VARIABLE
+};
+
+#define RTE_RING_MZ_PREFIX "RG_"
+/** The maximum length of a ring name. */
+#define RTE_RING_NAMESIZE (RTE_MEMZONE_NAMESIZE - \
+ sizeof(RTE_RING_MZ_PREFIX) + 1)
+
+/** prod/cons sync types */
+enum rte_ring_sync_type {
+ RTE_RING_SYNC_MT, /**< multi-thread safe (default mode) */
+ RTE_RING_SYNC_ST, /**< single thread only */
+};
+
+/**
+ * structures to hold a pair of head/tail values and other metadata.
+ * Depending on sync_type format of that structure might be different,
+ * but offset for *sync_type* and *tail* values should remain the same.
+ */
+struct rte_ring_headtail {
+ volatile uint32_t head; /**< prod/consumer head. */
+ volatile uint32_t tail; /**< prod/consumer tail. */
+ RTE_STD_C11
+ union {
+ /** sync type of prod/cons */
+ enum rte_ring_sync_type sync_type;
+ /** deprecated - True if single prod/cons */
+ uint32_t single;
+ };
+};
+
+/**
+ * An RTE ring structure.
+ *
+ * The producer and the consumer have a head and a tail index. The particularity
+ * of these index is that they are not between 0 and size(ring). These indexes
+ * are between 0 and 2^32, and we mask their value when we access the ring[]
+ * field. Thanks to this assumption, we can do subtractions between 2 index
+ * values in a modulo-32bit base: that's why the overflow of the indexes is not
+ * a problem.
+ */
+struct rte_ring {
+ /*
+ * Note: this field kept the RTE_MEMZONE_NAMESIZE size due to ABI
+ * compatibility requirements, it could be changed to RTE_RING_NAMESIZE
+ * next time the ABI changes
+ */
+ char name[RTE_MEMZONE_NAMESIZE] __rte_cache_aligned;
+ /**< Name of the ring. */
+ int flags; /**< Flags supplied at creation. */
+ const struct rte_memzone *memzone;
+ /**< Memzone, if any, containing the rte_ring */
+ uint32_t size; /**< Size of ring. */
+ uint32_t mask; /**< Mask (size-1) of ring. */
+ uint32_t capacity; /**< Usable size of ring */
+
+ char pad0 __rte_cache_aligned; /**< empty cache line */
+
+ /** Ring producer status. */
+ struct rte_ring_headtail prod __rte_cache_aligned;
+ char pad1 __rte_cache_aligned; /**< empty cache line */
+
+ /** Ring consumer status. */
+ struct rte_ring_headtail cons __rte_cache_aligned;
+ char pad2 __rte_cache_aligned; /**< empty cache line */
+};
+
+#define RING_F_SP_ENQ 0x0001 /**< The default enqueue is "single-producer". */
+#define RING_F_SC_DEQ 0x0002 /**< The default dequeue is "single-consumer". */
+/**
+ * Ring is to hold exactly requested number of entries.
+ * Without this flag set, the ring size requested must be a power of 2, and the
+ * usable space will be that size - 1. With the flag, the requested size will
+ * be rounded up to the next power of two, but the usable space will be exactly
+ * that requested. Worst case, if a power-of-2 size is requested, half the
+ * ring space will be wasted.
+ */
+#define RING_F_EXACT_SZ 0x0004
+#define RTE_RING_SZ_MASK (0x7fffffffU) /**< Ring size mask */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _RTE_RING_CORE_H_ */
diff --git a/lib/librte_ring/rte_ring_elem.h b/lib/librte_ring/rte_ring_elem.h
index 663addc73..7406c0b0f 100644
--- a/lib/librte_ring/rte_ring_elem.h
+++ b/lib/librte_ring/rte_ring_elem.h
@@ -20,21 +20,7 @@
extern "C" {
#endif
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <sys/queue.h>
-#include <errno.h>
-#include <rte_common.h>
-#include <rte_config.h>
-#include <rte_memory.h>
-#include <rte_lcore.h>
-#include <rte_atomic.h>
-#include <rte_branch_prediction.h>
-#include <rte_memzone.h>
-#include <rte_pause.h>
-
-#include "rte_ring.h"
+#include <rte_ring_core.h>
/**
* @warning
@@ -510,7 +496,7 @@ rte_ring_mp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_MP, free_space);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -539,7 +525,7 @@ rte_ring_sp_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_SP, free_space);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -570,7 +556,7 @@ rte_ring_enqueue_bulk_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->prod.single, free_space);
+ RTE_RING_QUEUE_FIXED, r->prod.sync_type, free_space);
}
/**
@@ -675,7 +661,7 @@ rte_ring_mc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_MC, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_MT, available);
}
/**
@@ -703,7 +689,7 @@ rte_ring_sc_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, __IS_SC, available);
+ RTE_RING_QUEUE_FIXED, RTE_RING_SYNC_ST, available);
}
/**
@@ -734,7 +720,7 @@ rte_ring_dequeue_bulk_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_FIXED, r->cons.single, available);
+ RTE_RING_QUEUE_FIXED, r->cons.sync_type, available);
}
/**
@@ -842,7 +828,7 @@ rte_ring_mp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, free_space);
}
/**
@@ -871,7 +857,7 @@ rte_ring_sp_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SP, free_space);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, free_space);
}
/**
@@ -902,7 +888,7 @@ rte_ring_enqueue_burst_elem(struct rte_ring *r, const void *obj_table,
unsigned int esize, unsigned int n, unsigned int *free_space)
{
return __rte_ring_do_enqueue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, r->prod.single, free_space);
+ RTE_RING_QUEUE_VARIABLE, r->prod.sync_type, free_space);
}
/**
@@ -934,7 +920,7 @@ rte_ring_mc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_MC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_MT, available);
}
/**
@@ -963,7 +949,7 @@ rte_ring_sc_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
unsigned int esize, unsigned int n, unsigned int *available)
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
- RTE_RING_QUEUE_VARIABLE, __IS_SC, available);
+ RTE_RING_QUEUE_VARIABLE, RTE_RING_SYNC_ST, available);
}
/**
@@ -995,9 +981,11 @@ rte_ring_dequeue_burst_elem(struct rte_ring *r, void *obj_table,
{
return __rte_ring_do_dequeue_elem(r, obj_table, esize, n,
RTE_RING_QUEUE_VARIABLE,
- r->cons.single, available);
+ r->cons.sync_type, available);
}
+#include <rte_ring.h>
+
#ifdef __cplusplus
}
#endif
--
2.17.1
^ permalink raw reply [relevance 9%]
* [dpdk-dev] [PATCH v4 0/9] New sync modes for ring
@ 2020-04-17 13:36 3% ` Konstantin Ananyev
2020-04-17 13:36 9% ` [dpdk-dev] [PATCH v4 2/9] ring: prepare ring to allow new sync schemes Konstantin Ananyev
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Konstantin Ananyev @ 2020-04-17 13:36 UTC (permalink / raw)
To: dev; +Cc: honnappa.nagarahalli, david.marchand, jielong.zjl, Konstantin Ananyev
V3 - V4 changes:
Address comments from Honnappa:
1. for new sync modes make legacy API wrappers around _elem_ calls
2. remove rte_ring_(hts|rts)_generic.h
3. few changes in C11 version
4. peek API - add missing functions for _elem_
5. remove _IS_SP/_IS_MP, etc. internal macros
6. fix param types (obj_table) for _elem_functions
7. fix formal API comments
8. deduplicate code for test_ring_stress
9. added functional tests for new sync modes
V2 - V3 changes:
1. Few more compilation fixes (for gcc 4.8.X)
2. Extra update devtools/libabigail.abignore (workaround)
V1 - V2 changes:
1. Fix compilation issues
2. Add C11 atomics support
3. Updates devtools/libabigail.abignore (workaround)
RFC - V1 changes:
1. remove ABI brekage (at least I hope I did)
2. Add support for ring_elem
3. Rework peek related API a bit
4. Rework test to make it less verbose and unite all test-cases
in one command
5. Add new test-case for MT peek API
TODO list:
1. Update docs
These days more and more customers use(/try to use) DPDK based apps within
overcommitted systems (multiple acttive threads over same pysical cores):
VM, container deployments, etc.
One quite common problem they hit:
Lock-Holder-Preemption/Lock-Waiter-Preemption with rte_ring.
LHP is quite a common problem for spin-based sync primitives
(spin-locks, etc.) on overcommitted systems.
The situation gets much worse when some sort of
fair-locking technique is used (ticket-lock, etc.).
As now not only lock-owner but also lock-waiters scheduling
order matters a lot (LWP).
These two problems are well-known for kernel within VMs:
http://www-archive.xenproject.org/files/xensummitboston08/LHP.pdf
https://www.cs.hs-rm.de/~kaiser/events/wamos2017/Slides/selcuk.pdf
The problem with rte_ring is that while head accusion is sort of
un-fair locking, waiting on tail is very similar to ticket lock schema -
tail has to be updated in particular order.
That makes current rte_ring implementation to perform
really pure on some overcommited scenarios.
It is probably not possible to completely resolve LHP problem in
userspace only (without some kernel communication/intervention).
But removing fairness at tail update helps to avoid LWP and
can mitigate the situation significantly.
This patch proposes two new optional ring synchronization modes:
1) Head/Tail Sync (HTS) mode
In that mode enqueue/dequeue operation is fully serialized:
only one thread at a time is allowed to perform given op.
As another enhancement provide ability to split enqueue/dequeue
operation into two phases:
- enqueue/dequeue start
- enqueue/dequeue finish
That allows user to inspect objects in the ring without removing
them from it (aka MT safe peek).
2) Relaxed Tail Sync (RTS)
The main difference from original MP/MC algorithm is that
tail value is increased not by every thread that finished enqueue/dequeue,
but only by the last one.
That allows threads to avoid spinning on ring tail value,
leaving actual tail value change to the last thread in the update queue.
Note that these new sync modes are optional.
For current rte_ring users nothing should change
(both in terms of API/ABI and performance).
Existing sync modes MP/MC,SP/SC kept untouched, set up in the same
way (via flags and _init_), and MP/MC remains as default one.
The only thing that changed:
Format of prod/cons now could differ depending on mode selected at _init_.
So user has to stick with one sync model through whole ring lifetime.
In other words, user can't create a ring for let say SP mode and then
in the middle of data-path change his mind and start using MP_RTS mode.
For existing modes (SP/MP, SC/MC) format remains the same and
user can still use them interchangeably, though of course it is an
error prone practice.
Test results on IA (see below) show significant improvements
for average enqueue/dequeue op times on overcommitted systems.
For 'classic' DPDK deployments (one thread per core) original MP/MC
algorithm still shows best numbers, though for 64-bit target
RTS numbers are not that far away.
Numbers were produced by new UT test-case: ring_stress_autotest, i.e.:
echo ring_stress_autotest | ./dpdk-test -n 4 --lcores='...'
X86_64 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
DEQ+ENQ average cycles/obj
MP/MC HTS RTS
1thread@1core(--lcores=6-7) 8.00 8.15 8.99
2thread@2core(--lcores=6-8) 19.14 19.61 20.35
4thread@4core(--lcores=6-10) 29.43 29.79 31.82
8thread@8core(--lcores=6-14) 110.59 192.81 119.50
16thread@16core(--lcores=6-22) 461.03 813.12 495.59
32thread/@32core(--lcores='6-22,55-70') 982.90 1972.38 1160.51
2thread@1core(--lcores='6,(10-11)@7' 20140.50 23.58 25.14
4thread@2core(--lcores='6,(10-11)@7,(20-21)@8' 153680.60 76.88 80.05
8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 280314.32 294.72 318.79
16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 643176.59 1144.02 1175.14
32thread@2core(--lcores='6,(10-25)@7,(30-45)@8' 4264238.80 4627.48 4892.68
8thread@2core(--lcores='6,(10-17)@(7,8))' 321085.98 298.59 307.47
16thread@4core(--lcores='6,(20-35)@(7-10))' 1900705.61 575.35 678.29
32thread@4core(--lcores='6,(20-51)@(7-10))' 5510445.85 2164.36 2714.12
i686 @ Intel(R) Xeon(R) Platinum 8160 CPU @ 2.10GHz
DEQ+ENQ average cycles/obj
MP/MC HTS RTS
1thread@1core(--lcores=6-7) 7.85 12.13 11.31
2thread@2core(--lcores=6-8) 17.89 24.52 21.86
8thread@8core(--lcores=6-14) 32.58 354.20 54.58
32thread/@32core(--lcores='6-22,55-70') 813.77 6072.41 2169.91
2thread@1core(--lcores='6,(10-11)@7' 16095.00 36.06 34.74
8thread@2core(--lcores='6,(10-13)@7,(20-23)@8' 1140354.54 346.61 361.57
16thread@2core(--lcores='6,(10-17)@7,(20-27)@8' 1920417.86 1314.90 1416.65
8thread@2core(--lcores='6,(10-17)@(7,8))' 594358.61 332.70 357.74
32thread@4core(--lcores='6,(20-51)@(7-10))' 5319896.86 2836.44 3028.87
Konstantin Ananyev (9):
test/ring: add contention stress test
ring: prepare ring to allow new sync schemes
ring: introduce RTS ring mode
test/ring: add contention stress test for RTS ring
ring: introduce HTS ring mode
test/ring: add contention stress test for HTS ring
ring: introduce peek style API
test/ring: add stress test for MT peek API
test/ring: add functional tests for new sync modes
app/test/Makefile | 5 +
app/test/meson.build | 5 +
app/test/test_pdump.c | 6 +-
app/test/test_ring.c | 93 ++++--
app/test/test_ring_hts_stress.c | 32 ++
app/test/test_ring_mpmc_stress.c | 31 ++
app/test/test_ring_peek_stress.c | 43 +++
app/test/test_ring_rts_stress.c | 32 ++
app/test/test_ring_stress.c | 57 ++++
app/test/test_ring_stress.h | 38 +++
app/test/test_ring_stress_impl.h | 396 ++++++++++++++++++++++
devtools/libabigail.abignore | 7 +
lib/librte_pdump/rte_pdump.c | 2 +-
lib/librte_port/rte_port_ring.c | 12 +-
lib/librte_ring/Makefile | 8 +-
lib/librte_ring/meson.build | 11 +-
lib/librte_ring/rte_ring.c | 114 ++++++-
lib/librte_ring/rte_ring.h | 243 ++++++++------
lib/librte_ring/rte_ring_c11_mem.h | 44 +++
lib/librte_ring/rte_ring_core.h | 181 ++++++++++
lib/librte_ring/rte_ring_elem.h | 141 ++++++--
lib/librte_ring/rte_ring_generic.h | 48 +++
lib/librte_ring/rte_ring_hts.h | 332 ++++++++++++++++++
lib/librte_ring/rte_ring_hts_c11_mem.h | 207 ++++++++++++
lib/librte_ring/rte_ring_peek.h | 446 +++++++++++++++++++++++++
lib/librte_ring/rte_ring_rts.h | 439 ++++++++++++++++++++++++
lib/librte_ring/rte_ring_rts_c11_mem.h | 179 ++++++++++
27 files changed, 2978 insertions(+), 174 deletions(-)
create mode 100644 app/test/test_ring_hts_stress.c
create mode 100644 app/test/test_ring_mpmc_stress.c
create mode 100644 app/test/test_ring_peek_stress.c
create mode 100644 app/test/test_ring_rts_stress.c
create mode 100644 app/test/test_ring_stress.c
create mode 100644 app/test/test_ring_stress.h
create mode 100644 app/test/test_ring_stress_impl.h
create mode 100644 lib/librte_ring/rte_ring_core.h
create mode 100644 lib/librte_ring/rte_ring_hts.h
create mode 100644 lib/librte_ring/rte_ring_hts_c11_mem.h
create mode 100644 lib/librte_ring/rte_ring_peek.h
create mode 100644 lib/librte_ring/rte_ring_rts.h
create mode 100644 lib/librte_ring/rte_ring_rts_c11_mem.h
--
2.17.1
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-17 11:47 4% ` Ray Kinsella
@ 2020-04-17 12:10 4% ` Thomas Monjalon
2020-04-17 15:42 9% ` Ray Kinsella
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-17 12:10 UTC (permalink / raw)
To: Neil Horman, Ray Kinsella; +Cc: dev, david.marchand
17/04/2020 13:47, Ray Kinsella:
> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > 17/04/2020 12:11, Ray Kinsella:
> >> check-abi.sh appears to be backward step in terms of usability.
> >
> > No, check-abi.sh benefits from a nice integration in build scripts.
> > See below.
> >
> >> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> >> And it will do the build, install, dump and comparison for me.
> >> And it picked up my 20.0.2 - > 21.0 changes no problem.
> >>
> >> With check-abi on the other hand, I need to the build and install myself.
> >> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> >> It silently fails when it doesn't find any ...
> >>
> >> Do I run abi-dumper on the so's myself, or how does it work?
> >
> > check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > Probably we should document usage in these scripts.
>
> Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
> Any tips or tricks would be welcome.
export DPDK_ABI_REF_VERSION=v20.02
or
export DPDK_ABI_REF_VERSION=v19.11
Depends on which compatibility you want to test...
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-17 10:20 8% ` Thomas Monjalon
2020-04-17 10:35 4% ` Ray Kinsella
@ 2020-04-17 11:47 4% ` Ray Kinsella
2020-04-17 12:10 4% ` Thomas Monjalon
1 sibling, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-17 11:47 UTC (permalink / raw)
To: Thomas Monjalon, Neil Horman; +Cc: dev, david.marchand
On 17/04/2020 11:20, Thomas Monjalon wrote:
> 17/04/2020 12:11, Ray Kinsella:
>>
>> On 16/04/2020 15:54, Neil Horman wrote:
>>> Since we've moved away from our initial validate-abi.sh script, in
>>> favor of check-abi.sh, which uses libabigail, remove the old script from
>>> the tree, and update the docs accordingly
>>>
>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>>> CC: thomas@monjalon.net
>>> CC: david.marchand@redhat.com
>>> CC: mdr@ashroe.eu
>>> ---
>>> MAINTAINERS | 1 -
>>> devtools/validate-abi.sh | 251 ---------------------
>>> doc/guides/contributing/abi_versioning.rst | 50 ++--
>>> 3 files changed, 18 insertions(+), 284 deletions(-)
>>> delete mode 100755 devtools/validate-abi.sh
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 4800f6884..84b633431 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -152,7 +152,6 @@ F: devtools/gen-abi.sh
>>> F: devtools/libabigail.abignore
>>> F: devtools/update-abi.sh
>>> F: devtools/update_version_map_abi.py
>>> -F: devtools/validate-abi.sh
>>> F: buildtools/check-experimental-syms.sh
>>> F: buildtools/map-list-symbol.sh
>>>
>>> diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh
>>> deleted file mode 100755
>>> index f64e19d38..000000000
>>> --- a/devtools/validate-abi.sh
>>> +++ /dev/null
>>> @@ -1,251 +0,0 @@
>>> -#!/usr/bin/env bash
>>> -# SPDX-License-Identifier: BSD-3-Clause
>>> -# Copyright(c) 2015 Neil Horman. All rights reserved.
>>> -# Copyright(c) 2017 6WIND S.A.
>>> -# All rights reserved
>>> -
>>> -set -e
>>> -
>>> -abicheck=abi-compliance-checker
>>> -abidump=abi-dumper
>>> -default_dst=abi-check
>>> -default_target=x86_64-native-linuxapp-gcc
>>> -
>>> -# trap on error
>>> -err_report() {
>>> - echo "$0: error at line $1"
>>> -}
>>> -trap 'err_report $LINENO' ERR
>>> -
>>> -print_usage () {
>>> - cat <<- END_OF_HELP
>>> - $(basename $0) [options] <rev1> <rev2>
>>> -
>>> - This script compares the ABI of 2 git revisions of the current
>>> - workspace. The output is a html report and a compilation log.
>>> -
>>> - The objective is to make sure that applications built against
>>> - DSOs from the first revision can still run when executed using
>>> - the DSOs built from the second revision.
>>> -
>>> - <rev1> and <rev2> are git commit id or tags.
>>> -
>>> - Options:
>>> - -h show this help
>>> - -j <num> enable parallel compilation with <num> threads
>>> - -v show compilation logs on the console
>>> - -d <dir> change working directory (default is ${default_dst})
>>> - -t <target> the dpdk target to use (default is ${default_target})
>>> - -f overwrite existing files in destination directory
>>> -
>>> - The script returns 0 on success, or the value of last failing
>>> - call of ${abicheck} (incompatible abi or the tool has run with errors).
>>> - The errors returned by ${abidump} are ignored.
>>> -
>>> - END_OF_HELP
>>> -}
>>> -
>>> -# log in the file, and on stdout if verbose
>>> -# $1: level string
>>> -# $2: string to be logged
>>> -log() {
>>> - echo "$1: $2"
>>> - if [ "${verbose}" != "true" ]; then
>>> - echo "$1: $2" >&3
>>> - fi
>>> -}
>>> -
>>> -# launch a command and log it, taking care of surrounding spaces with quotes
>>> -cmd() {
>>> - local i s whitespace ret
>>> - s=""
>>> - whitespace="[[:space:]]"
>>> - for i in "$@"; do
>>> - if [[ $i =~ $whitespace ]]; then
>>> - i=\"$i\"
>>> - fi
>>> - if [ -z "$s" ]; then
>>> - s="$i"
>>> - else
>>> - s="$s $i"
>>> - fi
>>> - done
>>> -
>>> - ret=0
>>> - log "CMD" "$s"
>>> - "$@" || ret=$?
>>> - if [ "$ret" != "0" ]; then
>>> - log "CMD" "previous command returned $ret"
>>> - fi
>>> -
>>> - return $ret
>>> -}
>>> -
>>> -# redirect or copy stderr/stdout to a file
>>> -# the syntax is unfamiliar, but it makes the rest of the
>>> -# code easier to read, avoiding the use of pipes
>>> -set_log_file() {
>>> - # save original stdout and stderr in fd 3 and 4
>>> - exec 3>&1
>>> - exec 4>&2
>>> - # create a new fd 5 that send to a file
>>> - exec 5> >(cat > $1)
>>> - # send stdout and stderr to fd 5
>>> - if [ "${verbose}" = "true" ]; then
>>> - exec 1> >(tee /dev/fd/5 >&3)
>>> - exec 2> >(tee /dev/fd/5 >&4)
>>> - else
>>> - exec 1>&5
>>> - exec 2>&5
>>> - fi
>>> -}
>>> -
>>> -# Make sure we configure SHARED libraries
>>> -# Also turn off IGB and KNI as those require kernel headers to build
>>> -fixup_config() {
>>> - local conf=config/defconfig_$target
>>> - cmd sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" $conf
>>> - cmd sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" $conf
>>> - cmd sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" $conf
>>> - cmd sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" $conf
>>> - cmd sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" $conf
>>> -}
>>> -
>>> -# build dpdk for the given tag and dump abi
>>> -# $1: hash of the revision
>>> -gen_abi() {
>>> - local i
>>> -
>>> - cmd git clone ${dpdkroot} ${dst}/${1}
>>> - cmd cd ${dst}/${1}
>>> -
>>> - log "INFO" "Checking out version ${1} of the dpdk"
>>> - # Move to the old version of the tree
>>> - cmd git checkout ${1}
>>> -
>>> - fixup_config
>>> -
>>> - # Now configure the build
>>> - log "INFO" "Configuring DPDK ${1}"
>>> - cmd make config T=$target O=$target
>>> -
>>> - # Checking abi compliance relies on using the dwarf information in
>>> - # the shared objects. Build with -g to include them.
>>> - log "INFO" "Building DPDK ${1}. This might take a moment"
>>> - cmd make -j$parallel O=$target V=1 EXTRA_CFLAGS="-g -Og -Wno-error" \
>>> - EXTRA_LDFLAGS="-g" || log "INFO" "The build failed"
>>> -
>>> - # Move to the lib directory
>>> - cmd cd ${PWD}/$target/lib
>>> - log "INFO" "Collecting ABI information for ${1}"
>>> - for i in *.so; do
>>> - [ -e "$i" ] || break
>>> - cmd $abidump ${i} -o $dst/${1}/${i}.dump -lver ${1} || true
>>> - # hack to ignore empty SymbolsInfo section (no public ABI)
>>> - if grep -q "'SymbolInfo' => {}," $dst/${1}/${i}.dump \
>>> - 2> /dev/null; then
>>> - log "INFO" "${i} has no public ABI, remove dump file"
>>> - cmd rm -f $dst/${1}/${i}.dump
>>> - fi
>>> - done
>>> -}
>>> -
>>> -verbose=false
>>> -parallel=1
>>> -dst=${default_dst}
>>> -target=${default_target}
>>> -force=0
>>> -while getopts j:vd:t:fh ARG ; do
>>> - case $ARG in
>>> - j ) parallel=$OPTARG ;;
>>> - v ) verbose=true ;;
>>> - d ) dst=$OPTARG ;;
>>> - t ) target=$OPTARG ;;
>>> - f ) force=1 ;;
>>> - h ) print_usage ; exit 0 ;;
>>> - ? ) print_usage ; exit 1 ;;
>>> - esac
>>> -done
>>> -shift $(($OPTIND - 1))
>>> -
>>> -if [ $# != 2 ]; then
>>> - print_usage
>>> - exit 1
>>> -fi
>>> -
>>> -tag1=$1
>>> -tag2=$2
>>> -
>>> -# convert path to absolute
>>> -case "${dst}" in
>>> - /*) ;;
>>> - *) dst=${PWD}/${dst} ;;
>>> -esac
>>> -dpdkroot=$(readlink -f $(dirname $0)/..)
>>> -
>>> -if [ -e "${dst}" -a "$force" = 0 ]; then
>>> - echo "The ${dst} directory is not empty. Remove it, use another"
>>> - echo "one (-d <dir>), or force overriding (-f)"
>>> - exit 1
>>> -fi
>>> -
>>> -rm -rf ${dst}
>>> -mkdir -p ${dst}
>>> -set_log_file ${dst}/abi-check.log
>>> -log "INFO" "Logs available in ${dst}/abi-check.log"
>>> -
>>> -command -v ${abicheck} || log "INFO" "Can't find ${abicheck} utility"
>>> -command -v ${abidump} || log "INFO" "Can't find ${abidump} utility"
>>> -
>>> -hash1=$(git show -s --format=%h "$tag1" -- 2> /dev/null | tail -1)
>>> -hash2=$(git show -s --format=%h "$tag2" -- 2> /dev/null | tail -1)
>>> -
>>> -# Make hashes available in output for non-local reference
>>> -tag1="$tag1 ($hash1)"
>>> -tag2="$tag2 ($hash2)"
>>> -
>>> -if [ "$hash1" = "$hash2" ]; then
>>> - log "ERROR" "$tag1 and $tag2 are the same revisions"
>>> - exit 1
>>> -fi
>>> -
>>> -cmd mkdir -p ${dst}
>>> -
>>> -# dump abi for each revision
>>> -gen_abi ${hash1}
>>> -gen_abi ${hash2}
>>> -
>>> -# compare the abi dumps
>>> -cmd cd ${dst}
>>> -ret=0
>>> -list=""
>>> -for i in ${hash2}/*.dump; do
>>> - name=`basename $i`
>>> - libname=${name%.dump}
>>> -
>>> - if [ ! -f ${hash1}/$name ]; then
>>> - log "INFO" "$NAME does not exist in $tag1. skipping..."
>>> - continue
>>> - fi
>>> -
>>> - local_ret=0
>>> - cmd $abicheck -l $libname \
>>> - -old ${hash1}/$name -new ${hash2}/$name || local_ret=$?
>>> - if [ $local_ret != 0 ]; then
>>> - log "NOTICE" "$abicheck returned $local_ret"
>>> - ret=$local_ret
>>> - list="$list $libname"
>>> - fi
>>> -done
>>> -
>>> -if [ $ret != 0 ]; then
>>> - log "NOTICE" "ABI may be incompatible, check reports/logs for details."
>>> - log "NOTICE" "Incompatible list: $list"
>>> -else
>>> - log "NOTICE" "No error detected, ABI is compatible."
>>> -fi
>>> -
>>> -log "INFO" "Logs are in ${dst}/abi-check.log"
>>> -log "INFO" "HTML reports are in ${dst}/compat_reports directory"
>>> -
>>> -exit $ret
>>> diff --git a/doc/guides/contributing/abi_versioning.rst b/doc/guides/contributing/abi_versioning.rst
>>> index a21f4e7a4..219823923 100644
>>> --- a/doc/guides/contributing/abi_versioning.rst
>>> +++ b/doc/guides/contributing/abi_versioning.rst
>>> @@ -482,41 +482,27 @@ Running the ABI Validator
>>> -------------------------
>>>
>>> The ``devtools`` directory in the DPDK source tree contains a utility program,
>>> -``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
>>> -Compliance Checker
>>> -<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
>>> +``check-abi.sh``, for validating the DPDK ABI based on the libabigail `abidiff
>>> +utility: <https://sourceware.org/libabigail/manual/abidiff.html>`_
>>>
>>> -This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
>>> -utilities which can be installed via a package manager. For example::
>>> +The syntax of the ``check-abi.sh`` utility is::
>>>
>>> - sudo yum install abi-compliance-checker
>>> - sudo yum install abi-dumper
>>> + ./devtools/check-abi.sh <refdir> <newdir>
>>>
>>> -The syntax of the ``validate-abi.sh`` utility is::
>>> +Where <refdir> specifies the directory housing the reference build of dpdk, and
>>> +<newdir> specifies the dpdk build directory to check the abi of
>>>
>>> - ./devtools/validate-abi.sh <REV1> <REV2>
>>> +Example:
>>> +To compare your build branch to the ABI of the master branch
>>> +after you have built your branch
>>>
>>> -Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
>>> -https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
>>> -on the local repo.
>>> +#. $ cd <path to dpdk src tree>
>>> +#. $ mkdir ~/ref
>>> +#. $ git clone --local --no-hardlinks --single-branch -b master . ~/ref
>>> +#. $ cd ~/ref
>>> +#. $ cp <path to dpdk src tree from above>/.config ./.config
>>> +#. $ make defconfig
>>> +#. $ make
>>> +#. $ <path to dpdk src tree>/devtools/check-abi.sh ~/ref <path to dpdk src tree>
>>>
>>> -For example::
>>> -
>>> - # Check between the previous and latest commit:
>>> - ./devtools/validate-abi.sh HEAD~1 HEAD
>>> -
>>> - # Check on a specific compilation target:
>>> - ./devtools/validate-abi.sh -t x86_64-native-linux-gcc HEAD~1 HEAD
>>> -
>>> - # Check between two tags:
>>> - ./devtools/validate-abi.sh v2.0.0 v2.1.0
>>> -
>>> - # Check between git master and local topic-branch "vhost-hacking":
>>> - ./devtools/validate-abi.sh master vhost-hacking
>>> -
>>> -After the validation script completes (it can take a while since it need to
>>> -compile both tags) it will create compatibility reports in the
>>> -``./abi-check/compat_report`` directory. Listed incompatibilities can be found
>>> -as follows::
>>> -
>>> - grep -lr Incompatible abi-check/compat_reports/
>>> +
>>>
>>
>> check-abi.sh appears to be backward step in terms of usability.
>
> No, check-abi.sh benefits from a nice integration in build scripts.
> See below.
>
>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
>> And it will do the build, install, dump and comparison for me.
>> And it picked up my 20.0.2 - > 21.0 changes no problem.
>>
>> With check-abi on the other hand, I need to the build and install myself.
>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
>> It silently fails when it doesn't find any ...
>>
>> Do I run abi-dumper on the so's myself, or how does it work?
>
> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> Probably we should document usage in these scripts.
>
Looks like I need to set DPDK_ABI_REF_VERSION=master, not obvious.
Any tips or tricks would be welcome.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-17 10:33 3% ` Ray Kinsella
@ 2020-04-17 11:46 5% ` Trahe, Fiona
2020-04-17 16:01 0% ` Ray Kinsella
2020-04-20 16:59 3% ` Trahe, Fiona
0 siblings, 2 replies; 200+ results
From: Trahe, Fiona @ 2020-04-17 11:46 UTC (permalink / raw)
To: Ray Kinsella, Thomas Monjalon, Richardson, Bruce
Cc: dev, Kusztal, ArkadiuszX, Neil Horman, Luca Boccassi,
Kevin Traynor, Yigit, Ferruh, Trahe, Fiona
Hi all,
> -----Original Message-----
> From: Ray Kinsella <mdr@ashroe.eu>
> Sent: Friday, April 17, 2020 11:34 AM
> To: Thomas Monjalon <thomas@monjalon.net>; Richardson, Bruce <bruce.richardson@intel.com>
> Cc: Trahe, Fiona <fiona.trahe@intel.com>; dev@dpdk.org; Kusztal, ArkadiuszX
> <arkadiuszx.kusztal@intel.com>; Neil Horman <nhorman@tuxdriver.com>; Luca Boccassi
> <bluca@debian.org>; Kevin Traynor <ktraynor@redhat.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
>
>
>
> On 17/04/2020 11:17, Thomas Monjalon wrote:
> > 17/04/2020 11:42, Ray Kinsella:
> >> On 17/04/2020 10:31, Bruce Richardson wrote:
> >>> On Fri, Apr 17, 2020 at 08:24:30AM +0100, Ray Kinsella wrote:
> >>>> On 16/04/2020 11:01, Thomas Monjalon wrote:
> >>>>> 16/04/2020 11:51, Bruce Richardson:
> >>>>>> On Wed, Apr 15, 2020 at 06:24:19PM +0100, Trahe, Fiona wrote:
> >>>>>>> 5a. If in 20.05 we add a version of a fn which breaks ABI 20.0, what should the name of the
> original function be? fn_v20, or fn_v20.0
> >>>>>>
> >>>>>> In technical terms it really doesn't matter, it's just a name that will be
> >>>>>> looked up in a table. I don't think we strictly enforce the naming, so
> >>>>>> whatever is clearest is best. I'd suggest the former.
> >>>>>
> >>>>> Each release can have a new ABI.
> >>>>
> >>>> How many ABI's do we want to support?
> >>>>
> >>> It's not how many we want to support, but for me it's a matter of how many
> >>> do we need to support. If an API is part of the stable set, it can't just
> >>> drop to being experimental for one or two releases - it's always stable
> >>> until deprecated. We also shouldn't have a situation where release 20.08 is
> >>> ABI compatible with 19.11 but not 20.02 and 20.05.
> >>
> >> True. Let me say it differently.
> >>
> >> Our only commitment is to support v20 - 19.11
> >> However you are correct, if something gets committed as v21 in 20.02, in practise should also be
> there in 20.05+ also.
> >> Because if it is committed as v21 and not as experimental, it should not be changing once
> committed.
> >>
> >> In answering Thomas,
> >> I was more commenting on the proliferation of ABI numbers & symbols we need to track in the
> build.
> >> With v20, v21 & Experimental we need to keep track of 3.
> >> If we start allowing quarterly builds to have managed ABI's, it will get confusing.
> >
> > I don't remember why we are using intermediate ABI versions
> > between v20 and v21.
> > If we can use v21 for new ABI and make sure compatibility is maintained
> > between all versions from 19.11 to 20.08, I'm fine.
[Fiona] Here's a hypothetical case, but it illustrates why I don't think there
should be an expectation to maintain ABI compatibility here.
Example: in 20.05 add a new info_get_v21() which includes ChaChaPoly.
In 20.08 add another new algorithm. info_get_v21() return now includes this.
info_get_v21() will become stable in 20.11 and compatibility must be maintained from then on.
In the meantime, the fn is not experimental - that wouldn't be appropriate as it was a stable API.
But an app either wants stability and so should build against 19.11, or if prepared to move up to
one non-stable-ABI quarterly release should be willing to rebuild for the next non-stable-ABI quarterly release.
I think it's an unnecessary burden to require ABI compatibility across quarterly releases.
And if required could end up with the version tracking hassle Ray referred to above with fn versions
of 20.0.1, 20.0.2, 20.0.3, v21, and potentially several versions of same fn.
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-17 10:35 4% ` Ray Kinsella
@ 2020-04-17 11:46 4% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2020-04-17 11:46 UTC (permalink / raw)
To: Neil Horman, Ray Kinsella; +Cc: dev, david.marchand
17/04/2020 12:35, Ray Kinsella:
> On 17/04/2020 11:20, Thomas Monjalon wrote:
> > 17/04/2020 12:11, Ray Kinsella:
> >> On 16/04/2020 15:54, Neil Horman wrote:
> >>> Since we've moved away from our initial validate-abi.sh script, in
> >>> favor of check-abi.sh, which uses libabigail, remove the old script from
> >>> the tree, and update the docs accordingly
> >>>
> >>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> >>> CC: thomas@monjalon.net
> >>> CC: david.marchand@redhat.com
> >>> CC: mdr@ashroe.eu
> >>> ---
> >>> MAINTAINERS | 1 -
> >>> devtools/validate-abi.sh | 251 ---------------------
> >>> doc/guides/contributing/abi_versioning.rst | 50 ++--
> >>> 3 files changed, 18 insertions(+), 284 deletions(-)
> >>> delete mode 100755 devtools/validate-abi.sh
> >>>
> >>> diff --git a/MAINTAINERS b/MAINTAINERS
> >>> index 4800f6884..84b633431 100644
> >>> --- a/MAINTAINERS
> >>> +++ b/MAINTAINERS
> >>> @@ -152,7 +152,6 @@ F: devtools/gen-abi.sh
> >>> F: devtools/libabigail.abignore
> >>> F: devtools/update-abi.sh
> >>> F: devtools/update_version_map_abi.py
> >>> -F: devtools/validate-abi.sh
> >>> F: buildtools/check-experimental-syms.sh
> >>> F: buildtools/map-list-symbol.sh
> >>>
> >>> diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh
> >>> deleted file mode 100755
> >>> index f64e19d38..000000000
> >>> --- a/devtools/validate-abi.sh
> >>> +++ /dev/null
> >>> @@ -1,251 +0,0 @@
> >>> -#!/usr/bin/env bash
> >>> -# SPDX-License-Identifier: BSD-3-Clause
> >>> -# Copyright(c) 2015 Neil Horman. All rights reserved.
> >>> -# Copyright(c) 2017 6WIND S.A.
> >>> -# All rights reserved
> >>> -
> >>> -set -e
> >>> -
> >>> -abicheck=abi-compliance-checker
> >>> -abidump=abi-dumper
> >>> -default_dst=abi-check
> >>> -default_target=x86_64-native-linuxapp-gcc
> >>> -
> >>> -# trap on error
> >>> -err_report() {
> >>> - echo "$0: error at line $1"
> >>> -}
> >>> -trap 'err_report $LINENO' ERR
> >>> -
> >>> -print_usage () {
> >>> - cat <<- END_OF_HELP
> >>> - $(basename $0) [options] <rev1> <rev2>
> >>> -
> >>> - This script compares the ABI of 2 git revisions of the current
> >>> - workspace. The output is a html report and a compilation log.
> >>> -
> >>> - The objective is to make sure that applications built against
> >>> - DSOs from the first revision can still run when executed using
> >>> - the DSOs built from the second revision.
> >>> -
> >>> - <rev1> and <rev2> are git commit id or tags.
> >>> -
> >>> - Options:
> >>> - -h show this help
> >>> - -j <num> enable parallel compilation with <num> threads
> >>> - -v show compilation logs on the console
> >>> - -d <dir> change working directory (default is ${default_dst})
> >>> - -t <target> the dpdk target to use (default is ${default_target})
> >>> - -f overwrite existing files in destination directory
> >>> -
> >>> - The script returns 0 on success, or the value of last failing
> >>> - call of ${abicheck} (incompatible abi or the tool has run with errors).
> >>> - The errors returned by ${abidump} are ignored.
> >>> -
> >>> - END_OF_HELP
> >>> -}
> >>> -
> >>> -# log in the file, and on stdout if verbose
> >>> -# $1: level string
> >>> -# $2: string to be logged
> >>> -log() {
> >>> - echo "$1: $2"
> >>> - if [ "${verbose}" != "true" ]; then
> >>> - echo "$1: $2" >&3
> >>> - fi
> >>> -}
> >>> -
> >>> -# launch a command and log it, taking care of surrounding spaces with quotes
> >>> -cmd() {
> >>> - local i s whitespace ret
> >>> - s=""
> >>> - whitespace="[[:space:]]"
> >>> - for i in "$@"; do
> >>> - if [[ $i =~ $whitespace ]]; then
> >>> - i=\"$i\"
> >>> - fi
> >>> - if [ -z "$s" ]; then
> >>> - s="$i"
> >>> - else
> >>> - s="$s $i"
> >>> - fi
> >>> - done
> >>> -
> >>> - ret=0
> >>> - log "CMD" "$s"
> >>> - "$@" || ret=$?
> >>> - if [ "$ret" != "0" ]; then
> >>> - log "CMD" "previous command returned $ret"
> >>> - fi
> >>> -
> >>> - return $ret
> >>> -}
> >>> -
> >>> -# redirect or copy stderr/stdout to a file
> >>> -# the syntax is unfamiliar, but it makes the rest of the
> >>> -# code easier to read, avoiding the use of pipes
> >>> -set_log_file() {
> >>> - # save original stdout and stderr in fd 3 and 4
> >>> - exec 3>&1
> >>> - exec 4>&2
> >>> - # create a new fd 5 that send to a file
> >>> - exec 5> >(cat > $1)
> >>> - # send stdout and stderr to fd 5
> >>> - if [ "${verbose}" = "true" ]; then
> >>> - exec 1> >(tee /dev/fd/5 >&3)
> >>> - exec 2> >(tee /dev/fd/5 >&4)
> >>> - else
> >>> - exec 1>&5
> >>> - exec 2>&5
> >>> - fi
> >>> -}
> >>> -
> >>> -# Make sure we configure SHARED libraries
> >>> -# Also turn off IGB and KNI as those require kernel headers to build
> >>> -fixup_config() {
> >>> - local conf=config/defconfig_$target
> >>> - cmd sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" $conf
> >>> - cmd sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" $conf
> >>> - cmd sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" $conf
> >>> - cmd sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" $conf
> >>> - cmd sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" $conf
> >>> -}
> >>> -
> >>> -# build dpdk for the given tag and dump abi
> >>> -# $1: hash of the revision
> >>> -gen_abi() {
> >>> - local i
> >>> -
> >>> - cmd git clone ${dpdkroot} ${dst}/${1}
> >>> - cmd cd ${dst}/${1}
> >>> -
> >>> - log "INFO" "Checking out version ${1} of the dpdk"
> >>> - # Move to the old version of the tree
> >>> - cmd git checkout ${1}
> >>> -
> >>> - fixup_config
> >>> -
> >>> - # Now configure the build
> >>> - log "INFO" "Configuring DPDK ${1}"
> >>> - cmd make config T=$target O=$target
> >>> -
> >>> - # Checking abi compliance relies on using the dwarf information in
> >>> - # the shared objects. Build with -g to include them.
> >>> - log "INFO" "Building DPDK ${1}. This might take a moment"
> >>> - cmd make -j$parallel O=$target V=1 EXTRA_CFLAGS="-g -Og -Wno-error" \
> >>> - EXTRA_LDFLAGS="-g" || log "INFO" "The build failed"
> >>> -
> >>> - # Move to the lib directory
> >>> - cmd cd ${PWD}/$target/lib
> >>> - log "INFO" "Collecting ABI information for ${1}"
> >>> - for i in *.so; do
> >>> - [ -e "$i" ] || break
> >>> - cmd $abidump ${i} -o $dst/${1}/${i}.dump -lver ${1} || true
> >>> - # hack to ignore empty SymbolsInfo section (no public ABI)
> >>> - if grep -q "'SymbolInfo' => {}," $dst/${1}/${i}.dump \
> >>> - 2> /dev/null; then
> >>> - log "INFO" "${i} has no public ABI, remove dump file"
> >>> - cmd rm -f $dst/${1}/${i}.dump
> >>> - fi
> >>> - done
> >>> -}
> >>> -
> >>> -verbose=false
> >>> -parallel=1
> >>> -dst=${default_dst}
> >>> -target=${default_target}
> >>> -force=0
> >>> -while getopts j:vd:t:fh ARG ; do
> >>> - case $ARG in
> >>> - j ) parallel=$OPTARG ;;
> >>> - v ) verbose=true ;;
> >>> - d ) dst=$OPTARG ;;
> >>> - t ) target=$OPTARG ;;
> >>> - f ) force=1 ;;
> >>> - h ) print_usage ; exit 0 ;;
> >>> - ? ) print_usage ; exit 1 ;;
> >>> - esac
> >>> -done
> >>> -shift $(($OPTIND - 1))
> >>> -
> >>> -if [ $# != 2 ]; then
> >>> - print_usage
> >>> - exit 1
> >>> -fi
> >>> -
> >>> -tag1=$1
> >>> -tag2=$2
> >>> -
> >>> -# convert path to absolute
> >>> -case "${dst}" in
> >>> - /*) ;;
> >>> - *) dst=${PWD}/${dst} ;;
> >>> -esac
> >>> -dpdkroot=$(readlink -f $(dirname $0)/..)
> >>> -
> >>> -if [ -e "${dst}" -a "$force" = 0 ]; then
> >>> - echo "The ${dst} directory is not empty. Remove it, use another"
> >>> - echo "one (-d <dir>), or force overriding (-f)"
> >>> - exit 1
> >>> -fi
> >>> -
> >>> -rm -rf ${dst}
> >>> -mkdir -p ${dst}
> >>> -set_log_file ${dst}/abi-check.log
> >>> -log "INFO" "Logs available in ${dst}/abi-check.log"
> >>> -
> >>> -command -v ${abicheck} || log "INFO" "Can't find ${abicheck} utility"
> >>> -command -v ${abidump} || log "INFO" "Can't find ${abidump} utility"
> >>> -
> >>> -hash1=$(git show -s --format=%h "$tag1" -- 2> /dev/null | tail -1)
> >>> -hash2=$(git show -s --format=%h "$tag2" -- 2> /dev/null | tail -1)
> >>> -
> >>> -# Make hashes available in output for non-local reference
> >>> -tag1="$tag1 ($hash1)"
> >>> -tag2="$tag2 ($hash2)"
> >>> -
> >>> -if [ "$hash1" = "$hash2" ]; then
> >>> - log "ERROR" "$tag1 and $tag2 are the same revisions"
> >>> - exit 1
> >>> -fi
> >>> -
> >>> -cmd mkdir -p ${dst}
> >>> -
> >>> -# dump abi for each revision
> >>> -gen_abi ${hash1}
> >>> -gen_abi ${hash2}
> >>> -
> >>> -# compare the abi dumps
> >>> -cmd cd ${dst}
> >>> -ret=0
> >>> -list=""
> >>> -for i in ${hash2}/*.dump; do
> >>> - name=`basename $i`
> >>> - libname=${name%.dump}
> >>> -
> >>> - if [ ! -f ${hash1}/$name ]; then
> >>> - log "INFO" "$NAME does not exist in $tag1. skipping..."
> >>> - continue
> >>> - fi
> >>> -
> >>> - local_ret=0
> >>> - cmd $abicheck -l $libname \
> >>> - -old ${hash1}/$name -new ${hash2}/$name || local_ret=$?
> >>> - if [ $local_ret != 0 ]; then
> >>> - log "NOTICE" "$abicheck returned $local_ret"
> >>> - ret=$local_ret
> >>> - list="$list $libname"
> >>> - fi
> >>> -done
> >>> -
> >>> -if [ $ret != 0 ]; then
> >>> - log "NOTICE" "ABI may be incompatible, check reports/logs for details."
> >>> - log "NOTICE" "Incompatible list: $list"
> >>> -else
> >>> - log "NOTICE" "No error detected, ABI is compatible."
> >>> -fi
> >>> -
> >>> -log "INFO" "Logs are in ${dst}/abi-check.log"
> >>> -log "INFO" "HTML reports are in ${dst}/compat_reports directory"
> >>> -
> >>> -exit $ret
> >>> diff --git a/doc/guides/contributing/abi_versioning.rst b/doc/guides/contributing/abi_versioning.rst
> >>> index a21f4e7a4..219823923 100644
> >>> --- a/doc/guides/contributing/abi_versioning.rst
> >>> +++ b/doc/guides/contributing/abi_versioning.rst
> >>> @@ -482,41 +482,27 @@ Running the ABI Validator
> >>> -------------------------
> >>>
> >>> The ``devtools`` directory in the DPDK source tree contains a utility program,
> >>> -``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
> >>> -Compliance Checker
> >>> -<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
> >>> +``check-abi.sh``, for validating the DPDK ABI based on the libabigail `abidiff
> >>> +utility: <https://sourceware.org/libabigail/manual/abidiff.html>`_
> >>>
> >>> -This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
> >>> -utilities which can be installed via a package manager. For example::
> >>> +The syntax of the ``check-abi.sh`` utility is::
> >>>
> >>> - sudo yum install abi-compliance-checker
> >>> - sudo yum install abi-dumper
> >>> + ./devtools/check-abi.sh <refdir> <newdir>
> >>>
> >>> -The syntax of the ``validate-abi.sh`` utility is::
> >>> +Where <refdir> specifies the directory housing the reference build of dpdk, and
> >>> +<newdir> specifies the dpdk build directory to check the abi of
> >>>
> >>> - ./devtools/validate-abi.sh <REV1> <REV2>
> >>> +Example:
> >>> +To compare your build branch to the ABI of the master branch
> >>> +after you have built your branch
> >>>
> >>> -Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
> >>> -https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
> >>> -on the local repo.
> >>> +#. $ cd <path to dpdk src tree>
> >>> +#. $ mkdir ~/ref
> >>> +#. $ git clone --local --no-hardlinks --single-branch -b master . ~/ref
> >>> +#. $ cd ~/ref
> >>> +#. $ cp <path to dpdk src tree from above>/.config ./.config
> >>> +#. $ make defconfig
> >>> +#. $ make
> >>> +#. $ <path to dpdk src tree>/devtools/check-abi.sh ~/ref <path to dpdk src tree>
> >>>
> >>> -For example::
> >>> -
> >>> - # Check between the previous and latest commit:
> >>> - ./devtools/validate-abi.sh HEAD~1 HEAD
> >>> -
> >>> - # Check on a specific compilation target:
> >>> - ./devtools/validate-abi.sh -t x86_64-native-linux-gcc HEAD~1 HEAD
> >>> -
> >>> - # Check between two tags:
> >>> - ./devtools/validate-abi.sh v2.0.0 v2.1.0
> >>> -
> >>> - # Check between git master and local topic-branch "vhost-hacking":
> >>> - ./devtools/validate-abi.sh master vhost-hacking
> >>> -
> >>> -After the validation script completes (it can take a while since it need to
> >>> -compile both tags) it will create compatibility reports in the
> >>> -``./abi-check/compat_report`` directory. Listed incompatibilities can be found
> >>> -as follows::
> >>> -
> >>> - grep -lr Incompatible abi-check/compat_reports/
> >>> +
> >>>
> >>
> >> check-abi.sh appears to be backward step in terms of usability.
> >
> > No, check-abi.sh benefits from a nice integration in build scripts.
> > See below.
> >
> >> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> >> And it will do the build, install, dump and comparison for me.
> >> And it picked up my 20.0.2 - > 21.0 changes no problem.
> >>
> >> With check-abi on the other hand, I need to the build and install myself.
> >> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> >> It silently fails when it doesn't find any ...
> >>
> >> Do I run abi-dumper on the so's myself, or how does it work?
> >
> > check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> > Probably we should document usage in these scripts.
> >
>
> ok in that case, this documentation should reference those scripts instead?
Maybe both?
No strong opinion.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-17 10:20 8% ` Thomas Monjalon
@ 2020-04-17 10:35 4% ` Ray Kinsella
2020-04-17 11:46 4% ` Thomas Monjalon
2020-04-17 11:47 4% ` Ray Kinsella
1 sibling, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-17 10:35 UTC (permalink / raw)
To: Thomas Monjalon, Neil Horman; +Cc: dev, david.marchand
On 17/04/2020 11:20, Thomas Monjalon wrote:
> 17/04/2020 12:11, Ray Kinsella:
>>
>> On 16/04/2020 15:54, Neil Horman wrote:
>>> Since we've moved away from our initial validate-abi.sh script, in
>>> favor of check-abi.sh, which uses libabigail, remove the old script from
>>> the tree, and update the docs accordingly
>>>
>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>>> CC: thomas@monjalon.net
>>> CC: david.marchand@redhat.com
>>> CC: mdr@ashroe.eu
>>> ---
>>> MAINTAINERS | 1 -
>>> devtools/validate-abi.sh | 251 ---------------------
>>> doc/guides/contributing/abi_versioning.rst | 50 ++--
>>> 3 files changed, 18 insertions(+), 284 deletions(-)
>>> delete mode 100755 devtools/validate-abi.sh
>>>
>>> diff --git a/MAINTAINERS b/MAINTAINERS
>>> index 4800f6884..84b633431 100644
>>> --- a/MAINTAINERS
>>> +++ b/MAINTAINERS
>>> @@ -152,7 +152,6 @@ F: devtools/gen-abi.sh
>>> F: devtools/libabigail.abignore
>>> F: devtools/update-abi.sh
>>> F: devtools/update_version_map_abi.py
>>> -F: devtools/validate-abi.sh
>>> F: buildtools/check-experimental-syms.sh
>>> F: buildtools/map-list-symbol.sh
>>>
>>> diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh
>>> deleted file mode 100755
>>> index f64e19d38..000000000
>>> --- a/devtools/validate-abi.sh
>>> +++ /dev/null
>>> @@ -1,251 +0,0 @@
>>> -#!/usr/bin/env bash
>>> -# SPDX-License-Identifier: BSD-3-Clause
>>> -# Copyright(c) 2015 Neil Horman. All rights reserved.
>>> -# Copyright(c) 2017 6WIND S.A.
>>> -# All rights reserved
>>> -
>>> -set -e
>>> -
>>> -abicheck=abi-compliance-checker
>>> -abidump=abi-dumper
>>> -default_dst=abi-check
>>> -default_target=x86_64-native-linuxapp-gcc
>>> -
>>> -# trap on error
>>> -err_report() {
>>> - echo "$0: error at line $1"
>>> -}
>>> -trap 'err_report $LINENO' ERR
>>> -
>>> -print_usage () {
>>> - cat <<- END_OF_HELP
>>> - $(basename $0) [options] <rev1> <rev2>
>>> -
>>> - This script compares the ABI of 2 git revisions of the current
>>> - workspace. The output is a html report and a compilation log.
>>> -
>>> - The objective is to make sure that applications built against
>>> - DSOs from the first revision can still run when executed using
>>> - the DSOs built from the second revision.
>>> -
>>> - <rev1> and <rev2> are git commit id or tags.
>>> -
>>> - Options:
>>> - -h show this help
>>> - -j <num> enable parallel compilation with <num> threads
>>> - -v show compilation logs on the console
>>> - -d <dir> change working directory (default is ${default_dst})
>>> - -t <target> the dpdk target to use (default is ${default_target})
>>> - -f overwrite existing files in destination directory
>>> -
>>> - The script returns 0 on success, or the value of last failing
>>> - call of ${abicheck} (incompatible abi or the tool has run with errors).
>>> - The errors returned by ${abidump} are ignored.
>>> -
>>> - END_OF_HELP
>>> -}
>>> -
>>> -# log in the file, and on stdout if verbose
>>> -# $1: level string
>>> -# $2: string to be logged
>>> -log() {
>>> - echo "$1: $2"
>>> - if [ "${verbose}" != "true" ]; then
>>> - echo "$1: $2" >&3
>>> - fi
>>> -}
>>> -
>>> -# launch a command and log it, taking care of surrounding spaces with quotes
>>> -cmd() {
>>> - local i s whitespace ret
>>> - s=""
>>> - whitespace="[[:space:]]"
>>> - for i in "$@"; do
>>> - if [[ $i =~ $whitespace ]]; then
>>> - i=\"$i\"
>>> - fi
>>> - if [ -z "$s" ]; then
>>> - s="$i"
>>> - else
>>> - s="$s $i"
>>> - fi
>>> - done
>>> -
>>> - ret=0
>>> - log "CMD" "$s"
>>> - "$@" || ret=$?
>>> - if [ "$ret" != "0" ]; then
>>> - log "CMD" "previous command returned $ret"
>>> - fi
>>> -
>>> - return $ret
>>> -}
>>> -
>>> -# redirect or copy stderr/stdout to a file
>>> -# the syntax is unfamiliar, but it makes the rest of the
>>> -# code easier to read, avoiding the use of pipes
>>> -set_log_file() {
>>> - # save original stdout and stderr in fd 3 and 4
>>> - exec 3>&1
>>> - exec 4>&2
>>> - # create a new fd 5 that send to a file
>>> - exec 5> >(cat > $1)
>>> - # send stdout and stderr to fd 5
>>> - if [ "${verbose}" = "true" ]; then
>>> - exec 1> >(tee /dev/fd/5 >&3)
>>> - exec 2> >(tee /dev/fd/5 >&4)
>>> - else
>>> - exec 1>&5
>>> - exec 2>&5
>>> - fi
>>> -}
>>> -
>>> -# Make sure we configure SHARED libraries
>>> -# Also turn off IGB and KNI as those require kernel headers to build
>>> -fixup_config() {
>>> - local conf=config/defconfig_$target
>>> - cmd sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" $conf
>>> - cmd sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" $conf
>>> - cmd sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" $conf
>>> - cmd sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" $conf
>>> - cmd sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" $conf
>>> -}
>>> -
>>> -# build dpdk for the given tag and dump abi
>>> -# $1: hash of the revision
>>> -gen_abi() {
>>> - local i
>>> -
>>> - cmd git clone ${dpdkroot} ${dst}/${1}
>>> - cmd cd ${dst}/${1}
>>> -
>>> - log "INFO" "Checking out version ${1} of the dpdk"
>>> - # Move to the old version of the tree
>>> - cmd git checkout ${1}
>>> -
>>> - fixup_config
>>> -
>>> - # Now configure the build
>>> - log "INFO" "Configuring DPDK ${1}"
>>> - cmd make config T=$target O=$target
>>> -
>>> - # Checking abi compliance relies on using the dwarf information in
>>> - # the shared objects. Build with -g to include them.
>>> - log "INFO" "Building DPDK ${1}. This might take a moment"
>>> - cmd make -j$parallel O=$target V=1 EXTRA_CFLAGS="-g -Og -Wno-error" \
>>> - EXTRA_LDFLAGS="-g" || log "INFO" "The build failed"
>>> -
>>> - # Move to the lib directory
>>> - cmd cd ${PWD}/$target/lib
>>> - log "INFO" "Collecting ABI information for ${1}"
>>> - for i in *.so; do
>>> - [ -e "$i" ] || break
>>> - cmd $abidump ${i} -o $dst/${1}/${i}.dump -lver ${1} || true
>>> - # hack to ignore empty SymbolsInfo section (no public ABI)
>>> - if grep -q "'SymbolInfo' => {}," $dst/${1}/${i}.dump \
>>> - 2> /dev/null; then
>>> - log "INFO" "${i} has no public ABI, remove dump file"
>>> - cmd rm -f $dst/${1}/${i}.dump
>>> - fi
>>> - done
>>> -}
>>> -
>>> -verbose=false
>>> -parallel=1
>>> -dst=${default_dst}
>>> -target=${default_target}
>>> -force=0
>>> -while getopts j:vd:t:fh ARG ; do
>>> - case $ARG in
>>> - j ) parallel=$OPTARG ;;
>>> - v ) verbose=true ;;
>>> - d ) dst=$OPTARG ;;
>>> - t ) target=$OPTARG ;;
>>> - f ) force=1 ;;
>>> - h ) print_usage ; exit 0 ;;
>>> - ? ) print_usage ; exit 1 ;;
>>> - esac
>>> -done
>>> -shift $(($OPTIND - 1))
>>> -
>>> -if [ $# != 2 ]; then
>>> - print_usage
>>> - exit 1
>>> -fi
>>> -
>>> -tag1=$1
>>> -tag2=$2
>>> -
>>> -# convert path to absolute
>>> -case "${dst}" in
>>> - /*) ;;
>>> - *) dst=${PWD}/${dst} ;;
>>> -esac
>>> -dpdkroot=$(readlink -f $(dirname $0)/..)
>>> -
>>> -if [ -e "${dst}" -a "$force" = 0 ]; then
>>> - echo "The ${dst} directory is not empty. Remove it, use another"
>>> - echo "one (-d <dir>), or force overriding (-f)"
>>> - exit 1
>>> -fi
>>> -
>>> -rm -rf ${dst}
>>> -mkdir -p ${dst}
>>> -set_log_file ${dst}/abi-check.log
>>> -log "INFO" "Logs available in ${dst}/abi-check.log"
>>> -
>>> -command -v ${abicheck} || log "INFO" "Can't find ${abicheck} utility"
>>> -command -v ${abidump} || log "INFO" "Can't find ${abidump} utility"
>>> -
>>> -hash1=$(git show -s --format=%h "$tag1" -- 2> /dev/null | tail -1)
>>> -hash2=$(git show -s --format=%h "$tag2" -- 2> /dev/null | tail -1)
>>> -
>>> -# Make hashes available in output for non-local reference
>>> -tag1="$tag1 ($hash1)"
>>> -tag2="$tag2 ($hash2)"
>>> -
>>> -if [ "$hash1" = "$hash2" ]; then
>>> - log "ERROR" "$tag1 and $tag2 are the same revisions"
>>> - exit 1
>>> -fi
>>> -
>>> -cmd mkdir -p ${dst}
>>> -
>>> -# dump abi for each revision
>>> -gen_abi ${hash1}
>>> -gen_abi ${hash2}
>>> -
>>> -# compare the abi dumps
>>> -cmd cd ${dst}
>>> -ret=0
>>> -list=""
>>> -for i in ${hash2}/*.dump; do
>>> - name=`basename $i`
>>> - libname=${name%.dump}
>>> -
>>> - if [ ! -f ${hash1}/$name ]; then
>>> - log "INFO" "$NAME does not exist in $tag1. skipping..."
>>> - continue
>>> - fi
>>> -
>>> - local_ret=0
>>> - cmd $abicheck -l $libname \
>>> - -old ${hash1}/$name -new ${hash2}/$name || local_ret=$?
>>> - if [ $local_ret != 0 ]; then
>>> - log "NOTICE" "$abicheck returned $local_ret"
>>> - ret=$local_ret
>>> - list="$list $libname"
>>> - fi
>>> -done
>>> -
>>> -if [ $ret != 0 ]; then
>>> - log "NOTICE" "ABI may be incompatible, check reports/logs for details."
>>> - log "NOTICE" "Incompatible list: $list"
>>> -else
>>> - log "NOTICE" "No error detected, ABI is compatible."
>>> -fi
>>> -
>>> -log "INFO" "Logs are in ${dst}/abi-check.log"
>>> -log "INFO" "HTML reports are in ${dst}/compat_reports directory"
>>> -
>>> -exit $ret
>>> diff --git a/doc/guides/contributing/abi_versioning.rst b/doc/guides/contributing/abi_versioning.rst
>>> index a21f4e7a4..219823923 100644
>>> --- a/doc/guides/contributing/abi_versioning.rst
>>> +++ b/doc/guides/contributing/abi_versioning.rst
>>> @@ -482,41 +482,27 @@ Running the ABI Validator
>>> -------------------------
>>>
>>> The ``devtools`` directory in the DPDK source tree contains a utility program,
>>> -``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
>>> -Compliance Checker
>>> -<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
>>> +``check-abi.sh``, for validating the DPDK ABI based on the libabigail `abidiff
>>> +utility: <https://sourceware.org/libabigail/manual/abidiff.html>`_
>>>
>>> -This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
>>> -utilities which can be installed via a package manager. For example::
>>> +The syntax of the ``check-abi.sh`` utility is::
>>>
>>> - sudo yum install abi-compliance-checker
>>> - sudo yum install abi-dumper
>>> + ./devtools/check-abi.sh <refdir> <newdir>
>>>
>>> -The syntax of the ``validate-abi.sh`` utility is::
>>> +Where <refdir> specifies the directory housing the reference build of dpdk, and
>>> +<newdir> specifies the dpdk build directory to check the abi of
>>>
>>> - ./devtools/validate-abi.sh <REV1> <REV2>
>>> +Example:
>>> +To compare your build branch to the ABI of the master branch
>>> +after you have built your branch
>>>
>>> -Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
>>> -https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
>>> -on the local repo.
>>> +#. $ cd <path to dpdk src tree>
>>> +#. $ mkdir ~/ref
>>> +#. $ git clone --local --no-hardlinks --single-branch -b master . ~/ref
>>> +#. $ cd ~/ref
>>> +#. $ cp <path to dpdk src tree from above>/.config ./.config
>>> +#. $ make defconfig
>>> +#. $ make
>>> +#. $ <path to dpdk src tree>/devtools/check-abi.sh ~/ref <path to dpdk src tree>
>>>
>>> -For example::
>>> -
>>> - # Check between the previous and latest commit:
>>> - ./devtools/validate-abi.sh HEAD~1 HEAD
>>> -
>>> - # Check on a specific compilation target:
>>> - ./devtools/validate-abi.sh -t x86_64-native-linux-gcc HEAD~1 HEAD
>>> -
>>> - # Check between two tags:
>>> - ./devtools/validate-abi.sh v2.0.0 v2.1.0
>>> -
>>> - # Check between git master and local topic-branch "vhost-hacking":
>>> - ./devtools/validate-abi.sh master vhost-hacking
>>> -
>>> -After the validation script completes (it can take a while since it need to
>>> -compile both tags) it will create compatibility reports in the
>>> -``./abi-check/compat_report`` directory. Listed incompatibilities can be found
>>> -as follows::
>>> -
>>> - grep -lr Incompatible abi-check/compat_reports/
>>> +
>>>
>>
>> check-abi.sh appears to be backward step in terms of usability.
>
> No, check-abi.sh benefits from a nice integration in build scripts.
> See below.
>
>> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
>> And it will do the build, install, dump and comparison for me.
>> And it picked up my 20.0.2 - > 21.0 changes no problem.
>>
>> With check-abi on the other hand, I need to the build and install myself.
>> check-abi requires dump files, but I see no reference in the documentation to how these are created.
>> It silently fails when it doesn't find any ...
>>
>> Do I run abi-dumper on the so's myself, or how does it work?
>
> check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
> Probably we should document usage in these scripts.
>
ok in that case, this documentation should reference those scripts instead?
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-17 10:17 4% ` Thomas Monjalon
@ 2020-04-17 10:33 3% ` Ray Kinsella
2020-04-17 11:46 5% ` Trahe, Fiona
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-17 10:33 UTC (permalink / raw)
To: Thomas Monjalon, Bruce Richardson
Cc: Trahe, Fiona, dev, Kusztal, ArkadiuszX, Neil Horman,
Luca Boccassi, Kevin Traynor, Yigit, Ferruh
On 17/04/2020 11:17, Thomas Monjalon wrote:
> 17/04/2020 11:42, Ray Kinsella:
>> On 17/04/2020 10:31, Bruce Richardson wrote:
>>> On Fri, Apr 17, 2020 at 08:24:30AM +0100, Ray Kinsella wrote:
>>>> On 16/04/2020 11:01, Thomas Monjalon wrote:
>>>>> 16/04/2020 11:51, Bruce Richardson:
>>>>>> On Wed, Apr 15, 2020 at 06:24:19PM +0100, Trahe, Fiona wrote:
>>>>>>> 5a. If in 20.05 we add a version of a fn which breaks ABI 20.0, what should the name of the original function be? fn_v20, or fn_v20.0
>>>>>>
>>>>>> In technical terms it really doesn't matter, it's just a name that will be
>>>>>> looked up in a table. I don't think we strictly enforce the naming, so
>>>>>> whatever is clearest is best. I'd suggest the former.
>>>>>
>>>>> Each release can have a new ABI.
>>>>
>>>> How many ABI's do we want to support?
>>>>
>>> It's not how many we want to support, but for me it's a matter of how many
>>> do we need to support. If an API is part of the stable set, it can't just
>>> drop to being experimental for one or two releases - it's always stable
>>> until deprecated. We also shouldn't have a situation where release 20.08 is
>>> ABI compatible with 19.11 but not 20.02 and 20.05.
>>
>> True. Let me say it differently.
>>
>> Our only commitment is to support v20 - 19.11
>> However you are correct, if something gets committed as v21 in 20.02, in practise should also be there in 20.05+ also.
>> Because if it is committed as v21 and not as experimental, it should not be changing once committed.
>>
>> In answering Thomas,
>> I was more commenting on the proliferation of ABI numbers & symbols we need to track in the build.
>> With v20, v21 & Experimental we need to keep track of 3.
>> If we start allowing quarterly builds to have managed ABI's, it will get confusing.
>
> I don't remember why we are using intermediate ABI versions
> between v20 and v21.
> If we can use v21 for new ABI and make sure compatibility is maintained
> between all versions from 19.11 to 20.08, I'm fine.
>
Well I guess we missed this in 20.02, so I recommend that we fix in 20.05.
It will mean that a couple of symbols versioned 20.0.2 in DPDK 20.02,
Will becomes 21.0 in DPDK 20.05 ... ABI checker will complain.
Apart from that I doubt anyone will notice?
Ray K
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
2020-04-17 10:11 9% ` Ray Kinsella
@ 2020-04-17 10:20 8% ` Thomas Monjalon
2020-04-17 10:35 4% ` Ray Kinsella
2020-04-17 11:47 4% ` Ray Kinsella
0 siblings, 2 replies; 200+ results
From: Thomas Monjalon @ 2020-04-17 10:20 UTC (permalink / raw)
To: Neil Horman, Ray Kinsella; +Cc: dev, david.marchand
17/04/2020 12:11, Ray Kinsella:
>
> On 16/04/2020 15:54, Neil Horman wrote:
> > Since we've moved away from our initial validate-abi.sh script, in
> > favor of check-abi.sh, which uses libabigail, remove the old script from
> > the tree, and update the docs accordingly
> >
> > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > CC: thomas@monjalon.net
> > CC: david.marchand@redhat.com
> > CC: mdr@ashroe.eu
> > ---
> > MAINTAINERS | 1 -
> > devtools/validate-abi.sh | 251 ---------------------
> > doc/guides/contributing/abi_versioning.rst | 50 ++--
> > 3 files changed, 18 insertions(+), 284 deletions(-)
> > delete mode 100755 devtools/validate-abi.sh
> >
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index 4800f6884..84b633431 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -152,7 +152,6 @@ F: devtools/gen-abi.sh
> > F: devtools/libabigail.abignore
> > F: devtools/update-abi.sh
> > F: devtools/update_version_map_abi.py
> > -F: devtools/validate-abi.sh
> > F: buildtools/check-experimental-syms.sh
> > F: buildtools/map-list-symbol.sh
> >
> > diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh
> > deleted file mode 100755
> > index f64e19d38..000000000
> > --- a/devtools/validate-abi.sh
> > +++ /dev/null
> > @@ -1,251 +0,0 @@
> > -#!/usr/bin/env bash
> > -# SPDX-License-Identifier: BSD-3-Clause
> > -# Copyright(c) 2015 Neil Horman. All rights reserved.
> > -# Copyright(c) 2017 6WIND S.A.
> > -# All rights reserved
> > -
> > -set -e
> > -
> > -abicheck=abi-compliance-checker
> > -abidump=abi-dumper
> > -default_dst=abi-check
> > -default_target=x86_64-native-linuxapp-gcc
> > -
> > -# trap on error
> > -err_report() {
> > - echo "$0: error at line $1"
> > -}
> > -trap 'err_report $LINENO' ERR
> > -
> > -print_usage () {
> > - cat <<- END_OF_HELP
> > - $(basename $0) [options] <rev1> <rev2>
> > -
> > - This script compares the ABI of 2 git revisions of the current
> > - workspace. The output is a html report and a compilation log.
> > -
> > - The objective is to make sure that applications built against
> > - DSOs from the first revision can still run when executed using
> > - the DSOs built from the second revision.
> > -
> > - <rev1> and <rev2> are git commit id or tags.
> > -
> > - Options:
> > - -h show this help
> > - -j <num> enable parallel compilation with <num> threads
> > - -v show compilation logs on the console
> > - -d <dir> change working directory (default is ${default_dst})
> > - -t <target> the dpdk target to use (default is ${default_target})
> > - -f overwrite existing files in destination directory
> > -
> > - The script returns 0 on success, or the value of last failing
> > - call of ${abicheck} (incompatible abi or the tool has run with errors).
> > - The errors returned by ${abidump} are ignored.
> > -
> > - END_OF_HELP
> > -}
> > -
> > -# log in the file, and on stdout if verbose
> > -# $1: level string
> > -# $2: string to be logged
> > -log() {
> > - echo "$1: $2"
> > - if [ "${verbose}" != "true" ]; then
> > - echo "$1: $2" >&3
> > - fi
> > -}
> > -
> > -# launch a command and log it, taking care of surrounding spaces with quotes
> > -cmd() {
> > - local i s whitespace ret
> > - s=""
> > - whitespace="[[:space:]]"
> > - for i in "$@"; do
> > - if [[ $i =~ $whitespace ]]; then
> > - i=\"$i\"
> > - fi
> > - if [ -z "$s" ]; then
> > - s="$i"
> > - else
> > - s="$s $i"
> > - fi
> > - done
> > -
> > - ret=0
> > - log "CMD" "$s"
> > - "$@" || ret=$?
> > - if [ "$ret" != "0" ]; then
> > - log "CMD" "previous command returned $ret"
> > - fi
> > -
> > - return $ret
> > -}
> > -
> > -# redirect or copy stderr/stdout to a file
> > -# the syntax is unfamiliar, but it makes the rest of the
> > -# code easier to read, avoiding the use of pipes
> > -set_log_file() {
> > - # save original stdout and stderr in fd 3 and 4
> > - exec 3>&1
> > - exec 4>&2
> > - # create a new fd 5 that send to a file
> > - exec 5> >(cat > $1)
> > - # send stdout and stderr to fd 5
> > - if [ "${verbose}" = "true" ]; then
> > - exec 1> >(tee /dev/fd/5 >&3)
> > - exec 2> >(tee /dev/fd/5 >&4)
> > - else
> > - exec 1>&5
> > - exec 2>&5
> > - fi
> > -}
> > -
> > -# Make sure we configure SHARED libraries
> > -# Also turn off IGB and KNI as those require kernel headers to build
> > -fixup_config() {
> > - local conf=config/defconfig_$target
> > - cmd sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" $conf
> > - cmd sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" $conf
> > - cmd sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" $conf
> > - cmd sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" $conf
> > - cmd sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" $conf
> > -}
> > -
> > -# build dpdk for the given tag and dump abi
> > -# $1: hash of the revision
> > -gen_abi() {
> > - local i
> > -
> > - cmd git clone ${dpdkroot} ${dst}/${1}
> > - cmd cd ${dst}/${1}
> > -
> > - log "INFO" "Checking out version ${1} of the dpdk"
> > - # Move to the old version of the tree
> > - cmd git checkout ${1}
> > -
> > - fixup_config
> > -
> > - # Now configure the build
> > - log "INFO" "Configuring DPDK ${1}"
> > - cmd make config T=$target O=$target
> > -
> > - # Checking abi compliance relies on using the dwarf information in
> > - # the shared objects. Build with -g to include them.
> > - log "INFO" "Building DPDK ${1}. This might take a moment"
> > - cmd make -j$parallel O=$target V=1 EXTRA_CFLAGS="-g -Og -Wno-error" \
> > - EXTRA_LDFLAGS="-g" || log "INFO" "The build failed"
> > -
> > - # Move to the lib directory
> > - cmd cd ${PWD}/$target/lib
> > - log "INFO" "Collecting ABI information for ${1}"
> > - for i in *.so; do
> > - [ -e "$i" ] || break
> > - cmd $abidump ${i} -o $dst/${1}/${i}.dump -lver ${1} || true
> > - # hack to ignore empty SymbolsInfo section (no public ABI)
> > - if grep -q "'SymbolInfo' => {}," $dst/${1}/${i}.dump \
> > - 2> /dev/null; then
> > - log "INFO" "${i} has no public ABI, remove dump file"
> > - cmd rm -f $dst/${1}/${i}.dump
> > - fi
> > - done
> > -}
> > -
> > -verbose=false
> > -parallel=1
> > -dst=${default_dst}
> > -target=${default_target}
> > -force=0
> > -while getopts j:vd:t:fh ARG ; do
> > - case $ARG in
> > - j ) parallel=$OPTARG ;;
> > - v ) verbose=true ;;
> > - d ) dst=$OPTARG ;;
> > - t ) target=$OPTARG ;;
> > - f ) force=1 ;;
> > - h ) print_usage ; exit 0 ;;
> > - ? ) print_usage ; exit 1 ;;
> > - esac
> > -done
> > -shift $(($OPTIND - 1))
> > -
> > -if [ $# != 2 ]; then
> > - print_usage
> > - exit 1
> > -fi
> > -
> > -tag1=$1
> > -tag2=$2
> > -
> > -# convert path to absolute
> > -case "${dst}" in
> > - /*) ;;
> > - *) dst=${PWD}/${dst} ;;
> > -esac
> > -dpdkroot=$(readlink -f $(dirname $0)/..)
> > -
> > -if [ -e "${dst}" -a "$force" = 0 ]; then
> > - echo "The ${dst} directory is not empty. Remove it, use another"
> > - echo "one (-d <dir>), or force overriding (-f)"
> > - exit 1
> > -fi
> > -
> > -rm -rf ${dst}
> > -mkdir -p ${dst}
> > -set_log_file ${dst}/abi-check.log
> > -log "INFO" "Logs available in ${dst}/abi-check.log"
> > -
> > -command -v ${abicheck} || log "INFO" "Can't find ${abicheck} utility"
> > -command -v ${abidump} || log "INFO" "Can't find ${abidump} utility"
> > -
> > -hash1=$(git show -s --format=%h "$tag1" -- 2> /dev/null | tail -1)
> > -hash2=$(git show -s --format=%h "$tag2" -- 2> /dev/null | tail -1)
> > -
> > -# Make hashes available in output for non-local reference
> > -tag1="$tag1 ($hash1)"
> > -tag2="$tag2 ($hash2)"
> > -
> > -if [ "$hash1" = "$hash2" ]; then
> > - log "ERROR" "$tag1 and $tag2 are the same revisions"
> > - exit 1
> > -fi
> > -
> > -cmd mkdir -p ${dst}
> > -
> > -# dump abi for each revision
> > -gen_abi ${hash1}
> > -gen_abi ${hash2}
> > -
> > -# compare the abi dumps
> > -cmd cd ${dst}
> > -ret=0
> > -list=""
> > -for i in ${hash2}/*.dump; do
> > - name=`basename $i`
> > - libname=${name%.dump}
> > -
> > - if [ ! -f ${hash1}/$name ]; then
> > - log "INFO" "$NAME does not exist in $tag1. skipping..."
> > - continue
> > - fi
> > -
> > - local_ret=0
> > - cmd $abicheck -l $libname \
> > - -old ${hash1}/$name -new ${hash2}/$name || local_ret=$?
> > - if [ $local_ret != 0 ]; then
> > - log "NOTICE" "$abicheck returned $local_ret"
> > - ret=$local_ret
> > - list="$list $libname"
> > - fi
> > -done
> > -
> > -if [ $ret != 0 ]; then
> > - log "NOTICE" "ABI may be incompatible, check reports/logs for details."
> > - log "NOTICE" "Incompatible list: $list"
> > -else
> > - log "NOTICE" "No error detected, ABI is compatible."
> > -fi
> > -
> > -log "INFO" "Logs are in ${dst}/abi-check.log"
> > -log "INFO" "HTML reports are in ${dst}/compat_reports directory"
> > -
> > -exit $ret
> > diff --git a/doc/guides/contributing/abi_versioning.rst b/doc/guides/contributing/abi_versioning.rst
> > index a21f4e7a4..219823923 100644
> > --- a/doc/guides/contributing/abi_versioning.rst
> > +++ b/doc/guides/contributing/abi_versioning.rst
> > @@ -482,41 +482,27 @@ Running the ABI Validator
> > -------------------------
> >
> > The ``devtools`` directory in the DPDK source tree contains a utility program,
> > -``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
> > -Compliance Checker
> > -<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
> > +``check-abi.sh``, for validating the DPDK ABI based on the libabigail `abidiff
> > +utility: <https://sourceware.org/libabigail/manual/abidiff.html>`_
> >
> > -This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
> > -utilities which can be installed via a package manager. For example::
> > +The syntax of the ``check-abi.sh`` utility is::
> >
> > - sudo yum install abi-compliance-checker
> > - sudo yum install abi-dumper
> > + ./devtools/check-abi.sh <refdir> <newdir>
> >
> > -The syntax of the ``validate-abi.sh`` utility is::
> > +Where <refdir> specifies the directory housing the reference build of dpdk, and
> > +<newdir> specifies the dpdk build directory to check the abi of
> >
> > - ./devtools/validate-abi.sh <REV1> <REV2>
> > +Example:
> > +To compare your build branch to the ABI of the master branch
> > +after you have built your branch
> >
> > -Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
> > -https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
> > -on the local repo.
> > +#. $ cd <path to dpdk src tree>
> > +#. $ mkdir ~/ref
> > +#. $ git clone --local --no-hardlinks --single-branch -b master . ~/ref
> > +#. $ cd ~/ref
> > +#. $ cp <path to dpdk src tree from above>/.config ./.config
> > +#. $ make defconfig
> > +#. $ make
> > +#. $ <path to dpdk src tree>/devtools/check-abi.sh ~/ref <path to dpdk src tree>
> >
> > -For example::
> > -
> > - # Check between the previous and latest commit:
> > - ./devtools/validate-abi.sh HEAD~1 HEAD
> > -
> > - # Check on a specific compilation target:
> > - ./devtools/validate-abi.sh -t x86_64-native-linux-gcc HEAD~1 HEAD
> > -
> > - # Check between two tags:
> > - ./devtools/validate-abi.sh v2.0.0 v2.1.0
> > -
> > - # Check between git master and local topic-branch "vhost-hacking":
> > - ./devtools/validate-abi.sh master vhost-hacking
> > -
> > -After the validation script completes (it can take a while since it need to
> > -compile both tags) it will create compatibility reports in the
> > -``./abi-check/compat_report`` directory. Listed incompatibilities can be found
> > -as follows::
> > -
> > - grep -lr Incompatible abi-check/compat_reports/
> > +
> >
>
> check-abi.sh appears to be backward step in terms of usability.
No, check-abi.sh benefits from a nice integration in build scripts.
See below.
> With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
> And it will do the build, install, dump and comparison for me.
> And it picked up my 20.0.2 - > 21.0 changes no problem.
>
> With check-abi on the other hand, I need to the build and install myself.
> check-abi requires dump files, but I see no reference in the documentation to how these are created.
> It silently fails when it doesn't find any ...
>
> Do I run abi-dumper on the so's myself, or how does it work?
check-abi.sh is integrated in test-build.sh and test-meson-builds.sh.
Probably we should document usage in these scripts.
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-17 9:42 3% ` Ray Kinsella
@ 2020-04-17 10:17 4% ` Thomas Monjalon
2020-04-17 10:33 3% ` Ray Kinsella
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2020-04-17 10:17 UTC (permalink / raw)
To: Bruce Richardson, Ray Kinsella
Cc: Trahe, Fiona, dev, Kusztal, ArkadiuszX, Neil Horman,
Luca Boccassi, Kevin Traynor, Yigit, Ferruh
17/04/2020 11:42, Ray Kinsella:
> On 17/04/2020 10:31, Bruce Richardson wrote:
> > On Fri, Apr 17, 2020 at 08:24:30AM +0100, Ray Kinsella wrote:
> >> On 16/04/2020 11:01, Thomas Monjalon wrote:
> >>> 16/04/2020 11:51, Bruce Richardson:
> >>>> On Wed, Apr 15, 2020 at 06:24:19PM +0100, Trahe, Fiona wrote:
> >>>>> 5a. If in 20.05 we add a version of a fn which breaks ABI 20.0, what should the name of the original function be? fn_v20, or fn_v20.0
> >>>>
> >>>> In technical terms it really doesn't matter, it's just a name that will be
> >>>> looked up in a table. I don't think we strictly enforce the naming, so
> >>>> whatever is clearest is best. I'd suggest the former.
> >>>
> >>> Each release can have a new ABI.
> >>
> >> How many ABI's do we want to support?
> >>
> > It's not how many we want to support, but for me it's a matter of how many
> > do we need to support. If an API is part of the stable set, it can't just
> > drop to being experimental for one or two releases - it's always stable
> > until deprecated. We also shouldn't have a situation where release 20.08 is
> > ABI compatible with 19.11 but not 20.02 and 20.05.
>
> True. Let me say it differently.
>
> Our only commitment is to support v20 - 19.11
> However you are correct, if something gets committed as v21 in 20.02, in practise should also be there in 20.05+ also.
> Because if it is committed as v21 and not as experimental, it should not be changing once committed.
>
> In answering Thomas,
> I was more commenting on the proliferation of ABI numbers & symbols we need to track in the build.
> With v20, v21 & Experimental we need to keep track of 3.
> If we start allowing quarterly builds to have managed ABI's, it will get confusing.
I don't remember why we are using intermediate ABI versions
between v20 and v21.
If we can use v21 for new ABI and make sure compatibility is maintained
between all versions from 19.11 to 20.08, I'm fine.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree
@ 2020-04-17 10:11 9% ` Ray Kinsella
2020-04-17 10:20 8% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-17 10:11 UTC (permalink / raw)
To: Neil Horman, dev; +Cc: thomas, david.marchand
On 16/04/2020 15:54, Neil Horman wrote:
> Since we've moved away from our initial validate-abi.sh script, in
> favor of check-abi.sh, which uses libabigail, remove the old script from
> the tree, and update the docs accordingly
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: thomas@monjalon.net
> CC: david.marchand@redhat.com
> CC: mdr@ashroe.eu
> ---
> MAINTAINERS | 1 -
> devtools/validate-abi.sh | 251 ---------------------
> doc/guides/contributing/abi_versioning.rst | 50 ++--
> 3 files changed, 18 insertions(+), 284 deletions(-)
> delete mode 100755 devtools/validate-abi.sh
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 4800f6884..84b633431 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -152,7 +152,6 @@ F: devtools/gen-abi.sh
> F: devtools/libabigail.abignore
> F: devtools/update-abi.sh
> F: devtools/update_version_map_abi.py
> -F: devtools/validate-abi.sh
> F: buildtools/check-experimental-syms.sh
> F: buildtools/map-list-symbol.sh
>
> diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh
> deleted file mode 100755
> index f64e19d38..000000000
> --- a/devtools/validate-abi.sh
> +++ /dev/null
> @@ -1,251 +0,0 @@
> -#!/usr/bin/env bash
> -# SPDX-License-Identifier: BSD-3-Clause
> -# Copyright(c) 2015 Neil Horman. All rights reserved.
> -# Copyright(c) 2017 6WIND S.A.
> -# All rights reserved
> -
> -set -e
> -
> -abicheck=abi-compliance-checker
> -abidump=abi-dumper
> -default_dst=abi-check
> -default_target=x86_64-native-linuxapp-gcc
> -
> -# trap on error
> -err_report() {
> - echo "$0: error at line $1"
> -}
> -trap 'err_report $LINENO' ERR
> -
> -print_usage () {
> - cat <<- END_OF_HELP
> - $(basename $0) [options] <rev1> <rev2>
> -
> - This script compares the ABI of 2 git revisions of the current
> - workspace. The output is a html report and a compilation log.
> -
> - The objective is to make sure that applications built against
> - DSOs from the first revision can still run when executed using
> - the DSOs built from the second revision.
> -
> - <rev1> and <rev2> are git commit id or tags.
> -
> - Options:
> - -h show this help
> - -j <num> enable parallel compilation with <num> threads
> - -v show compilation logs on the console
> - -d <dir> change working directory (default is ${default_dst})
> - -t <target> the dpdk target to use (default is ${default_target})
> - -f overwrite existing files in destination directory
> -
> - The script returns 0 on success, or the value of last failing
> - call of ${abicheck} (incompatible abi or the tool has run with errors).
> - The errors returned by ${abidump} are ignored.
> -
> - END_OF_HELP
> -}
> -
> -# log in the file, and on stdout if verbose
> -# $1: level string
> -# $2: string to be logged
> -log() {
> - echo "$1: $2"
> - if [ "${verbose}" != "true" ]; then
> - echo "$1: $2" >&3
> - fi
> -}
> -
> -# launch a command and log it, taking care of surrounding spaces with quotes
> -cmd() {
> - local i s whitespace ret
> - s=""
> - whitespace="[[:space:]]"
> - for i in "$@"; do
> - if [[ $i =~ $whitespace ]]; then
> - i=\"$i\"
> - fi
> - if [ -z "$s" ]; then
> - s="$i"
> - else
> - s="$s $i"
> - fi
> - done
> -
> - ret=0
> - log "CMD" "$s"
> - "$@" || ret=$?
> - if [ "$ret" != "0" ]; then
> - log "CMD" "previous command returned $ret"
> - fi
> -
> - return $ret
> -}
> -
> -# redirect or copy stderr/stdout to a file
> -# the syntax is unfamiliar, but it makes the rest of the
> -# code easier to read, avoiding the use of pipes
> -set_log_file() {
> - # save original stdout and stderr in fd 3 and 4
> - exec 3>&1
> - exec 4>&2
> - # create a new fd 5 that send to a file
> - exec 5> >(cat > $1)
> - # send stdout and stderr to fd 5
> - if [ "${verbose}" = "true" ]; then
> - exec 1> >(tee /dev/fd/5 >&3)
> - exec 2> >(tee /dev/fd/5 >&4)
> - else
> - exec 1>&5
> - exec 2>&5
> - fi
> -}
> -
> -# Make sure we configure SHARED libraries
> -# Also turn off IGB and KNI as those require kernel headers to build
> -fixup_config() {
> - local conf=config/defconfig_$target
> - cmd sed -i -e"$ a\CONFIG_RTE_BUILD_SHARED_LIB=y" $conf
> - cmd sed -i -e"$ a\CONFIG_RTE_NEXT_ABI=n" $conf
> - cmd sed -i -e"$ a\CONFIG_RTE_EAL_IGB_UIO=n" $conf
> - cmd sed -i -e"$ a\CONFIG_RTE_LIBRTE_KNI=n" $conf
> - cmd sed -i -e"$ a\CONFIG_RTE_KNI_KMOD=n" $conf
> -}
> -
> -# build dpdk for the given tag and dump abi
> -# $1: hash of the revision
> -gen_abi() {
> - local i
> -
> - cmd git clone ${dpdkroot} ${dst}/${1}
> - cmd cd ${dst}/${1}
> -
> - log "INFO" "Checking out version ${1} of the dpdk"
> - # Move to the old version of the tree
> - cmd git checkout ${1}
> -
> - fixup_config
> -
> - # Now configure the build
> - log "INFO" "Configuring DPDK ${1}"
> - cmd make config T=$target O=$target
> -
> - # Checking abi compliance relies on using the dwarf information in
> - # the shared objects. Build with -g to include them.
> - log "INFO" "Building DPDK ${1}. This might take a moment"
> - cmd make -j$parallel O=$target V=1 EXTRA_CFLAGS="-g -Og -Wno-error" \
> - EXTRA_LDFLAGS="-g" || log "INFO" "The build failed"
> -
> - # Move to the lib directory
> - cmd cd ${PWD}/$target/lib
> - log "INFO" "Collecting ABI information for ${1}"
> - for i in *.so; do
> - [ -e "$i" ] || break
> - cmd $abidump ${i} -o $dst/${1}/${i}.dump -lver ${1} || true
> - # hack to ignore empty SymbolsInfo section (no public ABI)
> - if grep -q "'SymbolInfo' => {}," $dst/${1}/${i}.dump \
> - 2> /dev/null; then
> - log "INFO" "${i} has no public ABI, remove dump file"
> - cmd rm -f $dst/${1}/${i}.dump
> - fi
> - done
> -}
> -
> -verbose=false
> -parallel=1
> -dst=${default_dst}
> -target=${default_target}
> -force=0
> -while getopts j:vd:t:fh ARG ; do
> - case $ARG in
> - j ) parallel=$OPTARG ;;
> - v ) verbose=true ;;
> - d ) dst=$OPTARG ;;
> - t ) target=$OPTARG ;;
> - f ) force=1 ;;
> - h ) print_usage ; exit 0 ;;
> - ? ) print_usage ; exit 1 ;;
> - esac
> -done
> -shift $(($OPTIND - 1))
> -
> -if [ $# != 2 ]; then
> - print_usage
> - exit 1
> -fi
> -
> -tag1=$1
> -tag2=$2
> -
> -# convert path to absolute
> -case "${dst}" in
> - /*) ;;
> - *) dst=${PWD}/${dst} ;;
> -esac
> -dpdkroot=$(readlink -f $(dirname $0)/..)
> -
> -if [ -e "${dst}" -a "$force" = 0 ]; then
> - echo "The ${dst} directory is not empty. Remove it, use another"
> - echo "one (-d <dir>), or force overriding (-f)"
> - exit 1
> -fi
> -
> -rm -rf ${dst}
> -mkdir -p ${dst}
> -set_log_file ${dst}/abi-check.log
> -log "INFO" "Logs available in ${dst}/abi-check.log"
> -
> -command -v ${abicheck} || log "INFO" "Can't find ${abicheck} utility"
> -command -v ${abidump} || log "INFO" "Can't find ${abidump} utility"
> -
> -hash1=$(git show -s --format=%h "$tag1" -- 2> /dev/null | tail -1)
> -hash2=$(git show -s --format=%h "$tag2" -- 2> /dev/null | tail -1)
> -
> -# Make hashes available in output for non-local reference
> -tag1="$tag1 ($hash1)"
> -tag2="$tag2 ($hash2)"
> -
> -if [ "$hash1" = "$hash2" ]; then
> - log "ERROR" "$tag1 and $tag2 are the same revisions"
> - exit 1
> -fi
> -
> -cmd mkdir -p ${dst}
> -
> -# dump abi for each revision
> -gen_abi ${hash1}
> -gen_abi ${hash2}
> -
> -# compare the abi dumps
> -cmd cd ${dst}
> -ret=0
> -list=""
> -for i in ${hash2}/*.dump; do
> - name=`basename $i`
> - libname=${name%.dump}
> -
> - if [ ! -f ${hash1}/$name ]; then
> - log "INFO" "$NAME does not exist in $tag1. skipping..."
> - continue
> - fi
> -
> - local_ret=0
> - cmd $abicheck -l $libname \
> - -old ${hash1}/$name -new ${hash2}/$name || local_ret=$?
> - if [ $local_ret != 0 ]; then
> - log "NOTICE" "$abicheck returned $local_ret"
> - ret=$local_ret
> - list="$list $libname"
> - fi
> -done
> -
> -if [ $ret != 0 ]; then
> - log "NOTICE" "ABI may be incompatible, check reports/logs for details."
> - log "NOTICE" "Incompatible list: $list"
> -else
> - log "NOTICE" "No error detected, ABI is compatible."
> -fi
> -
> -log "INFO" "Logs are in ${dst}/abi-check.log"
> -log "INFO" "HTML reports are in ${dst}/compat_reports directory"
> -
> -exit $ret
> diff --git a/doc/guides/contributing/abi_versioning.rst b/doc/guides/contributing/abi_versioning.rst
> index a21f4e7a4..219823923 100644
> --- a/doc/guides/contributing/abi_versioning.rst
> +++ b/doc/guides/contributing/abi_versioning.rst
> @@ -482,41 +482,27 @@ Running the ABI Validator
> -------------------------
>
> The ``devtools`` directory in the DPDK source tree contains a utility program,
> -``validate-abi.sh``, for validating the DPDK ABI based on the Linux `ABI
> -Compliance Checker
> -<http://ispras.linuxbase.org/index.php/ABI_compliance_checker>`_.
> +``check-abi.sh``, for validating the DPDK ABI based on the libabigail `abidiff
> +utility: <https://sourceware.org/libabigail/manual/abidiff.html>`_
>
> -This has a dependency on the ``abi-compliance-checker`` and ``and abi-dumper``
> -utilities which can be installed via a package manager. For example::
> +The syntax of the ``check-abi.sh`` utility is::
>
> - sudo yum install abi-compliance-checker
> - sudo yum install abi-dumper
> + ./devtools/check-abi.sh <refdir> <newdir>
>
> -The syntax of the ``validate-abi.sh`` utility is::
> +Where <refdir> specifies the directory housing the reference build of dpdk, and
> +<newdir> specifies the dpdk build directory to check the abi of
>
> - ./devtools/validate-abi.sh <REV1> <REV2>
> +Example:
> +To compare your build branch to the ABI of the master branch
> +after you have built your branch
>
> -Where ``REV1`` and ``REV2`` are valid gitrevisions(7)
> -https://www.kernel.org/pub/software/scm/git/docs/gitrevisions.html
> -on the local repo.
> +#. $ cd <path to dpdk src tree>
> +#. $ mkdir ~/ref
> +#. $ git clone --local --no-hardlinks --single-branch -b master . ~/ref
> +#. $ cd ~/ref
> +#. $ cp <path to dpdk src tree from above>/.config ./.config
> +#. $ make defconfig
> +#. $ make
> +#. $ <path to dpdk src tree>/devtools/check-abi.sh ~/ref <path to dpdk src tree>
>
> -For example::
> -
> - # Check between the previous and latest commit:
> - ./devtools/validate-abi.sh HEAD~1 HEAD
> -
> - # Check on a specific compilation target:
> - ./devtools/validate-abi.sh -t x86_64-native-linux-gcc HEAD~1 HEAD
> -
> - # Check between two tags:
> - ./devtools/validate-abi.sh v2.0.0 v2.1.0
> -
> - # Check between git master and local topic-branch "vhost-hacking":
> - ./devtools/validate-abi.sh master vhost-hacking
> -
> -After the validation script completes (it can take a while since it need to
> -compile both tags) it will create compatibility reports in the
> -``./abi-check/compat_report`` directory. Listed incompatibilities can be found
> -as follows::
> -
> - grep -lr Incompatible abi-check/compat_reports/
> +
>
check-abi.sh appears to be backward step in terms of usability.
With validate-abi.sh I do can do a "validate-abi.sh HEAD~1 HEAD".
And it will do the build, install, dump and comparison for me.
And it picked up my 20.0.2 - > 21.0 changes no problem.
With check-abi on the other hand, I need to the build and install myself.
check-abi requires dump files, but I see no reference in the documentation to how these are created.
It silently fails when it doesn't find any ...
Do I run abi-dumper on the so's myself, or how does it work?
^ permalink raw reply [relevance 9%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-17 9:31 4% ` Bruce Richardson
@ 2020-04-17 9:42 3% ` Ray Kinsella
2020-04-17 10:17 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-17 9:42 UTC (permalink / raw)
To: Bruce Richardson
Cc: Thomas Monjalon, Trahe, Fiona, dev, Kusztal, ArkadiuszX,
Neil Horman, Luca Boccassi, Kevin Traynor, Yigit, Ferruh
On 17/04/2020 10:31, Bruce Richardson wrote:
> On Fri, Apr 17, 2020 at 08:24:30AM +0100, Ray Kinsella wrote:
>>
>>
>> On 16/04/2020 11:01, Thomas Monjalon wrote:
>>> 16/04/2020 11:51, Bruce Richardson:
>>>> On Wed, Apr 15, 2020 at 06:24:19PM +0100, Trahe, Fiona wrote:
>>>>> 5a. If in 20.05 we add a version of a fn which breaks ABI 20.0, what should the name of the original function be? fn_v20, or fn_v20.0
>>>>
>>>> In technical terms it really doesn't matter, it's just a name that will be
>>>> looked up in a table. I don't think we strictly enforce the naming, so
>>>> whatever is clearest is best. I'd suggest the former.
>>>
>>> Each release can have a new ABI.
>>
>> How many ABI's do we want to support?
>>
> It's not how many we want to support, but for me it's a matter of how many
> do we need to support. If an API is part of the stable set, it can't just
> drop to being experimental for one or two releases - it's always stable
> until deprecated. We also shouldn't have a situation where release 20.08 is
> ABI compatible with 19.11 but not 20.02 and 20.05.
True. Let me say it differently.
Our only commitment is to support v20 - 19.11
However you are correct, if something gets committed as v21 in 20.02, in practise should also be there in 20.05+ also.
Because if it is committed as v21 and not as experimental, it should not be changing once committed.
In answering Thomas,
I was more commenting on the proliferation of ABI numbers & symbols we need to track in the build.
With v20, v21 & Experimental we need to keep track of 3.
If we start allowing quarterly builds to have managed ABI's, it will get confusing.
>
>>> The same function can have a different version in 20.02, 20.05 and 20.08.
>>> If you name it fn_v20 in 20.05, what will be the name for the new version
>>> in 20.08? I suggest using the release number when versioning a function.
>>>
>>
>> ok - so this is exactly _not_ what we wanted at the outset.
>>
>> We committed to support a single ABI, that is the 19.11 (v20) ABI until the 20.11 (v21) ABI.
>> We do _not_ support ABI stability in quarterly releases, as the support overhead would balloon overtime.
>>
>> Really why would we do this - who would benefit?
>>
>> Do we envisage a situation that someone who built against the say 20.02 shared libraries.
>> would expect their binaries to port to 20.05 without a rebuild?
>>
> I would have expected that, yes, as all have the v20 ABI.
> Maybe I need to change my expectations, though.
You are correct.
However I guess, I would still see them as slightly different levels of commitment.
>
> /Bruce
>
>> It would also defeat the purpose of EXPERIMENTAL, if the community where willing to support any permutation of an API.
>> Why would ever bother to use experimental?
>>
>> I have a bit more checking to do, but IMHO the following we should fix the following commits such that APIs are either EXPERIMENTAL or staged for v21.
>>
>> root@ashroe.eu:/build/dpdk# find . -name *.map | xargs grep 20.0.1
>> ./lib/librte_meter/rte_meter_version.map:DPDK_20.0.1 {
>> ./drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map:DPDK_20.0.1 {
>> ./drivers/net/ionic/rte_pmd_ionic_version.map:DPDK_20.0.1 {
>> ./drivers/common/octeontx2/rte_common_octeontx2_version.map:DPDK_20.0.1 {
>> ./drivers/common/mlx5/rte_common_mlx5_version.map:DPDK_20.0.1 {
>> ./drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map:DPDK_20.0.1 {
>>
>> Thanks,
>>
>> Ray K
>>
>>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
2020-04-17 7:24 5% ` Ray Kinsella
@ 2020-04-17 9:31 4% ` Bruce Richardson
2020-04-17 9:42 3% ` Ray Kinsella
0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2020-04-17 9:31 UTC (permalink / raw)
To: Ray Kinsella
Cc: Thomas Monjalon, Trahe, Fiona, dev, Kusztal, ArkadiuszX,
Neil Horman, Luca Boccassi, Kevin Traynor, Yigit, Ferruh
On Fri, Apr 17, 2020 at 08:24:30AM +0100, Ray Kinsella wrote:
>
>
> On 16/04/2020 11:01, Thomas Monjalon wrote:
> > 16/04/2020 11:51, Bruce Richardson:
> >> On Wed, Apr 15, 2020 at 06:24:19PM +0100, Trahe, Fiona wrote:
> >>> 5a. If in 20.05 we add a version of a fn which breaks ABI 20.0, what should the name of the original function be? fn_v20, or fn_v20.0
> >>
> >> In technical terms it really doesn't matter, it's just a name that will be
> >> looked up in a table. I don't think we strictly enforce the naming, so
> >> whatever is clearest is best. I'd suggest the former.
> >
> > Each release can have a new ABI.
>
> How many ABI's do we want to support?
>
It's not how many we want to support, but for me it's a matter of how many
do we need to support. If an API is part of the stable set, it can't just
drop to being experimental for one or two releases - it's always stable
until deprecated. We also shouldn't have a situation where release 20.08 is
ABI compatible with 19.11 but not 20.02 and 20.05.
> > The same function can have a different version in 20.02, 20.05 and 20.08.
> > If you name it fn_v20 in 20.05, what will be the name for the new version
> > in 20.08? I suggest using the release number when versioning a function.
> >
>
> ok - so this is exactly _not_ what we wanted at the outset.
>
> We committed to support a single ABI, that is the 19.11 (v20) ABI until the 20.11 (v21) ABI.
> We do _not_ support ABI stability in quarterly releases, as the support overhead would balloon overtime.
>
> Really why would we do this - who would benefit?
>
> Do we envisage a situation that someone who built against the say 20.02 shared libraries.
> would expect their binaries to port to 20.05 without a rebuild?
>
I would have expected that, yes, as all have the v20 ABI.
Maybe I need to change my expectations, though.
/Bruce
> It would also defeat the purpose of EXPERIMENTAL, if the community where willing to support any permutation of an API.
> Why would ever bother to use experimental?
>
> I have a bit more checking to do, but IMHO the following we should fix the following commits such that APIs are either EXPERIMENTAL or staged for v21.
>
> root@ashroe.eu:/build/dpdk# find . -name *.map | xargs grep 20.0.1
> ./lib/librte_meter/rte_meter_version.map:DPDK_20.0.1 {
> ./drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map:DPDK_20.0.1 {
> ./drivers/net/ionic/rte_pmd_ionic_version.map:DPDK_20.0.1 {
> ./drivers/common/octeontx2/rte_common_octeontx2_version.map:DPDK_20.0.1 {
> ./drivers/common/mlx5/rte_common_mlx5_version.map:DPDK_20.0.1 {
> ./drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map:DPDK_20.0.1 {
>
> Thanks,
>
> Ray K
>
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function
@ 2020-04-17 7:24 5% ` Ray Kinsella
2020-04-17 9:31 4% ` Bruce Richardson
0 siblings, 1 reply; 200+ results
From: Ray Kinsella @ 2020-04-17 7:24 UTC (permalink / raw)
To: Thomas Monjalon, Trahe, Fiona, Bruce Richardson
Cc: dev, Kusztal, ArkadiuszX, Neil Horman, Luca Boccassi,
Kevin Traynor, Yigit, Ferruh
On 16/04/2020 11:01, Thomas Monjalon wrote:
> 16/04/2020 11:51, Bruce Richardson:
>> On Wed, Apr 15, 2020 at 06:24:19PM +0100, Trahe, Fiona wrote:
>>> 5a. If in 20.05 we add a version of a fn which breaks ABI 20.0, what should the name of the original function be? fn_v20, or fn_v20.0
>>
>> In technical terms it really doesn't matter, it's just a name that will be
>> looked up in a table. I don't think we strictly enforce the naming, so
>> whatever is clearest is best. I'd suggest the former.
>
> Each release can have a new ABI.
How many ABI's do we want to support?
> The same function can have a different version in 20.02, 20.05 and 20.08.
> If you name it fn_v20 in 20.05, what will be the name for the new version
> in 20.08? I suggest using the release number when versioning a function.
>
ok - so this is exactly _not_ what we wanted at the outset.
We committed to support a single ABI, that is the 19.11 (v20) ABI until the 20.11 (v21) ABI.
We do _not_ support ABI stability in quarterly releases, as the support overhead would balloon overtime.
Really why would we do this - who would benefit?
Do we envisage a situation that someone who built against the say 20.02 shared libraries.
would expect their binaries to port to 20.05 without a rebuild?
It would also defeat the purpose of EXPERIMENTAL, if the community where willing to support any permutation of an API.
Why would ever bother to use experimental?
I have a bit more checking to do, but IMHO the following we should fix the following commits such that APIs are either EXPERIMENTAL or staged for v21.
root@ashroe.eu:/build/dpdk# find . -name *.map | xargs grep 20.0.1
./lib/librte_meter/rte_meter_version.map:DPDK_20.0.1 {
./drivers/vdpa/mlx5/rte_pmd_mlx5_vdpa_version.map:DPDK_20.0.1 {
./drivers/net/ionic/rte_pmd_ionic_version.map:DPDK_20.0.1 {
./drivers/common/octeontx2/rte_common_octeontx2_version.map:DPDK_20.0.1 {
./drivers/common/mlx5/rte_common_mlx5_version.map:DPDK_20.0.1 {
./drivers/raw/octeontx2_ep/rte_rawdev_octeontx2_ep_version.map:DPDK_20.0.1 {
Thanks,
Ray K
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH v2 01/10] Add __rte_internal tag for functions and version target
@ 2020-04-17 4:40 4% ` Wang, Haiyue
0 siblings, 0 replies; 200+ results
From: Wang, Haiyue @ 2020-04-17 4:40 UTC (permalink / raw)
To: Neil Horman
Cc: dev, Jerin Jacob Kollanukkaran, Richardson, Bruce,
Thomas Monjalon, David Marchand, Yigit, Ferruh
> -----Original Message-----
> From: Neil Horman <nhorman@tuxdriver.com>
> Sent: Friday, April 17, 2020 10:38
> To: Wang, Haiyue <haiyue.wang@intel.com>
> Cc: dev@dpdk.org; Jerin Jacob Kollanukkaran <jerinj@marvell.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Thomas Monjalon <thomas@monjalon.net>; David Marchand
> <david.marchand@redhat.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2 01/10] Add __rte_internal tag for functions and version target
>
> On Fri, Apr 17, 2020 at 02:04:30AM +0000, Wang, Haiyue wrote:
> > Hi Neil,
> >
> > > -----Original Message-----
> > > From: dev <dev-bounces@dpdk.org> On Behalf Of Neil Horman
> > > Sent: Thursday, June 13, 2019 22:24
> > > To: dev@dpdk.org
> > > Cc: Neil Horman <nhorman@tuxdriver.com>; Jerin Jacob Kollanukkaran <jerinj@marvell.com>;
> Richardson,
> > > Bruce <bruce.richardson@intel.com>; Thomas Monjalon <thomas@monjalon.net>
> > > Subject: [dpdk-dev] [PATCH v2 01/10] Add __rte_internal tag for functions and version target
> > >
> > > This tag is meant to be used on function prototypes to identify
> > > functions that are only meant to be used by internal DPDK libraries
> > > (i.e. libraries that are built while building the SDK itself, as
> > > identified by the defining of the BUILDING_RTE_SDK macro). When that
> > > flag is not set, it will resolve to an error function attribute, causing
> > > build breakage for any compilation unit attempting to build it
> > >
> > > Validate the use of this tag in much the same way we validate
> > > __rte_experimental. By adding an INTERNAL version to library map files,
> > > we can exempt internal-only functions from ABI checking, and handle them
> > > to ensure that symbols we wish to only be for internal use between dpdk
> > > libraries are properly tagged with __rte_experimental
> > >
> > > Note this patch updates the check-experimental-syms.sh script, which
> > > normally only check the EXPERIMENTAL section to also check the INTERNAL
> > > section now. As such its been renamed to the now more appropriate
> > > check-special-syms.sh
> > >
> > > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > > CC: Jerin Jacob Kollanukkaran <jerinj@marvell.com>
> > > CC: Bruce Richardson <bruce.richardson@intel.com>
> > > CC: Thomas Monjalon <thomas@monjalon.net>
> > > ---
> > > ...rimental-syms.sh => check-special-syms.sh} | 24 ++++++++++++++++++-
> > > lib/librte_eal/common/include/rte_compat.h | 12 ++++++++++
> > > mk/internal/rte.compile-pre.mk | 6 ++---
> > > mk/target/generic/rte.vars.mk | 2 +-
> > > 4 files changed, 39 insertions(+), 5 deletions(-)
> > > rename buildtools/{check-experimental-syms.sh => check-special-syms.sh} (53%)
> > >
> > ....
> >
> > > diff --git a/lib/librte_eal/common/include/rte_compat.h
> b/lib/librte_eal/common/include/rte_compat.h
> > > index 92ff28faf..739e8485c 100644
> > > --- a/lib/librte_eal/common/include/rte_compat.h
> > > +++ b/lib/librte_eal/common/include/rte_compat.h
> > > @@ -89,4 +89,16 @@ __attribute__((section(".text.experimental")))
> > >
> > > #endif
> > >
> > > +/*
> > > + * __rte_internal tags mark functions as internal only, If specified in public
> > > + * header files, this tag will resolve to an error directive, preventing
> > > + * external applications from attempting to make calls to functions not meant
> > > + * for consumption outside the dpdk library
> > > + */
> > > +#ifdef BUILDING_RTE_SDK
> > > +#define __rte_internal __attribute__((section(".text.internal")))
> > > +#else
> > > +#define __rte_internal __attribute__((error("This function cannot be used outside of the core
> DPDK
> > > library"), \
> > > + section(".text.internal")))
> > > +#endif
> > > #endif /* _RTE_COMPAT_H_ */
> >
> > Since struct definition is also a kind of ABI (am I right ? ;-) ), like:
> >
> Yes, thats correct, which is why I've advocated for making structs
> opaque as part of the abi, but I suppose thats not where we are. :)
>
Make sense, normally structs can't live alone without function API. A little
paranoid for type only ABI checking. ;-) And this definition is good for ABI
checking as we did it for EXPERIMENTAL.
Thanks!
Haiyue
> > drivers/bus/pci/rte_bus_pci.h
> > struct rte_pci_device {
> > ...
> > struct rte_intr_handle vfio_req_intr_handle;
> > /**< Handler of VFIO request interrupt */
> > } __rte_internal;
> >
> > Then will capture the errors anyway by using one of __rte_internal definition.
> > error: 'section' attribute does not apply to types [-Werror=attributes]
> > error: 'error' attribute does not apply to types
> >
> As it is currently written, the __rte_internal macro is only written to
> work on functions. If you don't want a struct to be part of the ABI, we
> would need to either:
>
> a) make a simmilar macro (say __rte_internal_data) which uses a simmilar
> gcc attibute to catch external usage.
>
> or
>
> b) just move the strucute definition to a location that isn't exposed as
> part of the external ABI
>
> Neil
>
> > > 2.20.1
> >
> >
^ permalink raw reply [relevance 4%]
Results 5801-6000 of ~18000 next (older) | prev (newer) | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2019-05-25 18:43 [dpdk-dev] [RFC PATCH 0/2] introduce __rte_internal tag Neil Horman
2019-06-13 14:23 ` [dpdk-dev] [PATCH v2 0/10] dpdk: " Neil Horman
2019-06-13 14:23 ` [dpdk-dev] [PATCH v2 01/10] Add __rte_internal tag for functions and version target Neil Horman
2020-04-17 2:04 ` Wang, Haiyue
2020-04-17 2:38 ` Neil Horman
2020-04-17 4:40 4% ` Wang, Haiyue
2020-04-22 13:52 4% ` [dpdk-dev] [PATCH v3 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-22 13:52 11% ` [dpdk-dev] [PATCH v3 1/1] eal: add internal ABI mark support Haiyue Wang
2020-04-22 14:13 4% ` David Marchand
2020-04-22 16:44 4% ` Wang, Haiyue
2020-04-22 16:37 4% ` [dpdk-dev] [PATCH v4 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-22 16:37 15% ` [dpdk-dev] [PATCH v4 1/1] eal: add internal ABI mark support Haiyue Wang
2020-04-23 3:19 4% ` [dpdk-dev] [PATCH v5 0/1] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-23 3:19 15% ` [dpdk-dev] [PATCH v5 1/1] eal: add internal ABI marking support Haiyue Wang
2020-04-24 14:52 7% ` David Marchand
2020-04-25 6:10 7% ` Wang, Haiyue
2020-04-25 14:21 4% ` David Marchand
2020-04-25 14:24 7% ` Thomas Monjalon
2020-04-25 6:04 5% ` [dpdk-dev] [PATCH v6 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-25 6:04 13% ` [dpdk-dev] [PATCH v6 1/6] eal: add internal ABI tag definition Haiyue Wang
2020-04-25 6:04 3% ` [dpdk-dev] [PATCH v6 2/6] build: enable internal API tag Haiyue Wang
2020-04-25 6:04 13% ` [dpdk-dev] [PATCH v6 4/6] devtools: ignore internal ABI check Haiyue Wang
2020-04-25 6:04 7% ` [dpdk-dev] [PATCH v6 5/6] devtools: exempt internal ABI checking Haiyue Wang
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag Haiyue Wang
2020-04-25 10:56 13% ` [dpdk-dev] [PATCH v7 1/6] eal: add internal ABI tag definition Haiyue Wang
2020-04-25 10:56 3% ` [dpdk-dev] [PATCH v7 2/6] build: enable internal API tag Haiyue Wang
2020-04-25 10:56 5% ` [dpdk-dev] [PATCH v7 3/6] mk: add internal tag check Haiyue Wang
2020-04-25 14:34 3% ` David Marchand
2020-04-25 10:56 13% ` [dpdk-dev] [PATCH v7 4/6] devtools: ignore internal ABI check Haiyue Wang
2020-04-25 10:56 7% ` [dpdk-dev] [PATCH v7 5/6] devtools: exempt internal ABI checking Haiyue Wang
2020-04-25 14:34 4% ` David Marchand
2020-04-25 14:39 0% ` [dpdk-dev] [PATCH v7 0/6] dpdk: introduce __rte_internal tag David Marchand
2020-04-25 16:34 0% ` Wang, Haiyue
2020-04-25 18:09 0% ` Wang, Haiyue
2020-01-04 1:33 [dpdk-dev] [PATCH 00/14] cleanup resources on shutdown Stephen Hemminger
2020-04-25 19:34 0% ` David Marchand
2020-01-17 14:57 [dpdk-dev] [PATCH v2 3/3] [20.05] mempool: return 0 if area is too small on populate Olivier Matz
2020-04-25 22:23 12% ` [dpdk-dev] [PATCH v3] " Thomas Monjalon
2020-04-26 16:52 12% ` [dpdk-dev] [PATCH v4] " Thomas Monjalon
2020-04-27 11:44 0% ` [dpdk-dev] [PATCH v3] " Ray Kinsella
2020-02-12 23:08 [dpdk-dev] [RFC 0/4] Enforce flag checking in API's Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 0/4] enforce checking on flag values " Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 1/4] ring: future proof flag settings Stephen Hemminger
2020-04-24 18:07 0% ` Honnappa Nagarahalli
2020-04-24 19:02 0% ` Stephen Hemminger
2020-04-25 9:20 0% ` Ananyev, Konstantin
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 2/4] hash: check flags on creation Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 3/4] stack: " Stephen Hemminger
2020-04-24 17:15 3% ` [dpdk-dev] [PATCH v2 4/4] cfgfile: check flags value Stephen Hemminger
2020-03-05 4:33 [dpdk-dev] [RFC v1 1/1] vfio: set vf token and gain vf device access vattunuru
2020-04-18 11:16 4% ` [dpdk-dev] [PATCH v7 0/2] support for VFIO-PCI VF token interface Haiyue Wang
2020-04-18 17:30 4% ` [dpdk-dev] [PATCH v8 " Haiyue Wang
2020-04-20 16:53 3% ` David Marchand
2020-04-20 17:02 3% ` Wang, Haiyue
2020-04-20 17:13 0% ` Thomas Monjalon
2020-04-20 17:37 0% ` Wang, Haiyue
2020-04-20 17:42 0% ` Thomas Monjalon
2020-04-21 1:38 3% ` Wang, Haiyue
2020-04-21 2:12 0% ` Thomas Monjalon
2020-04-21 2:52 4% ` Wang, Haiyue
2020-04-21 8:47 0% ` Thomas Monjalon
2020-04-21 17:35 0% ` Wang, Haiyue
2020-04-22 5:08 4% ` [dpdk-dev] [PATCH v9 " Haiyue Wang
2020-04-22 5:08 3% ` [dpdk-dev] [PATCH v9 2/2] eal: support for VFIO-PCI VF token Haiyue Wang
2020-04-22 8:23 ` Thomas Monjalon
2020-04-22 14:02 3% ` Wang, Haiyue
2020-04-26 1:55 4% ` [dpdk-dev] [PATCH v10 0/2] support for VFIO-PCI VF token interface Haiyue Wang
2020-03-18 20:41 [dpdk-dev] [PATCH] cryptodev: version rte_cryptodev_info_get function Arek Kusztal
2020-04-15 17:24 ` Trahe, Fiona
2020-04-16 9:51 ` Bruce Richardson
2020-04-16 10:01 ` Thomas Monjalon
2020-04-17 7:24 5% ` Ray Kinsella
2020-04-17 9:31 4% ` Bruce Richardson
2020-04-17 9:42 3% ` Ray Kinsella
2020-04-17 10:17 4% ` Thomas Monjalon
2020-04-17 10:33 3% ` Ray Kinsella
2020-04-17 11:46 5% ` Trahe, Fiona
2020-04-17 16:01 0% ` Ray Kinsella
2020-04-20 16:59 3% ` Trahe, Fiona
2020-04-20 17:31 4% ` Ray Kinsella
2020-04-20 17:37 3% ` Thomas Monjalon
2020-04-21 6:01 3% ` Ray Kinsella
2020-04-21 9:36 0% ` Thomas Monjalon
2020-04-22 8:21 0% ` Ray Kinsella
2020-03-19 17:18 [dpdk-dev] [PATCH 00/12] update and simplify telemetry library Ciara Power
2020-04-08 16:49 ` [dpdk-dev] [PATCH v2 00/16] " Ciara Power
2020-04-10 10:49 ` Morten Brørup
2020-04-10 14:21 ` Wiles, Keith
2020-04-10 18:06 ` [dpdk-dev] [PATCH v2 00/16] update and simplify telemetrylibrary Morten Brørup
2020-04-20 13:18 0% ` Bruce Richardson
2020-04-20 14:55 0% ` [dpdk-dev] [PATCH v2 00/16] update and simplifytelemetrylibrary Morten Brørup
2020-04-24 12:41 ` [dpdk-dev] [PATCH v4 00/18] update and simplify telemetry library Ciara Power
2020-04-24 12:41 ` [dpdk-dev] [PATCH v4 02/18] telemetry: move code to metrics for later reuse Ciara Power
2020-04-24 15:29 3% ` Stephen Hemminger
2020-04-24 15:49 0% ` Bruce Richardson
2020-03-22 17:20 [dpdk-dev] rte_vfio_container_dma_map/unmap functions Tal Shnaiderman
2020-04-17 14:09 ` Burakov, Anatoly
2020-04-19 13:09 ` Thomas Monjalon
2020-04-19 13:10 ` Thomas Monjalon
2020-04-20 14:07 3% ` Burakov, Anatoly
2020-04-20 17:39 3% ` Thomas Monjalon
2020-04-21 9:50 0% ` Burakov, Anatoly
2020-03-29 22:32 [dpdk-dev] [PATCH v1] common/mlx5: remove devx depndency on ibv and dv Ophir Munk
2020-04-09 7:24 ` David Marchand
2020-04-16 17:35 ` Ferruh Yigit
2020-04-16 20:00 ` Thomas Monjalon
2020-04-17 16:19 0% ` Ferruh Yigit
2020-03-30 12:15 [dpdk-dev] [PATCH v3] eal/cpuflags: add x86 based cpu flags Kevin Laatz
2020-04-16 11:00 ` [dpdk-dev] [PATCH v4] " Kevin Laatz
2020-04-25 16:04 4% ` Thomas Monjalon
2020-04-27 9:27 4% ` Ray Kinsella
2020-04-27 9:31 0% ` Laatz, Kevin
2020-04-27 9:35 0% ` Ray Kinsella
2020-04-27 10:08 0% ` Laatz, Kevin
2020-04-27 12:31 3% ` Thomas Monjalon
2020-04-27 13:58 0% ` Ray Kinsella
2020-03-30 16:00 [dpdk-dev] [PATCH 1/2] ethdev: add tm cap for private shaper packet mode Nithin Dabilpuram
2020-04-22 17:21 ` [dpdk-dev] [PATCH v4 1/4] ethdev: add tm support for shaper config in pkt mode Nithin Dabilpuram
2020-04-24 10:28 ` Dumitrescu, Cristian
2020-04-25 20:09 3% ` Ferruh Yigit
2020-04-27 9:19 4% ` Dumitrescu, Cristian
2020-04-27 16:12 4% ` Ferruh Yigit
2020-04-27 16:28 3% ` Dumitrescu, Cristian
2020-04-27 16:29 3% ` Jerin Jacob
2020-04-27 16:49 3% ` Ferruh Yigit
2020-04-02 11:26 [dpdk-dev] [PATCH 0/4] vhost: support vDPA virtio queue statistics Matan Azrad
2020-04-02 11:26 ` [dpdk-dev] [PATCH 1/4] vhost: inroduce operation to get vDPA queue stats Matan Azrad
2020-04-15 14:36 ` Maxime Coquelin
2020-04-16 9:06 ` Matan Azrad
2020-04-16 13:19 ` Maxime Coquelin
2020-04-19 6:18 0% ` Shahaf Shuler
2020-04-20 7:13 0% ` Maxime Coquelin
2020-04-20 15:57 0% ` Shahaf Shuler
2020-04-20 16:18 0% ` Maxime Coquelin
2020-04-02 18:32 [dpdk-dev] [PATCH v2 1/2] build: meson make experimental tag as global Jerin Jacob
2020-04-13 14:55 ` [dpdk-dev] [PATCH v5] build: disable experimental API check internally David Marchand
2020-04-14 14:23 ` David Marchand
2020-04-17 10:21 ` Trahe, Fiona
2020-04-17 13:23 ` David Marchand
2020-04-17 13:44 ` Trahe, Fiona
2020-04-17 13:56 4% ` David Marchand
2020-04-17 15:05 0% ` Trahe, Fiona
2020-04-17 15:52 0% ` Trahe, Fiona
2020-04-18 19:43 3% ` Chautru, Nicolas
2020-04-19 7:35 0% ` David Marchand
2020-04-19 16:17 0% ` Chautru, Nicolas
2020-04-03 17:42 [dpdk-dev] [PATCH v3 0/9] New sync modes for ring Konstantin Ananyev
2020-04-17 13:36 3% ` [dpdk-dev] [PATCH v4 " Konstantin Ananyev
2020-04-17 13:36 9% ` [dpdk-dev] [PATCH v4 2/9] ring: prepare ring to allow new sync schemes Konstantin Ananyev
2020-04-17 13:36 1% ` [dpdk-dev] [PATCH v4 3/9] ring: introduce RTS ring mode Konstantin Ananyev
2020-04-18 16:32 3% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Konstantin Ananyev
2020-04-18 16:32 9% ` [dpdk-dev] [PATCH v5 2/9] ring: prepare ring to allow new sync schemes Konstantin Ananyev
2020-04-19 2:31 0% ` Honnappa Nagarahalli
2020-04-18 16:32 1% ` [dpdk-dev] [PATCH v5 3/9] ring: introduce RTS ring mode Konstantin Ananyev
2020-04-19 2:31 0% ` Honnappa Nagarahalli
2020-04-19 2:32 0% ` [dpdk-dev] [PATCH v5 0/9] New sync modes for ring Honnappa Nagarahalli
2020-04-20 12:11 3% ` [dpdk-dev] [PATCH v6 00/10] " Konstantin Ananyev
2020-04-20 12:11 9% ` [dpdk-dev] [PATCH v6 02/10] ring: prepare ring to allow new sync schemes Konstantin Ananyev
2020-04-20 12:11 1% ` [dpdk-dev] [PATCH v6 03/10] ring: introduce RTS ring mode Konstantin Ananyev
2020-04-20 12:28 3% ` [dpdk-dev] [PATCH v7 00/10] New sync modes for ring Konstantin Ananyev
2020-04-20 12:28 9% ` [dpdk-dev] [PATCH v7 02/10] ring: prepare ring to allow new sync schemes Konstantin Ananyev
2020-04-20 12:28 1% ` [dpdk-dev] [PATCH v7 03/10] ring: introduce RTS ring mode Konstantin Ananyev
2020-04-21 11:31 0% ` [dpdk-dev] [PATCH v7 00/10] New sync modes for ring David Marchand
2020-04-10 9:46 [dpdk-dev] [PATCH] ethdev: support flow aging BillZhou
2020-04-14 8:32 ` [dpdk-dev] [PATCH v2] " Dong Zhou
2020-04-17 22:00 3% ` Ferruh Yigit
2020-04-17 22:07 0% ` Stephen Hemminger
2020-04-18 5:04 0% ` Bill Zhou
2020-04-18 9:44 0% ` Thomas Monjalon
2020-04-20 14:06 0% ` Ferruh Yigit
2020-04-20 16:10 3% ` Thomas Monjalon
2020-04-21 10:04 0% ` Ferruh Yigit
2020-04-21 10:09 0% ` Thomas Monjalon
2020-04-21 15:59 0% ` Andrew Rybchenko
2020-04-10 14:27 [dpdk-dev] [PATCH v3 0/4] add AESNI-MB rawdev for multi-function processing David Coyle
2020-04-14 14:44 ` Thomas Monjalon
2020-04-15 22:19 ` Doherty, Declan
2020-04-15 22:33 ` Thomas Monjalon
2020-04-21 16:46 ` Doherty, Declan
2020-04-21 17:23 ` Coyle, David
2020-04-22 10:51 ` Akhil Goyal
2020-04-22 13:17 ` Coyle, David
2020-04-22 13:44 3% ` Akhil Goyal
2020-04-22 14:21 0% ` Coyle, David
2020-04-10 16:43 [dpdk-dev] [PATCH v2 00/10] eal: Windows basic memory management Dmitry Kozlyuk
2020-04-14 19:44 ` [dpdk-dev] [PATCH v3 00/10] " Dmitry Kozlyuk
2020-04-14 19:44 ` [dpdk-dev] [PATCH v3 10/10] eal/windows: implement " Dmitry Kozlyuk
2020-04-16 18:34 ` Ranjit Menon
2020-04-23 1:00 3% ` Dmitry Kozlyuk
2020-04-13 15:00 [dpdk-dev] [PATCH v5 00/33] DPDK Trace support jerinj
2020-04-19 10:01 1% ` [dpdk-dev] [PATCH v6 " jerinj
2020-04-19 10:01 ` [dpdk-dev] [PATCH v6 05/33] eal/trace: implement trace operation APIs jerinj
2020-04-21 12:49 ` David Marchand
2020-04-21 13:40 3% ` Jerin Jacob
2020-04-21 14:09 0% ` David Marchand
2020-04-22 19:03 1% ` [dpdk-dev] [PATCH v7 00/32] DPDK Trace support jerinj
2020-04-16 14:54 [dpdk-dev] [PATCHv3] Remove validate-abi.sh from tree Neil Horman
2020-04-17 10:11 9% ` Ray Kinsella
2020-04-17 10:20 8% ` Thomas Monjalon
2020-04-17 10:35 4% ` Ray Kinsella
2020-04-17 11:46 4% ` Thomas Monjalon
2020-04-17 11:47 4% ` Ray Kinsella
2020-04-17 12:10 4% ` Thomas Monjalon
2020-04-17 15:42 9% ` Ray Kinsella
2020-04-17 16:10 4% ` Thomas Monjalon
2020-04-20 8:43 8% ` Ray Kinsella
2020-04-21 11:12 4% ` Neil Horman
2020-04-21 11:46 4% ` Thomas Monjalon
2020-04-21 18:56 4% ` Neil Horman
2020-04-21 21:42 4% ` Thomas Monjalon
2020-04-22 11:43 4% ` Ray Kinsella
2020-04-22 12:07 4% ` Neil Horman
2020-04-22 12:18 4% ` Thomas Monjalon
2020-04-22 13:19 4% ` Ray Kinsella
2020-04-22 13:30 4% ` Thomas Monjalon
2020-04-23 11:03 7% ` Neil Horman
2020-04-22 12:01 8% ` Neil Horman
2020-04-22 12:16 4% ` Thomas Monjalon
2020-04-23 10:57 4% ` Neil Horman
2020-04-17 14:59 11% [dpdk-dev] [PATCH v3] cryptodev: version cryptodev info get function Arek Kusztal
2020-04-20 14:22 3% ` Akhil Goyal
2020-04-20 15:21 0% ` Ray Kinsella
2020-04-20 16:54 3% ` Trahe, Fiona
2020-04-20 17:24 0% ` Ray Kinsella
2020-04-20 17:26 0% ` Ray Kinsella
2020-04-22 8:36 0% ` Ray Kinsella
2020-04-20 8:33 [dpdk-dev] [PATCH] cryptodev: add support for user callback functions Abhinandan Gujjar
2020-04-24 15:10 3% ` Ananyev, Konstantin
2020-04-20 9:34 15% [dpdk-dev] [PATCH] abi: change references to abi 20.0.1 to abi v21 Ray Kinsella
2020-04-20 11:57 9% ` Ray Kinsella
2020-04-20 12:20 9% ` David Marchand
2020-04-20 15:25 9% ` Ray Kinsella
2020-04-22 8:07 6% ` Ray Kinsella
2020-04-22 8:11 6% ` David Marchand
2020-04-22 8:18 9% ` Thomas Monjalon
2020-04-22 8:28 6% ` Ray Kinsella
2020-04-23 6:41 21% ` [dpdk-dev] [PATCH v2] " Ray Kinsella
2020-04-24 9:15 6% ` Thomas Monjalon
2020-04-24 14:10 6% ` David Marchand
2020-04-24 14:50 6% ` Ray Kinsella
2020-04-24 15:01 6% ` David Marchand
2020-04-27 9:06 11% ` [dpdk-dev] [PATCH v3] " Ray Kinsella
2020-04-27 9:06 16% ` Ray Kinsella
2020-04-27 13:45 10% ` [dpdk-dev] [PATCH v4] " Ray Kinsella
2020-04-27 13:45 21% ` Ray Kinsella
2020-04-20 16:05 [dpdk-dev] [PATCH v2] lib/timer: relax barrier for status update Phil Yang
2020-04-24 7:24 ` [dpdk-dev] [PATCH v3] " Phil Yang
2020-04-25 17:17 3% ` Thomas Monjalon
2020-04-26 7:36 3% ` Phil Yang
2020-04-26 12:18 0% ` Carrillo, Erik G
2020-04-26 14:20 0% ` Phil Yang
2020-04-26 19:30 0% ` Carrillo, Erik G
2020-04-26 14:45 2% ` [dpdk-dev] [PATCH v4] " Phil Yang
2020-04-21 1:33 13% [dpdk-dev] [PATCH] devtools: skip ABI check in static builds Thomas Monjalon
2020-04-21 6:11 4% ` Ray Kinsella
2020-04-21 9:15 4% ` Thomas Monjalon
2020-04-21 8:02 4% ` David Marchand
2020-04-21 9:20 4% ` Thomas Monjalon
2020-04-21 2:04 13% [dpdk-dev] [PATCH] devtools: remove useless files from ABI reference Thomas Monjalon
2020-04-21 7:49 9% ` David Marchand
2020-04-21 9:22 4% ` Thomas Monjalon
2020-04-21 9:26 4% ` David Marchand
2020-04-21 10:33 4% ` Bruce Richardson
2020-04-21 6:22 [dpdk-dev] [PATCH v3] ethdev: support flow aging Bill Zhou
2020-04-21 10:11 2% ` [dpdk-dev] [PATCH v4] " Bill Zhou
2020-04-21 17:13 0% ` Ferruh Yigit
2020-04-23 10:12 24% [dpdk-dev] [PATCH v1] abi: document reasons behind the three part versioning Ray Kinsella
2020-04-23 13:08 4% [dpdk-dev] DPDK Release Status Meeting 23/04/2020 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).