* Re: [dpdk-dev] [RFC] cmdline: rework as a wrapper to libedit
@ 2017-11-15 16:31 0% ` Wiles, Keith
0 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2017-11-15 16:31 UTC (permalink / raw)
To: Olivier MATZ
Cc: Adrien Mazarguil, Wu, Jingjing, dev, Thomas Monjalon, Yigit, Ferruh
> On Nov 15, 2017, at 12:04 AM, Olivier MATZ <olivier.matz@6wind.com> wrote:
>
> Hi,
>
> On Wed, Nov 15, 2017 at 04:12:07AM +0000, Wiles, Keith wrote:
>>
>>
>>> On Nov 9, 2017, at 5:43 AM, Adrien Mazarguil <adrien.mazarguil@6wind.com> wrote:
>>>
>>> This patch removes all code associated with symbols not internally relied
>>> on by other DPDK components, makes struct cmdline opaque and then proceeds
>>> to re-implement the remaining functionality as a wrapper to the editline
>>> library (also known as libedit) [1].
>>>
>>> Besides adding a new external dependency to its users, its large impact on
>>> librte_cmdline's API/ABI also warrants a major version number bump.
>>>
>>> While librte_cmdline served DPDK well all these years as a small, easy to
>>> use and self-sufficient interactive command-line handler, it started to
>>> show its limits with testpmd's flow (rte_flow) command, which required
>>> support for dynamic tokens and very long commands.
>>>
>>> This is the main motivation behind this rework. Long commands often need to
>>> be displayed on multiple lines, which are not properly supported by
>>> librte_cmdline's limited terminal handling capabilities, resulting in a
>>> rather frustrating user experience.
>>>
>>> Testpmd being one of the main tools used by PMD developers and given flow
>>> command lines won't get any shorter, this issue had to be addressed.
>>>
>>> Three options were considered:
>>>
>>> - Fixing and enhancing librte_cmdline.
>>>
>>> The amount of work necessary to add support for edition on multiple lines
>>> was deemed significant and the result would still have lacked in some
>>> areas, such as working backspace/delete keys in all terminals (i.e. full
>>> termcap support).
>>>
>>> - Making testpmd directly rely on a more capable library.
>>>
>>> All testpmd commands rely on the cmdline_parse interface provided by
>>> librte_cmdline. This approach would have required either a complete
>>> rewrite or importing the missing bits from librte_cmdline to wrap them
>>> around the new library, which naturally led to...
>>>
>>> - Converting librte_cmdline as a wrapper to a more capable library.
>>>
>>> Let's be honest, interactive command line handling isn't what makes DPDK
>>> shine. It's also far removed from its core functionality, but is still
>>> necessary in order to easily implement test and example programs; the
>>> cmdline_parse interface is particularly good at this.
>>>
>>> DPDK actually only relies on cmdline_parse. By removing all the other
>>> unused interfaces, implementing what remains on top of a different
>>> terminal-handling library would be quick and easy.
>>>
>>> This last approach was chosen for the stated reasons. Libedit is
>>> well-known, BSD-licensed, widely available [2], used by many projects, does
>>> everything needed and more [3].
>>>
>>> This rework results in the following changes:
>>>
>>> - Removed circular buffer management interface for command history
>>> (cmdline_cirbuf.c), command history being handled by libedit.
>>> - Removed raw command-line interpreter (cmdline_rdline.c).
>>> - Removed raw terminal handler (cmdline_vt100.c).
>>> - Removed all test/example code for the above.
>>> - Re-implemented high level interactive and non-interactive command-line
>>> handlers (cmdline.c and cmdline_socket.c) on top of libedit using its
>>> native interface, not its readline compatibility layer.
>>> - Made struct cmdline opaque so that applications relying on librte_cmdline
>>> do not need to include any libedit headers.
>>> - The only visible change for most applications besides being linked to
>>> libedit is they do not have to include cmdline_rdline.h anymore.
>>>
>>> As an added bonus, terminal resizing is now automatically handled.
>>>
>>> In the future, cmdline_parse could use libedit's advanced tokenizer as
>>> well to interpret quoted strings and escape sequences.
>>>
>>
>> I do agree that cmdline is getting pretty old and using libedit is one solution around the long commands, but it has a lot more problems IMO.
>>
>> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.
>>
>> I had decided to not use the circular buffer code in cmdline as it did have a few problems for what I wanted and decided to write a standard gap buffer scheme used in most editors for lines. I had looked at libedit at one point decided I did not want another dependence for DPDK. I expect even my version does not solve the long line problem, but we can convert to libedit. (and toss my pretty code :-)
>>
>> Fixing the long line problem is a very minor issue compared to everything else wrong with cmdline. I would suggest we look at CLI and improve it instead. We can add libedit to CLI and then finish testing the CLI with test-pmd. The first time I converted test-pmd I did remove and simplify the commands, but I was afraid that would cause a lot of problems for testing and scripts that people have written, but it is possible to fix these problems too.
>>
>>
>> I do not think fixing cmdline is the best answer and working to convert over to CLI is the better answer here.
>
> On my side, I think this patch goes in the correct direction:
> - it solves an issue of the command line library
> - it replaces a specific dpdk code by a well-known library which is widely used
We are ignoring the fact we are trying to patch something that is difficult to use and does not create a clean/simple design for the developer.
Just patching this with libedit now adds two more dependencies to the DPDK libedit and now ncurses. If we moved to CLI then we can fix the one thing we need fixed is the long command line and not require more dependencies to DPDK. Adding more dependencies to DPDK is going ti cause problems with the distro’s but I assume these are around. In Ubuntu 17.04 I had to pull in libedit and ncurses to use libedit.
>
> Olivier
Regards,
Keith
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC] cmdline: rework as a wrapper to libedit
@ 2017-11-16 9:23 0% ` Adrien Mazarguil
2017-11-16 16:48 0% ` Wiles, Keith
1 sibling, 1 reply; 200+ results
From: Adrien Mazarguil @ 2017-11-16 9:23 UTC (permalink / raw)
To: Wiles, Keith
Cc: Olivier Matz, Wu, Jingjing, dev, Thomas Monjalon, Yigit, Ferruh
Hi Keith,
On Wed, Nov 15, 2017 at 04:12:07AM +0000, Wiles, Keith wrote:
>
>
> > On Nov 9, 2017, at 5:43 AM, Adrien Mazarguil <adrien.mazarguil@6wind.com> wrote:
> >
> > This patch removes all code associated with symbols not internally relied
> > on by other DPDK components, makes struct cmdline opaque and then proceeds
> > to re-implement the remaining functionality as a wrapper to the editline
> > library (also known as libedit) [1].
> >
> > Besides adding a new external dependency to its users, its large impact on
> > librte_cmdline's API/ABI also warrants a major version number bump.
> >
> > While librte_cmdline served DPDK well all these years as a small, easy to
> > use and self-sufficient interactive command-line handler, it started to
> > show its limits with testpmd's flow (rte_flow) command, which required
> > support for dynamic tokens and very long commands.
> >
> > This is the main motivation behind this rework. Long commands often need to
> > be displayed on multiple lines, which are not properly supported by
> > librte_cmdline's limited terminal handling capabilities, resulting in a
> > rather frustrating user experience.
> >
> > Testpmd being one of the main tools used by PMD developers and given flow
> > command lines won't get any shorter, this issue had to be addressed.
> >
> > Three options were considered:
> >
> > - Fixing and enhancing librte_cmdline.
> >
> > The amount of work necessary to add support for edition on multiple lines
> > was deemed significant and the result would still have lacked in some
> > areas, such as working backspace/delete keys in all terminals (i.e. full
> > termcap support).
> >
> > - Making testpmd directly rely on a more capable library.
> >
> > All testpmd commands rely on the cmdline_parse interface provided by
> > librte_cmdline. This approach would have required either a complete
> > rewrite or importing the missing bits from librte_cmdline to wrap them
> > around the new library, which naturally led to...
> >
> > - Converting librte_cmdline as a wrapper to a more capable library.
> >
> > Let's be honest, interactive command line handling isn't what makes DPDK
> > shine. It's also far removed from its core functionality, but is still
> > necessary in order to easily implement test and example programs; the
> > cmdline_parse interface is particularly good at this.
> >
> > DPDK actually only relies on cmdline_parse. By removing all the other
> > unused interfaces, implementing what remains on top of a different
> > terminal-handling library would be quick and easy.
> >
> > This last approach was chosen for the stated reasons. Libedit is
> > well-known, BSD-licensed, widely available [2], used by many projects, does
> > everything needed and more [3].
> >
> > This rework results in the following changes:
> >
> > - Removed circular buffer management interface for command history
> > (cmdline_cirbuf.c), command history being handled by libedit.
> > - Removed raw command-line interpreter (cmdline_rdline.c).
> > - Removed raw terminal handler (cmdline_vt100.c).
> > - Removed all test/example code for the above.
> > - Re-implemented high level interactive and non-interactive command-line
> > handlers (cmdline.c and cmdline_socket.c) on top of libedit using its
> > native interface, not its readline compatibility layer.
> > - Made struct cmdline opaque so that applications relying on librte_cmdline
> > do not need to include any libedit headers.
> > - The only visible change for most applications besides being linked to
> > libedit is they do not have to include cmdline_rdline.h anymore.
> >
> > As an added bonus, terminal resizing is now automatically handled.
> >
> > In the future, cmdline_parse could use libedit's advanced tokenizer as
> > well to interpret quoted strings and escape sequences.
> >
>
> I do agree that cmdline is getting pretty old and using libedit is one solution around the long commands, but it has a lot more problems IMO.
Before going further, I'd like to put emphasis on the fact this RFC is not
pushing to retain librte_cmdline over your librte_cli proposal. Rather, it
removes about 30% of its code and shifts the blame to an external library
without modifying user applications.
It started some time ago as a quick hack to improve user experience with the
flow command in testpmd using the least amount of time and effort, which I
only recently reformatted as a proper RFC in order to get feedback from the
community.
> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.
Testpmd is indeed messy, but this is not librte_cmdline's fundamental fault
in my opinion, more likely the result of using a copy/paste approach to new
commands due to lack of time or interest in making things nicer than the
bare minimum to validate features. There's no design direction for it hence
the lack of uniformity in the command hierarchy.
> I had decided to not use the circular buffer code in cmdline as it did have a few problems for what I wanted and decided to write a standard gap buffer scheme used in most editors for lines. I had looked at libedit at one point decided I did not want another dependence for DPDK. I expect even my version does not solve the long line problem, but we can convert to libedit. (and toss my pretty code :-)
I'm not sure adding dependencies to DPDK is an issue anymore. Not in the
sense "there's so many of them already, no one will notice" but more with
the need to focus community efforts a bit more on what DPDK brings that
doesn't exist elsewhere.
How many DPDK contributors are experts in termcap handling and would care to
invest time in this area, compared to say, squeezing the last drop of
performance out of their employer's HW?
I understand you've invested a lot of effort in this but I think that even
if DPDK moves to librte_cli, the switch to libedit will be unavoidable.
Keep in mind every time some feature will be requested, someone will raise
the question "why not move to libedit instead?"
> Fixing the long line problem is a very minor issue compared to everything
> else wrong with cmdline.
I beg to differ on this point, however the reason may not be obvious if
you are not familiar with the flow command (the main reason behind this
RFC).
You should try it. It basically uses dynamic cmdline_parse tokens and help
strings which enables flexible arguments with contextual help (without
printing it for hundreds of unrelated commands) and more or less infinite
command lines. That was the only sane approach to interface rte_flow.
My point is there's already a case today for long lines support, it's not
minor given rte_flow is bound to replace a lot of the legacy APIs and
associated testpmd commands (flow_director_* to name a few).
> I would suggest we look at CLI and improve it instead. We can add libedit to CLI and then finish testing the CLI with test-pmd. The first time I converted test-pmd I did remove and simplify the commands, but I was afraid that would cause a lot of problems for testing and scripts that people have written, but it is possible to fix these problems too.
>
> I do not think fixing cmdline is the best answer and working to convert over to CLI is the better answer here.
In truth I didn't do my homework. Before your reply I completely forgot
about the librte_cli proposal and related dpdk-draft-cli tree. It didn't
cross my mind to check it out before working on this RFC.
I'm now aware of how much effort you put in this and what it takes to
reorder and reimplement all testpmd commands. That's huge. It seems like
we're fighting unrelated battles though.
To summarize:
- You don't like librte_cmdline for various reasons and provide librte_cli
as an alternative along a testpmd implementation. I assume the goal is to
remove librte_cmdline once every application has switched.
- I don't mind librte_cmdline, but I don't expect it to grow nor to be used
by applications outside test programs in DPDK itself, hence I choose to
strip its unused parts and make the rest a wrapper to libedit without
modifying applications.
Both are not incompatible, and since I think libedit will be unavoidable for
librte_cli, my approach can be seen as temporary until something replaces
librte_cmdline. In the meantime, users still benefit from much better
command line handling at no extra cost.
--
Adrien Mazarguil
6WIND
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC] cmdline: rework as a wrapper to libedit
2017-11-16 9:23 0% ` Adrien Mazarguil
@ 2017-11-16 16:48 0% ` Wiles, Keith
0 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2017-11-16 16:48 UTC (permalink / raw)
To: Adrien Mazarguil
Cc: Olivier Matz, Wu, Jingjing, dev, Thomas Monjalon, Yigit, Ferruh
> On Nov 16, 2017, at 1:23 AM, Adrien Mazarguil <adrien.mazarguil@6wind.com> wrote:
>
> Hi Keith,
>
> On Wed, Nov 15, 2017 at 04:12:07AM +0000, Wiles, Keith wrote:
>>
>>
>>> On Nov 9, 2017, at 5:43 AM, Adrien Mazarguil <adrien.mazarguil@6wind.com> wrote:
>>>
>>> This patch removes all code associated with symbols not internally relied
>>> on by other DPDK components, makes struct cmdline opaque and then proceeds
>>> to re-implement the remaining functionality as a wrapper to the editline
>>> library (also known as libedit) [1].
>>>
>>> Besides adding a new external dependency to its users, its large impact on
>>> librte_cmdline's API/ABI also warrants a major version number bump.
>>>
>>> While librte_cmdline served DPDK well all these years as a small, easy to
>>> use and self-sufficient interactive command-line handler, it started to
>>> show its limits with testpmd's flow (rte_flow) command, which required
>>> support for dynamic tokens and very long commands.
>>>
>>> This is the main motivation behind this rework. Long commands often need to
>>> be displayed on multiple lines, which are not properly supported by
>>> librte_cmdline's limited terminal handling capabilities, resulting in a
>>> rather frustrating user experience.
>>>
>>> Testpmd being one of the main tools used by PMD developers and given flow
>>> command lines won't get any shorter, this issue had to be addressed.
>>>
>>> Three options were considered:
>>>
>>> - Fixing and enhancing librte_cmdline.
>>>
>>> The amount of work necessary to add support for edition on multiple lines
>>> was deemed significant and the result would still have lacked in some
>>> areas, such as working backspace/delete keys in all terminals (i.e. full
>>> termcap support).
>>>
>>> - Making testpmd directly rely on a more capable library.
>>>
>>> All testpmd commands rely on the cmdline_parse interface provided by
>>> librte_cmdline. This approach would have required either a complete
>>> rewrite or importing the missing bits from librte_cmdline to wrap them
>>> around the new library, which naturally led to...
>>>
>>> - Converting librte_cmdline as a wrapper to a more capable library.
>>>
>>> Let's be honest, interactive command line handling isn't what makes DPDK
>>> shine. It's also far removed from its core functionality, but is still
>>> necessary in order to easily implement test and example programs; the
>>> cmdline_parse interface is particularly good at this.
>>>
>>> DPDK actually only relies on cmdline_parse. By removing all the other
>>> unused interfaces, implementing what remains on top of a different
>>> terminal-handling library would be quick and easy.
>>>
>>> This last approach was chosen for the stated reasons. Libedit is
>>> well-known, BSD-licensed, widely available [2], used by many projects, does
>>> everything needed and more [3].
>>>
>>> This rework results in the following changes:
>>>
>>> - Removed circular buffer management interface for command history
>>> (cmdline_cirbuf.c), command history being handled by libedit.
>>> - Removed raw command-line interpreter (cmdline_rdline.c).
>>> - Removed raw terminal handler (cmdline_vt100.c).
>>> - Removed all test/example code for the above.
>>> - Re-implemented high level interactive and non-interactive command-line
>>> handlers (cmdline.c and cmdline_socket.c) on top of libedit using its
>>> native interface, not its readline compatibility layer.
>>> - Made struct cmdline opaque so that applications relying on librte_cmdline
>>> do not need to include any libedit headers.
>>> - The only visible change for most applications besides being linked to
>>> libedit is they do not have to include cmdline_rdline.h anymore.
>>>
>>> As an added bonus, terminal resizing is now automatically handled.
>>>
>>> In the future, cmdline_parse could use libedit's advanced tokenizer as
>>> well to interpret quoted strings and escape sequences.
>>>
>>
>> I do agree that cmdline is getting pretty old and using libedit is one solution around the long commands, but it has a lot more problems IMO.
>
> Before going further, I'd like to put emphasis on the fact this RFC is not
> pushing to retain librte_cmdline over your librte_cli proposal. Rather, it
> removes about 30% of its code and shifts the blame to an external library
> without modifying user applications.
>
> It started some time ago as a quick hack to improve user experience with the
> flow command in testpmd using the least amount of time and effort, which I
> only recently reformatted as a proper RFC in order to get feedback from the
> community.
>
>> I do not agree it has severed DPDK well, just look at test-pmd and the hoops people have to jump thru to get a new command or variation of an existing command integrated into test-pmd it is very difficult. Also if you look at the command sets in test-pmd they are very odd in that similar commands can some times be set up completely different as cmdline is too rigid and difficult to use.
>
> Testpmd is indeed messy, but this is not librte_cmdline's fundamental fault
> in my opinion, more likely the result of using a copy/paste approach to new
> commands due to lack of time or interest in making things nicer than the
> bare minimum to validate features. There's no design direction for it hence
> the lack of uniformity in the command hierarchy.
>
>> I had decided to not use the circular buffer code in cmdline as it did have a few problems for what I wanted and decided to write a standard gap buffer scheme used in most editors for lines. I had looked at libedit at one point decided I did not want another dependence for DPDK. I expect even my version does not solve the long line problem, but we can convert to libedit. (and toss my pretty code :-)
>
> I'm not sure adding dependencies to DPDK is an issue anymore. Not in the
> sense "there's so many of them already, no one will notice" but more with
> the need to focus community efforts a bit more on what DPDK brings that
> doesn't exist elsewhere.
>
> How many DPDK contributors are experts in termcap handling and would care to
> invest time in this area, compared to say, squeezing the last drop of
> performance out of their employer's HW?
>
> I understand you've invested a lot of effort in this but I think that even
> if DPDK moves to librte_cli, the switch to libedit will be unavoidable.
>
> Keep in mind every time some feature will be requested, someone will raise
> the question "why not move to libedit instead?"
>
>> Fixing the long line problem is a very minor issue compared to everything
>> else wrong with cmdline.
>
> I beg to differ on this point, however the reason may not be obvious if
> you are not familiar with the flow command (the main reason behind this
> RFC).
>
> You should try it. It basically uses dynamic cmdline_parse tokens and help
> strings which enables flexible arguments with contextual help (without
> printing it for hundreds of unrelated commands) and more or less infinite
> command lines. That was the only sane approach to interface rte_flow.
>
> My point is there's already a case today for long lines support, it's not
> minor given rte_flow is bound to replace a lot of the legacy APIs and
> associated testpmd commands (flow_director_* to name a few).
>
>> I would suggest we look at CLI and improve it instead. We can add libedit to CLI and then finish testing the CLI with test-pmd. The first time I converted test-pmd I did remove and simplify the commands, but I was afraid that would cause a lot of problems for testing and scripts that people have written, but it is possible to fix these problems too.
>>
>> I do not think fixing cmdline is the best answer and working to convert over to CLI is the better answer here.
>
> In truth I didn't do my homework. Before your reply I completely forgot
> about the librte_cli proposal and related dpdk-draft-cli tree. It didn't
> cross my mind to check it out before working on this RFC.
>
> I'm now aware of how much effort you put in this and what it takes to
> reorder and reimplement all testpmd commands. That's huge. It seems like
> we're fighting unrelated battles though.
>
> To summarize:
>
> - You don't like librte_cmdline for various reasons and provide librte_cli
> as an alternative along a testpmd implementation. I assume the goal is to
> remove librte_cmdline once every application has switched.
>
> - I don't mind librte_cmdline, but I don't expect it to grow nor to be used
> by applications outside test programs in DPDK itself, hence I choose to
> strip its unused parts and make the rest a wrapper to libedit without
> modifying applications.
>
> Both are not incompatible, and since I think libedit will be unavoidable for
> librte_cli, my approach can be seen as temporary until something replaces
> librte_cmdline. In the meantime, users still benefit from much better
> command line handling at no extra cost.
OK, I understand your points and not to state your work was in vain, but it would have been better if we had applied the effort to the CLI. I do not agree per-say that libedit is required for CLI as the only feature we need is to handle long lines and their are easier ways to do then using libedit.
I was looking at the problem and I think we can handle long lines without libedit, I will try to put together an example soon.
For now we can accept your patch for cmdline as it does add the support without much effort.
>
> --
> Adrien Mazarguil
> 6WIND
Regards,
Keith
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC] cmdline: rework as a wrapper to libedit
@ 2017-11-16 16:53 0% ` Jim Thompson
1 sibling, 0 replies; 200+ results
From: Jim Thompson @ 2017-11-16 16:53 UTC (permalink / raw)
To: Adrien Mazarguil
Cc: Olivier Matz, Jingjing Wu, dev, Thomas Monjalon, Ferruh Yigit
How does this fit with all the work that Keith Wiles just discussed at DPDK Summit?
https://dpdk17.sched.com/event/Cqv3/new-command-line-interface-for-dpdk <https://dpdk17.sched.com/event/Cqv3/new-command-line-interface-for-dpdk>
Jim
> On Nov 9, 2017, at 7:43 AM, Adrien Mazarguil <adrien.mazarguil@6wind.com> wrote:
>
> This patch removes all code associated with symbols not internally relied
> on by other DPDK components, makes struct cmdline opaque and then proceeds
> to re-implement the remaining functionality as a wrapper to the editline
> library (also known as libedit) [1].
>
> Besides adding a new external dependency to its users, its large impact on
> librte_cmdline's API/ABI also warrants a major version number bump.
>
> While librte_cmdline served DPDK well all these years as a small, easy to
> use and self-sufficient interactive command-line handler, it started to
> show its limits with testpmd's flow (rte_flow) command, which required
> support for dynamic tokens and very long commands.
>
> This is the main motivation behind this rework. Long commands often need to
> be displayed on multiple lines, which are not properly supported by
> librte_cmdline's limited terminal handling capabilities, resulting in a
> rather frustrating user experience.
>
> Testpmd being one of the main tools used by PMD developers and given flow
> command lines won't get any shorter, this issue had to be addressed.
>
> Three options were considered:
>
> - Fixing and enhancing librte_cmdline.
>
> The amount of work necessary to add support for edition on multiple lines
> was deemed significant and the result would still have lacked in some
> areas, such as working backspace/delete keys in all terminals (i.e. full
> termcap support).
>
> - Making testpmd directly rely on a more capable library.
>
> All testpmd commands rely on the cmdline_parse interface provided by
> librte_cmdline. This approach would have required either a complete
> rewrite or importing the missing bits from librte_cmdline to wrap them
> around the new library, which naturally led to...
>
> - Converting librte_cmdline as a wrapper to a more capable library.
>
> Let's be honest, interactive command line handling isn't what makes DPDK
> shine. It's also far removed from its core functionality, but is still
> necessary in order to easily implement test and example programs; the
> cmdline_parse interface is particularly good at this.
>
> DPDK actually only relies on cmdline_parse. By removing all the other
> unused interfaces, implementing what remains on top of a different
> terminal-handling library would be quick and easy.
>
> This last approach was chosen for the stated reasons. Libedit is
> well-known, BSD-licensed, widely available [2], used by many projects, does
> everything needed and more [3].
>
> This rework results in the following changes:
>
> - Removed circular buffer management interface for command history
> (cmdline_cirbuf.c), command history being handled by libedit.
> - Removed raw command-line interpreter (cmdline_rdline.c).
> - Removed raw terminal handler (cmdline_vt100.c).
> - Removed all test/example code for the above.
> - Re-implemented high level interactive and non-interactive command-line
> handlers (cmdline.c and cmdline_socket.c) on top of libedit using its
> native interface, not its readline compatibility layer.
> - Made struct cmdline opaque so that applications relying on librte_cmdline
> do not need to include any libedit headers.
> - The only visible change for most applications besides being linked to
> libedit is they do not have to include cmdline_rdline.h anymore.
>
> As an added bonus, terminal resizing is now automatically handled.
>
> In the future, cmdline_parse could use libedit's advanced tokenizer as
> well to interpret quoted strings and escape sequences.
>
> [1] http://thrysoee.dk/editline/
> [2] It usually goes by the name "libedit" in Linux distributions.
> [3] http://netbsd.gw.com/cgi-bin/man-cgi?editline++NetBSD-current
>
> Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> ---
> app/test-pmd/cmdline.c | 1 -
> examples/bond/main.c | 1 -
> examples/cmdline/commands.c | 1 -
> examples/cmdline/main.c | 1 -
> .../ip_pipeline/pipeline/pipeline_common_fe.c | 1 -
> .../ip_pipeline/pipeline/pipeline_firewall.c | 1 -
> .../pipeline/pipeline_flow_actions.c | 1 -
> .../pipeline/pipeline_flow_classification.c | 1 -
> examples/ip_pipeline/thread_fe.c | 1 -
> examples/multi_process/simple_mp/main.c | 1 -
> examples/multi_process/simple_mp/mp_commands.c | 1 -
> examples/qos_sched/cmdline.c | 1 -
> examples/quota_watermark/qwctl/commands.c | 1 -
> examples/quota_watermark/qwctl/qwctl.c | 1 -
> .../guest_cli/vm_power_cli_guest.c | 1 -
> examples/vm_power_manager/vm_power_cli.c | 1 -
> lib/librte_cmdline/Makefile | 10 +-
> lib/librte_cmdline/cmdline.c | 385 +++--
> lib/librte_cmdline/cmdline.h | 22 +-
> lib/librte_cmdline/cmdline_cirbuf.c | 466 ------
> lib/librte_cmdline/cmdline_cirbuf.h | 245 ----
> lib/librte_cmdline/cmdline_parse.c | 7 +-
> lib/librte_cmdline/cmdline_rdline.c | 697 ---------
> lib/librte_cmdline/cmdline_rdline.h | 255 ----
> lib/librte_cmdline/cmdline_socket.c | 36 +-
> lib/librte_cmdline/cmdline_vt100.c | 185 ---
> lib/librte_cmdline/cmdline_vt100.h | 153 --
> lib/librte_cmdline/rte_cmdline_version.map | 41 +-
> mk/rte.app.mk | 2 +
> test/cmdline_test/cmdline_test.c | 1 -
> test/cmdline_test/commands.c | 69 -
> test/test/Makefile | 1 -
> test/test/commands.c | 1 -
> test/test/test.c | 1 -
> test/test/test_cmdline.c | 9 -
> test/test/test_cmdline.h | 6 -
> test/test/test_cmdline_cirbuf.c | 1330 ------------------
> test/test/test_cmdline_lib.c | 117 +-
> 38 files changed, 293 insertions(+), 3762 deletions(-)
>
> diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
> index f71d963..9fe625c 100644
> --- a/app/test-pmd/cmdline.c
> +++ b/app/test-pmd/cmdline.c
> @@ -77,7 +77,6 @@
> #include <rte_flow.h>
> #include <rte_gro.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/bond/main.c b/examples/bond/main.c
> index 8e3b1f3..d903314 100644
> --- a/examples/bond/main.c
> +++ b/examples/bond/main.c
> @@ -71,7 +71,6 @@
> #include <rte_arp.h>
> #include <rte_spinlock.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/cmdline/commands.c b/examples/cmdline/commands.c
> index f3ba247..e8fa7f0 100644
> --- a/examples/cmdline/commands.c
> +++ b/examples/cmdline/commands.c
> @@ -74,7 +74,6 @@
> #endif
> #endif
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_ipaddr.h>
> #include <cmdline_parse_num.h>
> diff --git a/examples/cmdline/main.c b/examples/cmdline/main.c
> index c6de944..c229f50 100644
> --- a/examples/cmdline/main.c
> +++ b/examples/cmdline/main.c
> @@ -65,7 +65,6 @@
> #include <termios.h>
> #include <sys/queue.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> diff --git a/examples/ip_pipeline/pipeline/pipeline_common_fe.c b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
> index 7521187..f1df197 100644
> --- a/examples/ip_pipeline/pipeline/pipeline_common_fe.c
> +++ b/examples/ip_pipeline/pipeline/pipeline_common_fe.c
> @@ -37,7 +37,6 @@
>
> #include <rte_common.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/ip_pipeline/pipeline/pipeline_firewall.c b/examples/ip_pipeline/pipeline/pipeline_firewall.c
> index a82e552..e49d9ca 100644
> --- a/examples/ip_pipeline/pipeline/pipeline_firewall.c
> +++ b/examples/ip_pipeline/pipeline/pipeline_firewall.c
> @@ -41,7 +41,6 @@
> #include <rte_common.h>
> #include <rte_hexdump.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions.c b/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
> index 349db6b..0f680db 100644
> --- a/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
> +++ b/examples/ip_pipeline/pipeline/pipeline_flow_actions.c
> @@ -40,7 +40,6 @@
> #include <rte_common.h>
> #include <rte_hexdump.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
> index 70b1938..b9e4ed5 100644
> --- a/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
> +++ b/examples/ip_pipeline/pipeline/pipeline_flow_classification.c
> @@ -40,7 +40,6 @@
> #include <rte_common.h>
> #include <rte_hexdump.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/ip_pipeline/thread_fe.c b/examples/ip_pipeline/thread_fe.c
> index 4590c2b..4f54094 100644
> --- a/examples/ip_pipeline/thread_fe.c
> +++ b/examples/ip_pipeline/thread_fe.c
> @@ -1,7 +1,6 @@
> #include <rte_common.h>
> #include <rte_ring.h>
> #include <rte_malloc.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/multi_process/simple_mp/main.c b/examples/multi_process/simple_mp/main.c
> index 62537b0..c0fc6ea 100644
> --- a/examples/multi_process/simple_mp/main.c
> +++ b/examples/multi_process/simple_mp/main.c
> @@ -64,7 +64,6 @@
> #include <rte_ring.h>
> #include <rte_log.h>
> #include <rte_mempool.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_socket.h>
> diff --git a/examples/multi_process/simple_mp/mp_commands.c b/examples/multi_process/simple_mp/mp_commands.c
> index ef6dc58..264dea2 100644
> --- a/examples/multi_process/simple_mp/mp_commands.c
> +++ b/examples/multi_process/simple_mp/mp_commands.c
> @@ -54,7 +54,6 @@
> #include <rte_mempool.h>
> #include <rte_string_fns.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_socket.h>
> diff --git a/examples/qos_sched/cmdline.c b/examples/qos_sched/cmdline.c
> index b62d165..c2a4f6b 100644
> --- a/examples/qos_sched/cmdline.c
> +++ b/examples/qos_sched/cmdline.c
> @@ -36,7 +36,6 @@
> #include <inttypes.h>
> #include <string.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/quota_watermark/qwctl/commands.c b/examples/quota_watermark/qwctl/commands.c
> index 5cac0e1..a30a35c 100644
> --- a/examples/quota_watermark/qwctl/commands.c
> +++ b/examples/quota_watermark/qwctl/commands.c
> @@ -36,7 +36,6 @@
> #include <string.h>
> #include <termios.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_num.h>
> #include <cmdline_parse_string.h>
> diff --git a/examples/quota_watermark/qwctl/qwctl.c b/examples/quota_watermark/qwctl/qwctl.c
> index 18ec17a..2831667 100644
> --- a/examples/quota_watermark/qwctl/qwctl.c
> +++ b/examples/quota_watermark/qwctl/qwctl.c
> @@ -42,7 +42,6 @@
> #include <rte_log.h>
> #include <rte_memzone.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> diff --git a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
> index 63f711e..83cd215 100644
> --- a/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
> +++ b/examples/vm_power_manager/guest_cli/vm_power_cli_guest.c
> @@ -37,7 +37,6 @@
> #include <stdio.h>
> #include <termios.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_parse_num.h>
> diff --git a/examples/vm_power_manager/vm_power_cli.c b/examples/vm_power_manager/vm_power_cli.c
> index 6f234fb..d013715 100644
> --- a/examples/vm_power_manager/vm_power_cli.c
> +++ b/examples/vm_power_manager/vm_power_cli.c
> @@ -39,7 +39,6 @@
> #include <termios.h>
> #include <errno.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_parse_num.h>
> diff --git a/lib/librte_cmdline/Makefile b/lib/librte_cmdline/Makefile
> index 2c48e62..35c8972 100644
> --- a/lib/librte_cmdline/Makefile
> +++ b/lib/librte_cmdline/Makefile
> @@ -38,28 +38,24 @@ CFLAGS += $(WERROR_FLAGS) -I$(SRCDIR) -O3
>
> EXPORT_MAP := rte_cmdline_version.map
>
> -LIBABIVER := 2
> +LIBABIVER := 3
>
> # all source are stored in SRCS-y
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) := cmdline.c
> -SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_cirbuf.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_etheraddr.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_ipaddr.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_num.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_string.c
> -SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_rdline.c
> -SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
>
> -CFLAGS += -D_GNU_SOURCE
> LDLIBS += -lrte_eal
>
> # install includes
> INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h
> -INCS += cmdline_parse_etheraddr.h cmdline_parse_string.h cmdline_rdline.h
> -INCS += cmdline_vt100.h cmdline_socket.h cmdline_cirbuf.h cmdline_parse_portlist.h
> +INCS += cmdline_parse_etheraddr.h cmdline_parse_string.h
> +INCS += cmdline_socket.h cmdline_parse_portlist.h
> SYMLINK-$(CONFIG_RTE_LIBRTE_CMDLINE)-include := $(INCS)
>
> include $(RTE_SDK)/mk/rte.lib.mk
> diff --git a/lib/librte_cmdline/cmdline.c b/lib/librte_cmdline/cmdline.c
> index d749165..1c19546 100644
> --- a/lib/librte_cmdline/cmdline.c
> +++ b/lib/librte_cmdline/cmdline.c
> @@ -58,79 +58,181 @@
> * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> */
>
> +#include <ctype.h>
> +#include <histedit.h>
> +#include <stdint.h>
> #include <stdio.h>
> #include <string.h>
> #include <unistd.h>
> #include <stdlib.h>
> #include <stdarg.h>
> -#include <inttypes.h>
> #include <fcntl.h>
> #include <poll.h>
> #include <errno.h>
> -#include <termios.h>
> -#include <netinet/in.h>
> -
> -#include <rte_string_fns.h>
>
> #include "cmdline_parse.h"
> -#include "cmdline_rdline.h"
> #include "cmdline.h"
>
> -static void
> -cmdline_valid_buffer(struct rdline *rdl, const char *buf,
> - __attribute__((unused)) unsigned int size)
> +struct cmdline {
> + char *line;
> + FILE *f_in;
> + FILE *f_out;
> + cmdline_parse_ctx_t *ctx;
> + EditLine *el;
> + History *hist;
> + HistEvent histev;
> + uint32_t eof:1;
> + uint32_t error:1;
> + char prompt[RDLINE_PROMPT_SIZE];
> +};
> +
> +void
> +cmdline_set_prompt(struct cmdline *cl, const char *prompt)
> {
> - struct cmdline *cl = rdl->opaque;
> - int ret;
> - ret = cmdline_parse(cl, buf);
> - if (ret == CMDLINE_PARSE_AMBIGUOUS)
> - cmdline_printf(cl, "Ambiguous command\n");
> - else if (ret == CMDLINE_PARSE_NOMATCH)
> - cmdline_printf(cl, "Command not found\n");
> - else if (ret == CMDLINE_PARSE_BAD_ARGS)
> - cmdline_printf(cl, "Bad arguments\n");
> + if (!cl || !prompt)
> + return;
> + snprintf(cl->prompt, sizeof(cl->prompt), "%s", prompt);
> }
>
> -static int
> -cmdline_complete_buffer(struct rdline *rdl, const char *buf,
> - char *dstbuf, unsigned int dstsize,
> - int *state)
> +void *
> +cmdline_ctx_get(struct cmdline *cl)
> {
> - struct cmdline *cl = rdl->opaque;
> - return cmdline_complete(cl, buf, state, dstbuf, dstsize);
> + if (!cl)
> + return NULL;
> + return cl->ctx;
> }
>
> -int
> -cmdline_write_char(struct rdline *rdl, char c)
> +static char *
> +cmdline_el_prompt(EditLine *el)
> {
> - int ret = -1;
> struct cmdline *cl;
>
> - if (!rdl)
> - return -1;
> -
> - cl = rdl->opaque;
> + if (el_get(el, EL_CLIENTDATA, &cl))
> + return NULL;
> + return cl->prompt;
> +}
>
> - if (cl->s_out >= 0)
> - ret = write(cl->s_out, &c, 1);
> +static unsigned char
> +cmdline_el_execute(EditLine *el, int c)
> +{
> + const LineInfo *li = el_line(el);
> + size_t len = li->lastchar - li->buffer;
> + char *line;
> + struct cmdline *cl;
> + int ret;
>
> - return ret;
> + (void)c;
> + if (el_get(el, EL_CLIENTDATA, &cl))
> + return CC_FATAL;
> + line = realloc(cl->line, len + 2);
> + if (!line) {
> + cl->error = 1;
> + return CC_FATAL;
> + }
> + cl->line = line;
> + memcpy(line, li->buffer, len);
> + line[len] = '\n';
> + line[len + 1] = '\0';
> + fputs("\r\n", cl->f_out);
> + ret = cmdline_parse(cl, line);
> + if (ret == CMDLINE_PARSE_AMBIGUOUS)
> + fprintf(cl->f_out, "Ambiguous command\r\n");
> + else if (ret == CMDLINE_PARSE_NOMATCH)
> + fprintf(cl->f_out, "Command not found\r\n");
> + else if (ret == CMDLINE_PARSE_BAD_ARGS)
> + fprintf(cl->f_out, "Bad arguments\r\n");
> + if (cl->error)
> + return CC_FATAL;
> + if (cl->eof)
> + return CC_EOF;
> + if (len) {
> + line[len] = '\0';
> + history(cl->hist, &cl->histev, H_ENTER, line);
> + }
> + return CC_NEWLINE;
> }
>
> +static unsigned char
> +cmdline_el_complete(EditLine *el, int c)
> +{
> + const LineInfo *li = el_line(el);
> + size_t pos = li->cursor - li->buffer;
> + char *line;
> + struct cmdline *cl;
> + char complete_buf[RDLINE_COMPLETE_SIZE];
> + int complete_state;
> + int ret;
>
> -void
> -cmdline_set_prompt(struct cmdline *cl, const char *prompt)
> + if (el_get(el, EL_CLIENTDATA, &cl))
> + return CC_FATAL;
> + line = realloc(cl->line, pos + 1);
> + if (!line) {
> + cl->error = 1;
> + return CC_FATAL;
> + }
> + cl->line = line;
> + memcpy(line, li->buffer, pos);
> + line[pos] = '\0';
> + if (c == '\t')
> + complete_state = 0;
> + else
> + complete_state = -1;
> + /* see in parse.h for help on complete() */
> + ret = cmdline_complete(cl, line, &complete_state,
> + complete_buf, sizeof(complete_buf));
> + /* no completion or error */
> + if (ret <= 0)
> + return CC_ARGHACK;
> + /* string must be NUL-terminated */
> + if (strnlen(complete_buf, sizeof(complete_buf)) == sizeof(complete_buf))
> + return CC_ERROR;
> + /* add chars */
> + if (ret == CMDLINE_PARSE_COMPLETED_BUFFER) {
> + /* if in the middle of a token, remove its suffix first */
> + for (pos = 0; li->cursor + pos != li->lastchar; pos++)
> + if (isblank(li->cursor[pos]))
> + break;
> + el_cursor(el, pos);
> + el_deletestr(el, pos);
> + if (el_insertstr(el, complete_buf))
> + return CC_ERROR;
> + return CC_REFRESH;
> + }
> + /* choice */
> + fputs("\r\n", cl->f_out);
> + while (ret) {
> + fputc(' ', cl->f_out);
> + fputs(complete_buf, cl->f_out);
> + fputs("\r\n", cl->f_out);
> + ret = cmdline_complete(cl, line, &complete_state,
> + complete_buf, sizeof(complete_buf));
> + }
> + el_set(el, EL_REFRESH);
> + return CC_REDISPLAY;
> +}
> +
> +static unsigned char
> +cmdline_el_delete_next_char_or_eof(EditLine *el, int c)
> {
> - if (!cl || !prompt)
> - return;
> - snprintf(cl->prompt, sizeof(cl->prompt), "%s", prompt);
> + const LineInfo *li = el_line(el);
> + struct cmdline *cl;
> +
> + (void)c;
> + if (el_get(el, EL_CLIENTDATA, &cl))
> + return CC_FATAL;
> + if (li->buffer == li->lastchar) {
> + cl->eof = 1;
> + return CC_EOF;
> + }
> + el_cursor(el, 1);
> + el_deletestr(el, 1);
> + return CC_REFRESH;
> }
>
> struct cmdline *
> cmdline_new(cmdline_parse_ctx_t *ctx, const char *prompt, int s_in, int s_out)
> {
> struct cmdline *cl;
> - int ret;
>
> if (!ctx || !prompt)
> return NULL;
> @@ -139,36 +241,89 @@ cmdline_new(cmdline_parse_ctx_t *ctx, const char *prompt, int s_in, int s_out)
> if (cl == NULL)
> return NULL;
> memset(cl, 0, sizeof(struct cmdline));
> - cl->s_in = s_in;
> - cl->s_out = s_out;
> + cl->line = NULL;
> + s_in = dup(s_in);
> + s_out = s_out != -1 ? dup(s_out) : open("/dev/null", O_WRONLY);
> + if (s_in == -1 || s_out == -1)
> + goto error;
> + cl->f_in = fdopen(s_in, "rb");
> + cl->f_out = fdopen(s_out, "wb");
> + if (!cl->f_in || !cl->f_out)
> + goto error;
> cl->ctx = ctx;
> -
> - ret = rdline_init(&cl->rdl, cmdline_write_char, cmdline_valid_buffer,
> - cmdline_complete_buffer);
> - if (ret != 0) {
> - free(cl);
> - return NULL;
> - }
> -
> - cl->rdl.opaque = cl;
> + cl->el = el_init("dpdk", cl->f_in, cl->f_out, stderr);
> + if (!cl->el)
> + goto error;
> + if (el_set(cl->el, EL_CLIENTDATA, cl))
> + goto error;
> cmdline_set_prompt(cl, prompt);
> - rdline_newline(&cl->rdl, cl->prompt);
> -
> + if (el_set(cl->el, EL_PROMPT, cmdline_el_prompt))
> + goto error;
> + if (el_set(cl->el, EL_EDITOR, "emacs"))
> + goto error;
> + if (el_set(cl->el, EL_SIGNAL, 1))
> + goto error;
> + cl->hist = history_init();
> + if (!cl->hist)
> + goto error;
> + if (history(cl->hist, &cl->histev, H_SETSIZE,
> + RDLINE_HISTORY_MAX_LINE) < 0)
> + goto error;
> + if (history(cl->hist, &cl->histev, H_SETUNIQUE, 1))
> + goto error;
> + if (el_set(cl->el, EL_HIST, history, cl->hist))
> + goto error;
> + if (el_set(cl->el, EL_ADDFN, "ed-execute", "Execute command",
> + cmdline_el_execute))
> + goto error;
> + if (el_set(cl->el, EL_BIND, "^J", "ed-execute", NULL))
> + goto error;
> + if (el_set(cl->el, EL_BIND, "^M", "ed-execute", NULL))
> + goto error;
> + if (el_set(cl->el, EL_ADDFN, "ed-complete", "Complete argument",
> + cmdline_el_complete))
> + goto error;
> + if (el_set(cl->el, EL_BIND, "^I", "ed-complete", NULL))
> + goto error;
> + if (el_set(cl->el, EL_BIND, "?", "ed-complete", NULL))
> + goto error;
> + if (el_set(cl->el, EL_ADDFN, "ed-delete-next-char-or-eof",
> + "Delete next character or assume EOF",
> + cmdline_el_delete_next_char_or_eof))
> + goto error;
> + if (el_set(cl->el, EL_BIND, "^D",
> + "ed-delete-next-char-or-eof", NULL))
> + goto error;
> + if (el_set(cl->el, EL_BIND, "^W", "ed-delete-prev-word", NULL))
> + goto error;
> return cl;
> +error:
> + if (cl->hist)
> + history_end(cl->hist);
> + if (cl->el)
> + el_end(cl->el);
> + if (cl->f_out)
> + fclose(cl->f_out);
> + else if (s_out != -1)
> + close(s_out);
> + if (cl->f_in)
> + fclose(cl->f_in);
> + else if (s_in != -1)
> + close(s_in);
> + free(cl);
> + return NULL;
> }
>
> void
> cmdline_free(struct cmdline *cl)
> {
> - dprintf("called\n");
> -
> if (!cl)
> return;
> -
> - if (cl->s_in > 2)
> - close(cl->s_in);
> - if (cl->s_out != cl->s_in && cl->s_out > 2)
> - close(cl->s_out);
> + history_end(cl->hist);
> + el_end(cl->el);
> + fclose(cl->f_out);
> + fclose(cl->f_in);
> + free(cl->line);
> free(cl);
> }
>
> @@ -180,70 +335,23 @@ cmdline_printf(const struct cmdline *cl, const char *fmt, ...)
> if (!cl || !fmt)
> return;
>
> -#ifdef _GNU_SOURCE
> - if (cl->s_out < 0)
> - return;
> - va_start(ap, fmt);
> - vdprintf(cl->s_out, fmt, ap);
> - va_end(ap);
> -#else
> - int ret;
> - char *buf;
> -
> - if (cl->s_out < 0)
> - return;
> -
> - buf = malloc(BUFSIZ);
> - if (buf == NULL)
> - return;
> va_start(ap, fmt);
> - ret = vsnprintf(buf, BUFSIZ, fmt, ap);
> + vfprintf(cl->f_out, fmt, ap);
> va_end(ap);
> - if (ret < 0) {
> - free(buf);
> - return;
> - }
> - if (ret >= BUFSIZ)
> - ret = BUFSIZ - 1;
> - ret = write(cl->s_out, buf, ret);
> - (void)ret;
> - free(buf);
> -#endif
> }
>
> int
> cmdline_in(struct cmdline *cl, const char *buf, int size)
> {
> - const char *history, *buffer;
> - size_t histlen, buflen;
> - int ret = 0;
> - int i, same;
> + int i;
>
> if (!cl || !buf)
> return -1;
>
> for (i=0; i<size; i++) {
> - ret = rdline_char_in(&cl->rdl, buf[i]);
> -
> - if (ret == RDLINE_RES_VALIDATED) {
> - buffer = rdline_get_buffer(&cl->rdl);
> - history = rdline_get_history_item(&cl->rdl, 0);
> - if (history) {
> - histlen = strnlen(history, RDLINE_BUF_SIZE);
> - same = !memcmp(buffer, history, histlen) &&
> - buffer[histlen] == '\n';
> - }
> - else
> - same = 0;
> - buflen = strnlen(buffer, RDLINE_BUF_SIZE);
> - if (buflen > 1 && !same)
> - rdline_add_history(&cl->rdl, buffer);
> - rdline_newline(&cl->rdl, cl->prompt);
> - }
> - else if (ret == RDLINE_RES_EOF)
> - return -1;
> - else if (ret == RDLINE_RES_EXITED)
> - return -1;
> + char tmp[2] = { buf[i], '\0' };
> +
> + el_push(cl->el, tmp);
> }
> return i;
> }
> @@ -253,7 +361,7 @@ cmdline_quit(struct cmdline *cl)
> {
> if (!cl)
> return;
> - rdline_quit(&cl->rdl);
> + cl->eof = 1;
> }
>
> int
> @@ -261,48 +369,49 @@ cmdline_poll(struct cmdline *cl)
> {
> struct pollfd pfd;
> int status;
> - ssize_t read_status;
> - char c;
> + int read_status;
> + int flags;
>
> if (!cl)
> return -EINVAL;
> - else if (cl->rdl.status == RDLINE_EXITED)
> + else if (cl->error)
> + return RDLINE_ERROR;
> + else if (cl->eof)
> return RDLINE_EXITED;
>
> - pfd.fd = cl->s_in;
> + pfd.fd = fileno(cl->f_in);
> pfd.events = POLLIN;
> pfd.revents = 0;
>
> status = poll(&pfd, 1, 0);
> if (status < 0)
> - return status;
> - else if (status > 0) {
> - c = -1;
> - read_status = read(cl->s_in, &c, 1);
> - if (read_status < 0)
> - return read_status;
> -
> - status = cmdline_in(cl, &c, 1);
> - if (status < 0 && cl->rdl.status != RDLINE_EXITED)
> - return status;
> - }
> -
> - return cl->rdl.status;
> + return RDLINE_ERROR;
> + if (!status)
> + return RDLINE_RUNNING;
> + flags = fcntl(pfd.fd, F_GETFL);
> + if (!(flags & O_NONBLOCK))
> + fcntl(pfd.fd, F_SETFL, flags | O_NONBLOCK);
> + if (!el_gets(cl->el, &read_status) && read_status == -1)
> + cl->error = 1;
> + if (!(flags & O_NONBLOCK))
> + fcntl(pfd.fd, F_SETFL, flags);
> + return cl->error ? RDLINE_ERROR :
> + cl->eof ? RDLINE_EXITED :
> + RDLINE_RUNNING;
> }
>
> void
> cmdline_interact(struct cmdline *cl)
> {
> - char c;
> -
> if (!cl)
> return;
>
> - c = -1;
> - while (1) {
> - if (read(cl->s_in, &c, 1) <= 0)
> - break;
> - if (cmdline_in(cl, &c, 1) < 0)
> - break;
> + while (!cl->error && !cl->eof) {
> + int read_status;
> +
> + if (el_gets(cl->el, &read_status))
> + continue;
> + if (read_status == -1)
> + cl->error = 1;
> }
> }
> diff --git a/lib/librte_cmdline/cmdline.h b/lib/librte_cmdline/cmdline.h
> index 65d73b0..4507268 100644
> --- a/lib/librte_cmdline/cmdline.h
> +++ b/lib/librte_cmdline/cmdline.h
> @@ -61,8 +61,6 @@
> #ifndef _CMDLINE_H_
> #define _CMDLINE_H_
>
> -#include <termios.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
>
> /**
> @@ -75,22 +73,26 @@
> extern "C" {
> #endif
>
> -struct cmdline {
> - int s_in;
> - int s_out;
> - cmdline_parse_ctx_t *ctx;
> - struct rdline rdl;
> - char prompt[RDLINE_PROMPT_SIZE];
> - struct termios oldterm;
> +#define RDLINE_PROMPT_SIZE 32
> +#define RDLINE_HISTORY_MAX_LINE 64
> +#define RDLINE_COMPLETE_SIZE 128
> +
> +enum rdline_status {
> + RDLINE_ERROR = -1,
> + RDLINE_INIT,
> + RDLINE_RUNNING,
> + RDLINE_EXITED,
> };
>
> +struct cmdline;
> +
> +void *cmdline_ctx_get(struct cmdline *cl);
> struct cmdline *cmdline_new(cmdline_parse_ctx_t *ctx, const char *prompt, int s_in, int s_out);
> void cmdline_set_prompt(struct cmdline *cl, const char *prompt);
> void cmdline_free(struct cmdline *cl);
> void cmdline_printf(const struct cmdline *cl, const char *fmt, ...)
> __attribute__((format(printf,2,3)));
> int cmdline_in(struct cmdline *cl, const char *buf, int size);
> -int cmdline_write_char(struct rdline *rdl, char c);
>
> /**
> * This function is nonblocking equivalent of ``cmdline_interact()``. It polls
> diff --git a/lib/librte_cmdline/cmdline_cirbuf.c b/lib/librte_cmdline/cmdline_cirbuf.c
> deleted file mode 100644
> index f506f88..0000000
> --- a/lib/librte_cmdline/cmdline_cirbuf.c
> +++ /dev/null
> @@ -1,466 +0,0 @@
> -/*-
> - * BSD LICENSE
> - *
> - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - * All rights reserved.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in
> - * the documentation and/or other materials provided with the
> - * distribution.
> - * * Neither the name of Intel Corporation nor the names of its
> - * contributors may be used to endorse or promote products derived
> - * from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in the
> - * documentation and/or other materials provided with the distribution.
> - * * Neither the name of the University of California, Berkeley nor the
> - * names of its contributors may be used to endorse or promote products
> - * derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include <string.h>
> -#include <errno.h>
> -#include <stdio.h>
> -
> -#include "cmdline_cirbuf.h"
> -
> -
> -int
> -cirbuf_init(struct cirbuf *cbuf, char *buf, unsigned int start, unsigned int maxlen)
> -{
> - if (!cbuf || !buf)
> - return -EINVAL;
> - cbuf->maxlen = maxlen;
> - cbuf->len = 0;
> - cbuf->start = start;
> - cbuf->end = start;
> - cbuf->buf = buf;
> - return 0;
> -}
> -
> -/* multiple add */
> -
> -int
> -cirbuf_add_buf_head(struct cirbuf *cbuf, const char *c, unsigned int n)
> -{
> - unsigned int e;
> -
> - if (!cbuf || !c || !n || n > CIRBUF_GET_FREELEN(cbuf))
> - return -EINVAL;
> -
> - e = CIRBUF_IS_EMPTY(cbuf) ? 1 : 0;
> -
> - if (n < cbuf->start + e) {
> - dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->start - n + e, n);
> - memcpy(cbuf->buf + cbuf->start - n + e, c, n);
> - }
> - else {
> - dprintf("s[%d] -> d[%d] (%d)\n", + n - (cbuf->start + e), 0,
> - cbuf->start + e);
> - dprintf("s[%d] -> d[%d] (%d)\n", cbuf->maxlen - n +
> - (cbuf->start + e), 0, n - (cbuf->start + e));
> - memcpy(cbuf->buf, c + n - (cbuf->start + e) , cbuf->start + e);
> - memcpy(cbuf->buf + cbuf->maxlen - n + (cbuf->start + e), c,
> - n - (cbuf->start + e));
> - }
> - cbuf->len += n;
> - cbuf->start += (cbuf->maxlen - n + e);
> - cbuf->start %= cbuf->maxlen;
> - return n;
> -}
> -
> -/* multiple add */
> -
> -int
> -cirbuf_add_buf_tail(struct cirbuf *cbuf, const char *c, unsigned int n)
> -{
> - unsigned int e;
> -
> - if (!cbuf || !c || !n || n > CIRBUF_GET_FREELEN(cbuf))
> - return -EINVAL;
> -
> - e = CIRBUF_IS_EMPTY(cbuf) ? 1 : 0;
> -
> - if (n < cbuf->maxlen - cbuf->end - 1 + e) {
> - dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->end + !e, n);
> - memcpy(cbuf->buf + cbuf->end + !e, c, n);
> - }
> - else {
> - dprintf("s[%d] -> d[%d] (%d)\n", cbuf->end + !e, 0,
> - cbuf->maxlen - cbuf->end - 1 + e);
> - dprintf("s[%d] -> d[%d] (%d)\n", cbuf->maxlen - cbuf->end - 1 +
> - e, 0, n - cbuf->maxlen + cbuf->end + 1 - e);
> - memcpy(cbuf->buf + cbuf->end + !e, c, cbuf->maxlen -
> - cbuf->end - 1 + e);
> - memcpy(cbuf->buf, c + cbuf->maxlen - cbuf->end - 1 + e,
> - n - cbuf->maxlen + cbuf->end + 1 - e);
> - }
> - cbuf->len += n;
> - cbuf->end += n - e;
> - cbuf->end %= cbuf->maxlen;
> - return n;
> -}
> -
> -/* add at head */
> -
> -static inline void
> -__cirbuf_add_head(struct cirbuf * cbuf, char c)
> -{
> - if (!CIRBUF_IS_EMPTY(cbuf)) {
> - cbuf->start += (cbuf->maxlen - 1);
> - cbuf->start %= cbuf->maxlen;
> - }
> - cbuf->buf[cbuf->start] = c;
> - cbuf->len ++;
> -}
> -
> -int
> -cirbuf_add_head_safe(struct cirbuf * cbuf, char c)
> -{
> - if (cbuf && !CIRBUF_IS_FULL(cbuf)) {
> - __cirbuf_add_head(cbuf, c);
> - return 0;
> - }
> - return -EINVAL;
> -}
> -
> -void
> -cirbuf_add_head(struct cirbuf * cbuf, char c)
> -{
> - __cirbuf_add_head(cbuf, c);
> -}
> -
> -/* add at tail */
> -
> -static inline void
> -__cirbuf_add_tail(struct cirbuf * cbuf, char c)
> -{
> - if (!CIRBUF_IS_EMPTY(cbuf)) {
> - cbuf->end ++;
> - cbuf->end %= cbuf->maxlen;
> - }
> - cbuf->buf[cbuf->end] = c;
> - cbuf->len ++;
> -}
> -
> -int
> -cirbuf_add_tail_safe(struct cirbuf * cbuf, char c)
> -{
> - if (cbuf && !CIRBUF_IS_FULL(cbuf)) {
> - __cirbuf_add_tail(cbuf, c);
> - return 0;
> - }
> - return -EINVAL;
> -}
> -
> -void
> -cirbuf_add_tail(struct cirbuf * cbuf, char c)
> -{
> - __cirbuf_add_tail(cbuf, c);
> -}
> -
> -
> -static inline void
> -__cirbuf_shift_left(struct cirbuf *cbuf)
> -{
> - unsigned int i;
> - char tmp = cbuf->buf[cbuf->start];
> -
> - for (i=0 ; i<cbuf->len ; i++) {
> - cbuf->buf[(cbuf->start+i)%cbuf->maxlen] =
> - cbuf->buf[(cbuf->start+i+1)%cbuf->maxlen];
> - }
> - cbuf->buf[(cbuf->start-1+cbuf->maxlen)%cbuf->maxlen] = tmp;
> - cbuf->start += (cbuf->maxlen - 1);
> - cbuf->start %= cbuf->maxlen;
> - cbuf->end += (cbuf->maxlen - 1);
> - cbuf->end %= cbuf->maxlen;
> -}
> -
> -static inline void
> -__cirbuf_shift_right(struct cirbuf *cbuf)
> -{
> - unsigned int i;
> - char tmp = cbuf->buf[cbuf->end];
> -
> - for (i=0 ; i<cbuf->len ; i++) {
> - cbuf->buf[(cbuf->end+cbuf->maxlen-i)%cbuf->maxlen] =
> - cbuf->buf[(cbuf->end+cbuf->maxlen-i-1)%cbuf->maxlen];
> - }
> - cbuf->buf[(cbuf->end+1)%cbuf->maxlen] = tmp;
> - cbuf->start += 1;
> - cbuf->start %= cbuf->maxlen;
> - cbuf->end += 1;
> - cbuf->end %= cbuf->maxlen;
> -}
> -
> -/* XXX we could do a better algorithm here... */
> -int
> -cirbuf_align_left(struct cirbuf * cbuf)
> -{
> - if (!cbuf)
> - return -EINVAL;
> -
> - if (cbuf->start < cbuf->maxlen/2) {
> - while (cbuf->start != 0) {
> - __cirbuf_shift_left(cbuf);
> - }
> - }
> - else {
> - while (cbuf->start != 0) {
> - __cirbuf_shift_right(cbuf);
> - }
> - }
> -
> - return 0;
> -}
> -
> -/* XXX we could do a better algorithm here... */
> -int
> -cirbuf_align_right(struct cirbuf * cbuf)
> -{
> - if (!cbuf)
> - return -EINVAL;
> -
> - if (cbuf->start >= cbuf->maxlen/2) {
> - while (cbuf->end != cbuf->maxlen-1) {
> - __cirbuf_shift_left(cbuf);
> - }
> - }
> - else {
> - while (cbuf->start != cbuf->maxlen-1) {
> - __cirbuf_shift_right(cbuf);
> - }
> - }
> -
> - return 0;
> -}
> -
> -/* buffer del */
> -
> -int
> -cirbuf_del_buf_head(struct cirbuf *cbuf, unsigned int size)
> -{
> - if (!cbuf || !size || size > CIRBUF_GET_LEN(cbuf))
> - return -EINVAL;
> -
> - cbuf->len -= size;
> - if (CIRBUF_IS_EMPTY(cbuf)) {
> - cbuf->start += size - 1;
> - cbuf->start %= cbuf->maxlen;
> - }
> - else {
> - cbuf->start += size;
> - cbuf->start %= cbuf->maxlen;
> - }
> - return 0;
> -}
> -
> -/* buffer del */
> -
> -int
> -cirbuf_del_buf_tail(struct cirbuf *cbuf, unsigned int size)
> -{
> - if (!cbuf || !size || size > CIRBUF_GET_LEN(cbuf))
> - return -EINVAL;
> -
> - cbuf->len -= size;
> - if (CIRBUF_IS_EMPTY(cbuf)) {
> - cbuf->end += (cbuf->maxlen - size + 1);
> - cbuf->end %= cbuf->maxlen;
> - }
> - else {
> - cbuf->end += (cbuf->maxlen - size);
> - cbuf->end %= cbuf->maxlen;
> - }
> - return 0;
> -}
> -
> -/* del at head */
> -
> -static inline void
> -__cirbuf_del_head(struct cirbuf * cbuf)
> -{
> - cbuf->len --;
> - if (!CIRBUF_IS_EMPTY(cbuf)) {
> - cbuf->start ++;
> - cbuf->start %= cbuf->maxlen;
> - }
> -}
> -
> -int
> -cirbuf_del_head_safe(struct cirbuf * cbuf)
> -{
> - if (cbuf && !CIRBUF_IS_EMPTY(cbuf)) {
> - __cirbuf_del_head(cbuf);
> - return 0;
> - }
> - return -EINVAL;
> -}
> -
> -void
> -cirbuf_del_head(struct cirbuf * cbuf)
> -{
> - __cirbuf_del_head(cbuf);
> -}
> -
> -/* del at tail */
> -
> -static inline void
> -__cirbuf_del_tail(struct cirbuf * cbuf)
> -{
> - cbuf->len --;
> - if (!CIRBUF_IS_EMPTY(cbuf)) {
> - cbuf->end += (cbuf->maxlen - 1);
> - cbuf->end %= cbuf->maxlen;
> - }
> -}
> -
> -int
> -cirbuf_del_tail_safe(struct cirbuf * cbuf)
> -{
> - if (cbuf && !CIRBUF_IS_EMPTY(cbuf)) {
> - __cirbuf_del_tail(cbuf);
> - return 0;
> - }
> - return -EINVAL;
> -}
> -
> -void
> -cirbuf_del_tail(struct cirbuf * cbuf)
> -{
> - __cirbuf_del_tail(cbuf);
> -}
> -
> -/* convert to buffer */
> -
> -int
> -cirbuf_get_buf_head(struct cirbuf *cbuf, char *c, unsigned int size)
> -{
> - unsigned int n;
> -
> - if (!cbuf || !c)
> - return -EINVAL;
> -
> - n = (size < CIRBUF_GET_LEN(cbuf)) ? size : CIRBUF_GET_LEN(cbuf);
> -
> - if (!n)
> - return 0;
> -
> - if (cbuf->start <= cbuf->end) {
> - dprintf("s[%d] -> d[%d] (%d)\n", cbuf->start, 0, n);
> - memcpy(c, cbuf->buf + cbuf->start , n);
> - }
> - else {
> - /* check if we need to go from end to the beginning */
> - if (n <= cbuf->maxlen - cbuf->start) {
> - dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->start, n);
> - memcpy(c, cbuf->buf + cbuf->start , n);
> - }
> - else {
> - dprintf("s[%d] -> d[%d] (%d)\n", cbuf->start, 0,
> - cbuf->maxlen - cbuf->start);
> - dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->maxlen - cbuf->start,
> - n - cbuf->maxlen + cbuf->start);
> - memcpy(c, cbuf->buf + cbuf->start , cbuf->maxlen - cbuf->start);
> - memcpy(c + cbuf->maxlen - cbuf->start, cbuf->buf,
> - n - cbuf->maxlen + cbuf->start);
> - }
> - }
> - return n;
> -}
> -
> -/* convert to buffer */
> -
> -int
> -cirbuf_get_buf_tail(struct cirbuf *cbuf, char *c, unsigned int size)
> -{
> - unsigned int n;
> -
> - if (!cbuf || !c)
> - return -EINVAL;
> -
> - n = (size < CIRBUF_GET_LEN(cbuf)) ? size : CIRBUF_GET_LEN(cbuf);
> -
> - if (!n)
> - return 0;
> -
> - if (cbuf->start <= cbuf->end) {
> - dprintf("s[%d] -> d[%d] (%d)\n", cbuf->end - n + 1, 0, n);
> - memcpy(c, cbuf->buf + cbuf->end - n + 1, n);
> - }
> - else {
> - /* check if we need to go from end to the beginning */
> - if (n <= cbuf->end + 1) {
> - dprintf("s[%d] -> d[%d] (%d)\n", 0, cbuf->end - n + 1, n);
> - memcpy(c, cbuf->buf + cbuf->end - n + 1, n);
> - }
> - else {
> - dprintf("s[%d] -> d[%d] (%d)\n", 0,
> - cbuf->maxlen - cbuf->start, cbuf->end + 1);
> - dprintf("s[%d] -> d[%d] (%d)\n",
> - cbuf->maxlen - n + cbuf->end + 1, 0, n - cbuf->end - 1);
> - memcpy(c + cbuf->maxlen - cbuf->start,
> - cbuf->buf, cbuf->end + 1);
> - memcpy(c, cbuf->buf + cbuf->maxlen - n + cbuf->end +1,
> - n - cbuf->end - 1);
> - }
> - }
> - return n;
> -}
> -
> -/* get head or get tail */
> -
> -char
> -cirbuf_get_head(struct cirbuf * cbuf)
> -{
> - return cbuf->buf[cbuf->start];
> -}
> -
> -/* get head or get tail */
> -
> -char
> -cirbuf_get_tail(struct cirbuf * cbuf)
> -{
> - return cbuf->buf[cbuf->end];
> -}
> diff --git a/lib/librte_cmdline/cmdline_cirbuf.h b/lib/librte_cmdline/cmdline_cirbuf.h
> deleted file mode 100644
> index 6321dec..0000000
> --- a/lib/librte_cmdline/cmdline_cirbuf.h
> +++ /dev/null
> @@ -1,245 +0,0 @@
> -/*-
> - * BSD LICENSE
> - *
> - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - * All rights reserved.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in
> - * the documentation and/or other materials provided with the
> - * distribution.
> - * * Neither the name of Intel Corporation nor the names of its
> - * contributors may be used to endorse or promote products derived
> - * from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in the
> - * documentation and/or other materials provided with the distribution.
> - * * Neither the name of the University of California, Berkeley nor the
> - * names of its contributors may be used to endorse or promote products
> - * derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#ifndef _CIRBUF_H_
> -#define _CIRBUF_H_
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -/**
> - * This structure is the header of a cirbuf type.
> - */
> -struct cirbuf {
> - unsigned int maxlen; /**< total len of the fifo (number of elements) */
> - unsigned int start; /**< indice of the first elt */
> - unsigned int end; /**< indice of the last elt */
> - unsigned int len; /**< current len of fifo */
> - char *buf;
> -};
> -
> -#ifdef RTE_LIBRTE_CMDLINE_DEBUG
> -#define dprintf_(fmt, ...) printf("line %3.3d - " fmt "%.0s", __LINE__, __VA_ARGS__)
> -#define dprintf(...) dprintf_(__VA_ARGS__, "dummy")
> -#else
> -#define dprintf(...) (void)0
> -#endif
> -
> -
> -/**
> - * Init the circular buffer
> - */
> -int cirbuf_init(struct cirbuf *cbuf, char *buf, unsigned int start, unsigned int maxlen);
> -
> -
> -/**
> - * Return 1 if the circular buffer is full
> - */
> -#define CIRBUF_IS_FULL(cirbuf) ((cirbuf)->maxlen == (cirbuf)->len)
> -
> -/**
> - * Return 1 if the circular buffer is empty
> - */
> -#define CIRBUF_IS_EMPTY(cirbuf) ((cirbuf)->len == 0)
> -
> -/**
> - * return current size of the circular buffer (number of used elements)
> - */
> -#define CIRBUF_GET_LEN(cirbuf) ((cirbuf)->len)
> -
> -/**
> - * return size of the circular buffer (used + free elements)
> - */
> -#define CIRBUF_GET_MAXLEN(cirbuf) ((cirbuf)->maxlen)
> -
> -/**
> - * return the number of free elts
> - */
> -#define CIRBUF_GET_FREELEN(cirbuf) ((cirbuf)->maxlen - (cirbuf)->len)
> -
> -/**
> - * Iterator for a circular buffer
> - * c: struct cirbuf pointer
> - * i: an integer type internally used in the macro
> - * e: char that takes the value for each iteration
> - */
> -#define CIRBUF_FOREACH(c, i, e) \
> - for ( i=0, e=(c)->buf[(c)->start] ; \
> - i<((c)->len) ; \
> - i ++, e=(c)->buf[((c)->start+i)%((c)->maxlen)])
> -
> -
> -/**
> - * Add a character at head of the circular buffer. Return 0 on success, or
> - * a negative value on error.
> - */
> -int cirbuf_add_head_safe(struct cirbuf *cbuf, char c);
> -
> -/**
> - * Add a character at head of the circular buffer. You _must_ check that you
> - * have enough free space in the buffer before calling this func.
> - */
> -void cirbuf_add_head(struct cirbuf *cbuf, char c);
> -
> -/**
> - * Add a character at tail of the circular buffer. Return 0 on success, or
> - * a negative value on error.
> - */
> -int cirbuf_add_tail_safe(struct cirbuf *cbuf, char c);
> -
> -/**
> - * Add a character at tail of the circular buffer. You _must_ check that you
> - * have enough free space in the buffer before calling this func.
> - */
> -void cirbuf_add_tail(struct cirbuf *cbuf, char c);
> -
> -/**
> - * Remove a char at the head of the circular buffer. Return 0 on
> - * success, or a negative value on error.
> - */
> -int cirbuf_del_head_safe(struct cirbuf *cbuf);
> -
> -/**
> - * Remove a char at the head of the circular buffer. You _must_ check
> - * that buffer is not empty before calling the function.
> - */
> -void cirbuf_del_head(struct cirbuf *cbuf);
> -
> -/**
> - * Remove a char at the tail of the circular buffer. Return 0 on
> - * success, or a negative value on error.
> - */
> -int cirbuf_del_tail_safe(struct cirbuf *cbuf);
> -
> -/**
> - * Remove a char at the tail of the circular buffer. You _must_ check
> - * that buffer is not empty before calling the function.
> - */
> -void cirbuf_del_tail(struct cirbuf *cbuf);
> -
> -/**
> - * Return the head of the circular buffer. You _must_ check that
> - * buffer is not empty before calling the function.
> - */
> -char cirbuf_get_head(struct cirbuf *cbuf);
> -
> -/**
> - * Return the tail of the circular buffer. You _must_ check that
> - * buffer is not empty before calling the function.
> - */
> -char cirbuf_get_tail(struct cirbuf *cbuf);
> -
> -/**
> - * Add a buffer at head of the circular buffer. 'c' is a pointer to a
> - * buffer, and n is the number of char to add. Return the number of
> - * copied bytes on success, or a negative value on error.
> - */
> -int cirbuf_add_buf_head(struct cirbuf *cbuf, const char *c, unsigned int n);
> -
> -/**
> - * Add a buffer at tail of the circular buffer. 'c' is a pointer to a
> - * buffer, and n is the number of char to add. Return the number of
> - * copied bytes on success, or a negative value on error.
> - */
> -int cirbuf_add_buf_tail(struct cirbuf *cbuf, const char *c, unsigned int n);
> -
> -/**
> - * Remove chars at the head of the circular buffer. Return 0 on
> - * success, or a negative value on error.
> - */
> -int cirbuf_del_buf_head(struct cirbuf *cbuf, unsigned int size);
> -
> -/**
> - * Remove chars at the tail of the circular buffer. Return 0 on
> - * success, or a negative value on error.
> - */
> -int cirbuf_del_buf_tail(struct cirbuf *cbuf, unsigned int size);
> -
> -/**
> - * Copy a maximum of 'size' characters from the head of the circular
> - * buffer to a flat one pointed by 'c'. Return the number of copied
> - * chars.
> - */
> -int cirbuf_get_buf_head(struct cirbuf *cbuf, char *c, unsigned int size);
> -
> -/**
> - * Copy a maximum of 'size' characters from the tail of the circular
> - * buffer to a flat one pointed by 'c'. Return the number of copied
> - * chars.
> - */
> -int cirbuf_get_buf_tail(struct cirbuf *cbuf, char *c, unsigned int size);
> -
> -
> -/**
> - * Set the start of the data to the index 0 of the internal buffer.
> - */
> -int cirbuf_align_left(struct cirbuf *cbuf);
> -
> -/**
> - * Set the end of the data to the last index of the internal buffer.
> - */
> -int cirbuf_align_right(struct cirbuf *cbuf);
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif /* _CIRBUF_H_ */
> diff --git a/lib/librte_cmdline/cmdline_parse.c b/lib/librte_cmdline/cmdline_parse.c
> index 3e12ee5..0cc0b57 100644
> --- a/lib/librte_cmdline/cmdline_parse.c
> +++ b/lib/librte_cmdline/cmdline_parse.c
> @@ -70,7 +70,6 @@
>
> #include <rte_string_fns.h>
>
> -#include "cmdline_rdline.h"
> #include "cmdline_parse.h"
> #include "cmdline.h"
>
> @@ -267,7 +266,7 @@ cmdline_parse(struct cmdline *cl, const char * buf)
> if (!cl || !buf)
> return CMDLINE_PARSE_BAD_ARGS;
>
> - ctx = cl->ctx;
> + ctx = cmdline_ctx_get(cl);
>
> /*
> * - look if the buffer contains at least one line
> @@ -386,7 +385,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state,
> if (!cl || !buf || !state || !dst)
> return -1;
>
> - ctx = cl->ctx;
> + ctx = cmdline_ctx_get(cl);
>
> debug_printf("%s called\n", __func__);
> memset(&token_hdr, 0, sizeof(token_hdr));
> @@ -398,7 +397,7 @@ cmdline_complete(struct cmdline *cl, const char *buf, int *state,
> if (isblank2(buf[i]) && !isblank2(buf[i+1]))
> partial_tok = buf+i+1;
> }
> - partial_tok_len = strnlen(partial_tok, RDLINE_BUF_SIZE);
> + partial_tok_len = strlen(partial_tok);
>
> /* first call -> do a first pass */
> if (*state <= 0) {
> diff --git a/lib/librte_cmdline/cmdline_rdline.c b/lib/librte_cmdline/cmdline_rdline.c
> deleted file mode 100644
> index 1ef2258..0000000
> --- a/lib/librte_cmdline/cmdline_rdline.c
> +++ /dev/null
> @@ -1,697 +0,0 @@
> -/*-
> - * BSD LICENSE
> - *
> - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - * All rights reserved.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in
> - * the documentation and/or other materials provided with the
> - * distribution.
> - * * Neither the name of Intel Corporation nor the names of its
> - * contributors may be used to endorse or promote products derived
> - * from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in the
> - * documentation and/or other materials provided with the distribution.
> - * * Neither the name of the University of California, Berkeley nor the
> - * names of its contributors may be used to endorse or promote products
> - * derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include <stdlib.h>
> -#include <stdio.h>
> -#include <stdint.h>
> -#include <string.h>
> -#include <stdarg.h>
> -#include <errno.h>
> -#include <ctype.h>
> -
> -#include "cmdline_cirbuf.h"
> -#include "cmdline_rdline.h"
> -
> -static void rdline_puts(struct rdline *rdl, const char *buf);
> -static void rdline_miniprintf(struct rdline *rdl,
> - const char *buf, unsigned int val);
> -
> -static void rdline_remove_old_history_item(struct rdline *rdl);
> -static void rdline_remove_first_history_item(struct rdline *rdl);
> -static unsigned int rdline_get_history_size(struct rdline *rdl);
> -
> -
> -/* isblank() needs _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE, so use our
> - * own. */
> -static int
> -isblank2(char c)
> -{
> - if (c == ' ' ||
> - c == '\t' )
> - return 1;
> - return 0;
> -}
> -
> -int
> -rdline_init(struct rdline *rdl,
> - rdline_write_char_t *write_char,
> - rdline_validate_t *validate,
> - rdline_complete_t *complete)
> -{
> - if (!rdl || !write_char || !validate || !complete)
> - return -EINVAL;
> - memset(rdl, 0, sizeof(*rdl));
> - rdl->validate = validate;
> - rdl->complete = complete;
> - rdl->write_char = write_char;
> - rdl->status = RDLINE_INIT;
> - return cirbuf_init(&rdl->history, rdl->history_buf, 0, RDLINE_HISTORY_BUF_SIZE);
> -}
> -
> -void
> -rdline_newline(struct rdline *rdl, const char *prompt)
> -{
> - unsigned int i;
> -
> - if (!rdl || !prompt)
> - return;
> -
> - vt100_init(&rdl->vt100);
> - cirbuf_init(&rdl->left, rdl->left_buf, 0, RDLINE_BUF_SIZE);
> - cirbuf_init(&rdl->right, rdl->right_buf, 0, RDLINE_BUF_SIZE);
> -
> - rdl->prompt_size = strnlen(prompt, RDLINE_PROMPT_SIZE-1);
> - if (prompt != rdl->prompt)
> - memcpy(rdl->prompt, prompt, rdl->prompt_size);
> - rdl->prompt[RDLINE_PROMPT_SIZE-1] = '\0';
> -
> - for (i=0 ; i<rdl->prompt_size ; i++)
> - rdl->write_char(rdl, rdl->prompt[i]);
> - rdl->status = RDLINE_RUNNING;
> -
> - rdl->history_cur_line = -1;
> -}
> -
> -void
> -rdline_stop(struct rdline *rdl)
> -{
> - if (!rdl)
> - return;
> - rdl->status = RDLINE_INIT;
> -}
> -
> -void
> -rdline_quit(struct rdline *rdl)
> -{
> - if (!rdl)
> - return;
> - rdl->status = RDLINE_EXITED;
> -}
> -
> -void
> -rdline_restart(struct rdline *rdl)
> -{
> - if (!rdl)
> - return;
> - rdl->status = RDLINE_RUNNING;
> -}
> -
> -void
> -rdline_reset(struct rdline *rdl)
> -{
> - if (!rdl)
> - return;
> - vt100_init(&rdl->vt100);
> - cirbuf_init(&rdl->left, rdl->left_buf, 0, RDLINE_BUF_SIZE);
> - cirbuf_init(&rdl->right, rdl->right_buf, 0, RDLINE_BUF_SIZE);
> -
> - rdl->status = RDLINE_RUNNING;
> -
> - rdl->history_cur_line = -1;
> -}
> -
> -const char *
> -rdline_get_buffer(struct rdline *rdl)
> -{
> - if (!rdl)
> - return NULL;
> - unsigned int len_l, len_r;
> - cirbuf_align_left(&rdl->left);
> - cirbuf_align_left(&rdl->right);
> -
> - len_l = CIRBUF_GET_LEN(&rdl->left);
> - len_r = CIRBUF_GET_LEN(&rdl->right);
> - memcpy(rdl->left_buf+len_l, rdl->right_buf, len_r);
> -
> - rdl->left_buf[len_l + len_r] = '\n';
> - rdl->left_buf[len_l + len_r + 1] = '\0';
> - return rdl->left_buf;
> -}
> -
> -static void
> -display_right_buffer(struct rdline *rdl, int force)
> -{
> - unsigned int i;
> - char tmp;
> -
> - if (!force && CIRBUF_IS_EMPTY(&rdl->right))
> - return;
> -
> - rdline_puts(rdl, vt100_clear_right);
> - CIRBUF_FOREACH(&rdl->right, i, tmp) {
> - rdl->write_char(rdl, tmp);
> - }
> - if (!CIRBUF_IS_EMPTY(&rdl->right))
> - rdline_miniprintf(rdl, vt100_multi_left,
> - CIRBUF_GET_LEN(&rdl->right));
> -}
> -
> -void
> -rdline_redisplay(struct rdline *rdl)
> -{
> - unsigned int i;
> - char tmp;
> -
> - if (!rdl)
> - return;
> -
> - rdline_puts(rdl, vt100_home);
> - for (i=0 ; i<rdl->prompt_size ; i++)
> - rdl->write_char(rdl, rdl->prompt[i]);
> - CIRBUF_FOREACH(&rdl->left, i, tmp) {
> - rdl->write_char(rdl, tmp);
> - }
> - display_right_buffer(rdl, 1);
> -}
> -
> -int
> -rdline_char_in(struct rdline *rdl, char c)
> -{
> - unsigned int i;
> - int cmd;
> - char tmp;
> - char *buf;
> -
> - if (!rdl)
> - return -EINVAL;
> -
> - if (rdl->status == RDLINE_EXITED)
> - return RDLINE_RES_EXITED;
> - if (rdl->status != RDLINE_RUNNING)
> - return RDLINE_RES_NOT_RUNNING;
> -
> - cmd = vt100_parser(&rdl->vt100, c);
> - if (cmd == -2)
> - return RDLINE_RES_SUCCESS;
> -
> - if (cmd >= 0) {
> - switch (cmd) {
> - /* move caret 1 char to the left */
> - case CMDLINE_KEY_CTRL_B:
> - case CMDLINE_KEY_LEFT_ARR:
> - if (CIRBUF_IS_EMPTY(&rdl->left))
> - break;
> - tmp = cirbuf_get_tail(&rdl->left);
> - cirbuf_del_tail(&rdl->left);
> - cirbuf_add_head(&rdl->right, tmp);
> - rdline_puts(rdl, vt100_left_arr);
> - break;
> -
> - /* move caret 1 char to the right */
> - case CMDLINE_KEY_CTRL_F:
> - case CMDLINE_KEY_RIGHT_ARR:
> - if (CIRBUF_IS_EMPTY(&rdl->right))
> - break;
> - tmp = cirbuf_get_head(&rdl->right);
> - cirbuf_del_head(&rdl->right);
> - cirbuf_add_tail(&rdl->left, tmp);
> - rdline_puts(rdl, vt100_right_arr);
> - break;
> -
> - /* move caret 1 word to the left */
> - /* keyboard equivalent: Alt+B */
> - case CMDLINE_KEY_WLEFT:
> - while (! CIRBUF_IS_EMPTY(&rdl->left) &&
> - (tmp = cirbuf_get_tail(&rdl->left)) &&
> - isblank2(tmp)) {
> - rdline_puts(rdl, vt100_left_arr);
> - cirbuf_del_tail(&rdl->left);
> - cirbuf_add_head(&rdl->right, tmp);
> - }
> - while (! CIRBUF_IS_EMPTY(&rdl->left) &&
> - (tmp = cirbuf_get_tail(&rdl->left)) &&
> - !isblank2(tmp)) {
> - rdline_puts(rdl, vt100_left_arr);
> - cirbuf_del_tail(&rdl->left);
> - cirbuf_add_head(&rdl->right, tmp);
> - }
> - break;
> -
> - /* move caret 1 word to the right */
> - /* keyboard equivalent: Alt+F */
> - case CMDLINE_KEY_WRIGHT:
> - while (! CIRBUF_IS_EMPTY(&rdl->right) &&
> - (tmp = cirbuf_get_head(&rdl->right)) &&
> - isblank2(tmp)) {
> - rdline_puts(rdl, vt100_right_arr);
> - cirbuf_del_head(&rdl->right);
> - cirbuf_add_tail(&rdl->left, tmp);
> - }
> - while (! CIRBUF_IS_EMPTY(&rdl->right) &&
> - (tmp = cirbuf_get_head(&rdl->right)) &&
> - !isblank2(tmp)) {
> - rdline_puts(rdl, vt100_right_arr);
> - cirbuf_del_head(&rdl->right);
> - cirbuf_add_tail(&rdl->left, tmp);
> - }
> - break;
> -
> - /* move caret to the left */
> - case CMDLINE_KEY_CTRL_A:
> - if (CIRBUF_IS_EMPTY(&rdl->left))
> - break;
> - rdline_miniprintf(rdl, vt100_multi_left,
> - CIRBUF_GET_LEN(&rdl->left));
> - while (! CIRBUF_IS_EMPTY(&rdl->left)) {
> - tmp = cirbuf_get_tail(&rdl->left);
> - cirbuf_del_tail(&rdl->left);
> - cirbuf_add_head(&rdl->right, tmp);
> - }
> - break;
> -
> - /* move caret to the right */
> - case CMDLINE_KEY_CTRL_E:
> - if (CIRBUF_IS_EMPTY(&rdl->right))
> - break;
> - rdline_miniprintf(rdl, vt100_multi_right,
> - CIRBUF_GET_LEN(&rdl->right));
> - while (! CIRBUF_IS_EMPTY(&rdl->right)) {
> - tmp = cirbuf_get_head(&rdl->right);
> - cirbuf_del_head(&rdl->right);
> - cirbuf_add_tail(&rdl->left, tmp);
> - }
> - break;
> -
> - /* delete 1 char from the left */
> - case CMDLINE_KEY_BKSPACE:
> - if(!cirbuf_del_tail_safe(&rdl->left)) {
> - rdline_puts(rdl, vt100_bs);
> - display_right_buffer(rdl, 1);
> - }
> - break;
> -
> - /* delete 1 char from the right */
> - case CMDLINE_KEY_SUPPR:
> - case CMDLINE_KEY_CTRL_D:
> - if (cmd == CMDLINE_KEY_CTRL_D &&
> - CIRBUF_IS_EMPTY(&rdl->left) &&
> - CIRBUF_IS_EMPTY(&rdl->right)) {
> - return RDLINE_RES_EOF;
> - }
> - if (!cirbuf_del_head_safe(&rdl->right)) {
> - display_right_buffer(rdl, 1);
> - }
> - break;
> -
> - /* delete 1 word from the left */
> - case CMDLINE_KEY_META_BKSPACE:
> - case CMDLINE_KEY_CTRL_W:
> - while (! CIRBUF_IS_EMPTY(&rdl->left) && isblank2(cirbuf_get_tail(&rdl->left))) {
> - rdline_puts(rdl, vt100_bs);
> - cirbuf_del_tail(&rdl->left);
> - }
> - while (! CIRBUF_IS_EMPTY(&rdl->left) && !isblank2(cirbuf_get_tail(&rdl->left))) {
> - rdline_puts(rdl, vt100_bs);
> - cirbuf_del_tail(&rdl->left);
> - }
> - display_right_buffer(rdl, 1);
> - break;
> -
> - /* delete 1 word from the right */
> - case CMDLINE_KEY_META_D:
> - while (! CIRBUF_IS_EMPTY(&rdl->right) && isblank2(cirbuf_get_head(&rdl->right)))
> - cirbuf_del_head(&rdl->right);
> - while (! CIRBUF_IS_EMPTY(&rdl->right) && !isblank2(cirbuf_get_head(&rdl->right)))
> - cirbuf_del_head(&rdl->right);
> - display_right_buffer(rdl, 1);
> - break;
> -
> - /* set kill buffer to contents on the right side of caret */
> - case CMDLINE_KEY_CTRL_K:
> - cirbuf_get_buf_head(&rdl->right, rdl->kill_buf, RDLINE_BUF_SIZE);
> - rdl->kill_size = CIRBUF_GET_LEN(&rdl->right);
> - cirbuf_del_buf_head(&rdl->right, rdl->kill_size);
> - rdline_puts(rdl, vt100_clear_right);
> - break;
> -
> - /* paste contents of kill buffer to the left side of caret */
> - case CMDLINE_KEY_CTRL_Y:
> - i=0;
> - while(CIRBUF_GET_LEN(&rdl->right) + CIRBUF_GET_LEN(&rdl->left) <
> - RDLINE_BUF_SIZE &&
> - i < rdl->kill_size) {
> - cirbuf_add_tail(&rdl->left, rdl->kill_buf[i]);
> - rdl->write_char(rdl, rdl->kill_buf[i]);
> - i++;
> - }
> - display_right_buffer(rdl, 0);
> - break;
> -
> - /* clear and newline */
> - case CMDLINE_KEY_CTRL_C:
> - rdline_puts(rdl, "\r\n");
> - rdline_newline(rdl, rdl->prompt);
> - break;
> -
> - /* redisplay (helps when prompt is lost in other output) */
> - case CMDLINE_KEY_CTRL_L:
> - rdline_redisplay(rdl);
> - break;
> -
> - /* autocomplete */
> - case CMDLINE_KEY_TAB:
> - case CMDLINE_KEY_HELP:
> - cirbuf_align_left(&rdl->left);
> - rdl->left_buf[CIRBUF_GET_LEN(&rdl->left)] = '\0';
> - if (rdl->complete) {
> - char tmp_buf[BUFSIZ];
> - int complete_state;
> - int ret;
> - unsigned int tmp_size;
> -
> - if (cmd == CMDLINE_KEY_TAB)
> - complete_state = 0;
> - else
> - complete_state = -1;
> -
> - /* see in parse.h for help on complete() */
> - ret = rdl->complete(rdl, rdl->left_buf,
> - tmp_buf, sizeof(tmp_buf),
> - &complete_state);
> - /* no completion or error */
> - if (ret <= 0) {
> - return RDLINE_RES_COMPLETE;
> - }
> -
> - tmp_size = strnlen(tmp_buf, sizeof(tmp_buf));
> - /* add chars */
> - if (ret == RDLINE_RES_COMPLETE) {
> - i=0;
> - while(CIRBUF_GET_LEN(&rdl->right) + CIRBUF_GET_LEN(&rdl->left) <
> - RDLINE_BUF_SIZE &&
> - i < tmp_size) {
> - cirbuf_add_tail(&rdl->left, tmp_buf[i]);
> - rdl->write_char(rdl, tmp_buf[i]);
> - i++;
> - }
> - display_right_buffer(rdl, 1);
> - return RDLINE_RES_COMPLETE; /* ?? */
> - }
> -
> - /* choice */
> - rdline_puts(rdl, "\r\n");
> - while (ret) {
> - rdl->write_char(rdl, ' ');
> - for (i=0 ; tmp_buf[i] ; i++)
> - rdl->write_char(rdl, tmp_buf[i]);
> - rdline_puts(rdl, "\r\n");
> - ret = rdl->complete(rdl, rdl->left_buf,
> - tmp_buf, sizeof(tmp_buf),
> - &complete_state);
> - }
> -
> - rdline_redisplay(rdl);
> - }
> - return RDLINE_RES_COMPLETE;
> -
> - /* complete buffer */
> - case CMDLINE_KEY_RETURN:
> - case CMDLINE_KEY_RETURN2:
> - rdline_get_buffer(rdl);
> - rdl->status = RDLINE_INIT;
> - rdline_puts(rdl, "\r\n");
> - if (rdl->history_cur_line != -1)
> - rdline_remove_first_history_item(rdl);
> -
> - if (rdl->validate)
> - rdl->validate(rdl, rdl->left_buf, CIRBUF_GET_LEN(&rdl->left)+2);
> - /* user may have stopped rdline */
> - if (rdl->status == RDLINE_EXITED)
> - return RDLINE_RES_EXITED;
> - return RDLINE_RES_VALIDATED;
> -
> - /* previous element in history */
> - case CMDLINE_KEY_UP_ARR:
> - case CMDLINE_KEY_CTRL_P:
> - if (rdl->history_cur_line == 0) {
> - rdline_remove_first_history_item(rdl);
> - }
> - if (rdl->history_cur_line <= 0) {
> - rdline_add_history(rdl, rdline_get_buffer(rdl));
> - rdl->history_cur_line = 0;
> - }
> -
> - buf = rdline_get_history_item(rdl, rdl->history_cur_line + 1);
> - if (!buf)
> - break;
> -
> - rdl->history_cur_line ++;
> - vt100_init(&rdl->vt100);
> - cirbuf_init(&rdl->left, rdl->left_buf, 0, RDLINE_BUF_SIZE);
> - cirbuf_init(&rdl->right, rdl->right_buf, 0, RDLINE_BUF_SIZE);
> - cirbuf_add_buf_tail(&rdl->left, buf, strnlen(buf, RDLINE_BUF_SIZE));
> - rdline_redisplay(rdl);
> - break;
> -
> - /* next element in history */
> - case CMDLINE_KEY_DOWN_ARR:
> - case CMDLINE_KEY_CTRL_N:
> - if (rdl->history_cur_line - 1 < 0)
> - break;
> -
> - rdl->history_cur_line --;
> - buf = rdline_get_history_item(rdl, rdl->history_cur_line);
> - if (!buf)
> - break;
> - vt100_init(&rdl->vt100);
> - cirbuf_init(&rdl->left, rdl->left_buf, 0, RDLINE_BUF_SIZE);
> - cirbuf_init(&rdl->right, rdl->right_buf, 0, RDLINE_BUF_SIZE);
> - cirbuf_add_buf_tail(&rdl->left, buf, strnlen(buf, RDLINE_BUF_SIZE));
> - rdline_redisplay(rdl);
> -
> - break;
> -
> -
> - default:
> - break;
> - }
> -
> - return RDLINE_RES_SUCCESS;
> - }
> -
> - if (!isprint((int)c))
> - return RDLINE_RES_SUCCESS;
> -
> - /* standard chars */
> - if (CIRBUF_GET_LEN(&rdl->left) + CIRBUF_GET_LEN(&rdl->right) >= RDLINE_BUF_SIZE)
> - return RDLINE_RES_SUCCESS;
> -
> - if (cirbuf_add_tail_safe(&rdl->left, c))
> - return RDLINE_RES_SUCCESS;
> -
> - rdl->write_char(rdl, c);
> - display_right_buffer(rdl, 0);
> -
> - return RDLINE_RES_SUCCESS;
> -}
> -
> -
> -/* HISTORY */
> -
> -static void
> -rdline_remove_old_history_item(struct rdline * rdl)
> -{
> - char tmp;
> -
> - while (! CIRBUF_IS_EMPTY(&rdl->history) ) {
> - tmp = cirbuf_get_head(&rdl->history);
> - cirbuf_del_head(&rdl->history);
> - if (!tmp)
> - break;
> - }
> -}
> -
> -static void
> -rdline_remove_first_history_item(struct rdline * rdl)
> -{
> - char tmp;
> -
> - if ( CIRBUF_IS_EMPTY(&rdl->history) ) {
> - return;
> - }
> - else {
> - cirbuf_del_tail(&rdl->history);
> - }
> -
> - while (! CIRBUF_IS_EMPTY(&rdl->history) ) {
> - tmp = cirbuf_get_tail(&rdl->history);
> - if (!tmp)
> - break;
> - cirbuf_del_tail(&rdl->history);
> - }
> -}
> -
> -static unsigned int
> -rdline_get_history_size(struct rdline * rdl)
> -{
> - unsigned int i, tmp, ret=0;
> -
> - CIRBUF_FOREACH(&rdl->history, i, tmp) {
> - if (tmp == 0)
> - ret ++;
> - }
> -
> - return ret;
> -}
> -
> -char *
> -rdline_get_history_item(struct rdline * rdl, unsigned int idx)
> -{
> - unsigned int len, i, tmp;
> -
> - if (!rdl)
> - return NULL;
> -
> - len = rdline_get_history_size(rdl);
> - if ( idx >= len ) {
> - return NULL;
> - }
> -
> - cirbuf_align_left(&rdl->history);
> -
> - CIRBUF_FOREACH(&rdl->history, i, tmp) {
> - if ( idx == len - 1) {
> - return rdl->history_buf + i;
> - }
> - if (tmp == 0)
> - len --;
> - }
> -
> - return NULL;
> -}
> -
> -int
> -rdline_add_history(struct rdline * rdl, const char * buf)
> -{
> - unsigned int len, i;
> -
> - if (!rdl || !buf)
> - return -EINVAL;
> -
> - len = strnlen(buf, RDLINE_BUF_SIZE);
> - for (i=0; i<len ; i++) {
> - if (buf[i] == '\n') {
> - len = i;
> - break;
> - }
> - }
> -
> - if ( len >= RDLINE_HISTORY_BUF_SIZE )
> - return -1;
> -
> - while ( len >= CIRBUF_GET_FREELEN(&rdl->history) ) {
> - rdline_remove_old_history_item(rdl);
> - }
> -
> - cirbuf_add_buf_tail(&rdl->history, buf, len);
> - cirbuf_add_tail(&rdl->history, 0);
> -
> - return 0;
> -}
> -
> -void
> -rdline_clear_history(struct rdline * rdl)
> -{
> - if (!rdl)
> - return;
> - cirbuf_init(&rdl->history, rdl->history_buf, 0, RDLINE_HISTORY_BUF_SIZE);
> -}
> -
> -
> -/* STATIC USEFUL FUNCS */
> -
> -static void
> -rdline_puts(struct rdline * rdl, const char * buf)
> -{
> - char c;
> - while ( (c = *(buf++)) != '\0' ) {
> - rdl->write_char(rdl, c);
> - }
> -}
> -
> -/* a very very basic printf with one arg and one format 'u' */
> -static void
> -rdline_miniprintf(struct rdline *rdl, const char * buf, unsigned int val)
> -{
> - char c, started=0, div=100;
> -
> - while ( (c=*(buf++)) ) {
> - if (c != '%') {
> - rdl->write_char(rdl, c);
> - continue;
> - }
> - c = *(buf++);
> - if (c != 'u') {
> - rdl->write_char(rdl, '%');
> - rdl->write_char(rdl, c);
> - continue;
> - }
> - /* val is never more than 255 */
> - while (div) {
> - c = (char)(val / div);
> - if (c || started) {
> - rdl->write_char(rdl, (char)(c+'0'));
> - started = 1;
> - }
> - val %= div;
> - div /= 10;
> - }
> - }
> -}
> diff --git a/lib/librte_cmdline/cmdline_rdline.h b/lib/librte_cmdline/cmdline_rdline.h
> deleted file mode 100644
> index 72e2dad..0000000
> --- a/lib/librte_cmdline/cmdline_rdline.h
> +++ /dev/null
> @@ -1,255 +0,0 @@
> -/*-
> - * BSD LICENSE
> - *
> - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - * All rights reserved.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in
> - * the documentation and/or other materials provided with the
> - * distribution.
> - * * Neither the name of Intel Corporation nor the names of its
> - * contributors may be used to endorse or promote products derived
> - * from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in the
> - * documentation and/or other materials provided with the distribution.
> - * * Neither the name of the University of California, Berkeley nor the
> - * names of its contributors may be used to endorse or promote products
> - * derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#ifndef _RDLINE_H_
> -#define _RDLINE_H_
> -
> -/**
> - * This file is a small equivalent to the GNU readline library, but it
> - * was originally designed for small systems, like Atmel AVR
> - * microcontrollers (8 bits). Indeed, we don't use any malloc that is
> - * sometimes not implemented (or just not recommended) on such
> - * systems.
> - *
> - * Obviously, it does not support as many things as the GNU readline,
> - * but at least it supports some interesting features like a kill
> - * buffer and a command history.
> - *
> - * It also have a feature that does not have the GNU readline (as far
> - * as I know): we can have several instances of it running at the same
> - * time, even on a monothread program, since it works with callbacks.
> - *
> - * The lib is designed for a client-side or a server-side use:
> - * - server-side: the server receives all data from a socket, including
> - * control chars, like arrows, tabulations, ... The client is
> - * very simple, it can be a telnet or a minicom through a serial line.
> - * - client-side: the client receives its data through its stdin for
> - * instance.
> - */
> -
> -#include <stdio.h>
> -#include <cmdline_cirbuf.h>
> -#include <cmdline_vt100.h>
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -/* configuration */
> -#define RDLINE_BUF_SIZE 512
> -#define RDLINE_PROMPT_SIZE 32
> -#define RDLINE_VT100_BUF_SIZE 8
> -#define RDLINE_HISTORY_BUF_SIZE BUFSIZ
> -#define RDLINE_HISTORY_MAX_LINE 64
> -
> -enum rdline_status {
> - RDLINE_INIT,
> - RDLINE_RUNNING,
> - RDLINE_EXITED
> -};
> -
> -struct rdline;
> -
> -typedef int (rdline_write_char_t)(struct rdline *rdl, char);
> -typedef void (rdline_validate_t)(struct rdline *rdl,
> - const char *buf, unsigned int size);
> -typedef int (rdline_complete_t)(struct rdline *rdl, const char *buf,
> - char *dstbuf, unsigned int dstsize,
> - int *state);
> -
> -struct rdline {
> - enum rdline_status status;
> - /* rdline bufs */
> - struct cirbuf left;
> - struct cirbuf right;
> - char left_buf[RDLINE_BUF_SIZE+2]; /* reserve 2 chars for the \n\0 */
> - char right_buf[RDLINE_BUF_SIZE];
> -
> - char prompt[RDLINE_PROMPT_SIZE];
> - unsigned int prompt_size;
> -
> - char kill_buf[RDLINE_BUF_SIZE];
> - unsigned int kill_size;
> -
> - /* history */
> - struct cirbuf history;
> - char history_buf[RDLINE_HISTORY_BUF_SIZE];
> - int history_cur_line;
> -
> - /* callbacks and func pointers */
> - rdline_write_char_t *write_char;
> - rdline_validate_t *validate;
> - rdline_complete_t *complete;
> -
> - /* vt100 parser */
> - struct cmdline_vt100 vt100;
> -
> - /* opaque pointer */
> - void *opaque;
> -};
> -
> -/**
> - * Init fields for a struct rdline. Call this only once at the beginning
> - * of your program.
> - * \param rdl A pointer to an uninitialized struct rdline
> - * \param write_char The function used by the function to write a character
> - * \param validate A pointer to the function to execute when the
> - * user validates the buffer.
> - * \param complete A pointer to the function to execute when the
> - * user completes the buffer.
> - */
> -int rdline_init(struct rdline *rdl,
> - rdline_write_char_t *write_char,
> - rdline_validate_t *validate,
> - rdline_complete_t *complete);
> -
> -
> -/**
> - * Init the current buffer, and display a prompt.
> - * \param rdl A pointer to a struct rdline
> - * \param prompt A string containing the prompt
> - */
> -void rdline_newline(struct rdline *rdl, const char *prompt);
> -
> -/**
> - * Call it and all received chars will be ignored.
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_stop(struct rdline *rdl);
> -
> -/**
> - * Same than rdline_stop() except that next calls to rdline_char_in()
> - * will return RDLINE_RES_EXITED.
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_quit(struct rdline *rdl);
> -
> -/**
> - * Restart after a call to rdline_stop() or rdline_quit()
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_restart(struct rdline *rdl);
> -
> -/**
> - * Redisplay the current buffer
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_redisplay(struct rdline *rdl);
> -
> -/**
> - * Reset the current buffer and setup for a new line.
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_reset(struct rdline *rdl);
> -
> -
> -/* return status for rdline_char_in() */
> -#define RDLINE_RES_SUCCESS 0
> -#define RDLINE_RES_VALIDATED 1
> -#define RDLINE_RES_COMPLETE 2
> -#define RDLINE_RES_NOT_RUNNING -1
> -#define RDLINE_RES_EOF -2
> -#define RDLINE_RES_EXITED -3
> -
> -/**
> - * append a char to the readline buffer.
> - * Return RDLINE_RES_VALIDATE when the line has been validated.
> - * Return RDLINE_RES_COMPLETE when the user asked to complete the buffer.
> - * Return RDLINE_RES_NOT_RUNNING if it is not running.
> - * Return RDLINE_RES_EOF if EOF (ctrl-d on an empty line).
> - * Else return RDLINE_RES_SUCCESS.
> - * XXX error case when the buffer is full ?
> - *
> - * \param rdl A pointer to a struct rdline
> - * \param c The character to append
> - */
> -int rdline_char_in(struct rdline *rdl, char c);
> -
> -/**
> - * Return the current buffer, terminated by '\0'.
> - * \param rdl A pointer to a struct rdline
> - */
> -const char *rdline_get_buffer(struct rdline *rdl);
> -
> -
> -/**
> - * Add the buffer to history.
> - * return < 0 on error.
> - * \param rdl A pointer to a struct rdline
> - * \param buf A buffer that is terminated by '\0'
> - */
> -int rdline_add_history(struct rdline *rdl, const char *buf);
> -
> -/**
> - * Clear current history
> - * \param rdl A pointer to a struct rdline
> - */
> -void rdline_clear_history(struct rdline *rdl);
> -
> -/**
> - * Get the i-th history item
> - */
> -char *rdline_get_history_item(struct rdline *rdl, unsigned int i);
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif /* _RDLINE_H_ */
> diff --git a/lib/librte_cmdline/cmdline_socket.c b/lib/librte_cmdline/cmdline_socket.c
> index 3fc243b..11524b5 100644
> --- a/lib/librte_cmdline/cmdline_socket.c
> +++ b/lib/librte_cmdline/cmdline_socket.c
> @@ -58,23 +58,18 @@
> * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> */
>
> -#include <stdio.h>
> -#include <string.h>
> +#include <stddef.h>
> #include <unistd.h>
> -#include <stdlib.h>
> -#include <stdarg.h>
> -#include <inttypes.h>
> #include <fcntl.h>
> -#include <termios.h>
>
> #include "cmdline_parse.h"
> -#include "cmdline_rdline.h"
> #include "cmdline_socket.h"
> #include "cmdline.h"
>
> struct cmdline *
> cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path)
> {
> + struct cmdline *cl;
> int fd;
>
> /* everything else is checked in cmdline_new() */
> @@ -83,37 +78,22 @@ cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path)
>
> fd = open(path, O_RDONLY, 0);
> if (fd < 0) {
> - dprintf("open() failed\n");
> return NULL;
> }
> - return cmdline_new(ctx, prompt, fd, -1);
> + cl = cmdline_new(ctx, prompt, fd, -1);
> + /* cmdline_new() duplicates fd */
> + close(fd);
> + return cl;
> }
>
> struct cmdline *
> cmdline_stdin_new(cmdline_parse_ctx_t *ctx, const char *prompt)
> {
> - struct cmdline *cl;
> - struct termios oldterm, term;
> -
> - tcgetattr(0, &oldterm);
> - memcpy(&term, &oldterm, sizeof(term));
> - term.c_lflag &= ~(ICANON | ECHO | ISIG);
> - tcsetattr(0, TCSANOW, &term);
> - setbuf(stdin, NULL);
> -
> - cl = cmdline_new(ctx, prompt, 0, 1);
> -
> - if (cl)
> - memcpy(&cl->oldterm, &oldterm, sizeof(term));
> -
> - return cl;
> + return cmdline_new(ctx, prompt, 0, 1);
> }
>
> void
> cmdline_stdin_exit(struct cmdline *cl)
> {
> - if (!cl)
> - return;
> -
> - tcsetattr(fileno(stdin), TCSANOW, &cl->oldterm);
> + cmdline_free(cl);
> }
> diff --git a/lib/librte_cmdline/cmdline_vt100.c b/lib/librte_cmdline/cmdline_vt100.c
> deleted file mode 100644
> index a253e8b..0000000
> --- a/lib/librte_cmdline/cmdline_vt100.c
> +++ /dev/null
> @@ -1,185 +0,0 @@
> -/*-
> - * BSD LICENSE
> - *
> - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - * All rights reserved.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in
> - * the documentation and/or other materials provided with the
> - * distribution.
> - * * Neither the name of Intel Corporation nor the names of its
> - * contributors may be used to endorse or promote products derived
> - * from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in the
> - * documentation and/or other materials provided with the distribution.
> - * * Neither the name of the University of California, Berkeley nor the
> - * names of its contributors may be used to endorse or promote products
> - * derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include <stdlib.h>
> -#include <stdint.h>
> -#include <stdio.h>
> -#include <string.h>
> -#include <stdarg.h>
> -#include <ctype.h>
> -#include <termios.h>
> -
> -#include "cmdline_vt100.h"
> -
> -const char *cmdline_vt100_commands[] = {
> - vt100_up_arr,
> - vt100_down_arr,
> - vt100_right_arr,
> - vt100_left_arr,
> - "\177",
> - "\n",
> - "\001",
> - "\005",
> - "\013",
> - "\031",
> - "\003",
> - "\006",
> - "\002",
> - vt100_suppr,
> - vt100_tab,
> - "\004",
> - "\014",
> - "\r",
> - "\033\177",
> - vt100_word_left,
> - vt100_word_right,
> - "?",
> - "\027",
> - "\020",
> - "\016",
> - "\033\144",
> -};
> -
> -void
> -vt100_init(struct cmdline_vt100 *vt)
> -{
> - if (!vt)
> - return;
> - vt->state = CMDLINE_VT100_INIT;
> -}
> -
> -
> -static int
> -match_command(char *buf, unsigned int size)
> -{
> - const char *cmd;
> - size_t cmdlen;
> - unsigned int i = 0;
> -
> - for (i=0 ; i<sizeof(cmdline_vt100_commands)/sizeof(const char *) ; i++) {
> - cmd = *(cmdline_vt100_commands + i);
> -
> - cmdlen = strnlen(cmd, CMDLINE_VT100_BUF_SIZE);
> - if (size == cmdlen &&
> - !strncmp(buf, cmd, cmdlen)) {
> - return i;
> - }
> - }
> -
> - return -1;
> -}
> -
> -int
> -vt100_parser(struct cmdline_vt100 *vt, char ch)
> -{
> - unsigned int size;
> - uint8_t c = (uint8_t) ch;
> -
> - if (!vt)
> - return -1;
> -
> - if (vt->bufpos >= CMDLINE_VT100_BUF_SIZE) {
> - vt->state = CMDLINE_VT100_INIT;
> - vt->bufpos = 0;
> - }
> -
> - vt->buf[vt->bufpos++] = c;
> - size = vt->bufpos;
> -
> - switch (vt->state) {
> - case CMDLINE_VT100_INIT:
> - if (c == 033) {
> - vt->state = CMDLINE_VT100_ESCAPE;
> - }
> - else {
> - vt->bufpos = 0;
> - goto match_command;
> - }
> - break;
> -
> - case CMDLINE_VT100_ESCAPE:
> - if (c == 0133) {
> - vt->state = CMDLINE_VT100_ESCAPE_CSI;
> - }
> - else if (c >= 060 && c <= 0177) { /* XXX 0177 ? */
> - vt->bufpos = 0;
> - vt->state = CMDLINE_VT100_INIT;
> - goto match_command;
> - }
> - break;
> -
> - case CMDLINE_VT100_ESCAPE_CSI:
> - if (c >= 0100 && c <= 0176) {
> - vt->bufpos = 0;
> - vt->state = CMDLINE_VT100_INIT;
> - goto match_command;
> - }
> - break;
> -
> - default:
> - vt->bufpos = 0;
> - break;
> - }
> -
> - return -2;
> -
> - match_command:
> - return match_command(vt->buf, size);
> -}
> diff --git a/lib/librte_cmdline/cmdline_vt100.h b/lib/librte_cmdline/cmdline_vt100.h
> deleted file mode 100644
> index 963add8..0000000
> --- a/lib/librte_cmdline/cmdline_vt100.h
> +++ /dev/null
> @@ -1,153 +0,0 @@
> -/*-
> - * BSD LICENSE
> - *
> - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - * All rights reserved.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in
> - * the documentation and/or other materials provided with the
> - * distribution.
> - * * Neither the name of Intel Corporation nor the names of its
> - * contributors may be used to endorse or promote products derived
> - * from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -/*
> - * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
> - * All rights reserved.
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in the
> - * documentation and/or other materials provided with the distribution.
> - * * Neither the name of the University of California, Berkeley nor the
> - * names of its contributors may be used to endorse or promote products
> - * derived from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
> - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
> - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
> - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
> - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
> - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
> - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
> - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
> - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#ifndef _CMDLINE_VT100_H_
> -#define _CMDLINE_VT100_H_
> -
> -#include <stdint.h>
> -
> -#ifdef __cplusplus
> -extern "C" {
> -#endif
> -
> -#define vt100_bell "\007"
> -#define vt100_bs "\010"
> -#define vt100_bs_clear "\010 \010"
> -#define vt100_tab "\011"
> -#define vt100_crnl "\012\015"
> -#define vt100_clear_right "\033[0K"
> -#define vt100_clear_left "\033[1K"
> -#define vt100_clear_down "\033[0J"
> -#define vt100_clear_up "\033[1J"
> -#define vt100_clear_line "\033[2K"
> -#define vt100_clear_screen "\033[2J"
> -#define vt100_up_arr "\033\133\101"
> -#define vt100_down_arr "\033\133\102"
> -#define vt100_right_arr "\033\133\103"
> -#define vt100_left_arr "\033\133\104"
> -#define vt100_multi_right "\033\133%uC"
> -#define vt100_multi_left "\033\133%uD"
> -#define vt100_suppr "\033\133\063\176"
> -#define vt100_home "\033M\033E"
> -#define vt100_word_left "\033\142"
> -#define vt100_word_right "\033\146"
> -
> -/* Result of parsing : it must be synchronized with
> - * cmdline_vt100_commands[] in vt100.c */
> -#define CMDLINE_KEY_UP_ARR 0
> -#define CMDLINE_KEY_DOWN_ARR 1
> -#define CMDLINE_KEY_RIGHT_ARR 2
> -#define CMDLINE_KEY_LEFT_ARR 3
> -#define CMDLINE_KEY_BKSPACE 4
> -#define CMDLINE_KEY_RETURN 5
> -#define CMDLINE_KEY_CTRL_A 6
> -#define CMDLINE_KEY_CTRL_E 7
> -#define CMDLINE_KEY_CTRL_K 8
> -#define CMDLINE_KEY_CTRL_Y 9
> -#define CMDLINE_KEY_CTRL_C 10
> -#define CMDLINE_KEY_CTRL_F 11
> -#define CMDLINE_KEY_CTRL_B 12
> -#define CMDLINE_KEY_SUPPR 13
> -#define CMDLINE_KEY_TAB 14
> -#define CMDLINE_KEY_CTRL_D 15
> -#define CMDLINE_KEY_CTRL_L 16
> -#define CMDLINE_KEY_RETURN2 17
> -#define CMDLINE_KEY_META_BKSPACE 18
> -#define CMDLINE_KEY_WLEFT 19
> -#define CMDLINE_KEY_WRIGHT 20
> -#define CMDLINE_KEY_HELP 21
> -#define CMDLINE_KEY_CTRL_W 22
> -#define CMDLINE_KEY_CTRL_P 23
> -#define CMDLINE_KEY_CTRL_N 24
> -#define CMDLINE_KEY_META_D 25
> -
> -extern const char *cmdline_vt100_commands[];
> -
> -enum cmdline_vt100_parser_state {
> - CMDLINE_VT100_INIT,
> - CMDLINE_VT100_ESCAPE,
> - CMDLINE_VT100_ESCAPE_CSI
> -};
> -
> -#define CMDLINE_VT100_BUF_SIZE 8
> -struct cmdline_vt100 {
> - uint8_t bufpos;
> - char buf[CMDLINE_VT100_BUF_SIZE];
> - enum cmdline_vt100_parser_state state;
> -};
> -
> -/**
> - * Init
> - */
> -void vt100_init(struct cmdline_vt100 *vt);
> -
> -/**
> - * Input a new character.
> - * Return -1 if the character is not part of a control sequence
> - * Return -2 if c is not the last char of a control sequence
> - * Else return the index in vt100_commands[]
> - */
> -int vt100_parser(struct cmdline_vt100 *vt, char c);
> -
> -#ifdef __cplusplus
> -}
> -#endif
> -
> -#endif
> diff --git a/lib/librte_cmdline/rte_cmdline_version.map b/lib/librte_cmdline/rte_cmdline_version.map
> index 04bcb38..3133199 100644
> --- a/lib/librte_cmdline/rte_cmdline_version.map
> +++ b/lib/librte_cmdline/rte_cmdline_version.map
> @@ -1,25 +1,6 @@
> DPDK_2.0 {
> global:
>
> - cirbuf_add_buf_head;
> - cirbuf_add_buf_tail;
> - cirbuf_add_head;
> - cirbuf_add_head_safe;
> - cirbuf_add_tail;
> - cirbuf_add_tail_safe;
> - cirbuf_align_left;
> - cirbuf_align_right;
> - cirbuf_del_buf_head;
> - cirbuf_del_buf_tail;
> - cirbuf_del_head;
> - cirbuf_del_head_safe;
> - cirbuf_del_tail;
> - cirbuf_del_tail_safe;
> - cirbuf_get_buf_head;
> - cirbuf_get_buf_tail;
> - cirbuf_get_head;
> - cirbuf_get_tail;
> - cirbuf_init;
> cmdline_complete;
> cmdline_complete_get_elt_string;
> cmdline_complete_get_nb_string;
> @@ -50,21 +31,6 @@ DPDK_2.0 {
> cmdline_token_num_ops;
> cmdline_token_portlist_ops;
> cmdline_token_string_ops;
> - cmdline_write_char;
> - rdline_add_history;
> - rdline_char_in;
> - rdline_clear_history;
> - rdline_get_buffer;
> - rdline_get_history_item;
> - rdline_init;
> - rdline_newline;
> - rdline_quit;
> - rdline_redisplay;
> - rdline_reset;
> - rdline_restart;
> - rdline_stop;
> - vt100_init;
> - vt100_parser;
>
> local: *;
> };
> @@ -75,3 +41,10 @@ DPDK_2.1 {
> cmdline_poll;
>
> } DPDK_2.0;
> +
> +DPDK_18.02 {
> + global:
> +
> + cmdline_ctx_get;
> +
> +} DPDK_2.1;
> diff --git a/mk/rte.app.mk b/mk/rte.app.mk
> index 6a6a745..504bb4e 100644
> --- a/mk/rte.app.mk
> +++ b/mk/rte.app.mk
> @@ -102,6 +102,8 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_RING) += -lrte_ring
> _LDLIBS-$(CONFIG_RTE_LIBRTE_PCI) += -lrte_pci
> _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL) += -lrte_eal
> _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline
> +
> +_LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += $(shell pkg-config --libs libedit)
> _LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder
> _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lrte_sched
>
> diff --git a/test/cmdline_test/cmdline_test.c b/test/cmdline_test/cmdline_test.c
> index 716b5f1..595efa5 100644
> --- a/test/cmdline_test/cmdline_test.c
> +++ b/test/cmdline_test/cmdline_test.c
> @@ -41,7 +41,6 @@
> #include <ctype.h>
> #include <sys/queue.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> diff --git a/test/cmdline_test/commands.c b/test/cmdline_test/commands.c
> index 404f51a..8481af9 100644
> --- a/test/cmdline_test/commands.c
> +++ b/test/cmdline_test/commands.c
> @@ -36,7 +36,6 @@
> #include <termios.h>
> #include <inttypes.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_string.h>
> #include <cmdline_parse_num.h>
> @@ -306,72 +305,6 @@ cmdline_parse_inst_t cmd_ambig_2 = {
>
>
>
> -/*** get_history_bufsize ***/
> -/* command that displays total space in history buffer
> - * this will be useful for testing history (to fill it up just enough to
> - * remove the last entry, we need to know how big it is).
> - */
> -
> -struct cmd_get_history_bufsize_result {
> - cmdline_fixed_string_t str;
> -};
> -
> -static void
> -cmd_get_history_bufsize_parsed(__attribute__((unused)) void *parsed_result,
> - struct cmdline *cl,
> - __attribute__((unused)) void *data)
> -{
> - cmdline_printf(cl, "History buffer size: %zu\n",
> - sizeof(cl->rdl.history_buf));
> -}
> -
> -cmdline_parse_token_string_t cmd_get_history_bufsize_tok =
> - TOKEN_STRING_INITIALIZER(struct cmd_get_history_bufsize_result, str,
> - "get_history_bufsize");
> -
> -cmdline_parse_inst_t cmd_get_history_bufsize = {
> - .f = cmd_get_history_bufsize_parsed, /* function to call */
> - .data = NULL, /* 2nd arg of func */
> - .help_str = "command that displays total space in history buffer",
> - .tokens = { /* token list, NULL terminated */
> - (void *)&cmd_get_history_bufsize_tok,
> - NULL,
> - },
> -};
> -
> -
> -
> -/*** clear_history ***/
> -/* clears history buffer */
> -
> -struct cmd_clear_history_result {
> - cmdline_fixed_string_t str;
> -};
> -
> -static void
> -cmd_clear_history_parsed(__attribute__((unused)) void *parsed_result,
> - struct cmdline *cl,
> - __attribute__((unused)) void *data)
> -{
> - rdline_clear_history(&cl->rdl);
> -}
> -
> -cmdline_parse_token_string_t cmd_clear_history_tok =
> - TOKEN_STRING_INITIALIZER(struct cmd_clear_history_result, str,
> - "clear_history");
> -
> -cmdline_parse_inst_t cmd_clear_history = {
> - .f = cmd_clear_history_parsed, /* function to call */
> - .data = NULL, /* 2nd arg of func */
> - .help_str = "clear command history",
> - .tokens = { /* token list, NULL terminated */
> - (void *)&cmd_clear_history_tok,
> - NULL,
> - },
> -};
> -
> -
> -
> /****************/
>
> cmdline_parse_ctx_t main_ctx[] = {
> @@ -381,8 +314,6 @@ cmdline_parse_ctx_t main_ctx[] = {
> (cmdline_parse_inst_t *)&cmd_single,
> (cmdline_parse_inst_t *)&cmd_single_long,
> (cmdline_parse_inst_t *)&cmd_num,
> - (cmdline_parse_inst_t *)&cmd_get_history_bufsize,
> - (cmdline_parse_inst_t *)&cmd_clear_history,
> (cmdline_parse_inst_t *)&cmd_autocomplete_1,
> (cmdline_parse_inst_t *)&cmd_autocomplete_2,
> NULL,
> diff --git a/test/test/Makefile b/test/test/Makefile
> index bb54c98..49e907c 100644
> --- a/test/test/Makefile
> +++ b/test/test/Makefile
> @@ -164,7 +164,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_num.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_etheraddr.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_portlist.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_ipaddr.c
> -SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_cirbuf.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_string.c
> SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += test_cmdline_lib.c
>
> diff --git a/test/test/commands.c b/test/test/commands.c
> index 4097a33..21a4a06 100644
> --- a/test/test/commands.c
> +++ b/test/test/commands.c
> @@ -66,7 +66,6 @@
> #include <rte_mbuf.h>
> #include <rte_devargs.h>
>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_parse_ipaddr.h>
> #include <cmdline_parse_num.h>
> diff --git a/test/test/test.c b/test/test/test.c
> index 0e6ff7c..6f48892 100644
> --- a/test/test/test.c
> +++ b/test/test/test.c
> @@ -42,7 +42,6 @@
> #include <sys/queue.h>
>
> #ifdef RTE_LIBRTE_CMDLINE
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> diff --git a/test/test/test_cmdline.c b/test/test/test_cmdline.c
> index 38c7256..056b569 100644
> --- a/test/test/test_cmdline.c
> +++ b/test/test/test_cmdline.c
> @@ -74,15 +74,6 @@ test_cmdline(void)
> return -1;
> if (test_parse_string_invalid_param() < 0)
> return -1;
> - printf("Testing circular buffer...\n");
> - if (test_cirbuf_char() < 0)
> - return -1;
> - if (test_cirbuf_string() < 0)
> - return -1;
> - if (test_cirbuf_align() < 0)
> - return -1;
> - if (test_cirbuf_invalid_param() < 0)
> - return -1;
> printf("Testing library functions...\n");
> if (test_cmdline_lib() < 0)
> return -1;
> diff --git a/test/test/test_cmdline.h b/test/test/test_cmdline.h
> index 0ee91c1..b55caa9 100644
> --- a/test/test/test_cmdline.h
> +++ b/test/test/test_cmdline.h
> @@ -61,12 +61,6 @@ int test_parse_string_valid(void);
> int test_parse_string_invalid_data(void);
> int test_parse_string_invalid_param(void);
>
> -/* cmdline_cirbuf tests */
> -int test_cirbuf_invalid_param(void);
> -int test_cirbuf_char(void);
> -int test_cirbuf_string(void);
> -int test_cirbuf_align(void);
> -
> /* test the rest of the library */
> int test_cmdline_lib(void);
>
> diff --git a/test/test/test_cmdline_cirbuf.c b/test/test/test_cmdline_cirbuf.c
> deleted file mode 100644
> index 2c32145..0000000
> --- a/test/test/test_cmdline_cirbuf.c
> +++ /dev/null
> @@ -1,1330 +0,0 @@
> -/*-
> - * BSD LICENSE
> - *
> - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> - * All rights reserved.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - *
> - * * Redistributions of source code must retain the above copyright
> - * notice, this list of conditions and the following disclaimer.
> - * * Redistributions in binary form must reproduce the above copyright
> - * notice, this list of conditions and the following disclaimer in
> - * the documentation and/or other materials provided with the
> - * distribution.
> - * * Neither the name of Intel Corporation nor the names of its
> - * contributors may be used to endorse or promote products derived
> - * from this software without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
> - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
> - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
> - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
> - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
> - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
> - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
> - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
> - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
> - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
> - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
> - */
> -
> -#include <stdio.h>
> -#include <stdlib.h>
> -#include <string.h>
> -
> -#include <rte_string_fns.h>
> -
> -#include <cmdline_cirbuf.h>
> -
> -#include "test_cmdline.h"
> -
> -/* different length strings */
> -#define CIRBUF_STR_HEAD " HEAD"
> -#define CIRBUF_STR_TAIL "TAIL"
> -
> -/* miscellaneous tests - they make bullseye happy */
> -static int
> -test_cirbuf_string_misc(void)
> -{
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - char tmp[CMDLINE_TEST_BUFSIZE];
> -
> - /* initialize buffers */
> - memset(buf, 0, sizeof(buf));
> - memset(tmp, 0, sizeof(tmp));
> -
> - /*
> - * initialize circular buffer
> - */
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> - /*
> - * add strings to head and tail, but read only tail
> - * this results in read operation that does not transcend
> - * from buffer end to buffer beginning (in other words,
> - * strlen <= cb->maxlen - cb->end)
> - */
> -
> - /* add string to head */
> - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> - != (sizeof(CIRBUF_STR_HEAD))) {
> - printf("Error: failed to add string to head!\n");
> - return -1;
> - }
> - /* add string to tail */
> - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> - != (sizeof(CIRBUF_STR_TAIL))) {
> - printf("Error: failed to add string to head!\n");
> - return -1;
> - }
> - /* read string from tail */
> - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL))
> - != (sizeof(CIRBUF_STR_TAIL))) {
> - printf("Error: failed to get string from tail!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) {
> - printf("Error: tail strings do not match!\n");
> - return -1;
> - }
> - /* clear buffers */
> - memset(tmp, 0, sizeof(tmp));
> - memset(buf, 0, sizeof(buf));
> -
> -
> -
> - /*
> - * add a string to buffer when start/end is at end of buffer
> - */
> -
> - /*
> - * reinitialize circular buffer with start at the end of cirbuf
> - */
> - if (cirbuf_init(&cb, buf, CMDLINE_TEST_BUFSIZE - 2, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> -
> - /* add string to tail */
> - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> - != (sizeof(CIRBUF_STR_TAIL))) {
> - printf("Error: failed to add string to tail!\n");
> - return -1;
> - }
> - /* read string from tail */
> - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL))
> - != (sizeof(CIRBUF_STR_TAIL))) {
> - printf("Error: failed to get string from tail!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) {
> - printf("Error: tail strings do not match!\n");
> - return -1;
> - }
> - /* clear tmp buffer */
> - memset(tmp, 0, sizeof(tmp));
> -
> -
> - /* add string to head */
> - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> - != (sizeof(CIRBUF_STR_HEAD))) {
> - printf("Error: failed to add string to head!\n");
> - return -1;
> - }
> - /* read string from tail */
> - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD))
> - != (sizeof(CIRBUF_STR_HEAD))) {
> - printf("Error: failed to get string from head!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) {
> - printf("Error: headstrings do not match!\n");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* test adding and deleting strings */
> -static int
> -test_cirbuf_string_add_del(void)
> -{
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - char tmp[CMDLINE_TEST_BUFSIZE];
> -
> - /* initialize buffers */
> - memset(buf, 0, sizeof(buf));
> - memset(tmp, 0, sizeof(tmp));
> -
> - /*
> - * initialize circular buffer
> - */
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* add string to head */
> - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> - != (sizeof(CIRBUF_STR_HEAD))) {
> - printf("Error: failed to add string to head!\n");
> - return -1;
> - }
> - /* read string from head */
> - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD))
> - != (sizeof(CIRBUF_STR_HEAD))) {
> - printf("Error: failed to get string from head!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) {
> - printf("Error: head strings do not match!\n");
> - return -1;
> - }
> - /* clear tmp buffer */
> - memset(tmp, 0, sizeof(tmp));
> - /* read string from tail */
> - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD))
> - != (sizeof(CIRBUF_STR_HEAD))) {
> - printf("Error: failed to get string from head!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) != 0) {
> - printf("Error: head strings do not match!\n");
> - return -1;
> - }
> - /* delete string from head*/
> - if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_HEAD)) < 0) {
> - printf("Error: failed to delete string from head!\n");
> - return -1;
> - }
> - /* verify string was deleted */
> - if (cirbuf_del_head_safe(&cb) == 0) {
> - printf("Error: buffer should have been empty!\n");
> - return -1;
> - }
> - /* clear tmp buffer */
> - memset(tmp, 0, sizeof(tmp));
> -
> -
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* add string to tail */
> - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> - != (sizeof(CIRBUF_STR_TAIL))) {
> - printf("Error: failed to add string to tail!\n");
> - return -1;
> - }
> - /* get string from tail */
> - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL))
> - != (sizeof(CIRBUF_STR_TAIL))) {
> - printf("Error: failed to get string from tail!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) {
> - printf("Error: tail strings do not match!\n");
> - return -1;
> - }
> - /* clear tmp buffer */
> - memset(tmp, 0, sizeof(tmp));
> - /* get string from head */
> - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_TAIL))
> - != (sizeof(CIRBUF_STR_TAIL))) {
> - printf("Error: failed to get string from tail!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) != 0) {
> - printf("Error: tail strings do not match!\n");
> - return -1;
> - }
> - /* delete string from tail */
> - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL)) < 0) {
> - printf("Error: failed to delete string from tail!\n");
> - return -1;
> - }
> - /* verify string was deleted */
> - if (cirbuf_del_tail_safe(&cb) == 0) {
> - printf("Error: buffer should have been empty!\n");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* test adding from head and deleting from tail, and vice versa */
> -static int
> -test_cirbuf_string_add_del_reverse(void)
> -{
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - char tmp[CMDLINE_TEST_BUFSIZE];
> -
> - /* initialize buffers */
> - memset(buf, 0, sizeof(buf));
> - memset(tmp, 0, sizeof(tmp));
> -
> - /*
> - * initialize circular buffer
> - */
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* add string to head */
> - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> - != (sizeof(CIRBUF_STR_HEAD))) {
> - printf("Error: failed to add string to head!\n");
> - return -1;
> - }
> - /* delete string from tail */
> - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_HEAD)) < 0) {
> - printf("Error: failed to delete string from tail!\n");
> - return -1;
> - }
> - /* verify string was deleted */
> - if (cirbuf_del_tail_safe(&cb) == 0) {
> - printf("Error: buffer should have been empty!\n");
> - return -1;
> - }
> - /* clear tmp buffer */
> - memset(tmp, 0, sizeof(tmp));
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* add string to tail */
> - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> - != (sizeof(CIRBUF_STR_TAIL))) {
> - printf("Error: failed to add string to tail!\n");
> - return -1;
> - }
> - /* delete string from head */
> - if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_TAIL)) < 0) {
> - printf("Error: failed to delete string from head!\n");
> - return -1;
> - }
> - /* verify string was deleted */
> - if (cirbuf_del_head_safe(&cb) == 0) {
> - printf("Error: buffer should have been empty!\n");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* try to write more than available */
> -static int
> -test_cirbuf_string_add_boundaries(void)
> -{
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - unsigned i;
> -
> - /* initialize buffers */
> - memset(buf, 0, sizeof(buf));
> -
> - /*
> - * initialize circular buffer
> - */
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* fill the buffer from tail */
> - for (i = 0; i < CMDLINE_TEST_BUFSIZE - sizeof(CIRBUF_STR_TAIL) + 1; i++)
> - cirbuf_add_tail_safe(&cb, 't');
> -
> - /* try adding a string to tail */
> - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> - > 0) {
> - printf("Error: buffer should have been full!\n");
> - return -1;
> - }
> - /* try adding a string to head */
> - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> - > 0) {
> - printf("Error: buffer should have been full!\n");
> - return -1;
> - }
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* fill the buffer from head */
> - for (i = 0; i < CMDLINE_TEST_BUFSIZE - sizeof(CIRBUF_STR_HEAD) + 1; i++)
> - cirbuf_add_head_safe(&cb, 'h');
> -
> - /* try adding a string to head */
> - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> - > 0) {
> - printf("Error: buffer should have been full!\n");
> - return -1;
> - }
> - /* try adding a string to tail */
> - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> - > 0) {
> - printf("Error: buffer should have been full!\n");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* try to read/delete more than written */
> -static int
> -test_cirbuf_string_get_del_boundaries(void)
> -{
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - char tmp[CMDLINE_TEST_BUFSIZE];
> -
> - /* initialize buffers */
> - memset(buf, 0, sizeof(buf));
> - memset(tmp, 0, sizeof(tmp));
> -
> - /*
> - * initialize circular buffer
> - */
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> -
> - /* add string to head */
> - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> - != (sizeof(CIRBUF_STR_HEAD))) {
> - printf("Error: failed to add string to head!\n");
> - return -1;
> - }
> - /* read more than written (head) */
> - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) + 1)
> - != sizeof(CIRBUF_STR_HEAD)) {
> - printf("Error: unexpected result when reading too much data!\n");
> - return -1;
> - }
> - /* read more than written (tail) */
> - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) + 1)
> - != sizeof(CIRBUF_STR_HEAD)) {
> - printf("Error: unexpected result when reading too much data!\n");
> - return -1;
> - }
> - /* delete more than written (head) */
> - if (cirbuf_del_buf_head(&cb, sizeof(CIRBUF_STR_HEAD) + 1) == 0) {
> - printf("Error: unexpected result when deleting too much data!\n");
> - return -1;
> - }
> - /* delete more than written (tail) */
> - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_HEAD) + 1) == 0) {
> - printf("Error: unexpected result when deleting too much data!\n");
> - return -1;
> - }
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* add string to tail */
> - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL))
> - != (sizeof(CIRBUF_STR_TAIL))) {
> - printf("Error: failed to add string to tail!\n");
> - return -1;
> - }
> - /* read more than written (tail) */
> - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_TAIL) + 1)
> - != sizeof(CIRBUF_STR_TAIL)) {
> - printf("Error: unexpected result when reading too much data!\n");
> - return -1;
> - }
> - /* read more than written (head) */
> - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_TAIL) + 1)
> - != sizeof(CIRBUF_STR_TAIL)) {
> - printf("Error: unexpected result when reading too much data!\n");
> - return -1;
> - }
> - /* delete more than written (tail) */
> - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL) + 1) == 0) {
> - printf("Error: unexpected result when deleting too much data!\n");
> - return -1;
> - }
> - /* delete more than written (head) */
> - if (cirbuf_del_buf_tail(&cb, sizeof(CIRBUF_STR_TAIL) + 1) == 0) {
> - printf("Error: unexpected result when deleting too much data!\n");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* try to read/delete less than written */
> -static int
> -test_cirbuf_string_get_del_partial(void)
> -{
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - char tmp[CMDLINE_TEST_BUFSIZE];
> - char tmp2[CMDLINE_TEST_BUFSIZE];
> -
> - /* initialize buffers */
> - memset(buf, 0, sizeof(buf));
> - memset(tmp, 0, sizeof(tmp));
> - memset(tmp2, 0, sizeof(tmp));
> -
> - snprintf(tmp2, sizeof(tmp2), "%s", CIRBUF_STR_HEAD);
> -
> - /*
> - * initialize circular buffer
> - */
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* add string to head */
> - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD))
> - != (sizeof(CIRBUF_STR_HEAD))) {
> - printf("Error: failed to add string to head!\n");
> - return -1;
> - }
> - /* read less than written (head) */
> - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1)
> - != sizeof(CIRBUF_STR_HEAD) - 1) {
> - printf("Error: unexpected result when reading from head!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, tmp2, sizeof(CIRBUF_STR_HEAD) - 1) != 0) {
> - printf("Error: strings mismatch!\n");
> - return -1;
> - }
> - memset(tmp, 0, sizeof(tmp));
> - /* read less than written (tail) */
> - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1)
> - != sizeof(CIRBUF_STR_HEAD) - 1) {
> - printf("Error: unexpected result when reading from tail!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 1) != 0) {
> - printf("Error: strings mismatch!\n");
> - return -1;
> - }
> -
> - /*
> - * verify correct deletion
> - */
> -
> - /* clear buffer */
> - memset(tmp, 0, sizeof(tmp));
> -
> - /* delete less than written (head) */
> - if (cirbuf_del_buf_head(&cb, 1) != 0) {
> - printf("Error: delete from head failed!\n");
> - return -1;
> - }
> - /* read from head */
> - if (cirbuf_get_buf_head(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 1)
> - != sizeof(CIRBUF_STR_HEAD) - 1) {
> - printf("Error: unexpected result when reading from head!\n");
> - return -1;
> - }
> - /* since we deleted from head, first char should be deleted */
> - if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 1) != 0) {
> - printf("Error: strings mismatch!\n");
> - return -1;
> - }
> - /* clear buffer */
> - memset(tmp, 0, sizeof(tmp));
> -
> - /* delete less than written (tail) */
> - if (cirbuf_del_buf_tail(&cb, 1) != 0) {
> - printf("Error: delete from tail failed!\n");
> - return -1;
> - }
> - /* read from tail */
> - if (cirbuf_get_buf_tail(&cb, tmp, sizeof(CIRBUF_STR_HEAD) - 2)
> - != sizeof(CIRBUF_STR_HEAD) - 2) {
> - printf("Error: unexpected result when reading from head!\n");
> - return -1;
> - }
> - /* since we deleted from tail, last char should be deleted */
> - if (strncmp(tmp, &tmp2[1], sizeof(CIRBUF_STR_HEAD) - 2) != 0) {
> - printf("Error: strings mismatch!\n");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* test cmdline_cirbuf char add/del functions */
> -static int
> -test_cirbuf_char_add_del(void)
> -{
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - char tmp[CMDLINE_TEST_BUFSIZE];
> -
> - /* clear buffer */
> - memset(buf, 0, sizeof(buf));
> - memset(tmp, 0, sizeof(tmp));
> -
> - /*
> - * initialize circular buffer
> - */
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> - /*
> - * try to delete something from cirbuf. since it's empty,
> - * these should fail.
> - */
> - if (cirbuf_del_head_safe(&cb) == 0) {
> - printf("Error: deleting from empty cirbuf head succeeded!\n");
> - return -1;
> - }
> - if (cirbuf_del_tail_safe(&cb) == 0) {
> - printf("Error: deleting from empty cirbuf tail succeeded!\n");
> - return -1;
> - }
> -
> - /*
> - * add, verify and delete. these should pass.
> - */
> - if (cirbuf_add_head_safe(&cb,'h') < 0) {
> - printf("Error: adding to cirbuf head failed!\n");
> - return -1;
> - }
> - if (cirbuf_get_head(&cb) != 'h') {
> - printf("Error: wrong head content!\n");
> - return -1;
> - }
> - if (cirbuf_del_head_safe(&cb) < 0) {
> - printf("Error: deleting from cirbuf head failed!\n");
> - return -1;
> - }
> - if (cirbuf_add_tail_safe(&cb,'t') < 0) {
> - printf("Error: adding to cirbuf tail failed!\n");
> - return -1;
> - }
> - if (cirbuf_get_tail(&cb) != 't') {
> - printf("Error: wrong tail content!\n");
> - return -1;
> - }
> - if (cirbuf_del_tail_safe(&cb) < 0) {
> - printf("Error: deleting from cirbuf tail failed!\n");
> - return -1;
> - }
> - /* do the same for unsafe versions. those are void. */
> - cirbuf_add_head(&cb,'h');
> - if (cirbuf_get_head(&cb) != 'h') {
> - printf("Error: wrong head content!\n");
> - return -1;
> - }
> - cirbuf_del_head(&cb);
> -
> - /* test if char has been deleted. we can't call cirbuf_get_head
> - * because it's unsafe, but we can call cirbuf_get_buf_head.
> - */
> - if (cirbuf_get_buf_head(&cb, tmp, 1) > 0) {
> - printf("Error: buffer should have been empty!\n");
> - return -1;
> - }
> -
> - cirbuf_add_tail(&cb,'t');
> - if (cirbuf_get_tail(&cb) != 't') {
> - printf("Error: wrong tail content!\n");
> - return -1;
> - }
> - cirbuf_del_tail(&cb);
> -
> - /* test if char has been deleted. we can't call cirbuf_get_tail
> - * because it's unsafe, but we can call cirbuf_get_buf_tail.
> - */
> - if (cirbuf_get_buf_tail(&cb, tmp, 1) > 0) {
> - printf("Error: buffer should have been empty!\n");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* test filling up buffer with chars */
> -static int
> -test_cirbuf_char_fill(void)
> -{
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - unsigned i;
> -
> - /* clear buffer */
> - memset(buf, 0, sizeof(buf));
> -
> - /*
> - * initialize circular buffer
> - */
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> - /*
> - * fill the buffer from head or tail, verify contents, test boundaries
> - * and clear the buffer
> - */
> -
> - /* fill the buffer from tail */
> - for (i = 0; i < CMDLINE_TEST_BUFSIZE; i++)
> - cirbuf_add_tail_safe(&cb, 't');
> - /* verify that contents of the buffer are what they are supposed to be */
> - for (i = 0; i < sizeof(buf); i++) {
> - if (buf[i] != 't') {
> - printf("Error: wrong content in buffer!\n");
> - return -1;
> - }
> - }
> - /* try to add to a full buffer from tail */
> - if (cirbuf_add_tail_safe(&cb, 't') == 0) {
> - printf("Error: buffer should have been full!\n");
> - return -1;
> - }
> - /* try to add to a full buffer from head */
> - if (cirbuf_add_head_safe(&cb, 'h') == 0) {
> - printf("Error: buffer should have been full!\n");
> - return -1;
> - }
> - /* delete buffer from tail */
> - for(i = 0; i < CMDLINE_TEST_BUFSIZE; i++)
> - cirbuf_del_tail_safe(&cb);
> - /* try to delete from an empty buffer */
> - if (cirbuf_del_tail_safe(&cb) >= 0) {
> - printf("Error: buffer should have been empty!\n");
> - return -1;
> - }
> -
> - /* fill the buffer from head */
> - for (i = 0; i < CMDLINE_TEST_BUFSIZE; i++)
> - cirbuf_add_head_safe(&cb, 'h');
> - /* verify that contents of the buffer are what they are supposed to be */
> - for (i = 0; i < sizeof(buf); i++) {
> - if (buf[i] != 'h') {
> - printf("Error: wrong content in buffer!\n");
> - return -1;
> - }
> - }
> - /* try to add to a full buffer from head */
> - if (cirbuf_add_head_safe(&cb,'h') >= 0) {
> - printf("Error: buffer should have been full!\n");
> - return -1;
> - }
> - /* try to add to a full buffer from tail */
> - if (cirbuf_add_tail_safe(&cb, 't') == 0) {
> - printf("Error: buffer should have been full!\n");
> - return -1;
> - }
> - /* delete buffer from head */
> - for(i = 0; i < CMDLINE_TEST_BUFSIZE; i++)
> - cirbuf_del_head_safe(&cb);
> - /* try to delete from an empty buffer */
> - if (cirbuf_del_head_safe(&cb) >= 0) {
> - printf("Error: buffer should have been empty!\n");
> - return -1;
> - }
> -
> - /*
> - * fill the buffer from both head and tail, with alternating characters,
> - * verify contents and clear the buffer
> - */
> -
> - /* fill half of buffer from tail */
> - for (i = 0; i < CMDLINE_TEST_BUFSIZE / 2; i++)
> - cirbuf_add_tail_safe(&cb, (char) (i % 2 ? 't' : 'T'));
> - /* fill other half of the buffer from head */
> - for (i = 0; i < CMDLINE_TEST_BUFSIZE / 2; i++)
> - cirbuf_add_head_safe(&cb, (char) (i % 2 ? 'H' : 'h')); /* added in reverse */
> -
> - /* verify that contents of the buffer are what they are supposed to be */
> - for (i = 0; i < sizeof(buf) / 2; i++) {
> - if (buf[i] != (char) (i % 2 ? 't' : 'T')) {
> - printf("Error: wrong content in buffer at %u!\n", i);
> - return -1;
> - }
> - }
> - for (i = sizeof(buf) / 2; i < sizeof(buf); i++) {
> - if (buf[i] != (char) (i % 2 ? 'h' : 'H')) {
> - printf("Error: wrong content in buffer %u!\n", i);
> - return -1;
> - }
> - }
> -
> - return 0;
> -}
> -
> -/* test left alignment */
> -static int
> -test_cirbuf_align_left(void)
> -{
> -#define HALF_OFFSET CMDLINE_TEST_BUFSIZE / 2
> -#define SMALL_OFFSET HALF_OFFSET / 2
> -/* resulting buffer lengths for each of the test cases */
> -#define LEN1 HALF_OFFSET - SMALL_OFFSET - 1
> -#define LEN2 HALF_OFFSET + SMALL_OFFSET + 2
> -#define LEN3 HALF_OFFSET - SMALL_OFFSET
> -#define LEN4 HALF_OFFSET + SMALL_OFFSET - 1
> -
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - char tmp[CMDLINE_TEST_BUFSIZE];
> - unsigned i;
> -
> - /*
> - * align left when start < end and start in left half
> - */
> -
> - /*
> - * initialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* push end into left half */
> - for (i = 0; i < HALF_OFFSET - 1; i++)
> - cirbuf_add_tail_safe(&cb, 't');
> -
> - /* push start into left half < end */
> - for (i = 0; i < SMALL_OFFSET; i++)
> - cirbuf_del_head_safe(&cb);
> -
> - /* align */
> - if (cirbuf_align_left(&cb) < 0) {
> - printf("Error: alignment failed!\n");
> - return -1;
> - }
> -
> - /* verify result */
> - if (cb.start != 0 || cb.len != LEN1 || cb.end != cb.len - 1) {
> - printf("Error: buffer alignment is wrong!\n");
> - return -1;
> - }
> -
> - /*
> - * align left when start > end and start in left half
> - */
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* push start into left half */
> - for (i = 0; i < HALF_OFFSET + 2; i++)
> - cirbuf_add_head_safe(&cb, 'h');
> -
> - /* push end into left half > start */
> - for (i = 0; i < SMALL_OFFSET; i++)
> - cirbuf_add_tail_safe(&cb, 't');
> -
> - /* align */
> - if (cirbuf_align_left(&cb) < 0) {
> - printf("Error: alignment failed!\n");
> - return -1;
> - }
> -
> - /* verify result */
> - if (cb.start != 0 || cb.len != LEN2 || cb.end != cb.len - 1) {
> - printf("Error: buffer alignment is wrong!");
> - return -1;
> - }
> -
> - /*
> - * align left when start < end and start in right half
> - */
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* push start into the right half */
> - for (i = 0; i < HALF_OFFSET; i++)
> - cirbuf_add_head_safe(&cb, 'h');
> -
> - /* push end into left half > start */
> - for (i = 0; i < SMALL_OFFSET; i++)
> - cirbuf_del_tail_safe(&cb);
> -
> - /* align */
> - if (cirbuf_align_left(&cb) < 0) {
> - printf("Error: alignment failed!\n");
> - return -1;
> - }
> -
> - /* verify result */
> - if (cb.start != 0 || cb.len != LEN3 || cb.end != cb.len - 1) {
> - printf("Error: buffer alignment is wrong!");
> - return -1;
> - }
> -
> - /*
> - * align left when start > end and start in right half
> - */
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* push start into the right half */
> - for (i = 0; i < HALF_OFFSET - 1; i++)
> - cirbuf_add_head_safe(&cb, 'h');
> -
> - /* push end into left half < start */
> - for (i = 0; i < SMALL_OFFSET; i++)
> - cirbuf_add_tail_safe(&cb, 't');
> -
> - /* align */
> - if (cirbuf_align_left(&cb) < 0) {
> - printf("Error: alignment failed!\n");
> - return -1;
> - }
> -
> - /* verify result */
> - if (cb.start != 0 || cb.len != LEN4 ||
> - cb.end != cb.len - 1) {
> - printf("Error: buffer alignment is wrong!");
> - return -1;
> - }
> -
> - /*
> - * Verify that alignment doesn't corrupt data
> - */
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* add string to tail and head */
> - if (cirbuf_add_buf_head(&cb, CIRBUF_STR_HEAD,
> - sizeof(CIRBUF_STR_HEAD)) < 0 || cirbuf_add_buf_tail(&cb,
> - CIRBUF_STR_TAIL, sizeof(CIRBUF_STR_TAIL)) < 0) {
> - printf("Error: failed to add strings!\n");
> - return -1;
> - }
> -
> - /* align */
> - if (cirbuf_align_left(&cb) < 0) {
> - printf("Error: alignment failed!\n");
> - return -1;
> - }
> -
> - /* get string from head */
> - if (cirbuf_get_buf_head(&cb, tmp,
> - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) {
> - printf("Error: failed to read string from head!\n");
> - return -1;
> - }
> -
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL,
> - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) {
> - printf("Error: strings mismatch!\n");
> - return -1;
> - }
> -
> - /* reset tmp buffer */
> - memset(tmp, 0, sizeof(tmp));
> -
> - /* get string from tail */
> - if (cirbuf_get_buf_tail(&cb, tmp,
> - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) {
> - printf("Error: failed to read string from head!\n");
> - return -1;
> - }
> -
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL,
> - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) {
> - printf("Error: strings mismatch!\n");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* test right alignment */
> -static int
> -test_cirbuf_align_right(void)
> -{
> -#define END_OFFSET CMDLINE_TEST_BUFSIZE - 1
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> - char tmp[CMDLINE_TEST_BUFSIZE];
> - unsigned i;
> -
> -
> - /*
> - * align right when start < end and start in left half
> - */
> -
> - /*
> - * initialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to initialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* push end into left half */
> - for (i = 0; i < HALF_OFFSET - 1; i++)
> - cirbuf_add_tail_safe(&cb, 't');
> -
> - /* push start into left half < end */
> - for (i = 0; i < SMALL_OFFSET; i++)
> - cirbuf_del_head_safe(&cb);
> -
> - /* align */
> - cirbuf_align_right(&cb);
> -
> - /* verify result */
> - if (cb.start != END_OFFSET || cb.len != LEN1 || cb.end != cb.len - 2) {
> - printf("Error: buffer alignment is wrong!\n");
> - return -1;
> - }
> -
> - /*
> - * align right when start > end and start in left half
> - */
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* push start into left half */
> - for (i = 0; i < HALF_OFFSET + 2; i++)
> - cirbuf_add_head_safe(&cb, 'h');
> -
> - /* push end into left half > start */
> - for (i = 0; i < SMALL_OFFSET; i++)
> - cirbuf_add_tail_safe(&cb, 't');
> -
> - /* align */
> - cirbuf_align_right(&cb);
> -
> - /* verify result */
> - if (cb.start != END_OFFSET || cb.len != LEN2 || cb.end != cb.len - 2) {
> - printf("Error: buffer alignment is wrong!");
> - return -1;
> - }
> -
> - /*
> - * align right when start < end and start in right half
> - */
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* push start into the right half */
> - for (i = 0; i < HALF_OFFSET; i++)
> - cirbuf_add_head_safe(&cb, 'h');
> -
> - /* push end into left half > start */
> - for (i = 0; i < SMALL_OFFSET; i++)
> - cirbuf_del_tail_safe(&cb);
> -
> - /* align */
> - cirbuf_align_right(&cb);
> -
> - /* verify result */
> - if (cb.end != END_OFFSET || cb.len != LEN3 || cb.start != cb.end - cb.len + 1) {
> - printf("Error: buffer alignment is wrong!");
> - return -1;
> - }
> -
> - /*
> - * align right when start > end and start in right half
> - */
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* push start into the right half */
> - for (i = 0; i < HALF_OFFSET - 1; i++)
> - cirbuf_add_head_safe(&cb, 'h');
> -
> - /* push end into left half < start */
> - for (i = 0; i < SMALL_OFFSET; i++)
> - cirbuf_add_tail_safe(&cb, 't');
> -
> - /* align */
> - cirbuf_align_right(&cb);
> -
> - /* verify result */
> - if (cb.end != END_OFFSET || cb.len != LEN4 || cb.start != cb.end - cb.len + 1) {
> - printf("Error: buffer alignment is wrong!");
> - return -1;
> - }
> -
> - /*
> - * Verify that alignment doesn't corrupt data
> - */
> -
> - /*
> - * reinitialize circular buffer
> - */
> - memset(buf, 0, sizeof(buf));
> - if (cirbuf_init(&cb, buf, 0, sizeof(buf)) < 0) {
> - printf("Error: failed to reinitialize circular buffer!\n");
> - return -1;
> - }
> -
> - /* add string to tail and head */
> - if (cirbuf_add_buf_tail(&cb, CIRBUF_STR_TAIL,
> - sizeof(CIRBUF_STR_TAIL)) < 0 || cirbuf_add_buf_head(&cb,
> - CIRBUF_STR_HEAD, sizeof(CIRBUF_STR_HEAD)) < 0) {
> - printf("Error: failed to add strings!\n");
> - return -1;
> - }
> -
> - /* align */
> - if (cirbuf_align_right(&cb) < 0) {
> - printf("Error: alignment failed!\n");
> - return -1;
> - }
> -
> - /* get string from head */
> - if (cirbuf_get_buf_head(&cb, tmp,
> - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) {
> - printf("Error: failed to read string from head!\n");
> - return -1;
> - }
> -
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL,
> - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) {
> - printf("Error: strings mismatch!\n");
> - return -1;
> - }
> -
> - /* reset tmp buffer */
> - memset(tmp, 0, sizeof(tmp));
> -
> - /* get string from tail */
> - if (cirbuf_get_buf_tail(&cb, tmp,
> - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) < 0) {
> - printf("Error: failed to read string from head!\n");
> - return -1;
> - }
> - /* verify string */
> - if (strncmp(tmp, CIRBUF_STR_HEAD "\0" CIRBUF_STR_TAIL,
> - sizeof(CIRBUF_STR_HEAD) + sizeof(CIRBUF_STR_TAIL)) != 0) {
> - printf("Error: strings mismatch!\n");
> - return -1;
> - }
> -
> - return 0;
> -}
> -
> -/* call functions with invalid parameters */
> -int
> -test_cirbuf_invalid_param(void)
> -{
> - struct cirbuf cb;
> - char buf[CMDLINE_TEST_BUFSIZE];
> -
> - /* null cirbuf */
> - if (cirbuf_init(0, buf, 0, sizeof(buf)) == 0)
> - return -1;
> - /* null buffer */
> - if (cirbuf_init(&cb, 0, 0, sizeof(buf)) == 0)
> - return -1;
> - /* null cirbuf */
> - if (cirbuf_add_head_safe(0, 'h') == 0)
> - return -1;
> - if (cirbuf_add_tail_safe(0, 't') == 0)
> - return -1;
> - if (cirbuf_del_head_safe(0) == 0)
> - return -1;
> - if (cirbuf_del_tail_safe(0) == 0)
> - return -1;
> - /* null buffer */
> - if (cirbuf_add_buf_head(&cb, 0, 0) == 0)
> - return -1;
> - if (cirbuf_add_buf_tail(&cb, 0, 0) == 0)
> - return -1;
> - /* null cirbuf */
> - if (cirbuf_add_buf_head(0, buf, 0) == 0)
> - return -1;
> - if (cirbuf_add_buf_tail(0, buf, 0) == 0)
> - return -1;
> - /* null size */
> - if (cirbuf_add_buf_head(&cb, buf, 0) == 0)
> - return -1;
> - if (cirbuf_add_buf_tail(&cb, buf, 0) == 0)
> - return -1;
> - /* null cirbuf */
> - if (cirbuf_del_buf_head(0, 0) == 0)
> - return -1;
> - if (cirbuf_del_buf_tail(0, 0) == 0)
> - return -1;
> - /* null size */
> - if (cirbuf_del_buf_head(&cb, 0) == 0)
> - return -1;
> - if (cirbuf_del_buf_tail(&cb, 0) == 0)
> - return -1;
> - /* null cirbuf */
> - if (cirbuf_get_buf_head(0, 0, 0) == 0)
> - return -1;
> - if (cirbuf_get_buf_tail(0, 0, 0) == 0)
> - return -1;
> - /* null buffer */
> - if (cirbuf_get_buf_head(&cb, 0, 0) == 0)
> - return -1;
> - if (cirbuf_get_buf_tail(&cb, 0, 0) == 0)
> - return -1;
> - /* null size, this is valid but should return 0 */
> - if (cirbuf_get_buf_head(&cb, buf, 0) != 0)
> - return -1;
> - if (cirbuf_get_buf_tail(&cb, buf, 0) != 0)
> - return -1;
> - /* null cirbuf */
> - if (cirbuf_align_left(0) == 0)
> - return -1;
> - if (cirbuf_align_right(0) == 0)
> - return -1;
> -
> - return 0;
> -}
> -
> -/* test cmdline_cirbuf char functions */
> -int
> -test_cirbuf_char(void)
> -{
> - int ret;
> -
> - ret = test_cirbuf_char_add_del();
> - if (ret < 0)
> - return -1;
> -
> - ret = test_cirbuf_char_fill();
> - if (ret < 0)
> - return -1;
> -
> - return 0;
> -}
> -
> -/* test cmdline_cirbuf string functions */
> -int
> -test_cirbuf_string(void)
> -{
> - if (test_cirbuf_string_add_del() < 0)
> - return -1;
> -
> - if (test_cirbuf_string_add_del_reverse() < 0)
> - return -1;
> -
> - if (test_cirbuf_string_add_boundaries() < 0)
> - return -1;
> -
> - if (test_cirbuf_string_get_del_boundaries() < 0)
> - return -1;
> -
> - if (test_cirbuf_string_get_del_partial() < 0)
> - return -1;
> -
> - if (test_cirbuf_string_misc() < 0)
> - return -1;
> -
> - return 0;
> -}
> -
> -/* test cmdline_cirbuf align functions */
> -int
> -test_cirbuf_align(void)
> -{
> - if (test_cirbuf_align_left() < 0)
> - return -1;
> - if (test_cirbuf_align_right() < 0)
> - return -1;
> - return 0;
> -}
> diff --git a/test/test/test_cmdline_lib.c b/test/test/test_cmdline_lib.c
> index 65b823a..93a80d0 100644
> --- a/test/test/test_cmdline_lib.c
> +++ b/test/test/test_cmdline_lib.c
> @@ -41,8 +41,6 @@
> #include <ctype.h>
> #include <sys/queue.h>
>
> -#include <cmdline_vt100.h>
> -#include <cmdline_rdline.h>
> #include <cmdline_parse.h>
> #include <cmdline_socket.h>
> #include <cmdline.h>
> @@ -50,113 +48,41 @@
> #include "test_cmdline.h"
>
> /****************************************************************/
> -/* static functions required for some tests */
> -static void
> -valid_buffer(__attribute__((unused))struct rdline *rdl,
> - __attribute__((unused))const char *buf,
> - __attribute__((unused)) unsigned int size)
> -{
> -}
> -
> -static int
> -complete_buffer(__attribute__((unused)) struct rdline *rdl,
> - __attribute__((unused)) const char *buf,
> - __attribute__((unused)) char *dstbuf,
> - __attribute__((unused)) unsigned int dstsize,
> - __attribute__((unused)) int *state)
> -{
> - return 0;
> -}
> -
> -/****************************************************************/
>
> static int
> test_cmdline_parse_fns(void)
> {
> - struct cmdline cl;
> + struct cmdline *cl;
> int i = 0;
> char dst[CMDLINE_TEST_BUFSIZE];
>
> + cl = cmdline_new(NULL, "prompt", 0, 1);
> + if (!cl)
> + goto error;
> if (cmdline_parse(NULL, "buffer") >= 0)
> goto error;
> - if (cmdline_parse(&cl, NULL) >= 0)
> + if (cmdline_parse(cl, NULL) >= 0)
> goto error;
>
> if (cmdline_complete(NULL, "buffer", &i, dst, sizeof(dst)) >= 0)
> goto error;
> - if (cmdline_complete(&cl, NULL, &i, dst, sizeof(dst)) >= 0)
> + if (cmdline_complete(cl, NULL, &i, dst, sizeof(dst)) >= 0)
> goto error;
> - if (cmdline_complete(&cl, "buffer", NULL, dst, sizeof(dst)) >= 0)
> + if (cmdline_complete(cl, "buffer", NULL, dst, sizeof(dst)) >= 0)
> goto error;
> - if (cmdline_complete(&cl, "buffer", &i, NULL, sizeof(dst)) >= 0)
> + if (cmdline_complete(cl, "buffer", &i, NULL, sizeof(dst)) >= 0)
> goto error;
>
> return 0;
>
> error:
> + if (cl)
> + cmdline_free(cl);
> printf("Error: function accepted null parameter!\n");
> return -1;
> }
>
> static int
> -test_cmdline_rdline_fns(void)
> -{
> - struct rdline rdl;
> - rdline_write_char_t *wc = &cmdline_write_char;
> - rdline_validate_t *v = &valid_buffer;
> - rdline_complete_t *c = &complete_buffer;
> -
> - if (rdline_init(NULL, wc, v, c) >= 0)
> - goto error;
> - if (rdline_init(&rdl, NULL, v, c) >= 0)
> - goto error;
> - if (rdline_init(&rdl, wc, NULL, c) >= 0)
> - goto error;
> - if (rdline_init(&rdl, wc, v, NULL) >= 0)
> - goto error;
> - if (rdline_char_in(NULL, 0) >= 0)
> - goto error;
> - if (rdline_get_buffer(NULL) != NULL)
> - goto error;
> - if (rdline_add_history(NULL, "history") >= 0)
> - goto error;
> - if (rdline_add_history(&rdl, NULL) >= 0)
> - goto error;
> - if (rdline_get_history_item(NULL, 0) != NULL)
> - goto error;
> -
> - /* void functions */
> - rdline_newline(NULL, "prompt");
> - rdline_newline(&rdl, NULL);
> - rdline_stop(NULL);
> - rdline_quit(NULL);
> - rdline_restart(NULL);
> - rdline_redisplay(NULL);
> - rdline_reset(NULL);
> - rdline_clear_history(NULL);
> -
> - return 0;
> -
> -error:
> - printf("Error: function accepted null parameter!\n");
> - return -1;
> -}
> -
> -static int
> -test_cmdline_vt100_fns(void)
> -{
> - if (vt100_parser(NULL, 0) >= 0) {
> - printf("Error: function accepted null parameter!\n");
> - return -1;
> - }
> -
> - /* void functions */
> - vt100_init(NULL);
> -
> - return 0;
> -}
> -
> -static int
> test_cmdline_socket_fns(void)
> {
> cmdline_parse_ctx_t ctx;
> @@ -193,7 +119,7 @@ static int
> test_cmdline_fns(void)
> {
> cmdline_parse_ctx_t ctx;
> - struct cmdline cl, *tmp;
> + struct cmdline *tmp;
>
> memset(&ctx, 0, sizeof(ctx));
> tmp = cmdline_new(&ctx, "test", -1, -1);
> @@ -206,10 +132,6 @@ test_cmdline_fns(void)
> goto error;
> if (cmdline_in(NULL, "buffer", CMDLINE_TEST_BUFSIZE) >= 0)
> goto error;
> - if (cmdline_in(&cl, NULL, CMDLINE_TEST_BUFSIZE) >= 0)
> - goto error;
> - if (cmdline_write_char(NULL, 0) >= 0)
> - goto error;
>
> /* void functions */
> cmdline_set_prompt(NULL, "prompt");
> @@ -220,16 +142,6 @@ test_cmdline_fns(void)
> cmdline_interact(NULL);
> cmdline_quit(NULL);
>
> - /* check if void calls change anything when they should fail */
> - cl = *tmp;
> -
> - cmdline_printf(&cl, NULL);
> - if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch;
> - cmdline_set_prompt(&cl, NULL);
> - if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch;
> - cmdline_in(&cl, NULL, CMDLINE_TEST_BUFSIZE);
> - if (memcmp(&cl, tmp, sizeof(cl))) goto mismatch;
> -
> cmdline_free(tmp);
>
> return 0;
> @@ -237,9 +149,6 @@ test_cmdline_fns(void)
> error:
> printf("Error: function accepted null parameter!\n");
> return -1;
> -mismatch:
> - printf("Error: data changed!\n");
> - return -1;
> }
>
> /* test library functions. the point of these tests is not so much to test
> @@ -251,10 +160,6 @@ test_cmdline_lib(void)
> {
> if (test_cmdline_parse_fns() < 0)
> return -1;
> - if (test_cmdline_rdline_fns() < 0)
> - return -1;
> - if (test_cmdline_vt100_fns() < 0)
> - return -1;
> if (test_cmdline_socket_fns() < 0)
> return -1;
> if (test_cmdline_fns() < 0)
> --
> 2.1.4
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] virtio: add new driver for crypto devices
@ 2017-11-17 17:10 1% Jay Zhou
0 siblings, 0 replies; 200+ results
From: Jay Zhou @ 2017-11-17 17:10 UTC (permalink / raw)
To: dev
Cc: yliu, maxime.coquelin, arei.gonglei, roy.fan.zhang, xin.zeng,
weidong.huang, wangxinxin.wang, longpeng2, jianjay.zhou
This patch series add a PMD for the virtio-crypto devices.
This patch series support a limited subset of crypto services.
Currently supporting symmetric algorithms(cipher only or chained algorithms),
and only the following algorithms are tested(because the backend of the virtio-crypto
only supports cipher only now):
Cipher algorithms:
- RTE_CRYPTO_CIPHER_AES_CBC (with 128-bit, 192-bit and 256-bit keys supported)
- RTE_CRYPTO_CIPHER_AES_CTR (with 128-bit, 192-bit and 256-bit keys supported)
Firstly build QEMU with libgcrypt cryptography support.
QEMU can then be started using the following parameters:
qemu-system-x86_64 \
[...] \
-object cryptodev-backend-builtin,id=cryptodev0 \
-device virtio-crypto-pci,id=crypto0,cryptodev=cryptodev0 \
[...]
Follow the steps listed in the link below
https://www.kernel.org/doc/html/v4.12/driver-api/uio-howto.html
to bind the uio_generic driver for the virtio-crypto device.
For example, 0000:00:04.0 is the domain, bus, device and function
number of the virtio-crypto device,
modprobe uio_pci_generic
echo -n 0000:00:04.0 > /sys/bus/pci/drivers/virtio-pci/unbind
echo "1af4 1054" > /sys/bus/pci/drivers/uio_pci_generic/new_id
The front-end virtio crypto PMD driver can be installed:
cd to the top-level DPDK directory
sed -i 's,\(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO\)=n,\1=y,' config/common_base
make config T=x86_64-native-linuxapp-gcc
make install T=x86_64-native-linuxapp-gcc
The test cases can be compiled as below:
cd to the top-level DPDK directory
export RTE_TARGET=x86_64-native-linuxapp-gcc
export RTE_SDK=`pwd`
cd to test/test
make
./test (MUST reserve huge pages memory)
type the command "cryptodev_virtio_autotest" to test
The result should be like this:
RTE>>cryptodev_virtio_autotest
+ ------------------------------------------------------- +
+ Test Suite : Crypto VIRTIO Unit Test Suite
+ ------------------------------------------------------- +
0) TestCase AES-128-CBC Encryption PASS
1) TestCase AES-128-CBC Decryption PASS
2) TestCase AES-192-CBC Encryption PASS
3) TestCase AES-192-CBC Decryption PASS
4) TestCase AES-256-CBC Encryption PASS
5) TestCase AES-256-CBC Decryption PASS
6) TestCase AES-256-CBC OOP Encryption PASS
7) TestCase AES-256-CBC OOP Decryption PASS
8) TestCase AES-128-CTR Encryption PASS
9) TestCase AES-128-CTR Decryption PASS
10) TestCase AES-192-CTR Encryption PASS
11) TestCase AES-192-CTR Decryption PASS
12) TestCase AES-256-CTR Encryption PASS
13) TestCase AES-256-CTR Decryption PASS
+ TestCase [ 0] : test_AES_cipheronly_virtio_all succeeded
+ ------------------------------------------------------- +
+ Test Suite Summary
+ Tests Total : 1
+ Tests Skipped : 0
+ Tests Executed : 1
+ Tests Unsupported: 0
+ Tests Passed : 1
+ Tests Failed : 0
+ ------------------------------------------------------- +
Test OK
TODO:
- Only some function tests (chained algorithms and performance
tests are not supported)
- Only supports session-oriented API implementation(session-less
APIs are not supported)
- Hash only is not supported (depends on the backend of virtio-crypto)
Signed-off-by: Jay Zhou <jianjay.zhou@huawei.com>
---
MAINTAINERS | 4 +
config/common_base | 20 +
drivers/crypto/Makefile | 1 +
drivers/crypto/virtio/Makefile | 59 +
drivers/crypto/virtio/virtio_crypto.h | 452 ++++++++
drivers/crypto/virtio/virtio_crypto_algs.h | 56 +
drivers/crypto/virtio/virtio_cryptodev.c | 1542 +++++++++++++++++++++++++++
drivers/crypto/virtio/virtio_cryptodev.h | 87 ++
drivers/crypto/virtio/virtio_logs.h | 76 ++
drivers/crypto/virtio/virtio_pci.c | 714 +++++++++++++
drivers/crypto/virtio/virtio_pci.h | 286 +++++
drivers/crypto/virtio/virtio_ring.h | 169 +++
drivers/crypto/virtio/virtio_rxtx.c | 569 ++++++++++
drivers/crypto/virtio/virtqueue.c | 80 ++
drivers/crypto/virtio/virtqueue.h | 208 ++++
mk/rte.app.mk | 1 +
test/test/test_cryptodev.c | 49 +
test/test/test_cryptodev.h | 1 +
test/test/test_cryptodev_aes_test_vectors.h | 45 +-
test/test/test_cryptodev_blockcipher.c | 9 +-
test/test/test_cryptodev_blockcipher.h | 1 +
21 files changed, 4413 insertions(+), 16 deletions(-)
create mode 100644 drivers/crypto/virtio/Makefile
create mode 100644 drivers/crypto/virtio/virtio_crypto.h
create mode 100644 drivers/crypto/virtio/virtio_crypto_algs.h
create mode 100644 drivers/crypto/virtio/virtio_cryptodev.c
create mode 100644 drivers/crypto/virtio/virtio_cryptodev.h
create mode 100644 drivers/crypto/virtio/virtio_logs.h
create mode 100644 drivers/crypto/virtio/virtio_pci.c
create mode 100644 drivers/crypto/virtio/virtio_pci.h
create mode 100644 drivers/crypto/virtio/virtio_ring.h
create mode 100644 drivers/crypto/virtio/virtio_rxtx.c
create mode 100644 drivers/crypto/virtio/virtqueue.c
create mode 100644 drivers/crypto/virtio/virtqueue.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 8ab08d2..deccd45 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -519,6 +519,10 @@ F: drivers/net/virtio/
F: doc/guides/nics/virtio.rst
F: doc/guides/nics/features/virtio*.ini
+Virtio crypto PMD
+M: Jay Zhou <jianjay.zhou@huawei.com>
+F: drivers/crypto/virtio/
+
Wind River AVP
M: Allain Legacy <allain.legacy@windriver.com>
M: Matt Peters <matt.peters@windriver.com>
diff --git a/config/common_base b/config/common_base
index 82ee754..011a6fe 100644
--- a/config/common_base
+++ b/config/common_base
@@ -504,6 +504,26 @@ CONFIG_RTE_LIBRTE_PMD_QAT_DEBUG_DRIVER=n
CONFIG_RTE_QAT_PMD_MAX_NB_SESSIONS=2048
#
+# Compile PMD for virtio crypto devices
+#
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO=n
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_INIT=n
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_SESSION=n
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_TX=n
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_RX=n
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_DRIVER=n
+CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_DUMP=n
+#
+# Number of maximum virtio crypto devices
+#
+CONFIG_RTE_MAX_VIRTIO_CRYPTO=32
+#
+# Number of sessions to create in the session memory pool
+# on a single virtio crypto device.
+#
+CONFIG_RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS=1024
+
+#
# Compile PMD for AESNI backed device
#
CONFIG_RTE_LIBRTE_PMD_AESNI_MB=n
diff --git a/drivers/crypto/Makefile b/drivers/crypto/Makefile
index 645b696..df44026 100644
--- a/drivers/crypto/Makefile
+++ b/drivers/crypto/Makefile
@@ -44,5 +44,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_PMD_MRVL_CRYPTO) += mrvl
DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += null
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA2_SEC) += dpaa2_sec
DIRS-$(CONFIG_RTE_LIBRTE_PMD_DPAA_SEC) += dpaa_sec
+DIRS-$(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO) += virtio
include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/drivers/crypto/virtio/Makefile b/drivers/crypto/virtio/Makefile
new file mode 100644
index 0000000..084e657
--- /dev/null
+++ b/drivers/crypto/virtio/Makefile
@@ -0,0 +1,59 @@
+# BSD LICENSE
+#
+# Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+# its contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+include $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_virtio_crypto.a
+
+CFLAGS += -O3
+CFLAGS += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_pmd_virtio_crypto_version.map
+
+LIBABIVER := 1
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO) += virtqueue.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO) += virtio_pci.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO) += virtio_rxtx.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO) += virtio_cryptodev.c
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO) += lib/librte_eal
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO) += lib/librte_mempool lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO) += lib/librte_cryptodev
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/crypto/virtio/virtio_crypto.h b/drivers/crypto/virtio/virtio_crypto.h
new file mode 100644
index 0000000..ba94e80
--- /dev/null
+++ b/drivers/crypto/virtio/virtio_crypto.h
@@ -0,0 +1,452 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTIO_CRYPTO_H_
+#define _VIRTIO_CRYPTO_H_
+
+#define VIRTIO_CRYPTO_SERVICE_CIPHER 0
+#define VIRTIO_CRYPTO_SERVICE_HASH 1
+#define VIRTIO_CRYPTO_SERVICE_MAC 2
+#define VIRTIO_CRYPTO_SERVICE_AEAD 3
+
+#define VIRTIO_CRYPTO_OPCODE(service, op) (((service) << 8) | (op))
+
+struct virtio_crypto_ctrl_header {
+#define VIRTIO_CRYPTO_CIPHER_CREATE_SESSION \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x02)
+#define VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x03)
+#define VIRTIO_CRYPTO_HASH_CREATE_SESSION \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x02)
+#define VIRTIO_CRYPTO_HASH_DESTROY_SESSION \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x03)
+#define VIRTIO_CRYPTO_MAC_CREATE_SESSION \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x02)
+#define VIRTIO_CRYPTO_MAC_DESTROY_SESSION \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x03)
+#define VIRTIO_CRYPTO_AEAD_CREATE_SESSION \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x02)
+#define VIRTIO_CRYPTO_AEAD_DESTROY_SESSION \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x03)
+ uint32_t opcode;
+ uint32_t algo;
+ uint32_t flag;
+ /* data virtqueue id */
+ uint32_t queue_id;
+};
+
+struct virtio_crypto_cipher_session_para {
+#define VIRTIO_CRYPTO_NO_CIPHER 0
+#define VIRTIO_CRYPTO_CIPHER_ARC4 1
+#define VIRTIO_CRYPTO_CIPHER_AES_ECB 2
+#define VIRTIO_CRYPTO_CIPHER_AES_CBC 3
+#define VIRTIO_CRYPTO_CIPHER_AES_CTR 4
+#define VIRTIO_CRYPTO_CIPHER_DES_ECB 5
+#define VIRTIO_CRYPTO_CIPHER_DES_CBC 6
+#define VIRTIO_CRYPTO_CIPHER_3DES_ECB 7
+#define VIRTIO_CRYPTO_CIPHER_3DES_CBC 8
+#define VIRTIO_CRYPTO_CIPHER_3DES_CTR 9
+#define VIRTIO_CRYPTO_CIPHER_KASUMI_F8 10
+#define VIRTIO_CRYPTO_CIPHER_SNOW3G_UEA2 11
+#define VIRTIO_CRYPTO_CIPHER_AES_F8 12
+#define VIRTIO_CRYPTO_CIPHER_AES_XTS 13
+#define VIRTIO_CRYPTO_CIPHER_ZUC_EEA3 14
+ uint32_t algo;
+ /* length of key */
+ uint32_t keylen;
+
+#define VIRTIO_CRYPTO_OP_ENCRYPT 1
+#define VIRTIO_CRYPTO_OP_DECRYPT 2
+ /* encrypt or decrypt */
+ uint32_t op;
+ uint32_t padding;
+};
+
+struct virtio_crypto_session_input {
+ /* Device-writable part */
+ uint64_t session_id;
+ uint32_t status;
+ uint32_t padding;
+};
+
+struct virtio_crypto_cipher_session_req {
+ struct virtio_crypto_cipher_session_para para;
+ uint8_t padding[32];
+};
+
+struct virtio_crypto_hash_session_para {
+#define VIRTIO_CRYPTO_NO_HASH 0
+#define VIRTIO_CRYPTO_HASH_MD5 1
+#define VIRTIO_CRYPTO_HASH_SHA1 2
+#define VIRTIO_CRYPTO_HASH_SHA_224 3
+#define VIRTIO_CRYPTO_HASH_SHA_256 4
+#define VIRTIO_CRYPTO_HASH_SHA_384 5
+#define VIRTIO_CRYPTO_HASH_SHA_512 6
+#define VIRTIO_CRYPTO_HASH_SHA3_224 7
+#define VIRTIO_CRYPTO_HASH_SHA3_256 8
+#define VIRTIO_CRYPTO_HASH_SHA3_384 9
+#define VIRTIO_CRYPTO_HASH_SHA3_512 10
+#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE128 11
+#define VIRTIO_CRYPTO_HASH_SHA3_SHAKE256 12
+ uint32_t algo;
+ /* hash result length */
+ uint32_t hash_result_len;
+ uint8_t padding[8];
+};
+
+struct virtio_crypto_hash_create_session_req {
+ struct virtio_crypto_hash_session_para para;
+ uint8_t padding[40];
+};
+
+struct virtio_crypto_mac_session_para {
+#define VIRTIO_CRYPTO_NO_MAC 0
+#define VIRTIO_CRYPTO_MAC_HMAC_MD5 1
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA1 2
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_224 3
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_256 4
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_384 5
+#define VIRTIO_CRYPTO_MAC_HMAC_SHA_512 6
+#define VIRTIO_CRYPTO_MAC_CMAC_3DES 25
+#define VIRTIO_CRYPTO_MAC_CMAC_AES 26
+#define VIRTIO_CRYPTO_MAC_KASUMI_F9 27
+#define VIRTIO_CRYPTO_MAC_SNOW3G_UIA2 28
+#define VIRTIO_CRYPTO_MAC_GMAC_AES 41
+#define VIRTIO_CRYPTO_MAC_GMAC_TWOFISH 42
+#define VIRTIO_CRYPTO_MAC_CBCMAC_AES 49
+#define VIRTIO_CRYPTO_MAC_CBCMAC_KASUMI_F9 50
+#define VIRTIO_CRYPTO_MAC_XCBC_AES 53
+ uint32_t algo;
+ /* hash result length */
+ uint32_t hash_result_len;
+ /* length of authenticated key */
+ uint32_t auth_key_len;
+ uint32_t padding;
+};
+
+struct virtio_crypto_mac_create_session_req {
+ struct virtio_crypto_mac_session_para para;
+ uint8_t padding[40];
+};
+
+struct virtio_crypto_aead_session_para {
+#define VIRTIO_CRYPTO_NO_AEAD 0
+#define VIRTIO_CRYPTO_AEAD_GCM 1
+#define VIRTIO_CRYPTO_AEAD_CCM 2
+#define VIRTIO_CRYPTO_AEAD_CHACHA20_POLY1305 3
+ uint32_t algo;
+ /* length of key */
+ uint32_t key_len;
+ /* hash result length */
+ uint32_t hash_result_len;
+ /* length of the additional authenticated data (AAD) in bytes */
+ uint32_t aad_len;
+ /* encrypt or decrypt, See above VIRTIO_CRYPTO_OP_* */
+ uint32_t op;
+ uint32_t padding;
+};
+
+struct virtio_crypto_aead_create_session_req {
+ struct virtio_crypto_aead_session_para para;
+ uint8_t padding[32];
+};
+
+struct virtio_crypto_alg_chain_session_para {
+#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER 1
+#define VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH 2
+ uint32_t alg_chain_order;
+/* Plain hash */
+#define VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN 1
+/* Authenticated hash (mac) */
+#define VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH 2
+/* Nested hash */
+#define VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED 3
+ uint32_t hash_mode;
+ struct virtio_crypto_cipher_session_para cipher_param;
+ union {
+ struct virtio_crypto_hash_session_para hash_param;
+ struct virtio_crypto_mac_session_para mac_param;
+ uint8_t padding[16];
+ } u;
+ /* length of the additional authenticated data (AAD) in bytes */
+ uint32_t aad_len;
+ uint32_t padding;
+};
+
+struct virtio_crypto_alg_chain_session_req {
+ struct virtio_crypto_alg_chain_session_para para;
+};
+
+struct virtio_crypto_sym_create_session_req {
+ union {
+ struct virtio_crypto_cipher_session_req cipher;
+ struct virtio_crypto_alg_chain_session_req chain;
+ uint8_t padding[48];
+ } u;
+
+ /* Device-readable part */
+
+/* No operation */
+#define VIRTIO_CRYPTO_SYM_OP_NONE 0
+/* Cipher only operation on the data */
+#define VIRTIO_CRYPTO_SYM_OP_CIPHER 1
+/*
+ * Chain any cipher with any hash or mac operation. The order
+ * depends on the value of alg_chain_order param
+ */
+#define VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING 2
+ uint32_t op_type;
+ uint32_t padding;
+};
+
+struct virtio_crypto_destroy_session_req {
+ /* Device-readable part */
+ uint64_t session_id;
+ uint8_t padding[48];
+};
+
+/* The request of the control virtqueue's packet */
+struct virtio_crypto_op_ctrl_req {
+ struct virtio_crypto_ctrl_header header;
+
+ union {
+ struct virtio_crypto_sym_create_session_req
+ sym_create_session;
+ struct virtio_crypto_hash_create_session_req
+ hash_create_session;
+ struct virtio_crypto_mac_create_session_req
+ mac_create_session;
+ struct virtio_crypto_aead_create_session_req
+ aead_create_session;
+ struct virtio_crypto_destroy_session_req
+ destroy_session;
+ uint8_t padding[56];
+ } u;
+};
+
+struct virtio_crypto_op_header {
+#define VIRTIO_CRYPTO_CIPHER_ENCRYPT \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x00)
+#define VIRTIO_CRYPTO_CIPHER_DECRYPT \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_CIPHER, 0x01)
+#define VIRTIO_CRYPTO_HASH \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_HASH, 0x00)
+#define VIRTIO_CRYPTO_MAC \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_MAC, 0x00)
+#define VIRTIO_CRYPTO_AEAD_ENCRYPT \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x00)
+#define VIRTIO_CRYPTO_AEAD_DECRYPT \
+ VIRTIO_CRYPTO_OPCODE(VIRTIO_CRYPTO_SERVICE_AEAD, 0x01)
+ uint32_t opcode;
+ /* algo should be service-specific algorithms */
+ uint32_t algo;
+ /* session_id should be service-specific algorithms */
+ uint64_t session_id;
+ /* control flag to control the request */
+ uint32_t flag;
+ uint32_t padding;
+};
+
+struct virtio_crypto_cipher_para {
+ /*
+ * Byte Length of valid IV/Counter
+ *
+ * For block ciphers in CBC or F8 mode, or for Kasumi in F8 mode, or for
+ * SNOW3G in UEA2 mode, this is the length of the IV (which
+ * must be the same as the block length of the cipher).
+ * For block ciphers in CTR mode, this is the length of the counter
+ * (which must be the same as the block length of the cipher).
+ * For AES-XTS, this is the 128bit tweak, i, from IEEE Std 1619-2007.
+ *
+ * The IV/Counter will be updated after every partial cryptographic
+ * operation.
+ */
+ uint32_t iv_len;
+ /* length of source data */
+ uint32_t src_data_len;
+ /* length of dst data */
+ uint32_t dst_data_len;
+ uint32_t padding;
+};
+
+struct virtio_crypto_hash_para {
+ /* length of source data */
+ uint32_t src_data_len;
+ /* hash result length */
+ uint32_t hash_result_len;
+};
+
+struct virtio_crypto_mac_para {
+ struct virtio_crypto_hash_para hash;
+};
+
+struct virtio_crypto_aead_para {
+ /*
+ * Byte Length of valid IV data pointed to by the below iv_addr
+ * parameter.
+ *
+ * For GCM mode, this is either 12 (for 96-bit IVs) or 16, in which
+ * case iv_addr points to J0.
+ * For CCM mode, this is the length of the nonce, which can be in the
+ * range 7 to 13 inclusive.
+ */
+ uint32_t iv_len;
+ /* length of additional auth data */
+ uint32_t aad_len;
+ /* length of source data */
+ uint32_t src_data_len;
+ /* length of dst data */
+ uint32_t dst_data_len;
+};
+
+struct virtio_crypto_cipher_data_req {
+ /* Device-readable part */
+ struct virtio_crypto_cipher_para para;
+ uint8_t padding[24];
+};
+
+struct virtio_crypto_hash_data_req {
+ /* Device-readable part */
+ struct virtio_crypto_hash_para para;
+ uint8_t padding[40];
+};
+
+struct virtio_crypto_mac_data_req {
+ /* Device-readable part */
+ struct virtio_crypto_mac_para para;
+ uint8_t padding[40];
+};
+
+struct virtio_crypto_alg_chain_data_para {
+ uint32_t iv_len;
+ /* Length of source data */
+ uint32_t src_data_len;
+ /* Length of destination data */
+ uint32_t dst_data_len;
+ /* Starting point for cipher processing in source data */
+ uint32_t cipher_start_src_offset;
+ /* Length of the source data that the cipher will be computed on */
+ uint32_t len_to_cipher;
+ /* Starting point for hash processing in source data */
+ uint32_t hash_start_src_offset;
+ /* Length of the source data that the hash will be computed on */
+ uint32_t len_to_hash;
+ /* Length of the additional auth data */
+ uint32_t aad_len;
+ /* Length of the hash result */
+ uint32_t hash_result_len;
+ uint32_t reserved;
+};
+
+struct virtio_crypto_alg_chain_data_req {
+ /* Device-readable part */
+ struct virtio_crypto_alg_chain_data_para para;
+};
+
+struct virtio_crypto_sym_data_req {
+ union {
+ struct virtio_crypto_cipher_data_req cipher;
+ struct virtio_crypto_alg_chain_data_req chain;
+ uint8_t padding[40];
+ } u;
+
+ /* See above VIRTIO_CRYPTO_SYM_OP_* */
+ uint32_t op_type;
+ uint32_t padding;
+};
+
+struct virtio_crypto_aead_data_req {
+ /* Device-readable part */
+ struct virtio_crypto_aead_para para;
+ uint8_t padding[32];
+};
+
+/* The request of the data virtqueue's packet */
+struct virtio_crypto_op_data_req {
+ struct virtio_crypto_op_header header;
+
+ union {
+ struct virtio_crypto_sym_data_req sym_req;
+ struct virtio_crypto_hash_data_req hash_req;
+ struct virtio_crypto_mac_data_req mac_req;
+ struct virtio_crypto_aead_data_req aead_req;
+ uint8_t padding[48];
+ } u;
+};
+
+#define VIRTIO_CRYPTO_OK 0
+#define VIRTIO_CRYPTO_ERR 1
+#define VIRTIO_CRYPTO_BADMSG 2
+#define VIRTIO_CRYPTO_NOTSUPP 3
+#define VIRTIO_CRYPTO_INVSESS 4 /* Invalid session id */
+
+/* The accelerator hardware is ready */
+#define VIRTIO_CRYPTO_S_HW_READY (1 << 0)
+
+struct virtio_crypto_config {
+ /* See VIRTIO_CRYPTO_OP_* above */
+ uint32_t status;
+
+ /*
+ * Maximum number of data queue
+ */
+ uint32_t max_dataqueues;
+
+ /*
+ * Specifies the services mask which the device support,
+ * see VIRTIO_CRYPTO_SERVICE_* above
+ */
+ uint32_t crypto_services;
+
+ /* Detailed algorithms mask */
+ uint32_t cipher_algo_l;
+ uint32_t cipher_algo_h;
+ uint32_t hash_algo;
+ uint32_t mac_algo_l;
+ uint32_t mac_algo_h;
+ uint32_t aead_algo;
+ /* Maximum length of cipher key */
+ uint32_t max_cipher_key_len;
+ /* Maximum length of authenticated key */
+ uint32_t max_auth_key_len;
+ uint32_t reserve;
+ /* Maximum size of each crypto request's content */
+ uint64_t max_size;
+};
+
+struct virtio_crypto_inhdr {
+ /* See VIRTIO_CRYPTO_* above */
+ uint8_t status;
+};
+
+#endif /* _VIRTIO_CRYPTO_H_ */
diff --git a/drivers/crypto/virtio/virtio_crypto_algs.h b/drivers/crypto/virtio/virtio_crypto_algs.h
new file mode 100644
index 0000000..76dc6f6
--- /dev/null
+++ b/drivers/crypto/virtio/virtio_crypto_algs.h
@@ -0,0 +1,56 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTIO_CRYPTO_ALGS_H_
+#define _VIRTIO_CRYPTO_ALGS_H_
+
+#include <rte_memory.h>
+#include "virtio_crypto.h"
+
+struct virtio_crypto_session {
+ uint64_t session_id;
+
+ struct {
+ uint16_t offset;
+ uint16_t length;
+ } iv;
+
+ struct {
+ uint32_t length;
+ phys_addr_t phys_addr;
+ } aad;
+
+ struct virtio_crypto_op_ctrl_req ctrl;
+};
+
+#endif /* _VIRTIO_CRYPTO_ALGS_H_ */
diff --git a/drivers/crypto/virtio/virtio_cryptodev.c b/drivers/crypto/virtio/virtio_cryptodev.c
new file mode 100644
index 0000000..9e6cd20
--- /dev/null
+++ b/drivers/crypto/virtio/virtio_cryptodev.c
@@ -0,0 +1,1542 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <errno.h>
+#include <unistd.h>
+#ifdef RTE_EXEC_ENV_LINUXAPP
+#include <dirent.h>
+#include <fcntl.h>
+#endif
+
+#include <rte_cryptodev.h>
+#include <rte_cryptodev_pmd.h>
+#include <rte_memcpy.h>
+#include <rte_string_fns.h>
+#include <rte_memzone.h>
+#include <rte_malloc.h>
+#include <rte_atomic.h>
+#include <rte_branch_prediction.h>
+#include <rte_pci.h>
+#include <rte_common.h>
+#include <rte_errno.h>
+
+#include <rte_memory.h>
+#include <rte_eal.h>
+#include <rte_dev.h>
+#include <rte_log.h>
+
+#include "virtio_crypto.h"
+#include "virtio_cryptodev.h"
+#include "virtio_logs.h"
+#include "virtqueue.h"
+#include "virtio_crypto_algs.h"
+
+static int virtio_crypto_dev_configure(struct rte_cryptodev *dev,
+ struct rte_cryptodev_config *config);
+static int virtio_crypto_dev_start(struct rte_cryptodev *dev);
+static void virtio_crypto_dev_stop(struct rte_cryptodev *dev);
+static int virtio_crypto_dev_close(struct rte_cryptodev *dev);
+static void virtio_crypto_dev_info_get(struct rte_cryptodev *dev,
+ struct rte_cryptodev_info *dev_info);
+static void virtio_crypto_dev_stats_get(struct rte_cryptodev *dev,
+ struct rte_cryptodev_stats *stats);
+static void virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev);
+static int virtio_crypto_qp_setup(struct rte_cryptodev *dev,
+ uint16_t queue_pair_id,
+ const struct rte_cryptodev_qp_conf *qp_conf,
+ int socket_id,
+ struct rte_mempool *session_pool);
+static int virtio_crypto_qp_release(struct rte_cryptodev *dev,
+ uint16_t queue_pair_id);
+static void virtio_crypto_dev_free_mbufs(struct rte_cryptodev *dev);
+static unsigned virtio_crypto_sym_get_session_private_size(
+ struct rte_cryptodev *dev);
+static void virtio_crypto_sym_clear_session( struct rte_cryptodev *dev,
+ struct rte_cryptodev_sym_session *sess);
+static int virtio_crypto_sym_configure_session(struct rte_cryptodev *dev,
+ struct rte_crypto_sym_xform *xform,
+ struct rte_cryptodev_sym_session *session,
+ struct rte_mempool *mp);
+
+/*
+ * The set of PCI devices this driver supports
+ */
+static const struct rte_pci_id pci_id_virtio_crypto_map[] = {
+ { RTE_PCI_DEVICE(VIRTIO_CRYPTO_PCI_VENDORID,
+ VIRTIO_CRYPTO_PCI_LEGACY_DEVICEID) },
+ { RTE_PCI_DEVICE(VIRTIO_CRYPTO_PCI_VENDORID,
+ VIRTIO_CRYPTO_PCI_MODERN_DEVICEID) },
+ { .vendor_id = 0, /* sentinel */ },
+};
+
+uint8_t cryptodev_virtio_driver_id;
+
+#define NUM_ENTRY_VIRTIO_CRYPTO_SYM_CREATE_SESSION 4
+
+static int
+virtio_crypto_send_command(struct virtqueue *vq,
+ struct virtio_crypto_op_ctrl_req *ctrl, uint8_t *cipher_key,
+ uint8_t *auth_key, struct virtio_crypto_session *session)
+{
+ uint8_t idx;
+ uint8_t needed = 1;
+ uint32_t head;
+ uint32_t cipher_keylen = 0;
+ uint32_t auth_keylen = 0;
+ uint32_t ctrl_req_length = sizeof(struct virtio_crypto_op_ctrl_req);
+ uint32_t input_length = sizeof(struct virtio_crypto_session_input);
+ uint32_t total_size = 0;
+ uint32_t input_offset = 0;
+ void *virt_addr_started = NULL;
+ phys_addr_t phys_addr_started;
+ struct vring_desc *desc;
+ uint32_t desc_offset;
+ struct virtio_crypto_session_input *input;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (vq == NULL) {
+ PMD_SESSION_LOG(ERR, "vq is NULL");
+ return -EINVAL;
+ }
+ if (ctrl == NULL) {
+ PMD_SESSION_LOG(ERR, "ctrl is NULL.");
+ return -EINVAL;
+ }
+ if (session == NULL) {
+ PMD_SESSION_LOG(ERR, "session is NULL.");
+ return -EINVAL;
+ }
+
+ /* cipher only is supported, it is available if auth_key is NULL */
+ if (!cipher_key) {
+ PMD_SESSION_LOG(ERR, "cipher key is NULL.");
+ return -EINVAL;
+ }
+ head = vq->vq_desc_head_idx;
+ PMD_INIT_LOG(DEBUG, "vq->vq_desc_head_idx = %d, vq = %p", head, vq);
+
+ if (vq->vq_free_cnt < needed) {
+ PMD_SESSION_LOG(ERR, "Not enough entry");
+ return -ENOSPC;
+ }
+
+ /* calculate the length of cipher key */
+ if (cipher_key) {
+ switch (ctrl->u.sym_create_session.op_type) {
+ case VIRTIO_CRYPTO_SYM_OP_CIPHER:
+ cipher_keylen
+ = ctrl->u.sym_create_session.u.cipher
+ .para.keylen;
+ break;
+ case VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING:
+ cipher_keylen
+ = ctrl->u.sym_create_session.u.chain
+ .para.cipher_param.keylen;
+ break;
+ default:
+ PMD_SESSION_LOG(ERR, "invalid op type");
+ return -EINVAL;
+ }
+ }
+
+ /* calculate the length of auth key */
+ if (auth_key) {
+ auth_keylen =
+ ctrl->u.sym_create_session.u.chain.para.u.mac_param
+ .auth_key_len;
+ }
+
+ /*
+ * malloc memory to store indirect vring_desc entries, including
+ * ctrl request, cipher key, auth key, session input and desc vring
+ */
+ desc_offset = ctrl_req_length + cipher_keylen + auth_keylen
+ + input_length;
+ virt_addr_started = rte_malloc(NULL,
+ desc_offset + NUM_ENTRY_VIRTIO_CRYPTO_SYM_CREATE_SESSION
+ * sizeof(struct vring_desc), RTE_CACHE_LINE_SIZE);
+ if (virt_addr_started == NULL) {
+ PMD_SESSION_LOG(ERR, "not enough heap memory");
+ return -ENOSPC;
+ }
+ phys_addr_started = rte_malloc_virt2phy(virt_addr_started);
+
+ /* address to store indirect vring desc entries */
+ desc = (struct vring_desc *)
+ ((uint8_t *)virt_addr_started + desc_offset);
+
+ idx = 0;
+ /* ctrl req part */
+ memcpy(virt_addr_started, ctrl, ctrl_req_length);
+ desc[idx].addr = phys_addr_started;
+ desc[idx].len = ctrl_req_length;
+ desc[idx].flags = VRING_DESC_F_NEXT;
+ desc[idx].next = idx + 1;
+ idx++;
+ total_size += ctrl_req_length;
+ input_offset += ctrl_req_length;
+
+ /* cipher key part */
+ if (cipher_keylen > 0) {
+ memcpy((uint8_t *)virt_addr_started + total_size,
+ cipher_key, cipher_keylen);
+
+ desc[idx].addr = phys_addr_started + total_size;
+ desc[idx].len = cipher_keylen;
+ desc[idx].flags = VRING_DESC_F_NEXT;
+ desc[idx].next = idx + 1;
+ idx++;
+
+ total_size += cipher_keylen;
+ input_offset += cipher_keylen;
+ }
+ /* auth key part */
+ if (auth_keylen > 0) {
+ memcpy((uint8_t *)virt_addr_started + total_size,
+ auth_key, auth_keylen);
+
+ desc[idx].addr = phys_addr_started + total_size;
+ desc[idx].len = auth_keylen;
+ desc[idx].flags = VRING_DESC_F_NEXT;
+ desc[idx].next = idx + 1;
+ idx++;
+ total_size += auth_keylen;
+ input_offset += auth_keylen;
+ }
+
+ /* input part */
+ input = (struct virtio_crypto_session_input *)
+ ((uint8_t *)virt_addr_started + input_offset);
+ input->status = VIRTIO_CRYPTO_ERR;
+ input->session_id = ~0ULL;
+ desc[idx].addr = phys_addr_started + total_size;
+ desc[idx].len = input_length;
+ desc[idx].flags = VRING_DESC_F_WRITE;
+ idx++;
+
+ /* use a single buffer */
+ vq->vq_ring.desc[head].flags = VRING_DESC_F_INDIRECT;
+ vq->vq_ring.desc[head].addr = phys_addr_started + desc_offset;
+ vq->vq_ring.desc[head].len = idx * sizeof(struct vring_desc);
+ vq->vq_free_cnt--;
+
+ vq->vq_desc_head_idx = vq->vq_ring.desc[head].next;
+
+ vq_crypto_update_avail_ring(vq, head);
+ vq_crypto_update_avail_idx(vq);
+
+ PMD_INIT_LOG(DEBUG, "vq->vq_queue_index = %d", vq->vq_queue_index);
+
+ virtqueue_crypto_notify(vq);
+
+ rte_rmb();
+ while (vq->vq_used_cons_idx == vq->vq_ring.used->idx) {
+ rte_rmb();
+ usleep(100);
+ }
+
+ while (vq->vq_used_cons_idx != vq->vq_ring.used->idx) {
+ uint32_t idx, desc_idx, used_idx;
+ struct vring_used_elem *uep;
+
+ used_idx = (uint32_t)(vq->vq_used_cons_idx
+ & (vq->vq_nentries - 1));
+ uep = &vq->vq_ring.used->ring[used_idx];
+ idx = (uint32_t) uep->id;
+ desc_idx = idx;
+
+ while (vq->vq_ring.desc[desc_idx].flags & VRING_DESC_F_NEXT) {
+ desc_idx = vq->vq_ring.desc[desc_idx].next;
+ vq->vq_free_cnt++;
+ }
+
+ vq->vq_ring.desc[desc_idx].next = vq->vq_desc_head_idx;
+ vq->vq_desc_head_idx = idx;
+
+ vq->vq_used_cons_idx++;
+ vq->vq_free_cnt++;
+ }
+
+ PMD_INIT_LOG(DEBUG, "vq->vq_free_cnt=%d\nvq->vq_desc_head_idx=%d",
+ vq->vq_free_cnt, vq->vq_desc_head_idx);
+
+ /* get the result */
+ if (input->status != VIRTIO_CRYPTO_OK) {
+ PMD_SESSION_LOG(ERR, "Something wrong on backend! "
+ "status=%"PRIu32", session_id=%"PRIu64"",
+ input->status, input->session_id);
+ rte_free(virt_addr_started);
+ return -1;
+ } else {
+ session->session_id = input->session_id;
+
+ PMD_SESSION_LOG(INFO, "Create session successfully, "
+ "session_id=%"PRIu64"", input->session_id);
+ rte_free(virt_addr_started);
+ return 0;
+ }
+}
+
+void virtio_crypto_queue_release(struct virtqueue *vq) {
+ struct virtio_crypto_hw *hw;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (vq) {
+ hw = vq->hw;
+ /* Select and deactivate the queue */
+ VTPCI_OPS(hw)->del_queue(hw, vq);
+
+ rte_memzone_free(vq->mz);
+ rte_free(vq);
+ }
+}
+
+int virtio_crypto_queue_setup(struct rte_cryptodev *dev,
+ int queue_type,
+ uint16_t vtpci_queue_idx,
+ uint16_t nb_desc,
+ int socket_id,
+ struct virtqueue **pvq)
+{
+ char vq_name[VIRTQUEUE_MAX_NAME_SZ];
+ const struct rte_memzone *mz;
+ unsigned int vq_size, size;
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+ struct virtqueue *vq = NULL;
+
+ PMD_INIT_FUNC_TRACE();
+
+ PMD_INIT_LOG(DEBUG, "setting up queue: %u", vtpci_queue_idx);
+
+ /*
+ * Read the virtqueue size from the Queue Size field
+ * Always power of 2 and if 0 virtqueue does not exist
+ */
+ vq_size = VTPCI_OPS(hw)->get_queue_num(hw, vtpci_queue_idx);
+ if (vq_size == 0) {
+ PMD_INIT_LOG(ERR, "virtqueue does not exist");
+ return -EINVAL;
+ }
+ PMD_INIT_LOG(DEBUG, "vq_size: %u", vq_size);
+
+ if (!rte_is_power_of_2(vq_size)) {
+ PMD_INIT_LOG(ERR, "virtqueue size is not powerof 2");
+ return -EINVAL;
+ }
+
+ if (queue_type == VTCRYPTO_DATAQ)
+ snprintf(vq_name, sizeof(vq_name), "dev%d_dataqueue%d",
+ dev->data->dev_id, vtpci_queue_idx);
+ else if (queue_type == VTCRYPTO_CTRLQ)
+ snprintf(vq_name, sizeof(vq_name), "dev%d_controlqueue",
+ dev->data->dev_id);
+ size = RTE_ALIGN_CEIL(sizeof(*vq) +
+ vq_size * sizeof(struct vq_desc_extra),
+ RTE_CACHE_LINE_SIZE);
+ vq = rte_zmalloc_socket(vq_name, size, RTE_CACHE_LINE_SIZE,
+ socket_id);
+ if (vq == NULL) {
+ PMD_INIT_LOG(ERR, "Can not allocate virtqueue");
+ return -ENOMEM;
+ }
+
+ vq->hw = hw;
+ vq->dev_id = dev->data->dev_id;
+ vq->vq_queue_index = vtpci_queue_idx;
+ vq->vq_nentries = vq_size;
+
+ /*
+ * Using part of the vring entries is permitted, but the maximum
+ * is vq_size
+ */
+ if (nb_desc == 0 || nb_desc > vq_size)
+ nb_desc = vq_size;
+ vq->vq_free_cnt = nb_desc;
+
+ /*
+ * Reserve a memzone for vring elements
+ */
+ size = vring_crypto_size(vq_size, VIRTIO_PCI_VRING_ALIGN);
+ vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
+ PMD_INIT_LOG(DEBUG, "%s vring_size: %d, rounded_vring_size: %d",
+ (queue_type == VTCRYPTO_DATAQ) ? "dataq" : "ctrlq",
+ size, vq->vq_ring_size);
+
+ mz = rte_memzone_reserve_aligned(vq_name, vq->vq_ring_size,
+ socket_id, 0, VIRTIO_PCI_VRING_ALIGN);
+ if (mz == NULL) {
+ if (rte_errno == EEXIST)
+ mz = rte_memzone_lookup(vq_name);
+ if (mz == NULL) {
+ PMD_INIT_LOG(ERR, "not enough memory");
+ rte_free(vq);
+ return -ENOMEM;
+ }
+ }
+
+ /*
+ * Virtio PCI device VIRTIO_PCI_QUEUE_PF register is 32bit,
+ * and only accepts 32 bit page frame number.
+ * Check if the allocated physical memory exceeds 16TB.
+ */
+ if ((mz->phys_addr + vq->vq_ring_size - 1)
+ >> (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) {
+ PMD_INIT_LOG(ERR, "vring address shouldn't be above 16TB!");
+ rte_free(vq);
+ rte_memzone_free(mz);
+ return -ENOMEM;
+ }
+
+ memset(mz->addr, 0, sizeof(mz->len));
+ vq->mz = mz;
+ vq->vq_ring_mem = mz->phys_addr;
+ vq->vq_ring_virt_mem = mz->addr;
+ PMD_INIT_LOG(DEBUG, "vq->vq_ring_mem(physical): 0x%"PRIx64,
+ (uint64_t)mz->phys_addr);
+ PMD_INIT_LOG(DEBUG, "vq->vq_ring_virt_mem: 0x%"PRIx64,
+ (uint64_t)(uintptr_t)mz->addr);
+
+ *pvq = vq;
+
+ return 0;
+}
+
+static int
+virtio_crypto_cq_setup(struct rte_cryptodev *dev, uint16_t queue_idx)
+{
+ struct virtqueue *vq;
+ int ret;
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ /* if virtio dev is started, do not touch the virtqueues */
+ if (dev->data->dev_started)
+ return 0;
+
+ PMD_INIT_FUNC_TRACE();
+
+ ret = virtio_crypto_queue_setup(dev, VTCRYPTO_CTRLQ, queue_idx,
+ 0, SOCKET_ID_ANY, &vq);
+ if (ret < 0) {
+ PMD_INIT_LOG(ERR, "control vq initialization failed");
+ return ret;
+ }
+
+ hw->cvq = vq;
+
+ return 0;
+}
+
+static void
+virtio_crypto_free_queues(struct rte_cryptodev *dev)
+{
+ unsigned int i;
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_FUNC_TRACE();
+
+ for (i = 0; i < hw->max_dataqueues; i++)
+ virtio_crypto_queue_release(dev->data->queue_pairs[i]);
+}
+
+static int
+virtio_crypto_dev_close(struct rte_cryptodev *dev __rte_unused)
+{
+ return 0;
+}
+
+/*
+ * dev_ops for virtio, bare necessities for basic operation
+ */
+static struct rte_cryptodev_ops virtio_crypto_dev_ops = {
+ /* Device related operations */
+ .dev_configure = virtio_crypto_dev_configure,
+ .dev_start = virtio_crypto_dev_start,
+ .dev_stop = virtio_crypto_dev_stop,
+ .dev_close = virtio_crypto_dev_close,
+ .dev_infos_get = virtio_crypto_dev_info_get,
+
+ .stats_get = virtio_crypto_dev_stats_get,
+ .stats_reset = virtio_crypto_dev_stats_reset,
+
+ .queue_pair_setup = virtio_crypto_qp_setup,
+ .queue_pair_release = virtio_crypto_qp_release,
+ .queue_pair_start = NULL,
+ .queue_pair_stop = NULL,
+ .queue_pair_count = NULL,
+
+ /* Crypto related operations */
+ .session_get_size = virtio_crypto_sym_get_session_private_size,
+ .session_configure = virtio_crypto_sym_configure_session,
+ .session_clear = virtio_crypto_sym_clear_session,
+ .qp_attach_session = NULL,
+ .qp_detach_session = NULL
+};
+
+static void
+virtio_crypto_update_stats(struct rte_cryptodev *dev,
+ struct rte_cryptodev_stats *stats)
+{
+ unsigned i;
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (stats == NULL) {
+ PMD_DRV_LOG(ERR, "invalid pointer");
+ return;
+ }
+
+ for (i = 0; i < hw->max_dataqueues; i++) {
+ const struct virtqueue *data_queue
+ = dev->data->queue_pairs[i];
+ if (data_queue == NULL)
+ continue;
+
+ stats->enqueued_count += data_queue->packets_sent_total;
+ stats->enqueue_err_count += data_queue->packets_sent_failed;
+
+ stats->dequeued_count += data_queue->packets_received_total;
+ stats->dequeue_err_count
+ += data_queue->packets_received_failed;
+ }
+}
+
+static void
+virtio_crypto_dev_stats_get(struct rte_cryptodev *dev,
+ struct rte_cryptodev_stats *stats)
+{
+ PMD_INIT_FUNC_TRACE();
+
+ virtio_crypto_update_stats(dev, stats);
+}
+
+static void
+virtio_crypto_dev_stats_reset(struct rte_cryptodev *dev)
+{
+ unsigned int i;
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_FUNC_TRACE();
+
+ for (i = 0; i < hw->max_dataqueues; i++) {
+ struct virtqueue *data_queue = dev->data->queue_pairs[i];
+ if (data_queue == NULL)
+ continue;
+
+ data_queue->packets_sent_total = 0;
+ data_queue->packets_sent_failed = 0;
+
+ data_queue->packets_received_total = 0;
+ data_queue->packets_received_failed = 0;
+ }
+}
+
+static int
+virtio_crypto_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
+ const struct rte_cryptodev_qp_conf *qp_conf,
+ int socket_id,
+ struct rte_mempool *session_pool __rte_unused)
+{
+ int ret;
+ struct virtqueue *vq;
+
+ PMD_INIT_FUNC_TRACE();
+
+ /* if virtio dev is started, do not touch the virtqueues */
+ if (dev->data->dev_started)
+ return 0;
+
+ ret = virtio_crypto_queue_setup(dev, VTCRYPTO_DATAQ, queue_pair_id,
+ qp_conf->nb_descriptors, socket_id, &vq);
+ if (ret < 0) {
+ PMD_INIT_LOG(ERR,
+ "virtio crypto data queue initialization failed\n");
+ return ret;
+ }
+
+ dev->data->queue_pairs[queue_pair_id] = vq;
+
+ return 0;
+}
+
+static int
+virtio_crypto_qp_release(struct rte_cryptodev *dev, uint16_t queue_pair_id)
+{
+ struct virtqueue *vq
+ = (struct virtqueue *)dev->data->queue_pairs[queue_pair_id];
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (vq == NULL) {
+ PMD_DRV_LOG(DEBUG, "vq already freed");
+ return 0;
+ }
+
+ virtio_crypto_queue_release(vq);
+ return 0;
+}
+
+static inline int
+vtpci_with_feature(struct virtio_crypto_hw *hw, uint64_t bit)
+{
+ PMD_INIT_FUNC_TRACE();
+
+ return (hw->guest_features & (1ULL << bit)) != 0;
+}
+
+static int
+virtio_negotiate_features(struct virtio_crypto_hw *hw, uint64_t req_features)
+{
+ uint64_t host_features;
+
+ PMD_INIT_FUNC_TRACE();
+
+ /* Prepare guest_features: feature that driver wants to support */
+ PMD_INIT_LOG(DEBUG, "guest_features before negotiate = %" PRIx64,
+ req_features);
+
+ /* Read device(host) feature bits */
+ host_features = VTPCI_OPS(hw)->get_features(hw);
+ PMD_INIT_LOG(DEBUG, "host_features before negotiate = %" PRIx64,
+ host_features);
+
+ /*
+ * Negotiate features: Subset of device feature bits are written back
+ * guest feature bits.
+ */
+ hw->guest_features = req_features;
+ hw->guest_features = vtpci_negotiate_features_crypto(hw, host_features);
+ PMD_INIT_LOG(DEBUG, "features after negotiate = %" PRIx64,
+ hw->guest_features);
+
+ if (hw->modern) {
+ if (!vtpci_with_feature(hw, VIRTIO_F_VERSION_1)) {
+ PMD_INIT_LOG(ERR,
+ "VIRTIO_F_VERSION_1 features is not enabled.");
+ return -1;
+ }
+ vtpci_set_status_crypto(hw, VIRTIO_CONFIG_STATUS_FEATURES_OK);
+ if (!(vtpci_get_status_crypto(hw) & VIRTIO_CONFIG_STATUS_FEATURES_OK)) {
+ PMD_INIT_LOG(ERR,
+ "failed to set FEATURES_OK status!");
+ return -1;
+ }
+ }
+
+ hw->req_guest_features = req_features;
+
+ return 0;
+}
+
+/* reset device and renegotiate features if needed */
+static int
+virtio_crypto_init_device(struct rte_cryptodev *cryptodev, uint64_t req_features)
+{
+ struct virtio_crypto_hw *hw = cryptodev->data->dev_private;
+ struct virtio_crypto_config *config;
+ struct virtio_crypto_config local_config;
+
+ PMD_INIT_FUNC_TRACE();
+
+ /* Reset the device although not necessary at startup */
+ vtpci_reset_crypto(hw);
+
+ /* Tell the host we've noticed this device. */
+ vtpci_set_status_crypto(hw, VIRTIO_CONFIG_STATUS_ACK);
+
+ /* Tell the host we've known how to drive the device. */
+ vtpci_set_status_crypto(hw, VIRTIO_CONFIG_STATUS_DRIVER);
+ if (virtio_negotiate_features(hw, req_features) < 0)
+ return -1;
+
+ config = &local_config;
+ /* Get status of the device */
+ vtpci_read_dev_config_crypto(hw,
+ offsetof(struct virtio_crypto_config, status),
+ &config->status, sizeof(config->status));
+ if (config->status != VIRTIO_CRYPTO_S_HW_READY) {
+ PMD_DRV_LOG(ERR, "accelerator hardware is "
+ "not ready");
+ return -1;
+ }
+
+ /* Get number of data queues */
+ vtpci_read_dev_config_crypto(hw,
+ offsetof(struct virtio_crypto_config, max_dataqueues),
+ &config->max_dataqueues,
+ sizeof(config->max_dataqueues));
+ hw->max_dataqueues =
+ (config->max_dataqueues > VIRTIO_MAX_DATA_QUEUES) ?
+ VIRTIO_MAX_DATA_QUEUES : config->max_dataqueues;
+
+ PMD_INIT_LOG(DEBUG, "config->max_dataqueues=%d",
+ config->max_dataqueues);
+ PMD_INIT_LOG(DEBUG, "config->status=%d", config->status);
+
+ PMD_INIT_LOG(DEBUG, "hw->max_dataqueues=%d",
+ hw->max_dataqueues);
+
+ /* setup and start control queue only */
+ if (virtio_crypto_cq_setup(cryptodev, config->max_dataqueues) < 0) {
+ PMD_INIT_LOG(ERR, "control queue setup error");
+ return -1;
+ }
+ virtio_crypto_cq_start(cryptodev);
+
+ return 0;
+}
+
+/*
+ * This function is based on probe() function
+ * It returns 0 on success.
+ */
+static int
+crypto_virtio_create(const char *name, struct rte_pci_device *pci_dev,
+ struct rte_cryptodev_pmd_init_params *init_params)
+{
+ struct rte_cryptodev *cryptodev;
+ struct virtio_crypto_hw *hw;
+
+ PMD_INIT_FUNC_TRACE();
+
+ cryptodev = rte_cryptodev_pmd_create(name, &pci_dev->device,
+ init_params);
+ if (cryptodev == NULL)
+ return -ENODEV;
+
+ cryptodev->driver_id = cryptodev_virtio_driver_id;
+ cryptodev->dev_ops = &virtio_crypto_dev_ops;
+
+ cryptodev->enqueue_burst = virtio_crypto_pkt_tx_burst;
+ cryptodev->dequeue_burst = virtio_crypto_pkt_rx_burst;
+
+ cryptodev->feature_flags = RTE_CRYPTODEV_FF_SYMMETRIC_CRYPTO |
+ RTE_CRYPTODEV_FF_SYM_OPERATION_CHAINING;
+
+ hw = cryptodev->data->dev_private;
+ hw->dev_id = cryptodev->data->dev_id;
+
+ PMD_INIT_LOG(DEBUG, "dev %d vendorID=0x%x deviceID=0x%x",
+ cryptodev->data->dev_id, pci_dev->id.vendor_id,
+ pci_dev->id.device_id);
+
+ /* init legacy or modern device */
+ if (vtpci_init_crypto(pci_dev, hw))
+ return -1;
+
+ /* reset device and negotiate default features */
+ if (virtio_crypto_init_device(cryptodev,
+ VIRTIO_CRYPTO_PMD_GUEST_FEATURES))
+ return -1;
+
+ return 0;
+}
+
+static int
+virtio_crypto_dev_uninit(struct rte_cryptodev *cryptodev)
+{
+ struct virtio_crypto_hw *hw = cryptodev->data->dev_private;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (rte_eal_process_type() == RTE_PROC_SECONDARY)
+ return -EPERM;
+
+ if (cryptodev->data->dev_started) {
+ virtio_crypto_dev_stop(cryptodev);
+ virtio_crypto_dev_close(cryptodev);
+ }
+
+ cryptodev->dev_ops = NULL;
+ cryptodev->enqueue_burst = NULL;
+ cryptodev->dequeue_burst = NULL;
+
+ /* release control queue */
+ virtio_crypto_queue_release(hw->cvq);
+
+ rte_free(cryptodev->data);
+ cryptodev->data = NULL;
+
+ PMD_DRV_LOG(INFO, "dev_uninit completed");
+
+ return 0;
+}
+
+static int
+virtio_crypto_dev_configure(struct rte_cryptodev *dev __rte_unused,
+ struct rte_cryptodev_config *config __rte_unused)
+{
+ PMD_INIT_FUNC_TRACE();
+
+ return 0;
+}
+
+static void
+virtio_crypto_dev_stop(struct rte_cryptodev *dev)
+{
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_FUNC_TRACE();
+ PMD_DRV_LOG(DEBUG, "virtio_dev_stop");
+
+ vtpci_reset_crypto(hw);
+
+ virtio_crypto_dev_free_mbufs(dev);
+ virtio_crypto_free_queues(dev);
+
+ dev->data->dev_started = 0;
+}
+
+static int
+virtio_crypto_dev_start(struct rte_cryptodev *dev)
+{
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ if (dev->data->dev_started)
+ return 0;
+
+ /* Do final configuration before queue engine starts */
+ virtio_crypto_dq_start(dev);
+ vtpci_reinit_complete_crypto(hw);
+
+ dev->data->dev_started = 1;
+
+ return 0;
+}
+
+static void virtio_crypto_dev_free_mbufs(struct rte_cryptodev *dev)
+{
+ uint32_t i;
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ for (i = 0; i < hw->max_dataqueues; i++) {
+ PMD_INIT_LOG(DEBUG, "Before freeing dataq[%d] used "
+ "and unused buf", i);
+ VIRTQUEUE_DUMP((struct virtqueue *)
+ dev->data->queue_pairs[i]);
+
+ PMD_INIT_LOG(DEBUG, "queue_pairs[%d]=%p",
+ i, dev->data->queue_pairs[i]);
+
+ virtqueue_crypto_detatch_unused(dev->data->queue_pairs[i]);
+
+ PMD_INIT_LOG(DEBUG, "After freeing dataq[%d] used and "
+ "unused buf", i);
+ VIRTQUEUE_DUMP(
+ (struct virtqueue *)dev->data->queue_pairs[i]);
+ }
+}
+
+static unsigned virtio_crypto_sym_get_session_private_size(
+ struct rte_cryptodev *dev __rte_unused)
+{
+ PMD_INIT_FUNC_TRACE();
+
+ return RTE_ALIGN_CEIL(sizeof(struct virtio_crypto_session), 8);
+}
+
+static int virtio_crypto_check_sym_session_paras(
+ struct rte_cryptodev *dev)
+{
+ struct virtio_crypto_hw *hw;
+ struct virtqueue *vq;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (unlikely(dev == NULL)) {
+ PMD_SESSION_LOG(ERR, "dev is NULL");
+ return -1;
+ }
+ if (unlikely(dev->data == NULL)) {
+ PMD_SESSION_LOG(ERR, "dev->data is NULL");
+ return -1;
+ }
+ hw = dev->data->dev_private;
+ if (unlikely(hw == NULL)) {
+ PMD_SESSION_LOG(ERR, "hw is NULL");
+ return -1;
+ }
+ vq = hw->cvq;
+ if (unlikely(vq == NULL)) {
+ PMD_SESSION_LOG(ERR, "vq is NULL");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int virtio_crypto_check_sym_clear_session_paras(
+ struct rte_cryptodev *dev,
+ struct rte_cryptodev_sym_session *sess)
+{
+ PMD_INIT_FUNC_TRACE();
+
+ if (sess == NULL) {
+ PMD_SESSION_LOG(ERR, "vq is NULL");
+ return -1;
+ }
+
+ return virtio_crypto_check_sym_session_paras(dev);
+}
+
+#define NUM_ENTRY_VIRTIO_CRYPTO_SYM_CLEAR_SESSION 2
+
+static void virtio_crypto_sym_clear_session(
+ struct rte_cryptodev *dev,
+ struct rte_cryptodev_sym_session *sess)
+{
+ struct virtio_crypto_hw *hw;
+ struct virtqueue *vq;
+ struct virtio_crypto_session *session;
+ struct virtio_crypto_op_ctrl_req *ctrl;
+ struct vring_desc *desc;
+ uint8_t *status;
+ uint8_t needed = 1;
+ uint32_t head;
+ uint8_t *malloc_addr;
+ uint64_t malloc_phys_addr;
+ uint8_t status_len = sizeof(struct virtio_crypto_inhdr);
+ uint32_t op_ctrl_req_len = sizeof(struct virtio_crypto_op_ctrl_req);
+ uint32_t desc_offset_len = op_ctrl_req_len + status_len;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (virtio_crypto_check_sym_clear_session_paras(dev, sess) < 0)
+ return;
+
+ hw = dev->data->dev_private;
+ vq = hw->cvq;
+ session = (struct virtio_crypto_session *)get_session_private_data(
+ sess, cryptodev_virtio_driver_id);
+
+ if (session == NULL) {
+ PMD_SESSION_LOG(ERR, "Invalid session parameter");
+ }
+
+ PMD_SESSION_LOG(INFO, "vq->vq_desc_head_idx = %d, "
+ "vq = %p", vq->vq_desc_head_idx, vq);
+
+ if (vq->vq_free_cnt < needed) {
+ PMD_SESSION_LOG(ERR,
+ "vq->vq_free_cnt = %d is less than %d, "
+ "not enough", vq->vq_free_cnt, needed);
+ return;
+ }
+
+ /*
+ * malloc memory to store information of ctrl request op,
+ * return status and desc vring
+ */
+ malloc_addr = rte_malloc(NULL, op_ctrl_req_len + status_len
+ + NUM_ENTRY_VIRTIO_CRYPTO_SYM_CLEAR_SESSION
+ * sizeof(struct vring_desc), RTE_CACHE_LINE_SIZE);
+ if (malloc_addr == NULL) {
+ PMD_SESSION_LOG(ERR, "not enough heap room");
+ return;
+ }
+ malloc_phys_addr = rte_malloc_virt2phy(malloc_addr);
+
+ /* assign ctrl request op part */
+ ctrl = (struct virtio_crypto_op_ctrl_req *)malloc_addr;
+ ctrl->header.opcode = VIRTIO_CRYPTO_CIPHER_DESTROY_SESSION;
+ /* Set the default dataqueue id to 0 */
+ ctrl->header.queue_id = 0;
+ ctrl->u.destroy_session.session_id = session->session_id;
+
+ /* assign status part */
+ status = &(((struct virtio_crypto_inhdr *)
+ ((uint8_t *)malloc_addr + op_ctrl_req_len))->status);
+ *status = VIRTIO_CRYPTO_ERR;
+
+ /* assign indirect desc vring part */
+ desc = (struct vring_desc *)((uint8_t *)malloc_addr
+ + desc_offset_len);
+
+ /* ctrl request part */
+ desc[0].addr = malloc_phys_addr;
+ desc[0].len = op_ctrl_req_len;
+ desc[0].flags = VRING_DESC_F_NEXT;
+ desc[0].next = 1;
+
+ /* status part */
+ desc[1].addr = malloc_phys_addr + op_ctrl_req_len;
+ desc[1].len = status_len;
+ desc[1].flags = VRING_DESC_F_WRITE;
+
+ /* use only a single buffer */
+ head = vq->vq_desc_head_idx;
+ vq->vq_ring.desc[head].flags = VRING_DESC_F_INDIRECT;
+ vq->vq_ring.desc[head].addr = malloc_phys_addr + desc_offset_len;
+ vq->vq_ring.desc[head].len
+ = NUM_ENTRY_VIRTIO_CRYPTO_SYM_CLEAR_SESSION
+ * sizeof(struct vring_desc);
+
+ vq->vq_free_cnt -= needed;
+
+ vq->vq_desc_head_idx = vq->vq_ring.desc[head].next;
+
+ vq_crypto_update_avail_ring(vq, head);
+ vq_crypto_update_avail_idx(vq);
+
+ PMD_INIT_LOG(DEBUG, "vq->vq_queue_index = %d", vq->vq_queue_index);
+
+ virtqueue_crypto_notify(vq);
+
+ rte_rmb();
+ while (vq->vq_used_cons_idx == vq->vq_ring.used->idx) {
+ rte_rmb();
+ usleep(100);
+ }
+
+ while (vq->vq_used_cons_idx != vq->vq_ring.used->idx) {
+ uint32_t idx, desc_idx, used_idx;
+ struct vring_used_elem *uep;
+
+ used_idx = (uint32_t)(vq->vq_used_cons_idx
+ & (vq->vq_nentries - 1));
+ uep = &vq->vq_ring.used->ring[used_idx];
+ idx = (uint32_t) uep->id;
+ desc_idx = idx;
+ while (vq->vq_ring.desc[desc_idx].flags
+ & VRING_DESC_F_NEXT) {
+ desc_idx = vq->vq_ring.desc[desc_idx].next;
+ vq->vq_free_cnt++;
+ }
+
+ vq->vq_ring.desc[desc_idx].next = vq->vq_desc_head_idx;
+ vq->vq_desc_head_idx = idx;
+ vq->vq_used_cons_idx++;
+ vq->vq_free_cnt++;
+ }
+
+ if (*status != VIRTIO_CRYPTO_OK) {
+ PMD_SESSION_LOG(ERR, "Close session failed "
+ "status=%"PRIu32", session_id=%"PRIu64"",
+ *status, session->session_id);
+ rte_free(malloc_addr);
+ return;
+ }
+
+ PMD_INIT_LOG(DEBUG, "vq->vq_free_cnt=%d\nvq->vq_desc_head_idx=%d",
+ vq->vq_free_cnt, vq->vq_desc_head_idx);
+
+ PMD_SESSION_LOG(INFO, "Close session successfully "
+ "session_id=%"PRIu64"", session->session_id);
+
+ if (sess) {
+ memset(sess, 0, sizeof(struct virtio_crypto_session));
+ rte_free(malloc_addr);
+ }
+}
+
+static struct rte_crypto_cipher_xform *
+virtio_crypto_get_cipher_xform(struct rte_crypto_sym_xform *xform)
+{
+ do {
+ if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
+ return &xform->cipher;
+
+ xform = xform->next;
+ } while (xform);
+
+ return NULL;
+}
+
+static struct rte_crypto_auth_xform *
+virtio_crypto_get_auth_xform(struct rte_crypto_sym_xform *xform)
+{
+ do {
+ if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH)
+ return &xform->auth;
+
+ xform = xform->next;
+ } while (xform);
+
+ return NULL;
+}
+
+/** Get xform chain order */
+static int
+virtio_crypto_get_chain_order(struct rte_crypto_sym_xform *xform)
+{
+ if (xform == NULL)
+ return -1;
+
+ /* Cipher Only */
+ if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
+ xform->next == NULL)
+ return VIRTIO_CRYPTO_CMD_CIPHER;
+
+ /* Authentication Only */
+ if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
+ xform->next == NULL)
+ return VIRTIO_CRYPTO_CMD_AUTH;
+
+ /* Authenticate then Cipher */
+ if (xform->type == RTE_CRYPTO_SYM_XFORM_AUTH &&
+ xform->next->type == RTE_CRYPTO_SYM_XFORM_CIPHER)
+ return VIRTIO_CRYPTO_CMD_HASH_CIPHER;
+
+ /* Cipher then Authenticate */
+ if (xform->type == RTE_CRYPTO_SYM_XFORM_CIPHER &&
+ xform->next->type == RTE_CRYPTO_SYM_XFORM_AUTH)
+ return VIRTIO_CRYPTO_CMD_CIPHER_HASH;
+
+ return -1;
+}
+
+static int virtio_crypto_sym_pad_cipher_param(struct virtio_crypto_cipher_session_para *para,
+ struct rte_crypto_cipher_xform *cipher_xform)
+{
+ switch (cipher_xform->algo) {
+ case RTE_CRYPTO_CIPHER_NULL:
+ para->algo = VIRTIO_CRYPTO_NO_CIPHER;
+ break;
+ case RTE_CRYPTO_CIPHER_3DES_CBC:
+ para->algo = VIRTIO_CRYPTO_CIPHER_3DES_CBC;
+ break;
+ case RTE_CRYPTO_CIPHER_3DES_CTR:
+ para->algo = VIRTIO_CRYPTO_CIPHER_3DES_CTR;
+ break;
+ case RTE_CRYPTO_CIPHER_3DES_ECB:
+ para->algo = VIRTIO_CRYPTO_CIPHER_3DES_ECB;
+ break;
+ case RTE_CRYPTO_CIPHER_AES_CBC:
+ para->algo = VIRTIO_CRYPTO_CIPHER_AES_CBC;
+ break;
+ case RTE_CRYPTO_CIPHER_AES_CTR:
+ para->algo = VIRTIO_CRYPTO_CIPHER_AES_CTR;
+ break;
+ case RTE_CRYPTO_CIPHER_AES_ECB:
+ para->algo = VIRTIO_CRYPTO_CIPHER_AES_ECB;
+ break;
+ case RTE_CRYPTO_CIPHER_AES_F8:
+ para->algo = VIRTIO_CRYPTO_CIPHER_AES_F8;
+ break;
+ case RTE_CRYPTO_CIPHER_AES_XTS:
+ para->algo = VIRTIO_CRYPTO_CIPHER_AES_XTS;
+ break;
+ case RTE_CRYPTO_CIPHER_ARC4:
+ para->algo = VIRTIO_CRYPTO_CIPHER_ARC4;
+ break;
+ case RTE_CRYPTO_CIPHER_KASUMI_F8:
+ para->algo = VIRTIO_CRYPTO_CIPHER_KASUMI_F8;
+ break;
+ case RTE_CRYPTO_CIPHER_SNOW3G_UEA2:
+ para->algo = VIRTIO_CRYPTO_CIPHER_SNOW3G_UEA2;
+ break;
+ case RTE_CRYPTO_CIPHER_ZUC_EEA3:
+ para->algo = VIRTIO_CRYPTO_CIPHER_ZUC_EEA3;
+ break;
+ case RTE_CRYPTO_CIPHER_DES_CBC:
+ para->algo = VIRTIO_CRYPTO_CIPHER_DES_CBC;
+ break;
+ default:
+ PMD_SESSION_LOG(ERR, "Crypto: Unsupported Cipher alg %u",
+ cipher_xform->algo);
+ return -1;
+ }
+
+ para->keylen = cipher_xform->key.length;
+ switch (cipher_xform->op) {
+ case RTE_CRYPTO_CIPHER_OP_ENCRYPT:
+ para->op = VIRTIO_CRYPTO_OP_ENCRYPT;
+ break;
+ case RTE_CRYPTO_CIPHER_OP_DECRYPT:
+ para->op = VIRTIO_CRYPTO_OP_DECRYPT;
+ break;
+ default:
+ PMD_SESSION_LOG(ERR, "Unsupported cipher operation parameter");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int virtio_crypto_sym_pad_auth_param(
+ struct virtio_crypto_op_ctrl_req *ctrl,
+ struct rte_crypto_auth_xform *auth_xform)
+{
+ uint32_t *algo;
+
+ switch (ctrl->u.sym_create_session.u.chain.para.hash_mode) {
+ case VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN:
+ algo = &ctrl->u.sym_create_session.u.chain.para.u.hash_param.algo;
+ break;
+ case VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH:
+ algo = &ctrl->u.sym_create_session.u.chain.para.u.mac_param.algo;
+ break;
+ default:
+ PMD_SESSION_LOG(ERR, "Unsupported hash mode %u specified",
+ ctrl->u.sym_create_session.u.chain.para.hash_mode);
+ return -1;
+ }
+
+ switch (auth_xform->algo) {
+ case RTE_CRYPTO_AUTH_NULL:
+ *algo = VIRTIO_CRYPTO_NO_MAC;
+ break;
+ case RTE_CRYPTO_AUTH_AES_CBC_MAC:
+ *algo = VIRTIO_CRYPTO_MAC_CBCMAC_AES;
+ break;
+ case RTE_CRYPTO_AUTH_AES_CMAC:
+ *algo = VIRTIO_CRYPTO_MAC_CMAC_AES;
+ break;
+ case RTE_CRYPTO_AUTH_AES_GMAC:
+ *algo = VIRTIO_CRYPTO_MAC_GMAC_AES;
+ break;
+ case RTE_CRYPTO_AUTH_AES_XCBC_MAC:
+ *algo = VIRTIO_CRYPTO_MAC_XCBC_AES;
+ break;
+ case RTE_CRYPTO_AUTH_KASUMI_F9:
+ *algo = VIRTIO_CRYPTO_MAC_KASUMI_F9;
+ break;
+ case RTE_CRYPTO_AUTH_MD5:
+ *algo = VIRTIO_CRYPTO_HASH_MD5;
+ break;
+ case RTE_CRYPTO_AUTH_MD5_HMAC:
+ *algo = VIRTIO_CRYPTO_MAC_HMAC_MD5;
+ break;
+ case RTE_CRYPTO_AUTH_SHA1:
+ *algo = VIRTIO_CRYPTO_HASH_SHA1;
+ break;
+ case RTE_CRYPTO_AUTH_SHA1_HMAC:
+ *algo = VIRTIO_CRYPTO_MAC_HMAC_SHA1;
+ break;
+ case RTE_CRYPTO_AUTH_SHA224:
+ *algo = VIRTIO_CRYPTO_HASH_SHA_224;
+ break;
+ case RTE_CRYPTO_AUTH_SHA224_HMAC:
+ *algo = VIRTIO_CRYPTO_MAC_HMAC_SHA_224;
+ break;
+ case RTE_CRYPTO_AUTH_SHA256:
+ *algo = VIRTIO_CRYPTO_HASH_SHA_256;
+ break;
+ case RTE_CRYPTO_AUTH_SHA256_HMAC:
+ *algo = VIRTIO_CRYPTO_MAC_HMAC_SHA_256;
+ break;
+ case RTE_CRYPTO_AUTH_SHA384:
+ *algo = VIRTIO_CRYPTO_HASH_SHA_384;
+ break;
+ case RTE_CRYPTO_AUTH_SHA384_HMAC:
+ *algo = VIRTIO_CRYPTO_MAC_HMAC_SHA_384;
+ break;
+ case RTE_CRYPTO_AUTH_SHA512:
+ *algo = VIRTIO_CRYPTO_HASH_SHA_512;
+ break;
+ case RTE_CRYPTO_AUTH_SHA512_HMAC:
+ *algo = VIRTIO_CRYPTO_MAC_HMAC_SHA_512;
+ break;
+ case RTE_CRYPTO_AUTH_SNOW3G_UIA2:
+ *algo = VIRTIO_CRYPTO_MAC_SNOW3G_UIA2;
+ break;
+ default:
+ PMD_SESSION_LOG(ERR,
+ "Crypto: Undefined Hash algo %u specified",
+ auth_xform->algo);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int virtio_crypto_sym_pad_op_ctrl_req(
+ struct virtio_crypto_op_ctrl_req *ctrl,
+ struct rte_crypto_sym_xform *xform, bool is_chainned,
+ uint8_t **cipher_key_data, uint8_t **auth_key_data,
+ struct virtio_crypto_session *session)
+{
+ int ret;
+ struct rte_crypto_auth_xform *auth_xform = NULL;
+ struct rte_crypto_cipher_xform *cipher_xform = NULL;
+
+ if (ctrl == NULL) {
+ PMD_SESSION_LOG(ERR, "ctrl request is NULL");
+ return -1;
+ }
+
+ if (xform == NULL) {
+ PMD_SESSION_LOG(ERR, "xform is NULL");
+ return -1;
+ }
+
+ /* Get cipher xform from crypto xform chain */
+ cipher_xform = virtio_crypto_get_cipher_xform(xform);
+ if (cipher_xform) {
+ if (is_chainned)
+ ret = virtio_crypto_sym_pad_cipher_param(
+ &ctrl->u.sym_create_session.u.chain.para
+ .cipher_param, cipher_xform);
+ else
+ ret = virtio_crypto_sym_pad_cipher_param(
+ &ctrl->u.sym_create_session.u.cipher.para,
+ cipher_xform);
+
+ if (ret < 0) {
+ PMD_SESSION_LOG(ERR,
+ "pad cipher parameter failed");
+ return -1;
+ }
+
+ *cipher_key_data = cipher_xform->key.data;
+
+ session->iv.offset = cipher_xform->iv.offset;
+ session->iv.length = cipher_xform->iv.length;
+ }
+
+ /* Get auth xform from crypto xform chain */
+ auth_xform = virtio_crypto_get_auth_xform(xform);
+ if (auth_xform) {
+ /* FIXME: support VIRTIO_CRYPTO_SYM_HASH_MODE_NESTED */
+ if (auth_xform->key.length) {
+ ctrl->u.sym_create_session.u.chain.para.hash_mode
+ = VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH;
+ ctrl->u.sym_create_session.u.chain.para.u.mac_param.
+ auth_key_len = (uint32_t)auth_xform->key.length;
+ ctrl->u.sym_create_session.u.chain.para.u.mac_param.
+ hash_result_len = auth_xform->digest_length;
+
+ *auth_key_data = auth_xform->key.data;
+ } else {
+ ctrl->u.sym_create_session.u.chain.para.hash_mode
+ = VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN;
+ ctrl->u.sym_create_session.u.chain.para.u.hash_param.
+ hash_result_len = auth_xform->digest_length;
+ }
+
+ ret = virtio_crypto_sym_pad_auth_param(ctrl, auth_xform);
+ if (ret < 0) {
+ PMD_SESSION_LOG(ERR, "pad auth parameter failed");
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int virtio_crypto_check_sym_configure_session_paras(
+ struct rte_cryptodev *dev,
+ struct rte_crypto_sym_xform *xform,
+ struct rte_cryptodev_sym_session *sym_sess,
+ struct rte_mempool *mempool)
+{
+ if (unlikely(xform == NULL) || unlikely(sym_sess == NULL) ||
+ unlikely(mempool == NULL)) {
+ PMD_SESSION_LOG(ERR, "NULL pointer");
+ return -1;
+ }
+
+ if (virtio_crypto_check_sym_session_paras(dev) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int virtio_crypto_sym_configure_session(
+ struct rte_cryptodev *dev,
+ struct rte_crypto_sym_xform *xform,
+ struct rte_cryptodev_sym_session *sess,
+ struct rte_mempool *mempool)
+{
+ void *session_private;
+ int ret;
+ uint8_t *cipher_key_data = NULL;
+ uint8_t *auth_key_data = NULL;
+ struct virtio_crypto_hw *hw;
+ struct virtqueue *vq;
+ struct virtio_crypto_session *session;
+ struct virtio_crypto_op_ctrl_req *ctrl;
+ enum virtio_crypto_cmd_id cmd_id;
+
+ PMD_INIT_FUNC_TRACE();
+
+ ret = virtio_crypto_check_sym_configure_session_paras(dev, xform,
+ sess, mempool);
+ if (ret < 0) {
+ PMD_SESSION_LOG(ERR, "Invalid parameters");
+ return ret;
+ }
+
+ if (rte_mempool_get(mempool, &session_private)) {
+ PMD_SESSION_LOG(ERR,
+ "Couldn't get object from session mempool");
+ return -ENOMEM;
+ }
+
+ session = (struct virtio_crypto_session *)session_private;
+ ctrl = &session->ctrl;
+ memset(ctrl, 0, sizeof(struct virtio_crypto_op_ctrl_req));
+ ctrl->header.opcode = VIRTIO_CRYPTO_CIPHER_CREATE_SESSION;
+ /* FIXME: support multiqueue */
+ ctrl->header.queue_id = 0;
+
+ hw = dev->data->dev_private;
+ vq = hw->cvq;
+
+ cmd_id = virtio_crypto_get_chain_order(xform);
+ if (cmd_id == VIRTIO_CRYPTO_CMD_CIPHER_HASH)
+ ctrl->u.sym_create_session.u.chain.para.alg_chain_order
+ = VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_CIPHER_THEN_HASH;
+ if (cmd_id == VIRTIO_CRYPTO_CMD_HASH_CIPHER)
+ ctrl->u.sym_create_session.u.chain.para.alg_chain_order
+ = VIRTIO_CRYPTO_SYM_ALG_CHAIN_ORDER_HASH_THEN_CIPHER;
+
+ switch (cmd_id) {
+ case VIRTIO_CRYPTO_CMD_CIPHER_HASH:
+ case VIRTIO_CRYPTO_CMD_HASH_CIPHER:
+ ctrl->u.sym_create_session.op_type
+ = VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING;
+
+ ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl,
+ xform, true, &cipher_key_data, &auth_key_data, session);
+ if (ret < 0) {
+ PMD_SESSION_LOG(ERR,
+ "padding sym op ctrl req failed");
+ goto error_out;
+ }
+ ret = virtio_crypto_send_command(vq, ctrl,
+ cipher_key_data, auth_key_data, session);
+ if (ret < 0) {
+ PMD_SESSION_LOG(ERR,
+ "create session failed: %d", ret);
+ goto error_out;
+ }
+ break;
+ case VIRTIO_CRYPTO_CMD_CIPHER:
+ ctrl->u.sym_create_session.op_type
+ = VIRTIO_CRYPTO_SYM_OP_CIPHER;
+ ret = virtio_crypto_sym_pad_op_ctrl_req(ctrl,
+ xform, false, &cipher_key_data, &auth_key_data, session);
+ if (ret < 0) {
+ PMD_SESSION_LOG(ERR,
+ "padding sym op ctrl req failed");
+ goto error_out;
+ }
+ ret = virtio_crypto_send_command(vq, ctrl,
+ cipher_key_data, NULL, session);
+ if (ret < 0) {
+ PMD_SESSION_LOG(ERR,
+ "create session failed: %d", ret);
+ goto error_out;
+ }
+ break;
+ default:
+ PMD_SESSION_LOG(ERR,
+ "Unsupported operation chain order parameter");
+ goto error_out;
+ }
+
+ set_session_private_data(sess, dev->driver_id,
+ session_private);
+
+ return 0;
+
+error_out:
+ return -1;
+}
+
+static void
+virtio_crypto_dev_info_get(struct rte_cryptodev *dev,
+ struct rte_cryptodev_info *info)
+{
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_FUNC_TRACE();
+
+ if (info != NULL) {
+ info->driver_id = cryptodev_virtio_driver_id;
+ info->pci_dev = RTE_DEV_TO_PCI(dev->device);
+ info->feature_flags = dev->feature_flags;
+ info->max_nb_queue_pairs = hw->max_dataqueues;
+ info->sym.max_nb_sessions = RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS;
+ }
+}
+
+static int crypto_virtio_pci_probe(
+ struct rte_pci_driver *pci_drv __rte_unused,
+ struct rte_pci_device *pci_dev)
+{
+ struct rte_cryptodev_pmd_init_params init_params = {
+ .name = "",
+ .socket_id = rte_socket_id(),
+ .private_data_size = sizeof(struct virtio_crypto_hw),
+ .max_nb_sessions = RTE_VIRTIO_CRYPTO_PMD_MAX_NB_SESSIONS
+ };
+ char name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+ PMD_DRV_LOG(DEBUG, "Found Crypto device at %02x:%02x.%x",
+ pci_dev->addr.bus,
+ pci_dev->addr.devid,
+ pci_dev->addr.function);
+
+ rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
+
+ return crypto_virtio_create(name, pci_dev, &init_params);
+}
+
+static int crypto_virtio_pci_remove(struct rte_pci_device *pci_dev)
+{
+ struct rte_cryptodev *cryptodev;
+ char cryptodev_name[RTE_CRYPTODEV_NAME_MAX_LEN];
+
+ if (pci_dev == NULL)
+ return -EINVAL;
+
+ rte_pci_device_name(&pci_dev->addr, cryptodev_name,
+ sizeof(cryptodev_name));
+
+ cryptodev = rte_cryptodev_pmd_get_named_dev(cryptodev_name);
+ if (cryptodev == NULL)
+ return -ENODEV;
+
+ return virtio_crypto_dev_uninit(cryptodev);
+}
+
+static struct rte_pci_driver rte_virtio_crypto_driver = {
+ .id_table = pci_id_virtio_crypto_map,
+ .drv_flags = 0,
+ .probe = crypto_virtio_pci_probe,
+ .remove = crypto_virtio_pci_remove
+};
+
+static struct cryptodev_driver virtio_crypto_drv;
+
+RTE_PMD_REGISTER_PCI(CRYPTODEV_NAME_VIRTIO_SYM_PMD, rte_virtio_crypto_driver);
+RTE_PMD_REGISTER_CRYPTO_DRIVER(virtio_crypto_drv, rte_virtio_crypto_driver,
+ cryptodev_virtio_driver_id);
diff --git a/drivers/crypto/virtio/virtio_cryptodev.h b/drivers/crypto/virtio/virtio_cryptodev.h
new file mode 100644
index 0000000..5d22ab8
--- /dev/null
+++ b/drivers/crypto/virtio/virtio_cryptodev.h
@@ -0,0 +1,87 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTIO_CRYPTODEV_H_
+#define _VIRTIO_CRYPTODEV_H_
+
+#include "virtio_pci.h"
+#include "virtio_crypto.h"
+
+#ifndef PAGE_SIZE
+#define PAGE_SIZE 4096
+#endif
+
+#define CRYPTODEV_NAME_VIRTIO_SYM_PMD crypto_virtio
+
+#define VIRTIO_MAX_DATA_QUEUES 128
+
+/* Features desired/implemented by this driver. */
+#define VIRTIO_CRYPTO_PMD_GUEST_FEATURES (1ULL << VIRTIO_F_VERSION_1)
+
+extern uint8_t cryptodev_virtio_driver_id;
+
+enum virtio_crypto_cmd_id {
+ VIRTIO_CRYPTO_CMD_CIPHER = 0,
+ VIRTIO_CRYPTO_CMD_AUTH = 1,
+ VIRTIO_CRYPTO_CMD_CIPHER_HASH = 2,
+ VIRTIO_CRYPTO_CMD_HASH_CIPHER = 3
+};
+
+/*
+ * Control queue function prototype
+ */
+void virtio_crypto_cq_start(struct rte_cryptodev *dev);
+
+/*
+ * Data queue function prototype
+ */
+void virtio_crypto_dq_start(struct rte_cryptodev *dev);
+
+int virtio_crypto_queue_setup(struct rte_cryptodev *dev,
+ int queue_type,
+ uint16_t vtpci_queue_idx,
+ uint16_t nb_desc,
+ int socket_id,
+ struct virtqueue **pvq);
+
+void virtio_crypto_queue_release(struct virtqueue *vq);
+
+uint16_t virtio_crypto_pkt_tx_burst(void *tx_queue,
+ struct rte_crypto_op **tx_pkts,
+ uint16_t nb_pkts);
+
+uint16_t virtio_crypto_pkt_rx_burst(void *tx_queue,
+ struct rte_crypto_op **tx_pkts,
+ uint16_t nb_pkts);
+
+#endif /* _VIRTIO_CRYPTODEV_H_ */
diff --git a/drivers/crypto/virtio/virtio_logs.h b/drivers/crypto/virtio/virtio_logs.h
new file mode 100644
index 0000000..41c663d
--- /dev/null
+++ b/drivers/crypto/virtio/virtio_logs.h
@@ -0,0 +1,76 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTIO_LOGS_H_
+#define _VIRTIO_LOGS_H_
+
+#include <rte_log.h>
+
+#ifdef RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_INIT
+#define PMD_INIT_LOG(level, fmt, args...) \
+ RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
+#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
+#else
+#define PMD_INIT_LOG(level, fmt, args...) do { } while (0)
+#define PMD_INIT_FUNC_TRACE() do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_SESSION
+#define PMD_SESSION_LOG(level, fmt, args...) \
+ RTE_LOG(level, PMD, "%s() session: " fmt "\n", __func__, ## args)
+#else
+#define PMD_SESSION_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_RX
+#define PMD_RX_LOG(level, fmt, args...) \
+ RTE_LOG(level, PMD, "%s() rx: " fmt "\n", __func__, ## args)
+#else
+#define PMD_RX_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_TX
+#define PMD_TX_LOG(level, fmt, args...) \
+ RTE_LOG(level, PMD, "%s() tx: " fmt "\n", __func__, ## args)
+#else
+#define PMD_TX_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#ifdef RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_DRIVER
+#define PMD_DRV_LOG(level, fmt, args...) \
+ RTE_LOG(level, PMD, "%s(): driver " fmt "\n", __func__, ## args)
+#else
+#define PMD_DRV_LOG(level, fmt, args...) do { } while (0)
+#endif
+
+#endif /* _VIRTIO_LOGS_H_ */
\ No newline at end of file
diff --git a/drivers/crypto/virtio/virtio_pci.c b/drivers/crypto/virtio/virtio_pci.c
new file mode 100644
index 0000000..d594ea5
--- /dev/null
+++ b/drivers/crypto/virtio/virtio_pci.c
@@ -0,0 +1,714 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+
+#ifdef RTE_EXEC_ENV_LINUXAPP
+ #include <dirent.h>
+ #include <fcntl.h>
+#endif
+
+#include <rte_io.h>
+#include <rte_bus.h>
+#include <rte_dev.h>
+#include <rte_devargs.h>
+
+#include "virtio_pci.h"
+#include "virtio_logs.h"
+#include "virtqueue.h"
+
+/*
+ * Following macros are derived from linux/pci_regs.h, however,
+ * we can't simply include that header here, as there is no such
+ * file for non-Linux platform.
+ */
+#define PCI_CAPABILITY_LIST 0x34
+#define PCI_CAP_ID_VNDR 0x09
+#define PCI_CAP_ID_MSIX 0x11
+
+/*
+ * The remaining space is defined by each driver as the per-driver
+ * configuration space.
+ */
+#define VIRTIO_PCI_CONFIG(hw) (((hw)->use_msix) ? 24 : 20)
+
+static inline int
+check_vq_phys_addr_ok(struct virtqueue *vq)
+{
+ /* Virtio PCI device VIRTIO_PCI_QUEUE_PF register is 32bit,
+ * and only accepts 32 bit page frame number.
+ * Check if the allocated physical memory exceeds 16TB.
+ */
+ if ((vq->vq_ring_mem + vq->vq_ring_size - 1) >>
+ (VIRTIO_PCI_QUEUE_ADDR_SHIFT + 32)) {
+ PMD_INIT_LOG(ERR, "vring address shouldn't be above 16TB!");
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Since we are in legacy mode:
+ * http://ozlabs.org/~rusty/virtio-spec/virtio-0.9.5.pdf
+ *
+ * "Note that this is possible because while the virtio header is PCI (i.e.
+ * little) endian, the device-specific region is encoded in the native endian of
+ * the guest (where such distinction is applicable)."
+ *
+ * For powerpc which supports both, qemu supposes that cpu is big endian and
+ * enforces this for the virtio-net stuff.
+ */
+static void
+legacy_read_dev_config(struct virtio_crypto_hw *hw, size_t offset,
+ void *dst, int length)
+{
+#ifdef RTE_ARCH_PPC_64
+ int size;
+
+ while (length > 0) {
+ if (length >= 4) {
+ size = 4;
+ rte_pci_ioport_read(VTPCI_IO(hw), dst, size,
+ VIRTIO_PCI_CONFIG(hw) + offset);
+ *(uint32_t *)dst = rte_be_to_cpu_32(*(uint32_t *)dst);
+ } else if (length >= 2) {
+ size = 2;
+ rte_pci_ioport_read(VTPCI_IO(hw), dst, size,
+ VIRTIO_PCI_CONFIG(hw) + offset);
+ *(uint16_t *)dst = rte_be_to_cpu_16(*(uint16_t *)dst);
+ } else {
+ size = 1;
+ rte_pci_ioport_read(VTPCI_IO(hw), dst, size,
+ VIRTIO_PCI_CONFIG(hw) + offset);
+ }
+
+ dst = (char *)dst + size;
+ offset += size;
+ length -= size;
+ }
+#else
+ rte_pci_ioport_read(VTPCI_IO(hw), dst, length,
+ VIRTIO_PCI_CONFIG(hw) + offset);
+#endif
+}
+
+static void
+legacy_write_dev_config(struct virtio_crypto_hw *hw, size_t offset,
+ const void *src, int length)
+{
+#ifdef RTE_ARCH_PPC_64
+ union {
+ uint32_t u32;
+ uint16_t u16;
+ } tmp;
+ int size;
+
+ while (length > 0) {
+ if (length >= 4) {
+ size = 4;
+ tmp.u32 = rte_cpu_to_be_32(*(const uint32_t *)src);
+ rte_pci_ioport_write(VTPCI_IO(hw), &tmp.u32, size,
+ VIRTIO_PCI_CONFIG(hw) + offset);
+ } else if (length >= 2) {
+ size = 2;
+ tmp.u16 = rte_cpu_to_be_16(*(const uint16_t *)src);
+ rte_pci_ioport_write(VTPCI_IO(hw), &tmp.u16, size,
+ VIRTIO_PCI_CONFIG(hw) + offset);
+ } else {
+ size = 1;
+ rte_pci_ioport_write(VTPCI_IO(hw), src, size,
+ VIRTIO_PCI_CONFIG(hw) + offset);
+ }
+
+ src = (const char *)src + size;
+ offset += size;
+ length -= size;
+ }
+#else
+ rte_pci_ioport_write(VTPCI_IO(hw), src, length,
+ VIRTIO_PCI_CONFIG(hw) + offset);
+#endif
+}
+
+static uint64_t
+legacy_get_features(struct virtio_crypto_hw *hw)
+{
+ uint32_t dst;
+
+ rte_pci_ioport_read(VTPCI_IO(hw), &dst, 4, VIRTIO_PCI_HOST_FEATURES);
+ return dst;
+}
+
+static void
+legacy_set_features(struct virtio_crypto_hw *hw, uint64_t features)
+{
+ if ((features >> 32) != 0) {
+ PMD_DRV_LOG(ERR,
+ "only 32 bit features are allowed for legacy virtio!");
+ return;
+ }
+ rte_pci_ioport_write(VTPCI_IO(hw), &features, 4,
+ VIRTIO_PCI_GUEST_FEATURES);
+}
+
+static uint8_t
+legacy_get_status(struct virtio_crypto_hw *hw)
+{
+ uint8_t dst;
+
+ rte_pci_ioport_read(VTPCI_IO(hw), &dst, 1, VIRTIO_PCI_STATUS);
+ return dst;
+}
+
+static void
+legacy_set_status(struct virtio_crypto_hw *hw, uint8_t status)
+{
+ rte_pci_ioport_write(VTPCI_IO(hw), &status, 1, VIRTIO_PCI_STATUS);
+}
+
+static void
+legacy_reset(struct virtio_crypto_hw *hw)
+{
+ legacy_set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
+}
+
+static uint8_t
+legacy_get_isr(struct virtio_crypto_hw *hw)
+{
+ uint8_t dst;
+
+ rte_pci_ioport_read(VTPCI_IO(hw), &dst, 1, VIRTIO_PCI_ISR);
+ return dst;
+}
+
+/* Enable one vector (0) for Link State Intrerrupt */
+static uint16_t
+legacy_set_config_irq(struct virtio_crypto_hw *hw, uint16_t vec)
+{
+ uint16_t dst;
+
+ rte_pci_ioport_write(VTPCI_IO(hw), &vec, 2, VIRTIO_MSI_CONFIG_VECTOR);
+ rte_pci_ioport_read(VTPCI_IO(hw), &dst, 2, VIRTIO_MSI_CONFIG_VECTOR);
+ return dst;
+}
+
+static uint16_t
+legacy_set_queue_irq(struct virtio_crypto_hw *hw, struct virtqueue *vq, uint16_t vec)
+{
+ uint16_t dst;
+
+ rte_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2,
+ VIRTIO_PCI_QUEUE_SEL);
+ rte_pci_ioport_write(VTPCI_IO(hw), &vec, 2, VIRTIO_MSI_QUEUE_VECTOR);
+ rte_pci_ioport_read(VTPCI_IO(hw), &dst, 2, VIRTIO_MSI_QUEUE_VECTOR);
+ return dst;
+}
+
+static uint16_t
+legacy_get_queue_num(struct virtio_crypto_hw *hw, uint16_t queue_id)
+{
+ uint16_t dst;
+
+ rte_pci_ioport_write(VTPCI_IO(hw), &queue_id, 2, VIRTIO_PCI_QUEUE_SEL);
+ rte_pci_ioport_read(VTPCI_IO(hw), &dst, 2, VIRTIO_PCI_QUEUE_NUM);
+ return dst;
+}
+
+static int
+legacy_setup_queue(struct virtio_crypto_hw *hw, struct virtqueue *vq)
+{
+ uint32_t src;
+
+ if (!check_vq_phys_addr_ok(vq))
+ return -1;
+
+ rte_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2,
+ VIRTIO_PCI_QUEUE_SEL);
+ src = vq->vq_ring_mem >> VIRTIO_PCI_QUEUE_ADDR_SHIFT;
+ rte_pci_ioport_write(VTPCI_IO(hw), &src, 4, VIRTIO_PCI_QUEUE_PFN);
+
+ return 0;
+}
+
+static void
+legacy_del_queue(struct virtio_crypto_hw *hw, struct virtqueue *vq)
+{
+ uint32_t src = 0;
+
+ rte_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2,
+ VIRTIO_PCI_QUEUE_SEL);
+ rte_pci_ioport_write(VTPCI_IO(hw), &src, 4, VIRTIO_PCI_QUEUE_PFN);
+}
+
+static void
+legacy_notify_queue(struct virtio_crypto_hw *hw, struct virtqueue *vq)
+{
+ rte_pci_ioport_write(VTPCI_IO(hw), &vq->vq_queue_index, 2,
+ VIRTIO_PCI_QUEUE_NOTIFY);
+}
+
+const struct virtio_pci_ops legacy_ops_crypto = {
+ .read_dev_cfg = legacy_read_dev_config,
+ .write_dev_cfg = legacy_write_dev_config,
+ .reset = legacy_reset,
+ .get_status = legacy_get_status,
+ .set_status = legacy_set_status,
+ .get_features = legacy_get_features,
+ .set_features = legacy_set_features,
+ .get_isr = legacy_get_isr,
+ .set_config_irq = legacy_set_config_irq,
+ .set_queue_irq = legacy_set_queue_irq,
+ .get_queue_num = legacy_get_queue_num,
+ .setup_queue = legacy_setup_queue,
+ .del_queue = legacy_del_queue,
+ .notify_queue = legacy_notify_queue,
+};
+
+static inline void
+io_write64_twopart(uint64_t val, uint32_t *lo, uint32_t *hi)
+{
+ rte_write32(val & ((1ULL << 32) - 1), lo);
+ rte_write32(val >> 32, hi);
+}
+
+static void
+modern_read_dev_config(struct virtio_crypto_hw *hw, size_t offset,
+ void *dst, int length)
+{
+ int i;
+ uint8_t *p;
+ uint8_t old_gen, new_gen;
+
+ do {
+ old_gen = rte_read8(&hw->common_cfg->config_generation);
+
+ p = dst;
+ for (i = 0; i < length; i++)
+ *p++ = rte_read8((uint8_t *)hw->dev_cfg + offset + i);
+
+ new_gen = rte_read8(&hw->common_cfg->config_generation);
+ } while (old_gen != new_gen);
+}
+
+static void
+modern_write_dev_config(struct virtio_crypto_hw *hw, size_t offset,
+ const void *src, int length)
+{
+ int i;
+ const uint8_t *p = src;
+
+ for (i = 0; i < length; i++)
+ rte_write8((*p++), (((uint8_t *)hw->dev_cfg) + offset + i));
+}
+
+static uint64_t
+modern_get_features(struct virtio_crypto_hw *hw)
+{
+ uint32_t features_lo, features_hi;
+
+ rte_write32(0, &hw->common_cfg->device_feature_select);
+ features_lo = rte_read32(&hw->common_cfg->device_feature);
+
+ rte_write32(1, &hw->common_cfg->device_feature_select);
+ features_hi = rte_read32(&hw->common_cfg->device_feature);
+
+ return ((uint64_t)features_hi << 32) | features_lo;
+}
+
+static void
+modern_set_features(struct virtio_crypto_hw *hw, uint64_t features)
+{
+ rte_write32(0, &hw->common_cfg->guest_feature_select);
+ rte_write32(features & ((1ULL << 32) - 1),
+ &hw->common_cfg->guest_feature);
+
+ rte_write32(1, &hw->common_cfg->guest_feature_select);
+ rte_write32(features >> 32,
+ &hw->common_cfg->guest_feature);
+}
+
+static uint8_t
+modern_get_status(struct virtio_crypto_hw *hw)
+{
+ return rte_read8(&hw->common_cfg->device_status);
+}
+
+static void
+modern_set_status(struct virtio_crypto_hw *hw, uint8_t status)
+{
+ rte_write8(status, &hw->common_cfg->device_status);
+}
+
+static void
+modern_reset(struct virtio_crypto_hw *hw)
+{
+ modern_set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
+ modern_get_status(hw);
+}
+
+static uint8_t
+modern_get_isr(struct virtio_crypto_hw *hw)
+{
+ return rte_read8(hw->isr);
+}
+
+static uint16_t
+modern_set_config_irq(struct virtio_crypto_hw *hw, uint16_t vec)
+{
+ rte_write16(vec, &hw->common_cfg->msix_config);
+ return rte_read16(&hw->common_cfg->msix_config);
+}
+
+static uint16_t
+modern_set_queue_irq(struct virtio_crypto_hw *hw, struct virtqueue *vq, uint16_t vec)
+{
+ rte_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
+ rte_write16(vec, &hw->common_cfg->queue_msix_vector);
+ return rte_read16(&hw->common_cfg->queue_msix_vector);
+}
+
+static uint16_t
+modern_get_queue_num(struct virtio_crypto_hw *hw, uint16_t queue_id)
+{
+ rte_write16(queue_id, &hw->common_cfg->queue_select);
+ return rte_read16(&hw->common_cfg->queue_size);
+}
+
+static int
+modern_setup_queue(struct virtio_crypto_hw *hw, struct virtqueue *vq)
+{
+ uint64_t desc_addr, avail_addr, used_addr;
+ uint16_t notify_off;
+
+ if (!check_vq_phys_addr_ok(vq))
+ return -1;
+
+ desc_addr = vq->vq_ring_mem;
+ avail_addr = desc_addr + vq->vq_nentries * sizeof(struct vring_desc);
+ used_addr = RTE_ALIGN_CEIL(avail_addr + offsetof(struct vring_avail,
+ ring[vq->vq_nentries]),
+ VIRTIO_PCI_VRING_ALIGN);
+
+ rte_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
+
+ io_write64_twopart(desc_addr, &hw->common_cfg->queue_desc_lo,
+ &hw->common_cfg->queue_desc_hi);
+ io_write64_twopart(avail_addr, &hw->common_cfg->queue_avail_lo,
+ &hw->common_cfg->queue_avail_hi);
+ io_write64_twopart(used_addr, &hw->common_cfg->queue_used_lo,
+ &hw->common_cfg->queue_used_hi);
+
+ notify_off = rte_read16(&hw->common_cfg->queue_notify_off);
+ vq->notify_addr = (void *)((uint8_t *)hw->notify_base +
+ notify_off * hw->notify_off_multiplier);
+
+ rte_write16(1, &hw->common_cfg->queue_enable);
+
+ PMD_INIT_LOG(DEBUG, "queue %u addresses:", vq->vq_queue_index);
+ PMD_INIT_LOG(DEBUG, "\t desc_addr: %" PRIx64, desc_addr);
+ PMD_INIT_LOG(DEBUG, "\t aval_addr: %" PRIx64, avail_addr);
+ PMD_INIT_LOG(DEBUG, "\t used_addr: %" PRIx64, used_addr);
+ PMD_INIT_LOG(DEBUG, "\t notify addr: %p (notify offset: %u)",
+ vq->notify_addr, notify_off);
+
+ return 0;
+}
+
+static void
+modern_del_queue(struct virtio_crypto_hw *hw, struct virtqueue *vq)
+{
+ rte_write16(vq->vq_queue_index, &hw->common_cfg->queue_select);
+
+ io_write64_twopart(0, &hw->common_cfg->queue_desc_lo,
+ &hw->common_cfg->queue_desc_hi);
+ io_write64_twopart(0, &hw->common_cfg->queue_avail_lo,
+ &hw->common_cfg->queue_avail_hi);
+ io_write64_twopart(0, &hw->common_cfg->queue_used_lo,
+ &hw->common_cfg->queue_used_hi);
+
+ rte_write16(0, &hw->common_cfg->queue_enable);
+}
+
+static void
+modern_notify_queue(struct virtio_crypto_hw *hw __rte_unused, struct virtqueue *vq)
+{
+ rte_write16(vq->vq_queue_index, vq->notify_addr);
+}
+
+const struct virtio_pci_ops modern_ops_crypto = {
+ .read_dev_cfg = modern_read_dev_config,
+ .write_dev_cfg = modern_write_dev_config,
+ .reset = modern_reset,
+ .get_status = modern_get_status,
+ .set_status = modern_set_status,
+ .get_features = modern_get_features,
+ .set_features = modern_set_features,
+ .get_isr = modern_get_isr,
+ .set_config_irq = modern_set_config_irq,
+ .set_queue_irq = modern_set_queue_irq,
+ .get_queue_num = modern_get_queue_num,
+ .setup_queue = modern_setup_queue,
+ .del_queue = modern_del_queue,
+ .notify_queue = modern_notify_queue,
+};
+
+void
+vtpci_read_dev_config_crypto(struct virtio_crypto_hw *hw, size_t offset,
+ void *dst, int length)
+{
+ VTPCI_OPS(hw)->read_dev_cfg(hw, offset, dst, length);
+}
+
+void
+vtpci_write_dev_config_crypto(struct virtio_crypto_hw *hw, size_t offset,
+ const void *src, int length)
+{
+ VTPCI_OPS(hw)->write_dev_cfg(hw, offset, src, length);
+}
+
+uint64_t
+vtpci_negotiate_features_crypto(struct virtio_crypto_hw *hw, uint64_t host_features)
+{
+ uint64_t features;
+
+ /*
+ * Limit negotiated features to what the driver, virtqueue, and
+ * host all support.
+ */
+ features = host_features & hw->guest_features;
+ VTPCI_OPS(hw)->set_features(hw, features);
+
+ return features;
+}
+
+void
+vtpci_reset_crypto(struct virtio_crypto_hw *hw)
+{
+ VTPCI_OPS(hw)->set_status(hw, VIRTIO_CONFIG_STATUS_RESET);
+ /* flush status write */
+ VTPCI_OPS(hw)->get_status(hw);
+}
+
+void
+vtpci_reinit_complete_crypto(struct virtio_crypto_hw *hw)
+{
+ vtpci_set_status_crypto(hw, VIRTIO_CONFIG_STATUS_DRIVER_OK);
+}
+
+void
+vtpci_set_status_crypto(struct virtio_crypto_hw *hw, uint8_t status)
+{
+ if (status != VIRTIO_CONFIG_STATUS_RESET)
+ status |= VTPCI_OPS(hw)->get_status(hw);
+
+ VTPCI_OPS(hw)->set_status(hw, status);
+}
+
+uint8_t
+vtpci_get_status_crypto(struct virtio_crypto_hw *hw)
+{
+ return VTPCI_OPS(hw)->get_status(hw);
+}
+
+uint8_t
+vtpci_isr_crypto(struct virtio_crypto_hw *hw)
+{
+ return VTPCI_OPS(hw)->get_isr(hw);
+}
+
+static void *
+get_cfg_addr(struct rte_pci_device *dev, struct virtio_pci_cap *cap)
+{
+ uint8_t bar = cap->bar;
+ uint32_t length = cap->length;
+ uint32_t offset = cap->offset;
+ uint8_t *base;
+
+ if (bar >= PCI_MAX_RESOURCE) {
+ PMD_INIT_LOG(ERR, "invalid bar: %u", bar);
+ return NULL;
+ }
+
+ if (offset + length < offset) {
+ PMD_INIT_LOG(ERR, "offset(%u) + length(%u) overflows",
+ offset, length);
+ return NULL;
+ }
+
+ if (offset + length > dev->mem_resource[bar].len) {
+ PMD_INIT_LOG(ERR,
+ "invalid cap: overflows bar space: %u > %" PRIu64,
+ offset + length, dev->mem_resource[bar].len);
+ return NULL;
+ }
+
+ base = dev->mem_resource[bar].addr;
+ if (base == NULL) {
+ PMD_INIT_LOG(ERR, "bar %u base addr is NULL", bar);
+ return NULL;
+ }
+
+ return base + offset;
+}
+
+#define PCI_MSIX_ENABLE 0x8000
+
+static int
+virtio_read_caps(struct rte_pci_device *dev, struct virtio_crypto_hw *hw)
+{
+ uint8_t pos;
+ struct virtio_pci_cap cap;
+ int ret;
+
+ if (rte_pci_map_device(dev)) {
+ PMD_INIT_LOG(DEBUG, "failed to map pci device!");
+ return -1;
+ }
+
+ ret = rte_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST);
+ if (ret < 0) {
+ PMD_INIT_LOG(DEBUG, "failed to read pci capability list");
+ return -1;
+ }
+
+ while (pos) {
+ ret = rte_pci_read_config(dev, &cap, sizeof(cap), pos);
+ if (ret < 0) {
+ PMD_INIT_LOG(ERR,
+ "failed to read pci cap at pos: %x", pos);
+ break;
+ }
+
+ if (cap.cap_vndr == PCI_CAP_ID_MSIX) {
+ /* Transitional devices would also have this capability,
+ * that's why we also check if msix is enabled.
+ * 1st byte is cap ID; 2nd byte is the position of next
+ * cap; next two bytes are the flags.
+ */
+ uint16_t flags = ((uint16_t *)&cap)[1];
+
+ if (flags & PCI_MSIX_ENABLE)
+ hw->use_msix = 1;
+ }
+
+ if (cap.cap_vndr != PCI_CAP_ID_VNDR) {
+ PMD_INIT_LOG(DEBUG,
+ "[%2x] skipping non VNDR cap id: %02x",
+ pos, cap.cap_vndr);
+ goto next;
+ }
+
+ PMD_INIT_LOG(DEBUG,
+ "[%2x] cfg type: %u, bar: %u, offset: %04x, len: %u",
+ pos, cap.cfg_type, cap.bar, cap.offset, cap.length);
+
+ switch (cap.cfg_type) {
+ case VIRTIO_PCI_CAP_COMMON_CFG:
+ hw->common_cfg = get_cfg_addr(dev, &cap);
+ break;
+ case VIRTIO_PCI_CAP_NOTIFY_CFG:
+ rte_pci_read_config(dev, &hw->notify_off_multiplier,
+ 4, pos + sizeof(cap));
+ hw->notify_base = get_cfg_addr(dev, &cap);
+ break;
+ case VIRTIO_PCI_CAP_DEVICE_CFG:
+ hw->dev_cfg = get_cfg_addr(dev, &cap);
+ break;
+ case VIRTIO_PCI_CAP_ISR_CFG:
+ hw->isr = get_cfg_addr(dev, &cap);
+ break;
+ }
+
+next:
+ pos = cap.cap_next;
+ }
+
+ if (hw->common_cfg == NULL || hw->notify_base == NULL ||
+ hw->dev_cfg == NULL || hw->isr == NULL) {
+ PMD_INIT_LOG(INFO, "no modern virtio pci device found.");
+ return -1;
+ }
+
+ PMD_INIT_LOG(INFO, "found modern virtio pci device.");
+
+ PMD_INIT_LOG(DEBUG, "common cfg mapped at: %p", hw->common_cfg);
+ PMD_INIT_LOG(DEBUG, "device cfg mapped at: %p", hw->dev_cfg);
+ PMD_INIT_LOG(DEBUG, "isr cfg mapped at: %p", hw->isr);
+ PMD_INIT_LOG(DEBUG, "notify base: %p, notify off multiplier: %u",
+ hw->notify_base, hw->notify_off_multiplier);
+
+ return 0;
+}
+
+/*
+ * Return -1:
+ * if there is error mapping with VFIO/UIO.
+ * if port map error when driver type is KDRV_NONE.
+ * if whitelisted but driver type is KDRV_UNKNOWN.
+ * Return 1 if kernel driver is managing the device.
+ * Return 0 on success.
+ */
+int
+vtpci_init_crypto(struct rte_pci_device *dev, struct virtio_crypto_hw *hw)
+{
+ /*
+ * Try if we can succeed reading virtio pci caps, which exists
+ * only on modern pci device. If failed, we fallback to legacy
+ * virtio handling.
+ */
+ if (virtio_read_caps(dev, hw) == 0) {
+ PMD_INIT_LOG(INFO, "modern virtio pci detected.");
+ virtio_hw_internal[hw->dev_id].vtpci_ops = &modern_ops_crypto;
+ hw->modern = 1;
+ return 0;
+ }
+
+ PMD_INIT_LOG(INFO, "trying with legacy virtio pci.");
+ if (rte_pci_ioport_map(dev, 0, VTPCI_IO(hw)) < 0) {
+ if (dev->kdrv == RTE_KDRV_UNKNOWN &&
+ (!dev->device.devargs ||
+ dev->device.devargs->bus !=
+ rte_bus_find_by_name("pci"))) {
+ PMD_INIT_LOG(INFO,
+ "skip kernel managed virtio device.");
+ return -1;
+ }
+ return -1;
+ }
+
+ virtio_hw_internal[hw->dev_id].vtpci_ops = &legacy_ops_crypto;
+ hw->modern = 0;
+
+ return 0;
+}
diff --git a/drivers/crypto/virtio/virtio_pci.h b/drivers/crypto/virtio/virtio_pci.h
new file mode 100644
index 0000000..888a4c2
--- /dev/null
+++ b/drivers/crypto/virtio/virtio_pci.h
@@ -0,0 +1,286 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTIO_PCI_H_
+#define _VIRTIO_PCI_H_
+
+#include <stdint.h>
+
+#ifdef __FreeBSD__
+#include <sys/types.h>
+#include <machine/cpufunc.h>
+#else
+#include <sys/io.h>
+#endif
+
+#include <rte_cryptodev.h>
+#include <rte_bus_pci.h>
+
+struct virtqueue;
+
+/* VirtIO PCI vendor/device ID. */
+#define VIRTIO_CRYPTO_PCI_VENDORID 0x1AF4
+#define VIRTIO_CRYPTO_PCI_LEGACY_DEVICEID 0x1014
+#define VIRTIO_CRYPTO_PCI_MODERN_DEVICEID 0x1054
+
+/* VirtIO ABI version, this must match exactly. */
+#define VIRTIO_PCI_ABI_VERSION 0
+
+/*
+ * VirtIO Header, located in BAR 0.
+ */
+#define VIRTIO_PCI_HOST_FEATURES 0 /* host's supported features (32bit, RO)*/
+#define VIRTIO_PCI_GUEST_FEATURES 4 /* guest's supported features (32, RW) */
+#define VIRTIO_PCI_QUEUE_PFN 8 /* physical address of VQ (32, RW) */
+#define VIRTIO_PCI_QUEUE_NUM 12 /* number of ring entries (16, RO) */
+#define VIRTIO_PCI_QUEUE_SEL 14 /* current VQ selection (16, RW) */
+#define VIRTIO_PCI_QUEUE_NOTIFY 16 /* notify host regarding VQ (16, RW) */
+#define VIRTIO_PCI_STATUS 18 /* device status register (8, RW) */
+/* interrupt status register, reading also clears the register (8, RO) */
+#define VIRTIO_PCI_ISR 19
+/* Only if MSIX is enabled: */
+#define VIRTIO_MSI_CONFIG_VECTOR 20 /* configuration change vector (16, RW) */
+/* vector for selected VQ notifications (16, RW) */
+#define VIRTIO_MSI_QUEUE_VECTOR 22
+
+/* The bit of the ISR which indicates a device has an interrupt. */
+#define VIRTIO_PCI_ISR_INTR 0x1
+/* The bit of the ISR which indicates a device configuration change. */
+#define VIRTIO_PCI_ISR_CONFIG 0x2
+/* Vector value used to disable MSI for queue. */
+#define VIRTIO_MSI_NO_VECTOR 0xFFFF
+
+/* Status byte for guest to report progress. */
+#define VIRTIO_CONFIG_STATUS_RESET 0x00
+#define VIRTIO_CONFIG_STATUS_ACK 0x01
+#define VIRTIO_CONFIG_STATUS_DRIVER 0x02
+#define VIRTIO_CONFIG_STATUS_DRIVER_OK 0x04
+#define VIRTIO_CONFIG_STATUS_FEATURES_OK 0x08
+#define VIRTIO_CONFIG_STATUS_FAILED 0x80
+
+/*
+ * Each virtqueue indirect descriptor list must be physically contiguous.
+ * To allow us to malloc(9) each list individually, limit the number
+ * supported to what will fit in one page. With 4KB pages, this is a limit
+ * of 256 descriptors. If there is ever a need for more, we can switch to
+ * contigmalloc(9) for the larger allocations, similar to what
+ * bus_dmamem_alloc(9) does.
+ *
+ * Note the sizeof(struct vring_desc) is 16 bytes.
+ */
+#define VIRTIO_MAX_INDIRECT ((int) (PAGE_SIZE / 16))
+
+/* The feature bitmap for virtio crypto */
+
+/* virtio_crypto_config.status available */
+#define VIRTIO_CRYPTO_F_STATUS 0
+/* Device supports Receive Flow Steering */
+#define VIRTIO_CRYPTO_F_MQ 1
+
+/*
+ * Do we get callbacks when the ring is completely used, even if we've
+ * suppressed them?
+ */
+#define VIRTIO_F_NOTIFY_ON_EMPTY 24
+
+/* Can the device handle any descriptor layout? */
+#define VIRTIO_F_ANY_LAYOUT 27
+
+/* We support indirect buffer descriptors */
+#define VIRTIO_RING_F_INDIRECT_DESC 28
+
+#define VIRTIO_F_VERSION_1 32
+#define VIRTIO_F_IOMMU_PLATFORM 33
+
+/*
+ * The Guest publishes the used index for which it expects an interrupt
+ * at the end of the avail ring. Host should ignore the avail->flags field.
+ */
+/*
+ * The Host publishes the avail index for which it expects a kick
+ * at the end of the used ring. Guest should ignore the used->flags field.
+ */
+#define VIRTIO_RING_F_EVENT_IDX 29
+
+/*
+ * Maximum number of virtqueues per device.
+ */
+#define VIRTIO_MAX_VIRTQUEUES_PAIRS 8
+
+/* Common configuration */
+#define VIRTIO_PCI_CAP_COMMON_CFG 1
+/* Notifications */
+#define VIRTIO_PCI_CAP_NOTIFY_CFG 2
+/* ISR Status */
+#define VIRTIO_PCI_CAP_ISR_CFG 3
+/* Device specific configuration */
+#define VIRTIO_PCI_CAP_DEVICE_CFG 4
+/* PCI configuration access */
+#define VIRTIO_PCI_CAP_PCI_CFG 5
+
+/* This is the PCI capability header: */
+struct virtio_pci_cap {
+ uint8_t cap_vndr; /* Generic PCI field: PCI_CAP_ID_VNDR */
+ uint8_t cap_next; /* Generic PCI field: next ptr. */
+ uint8_t cap_len; /* Generic PCI field: capability length */
+ uint8_t cfg_type; /* Identifies the structure. */
+ uint8_t bar; /* Where to find it. */
+ uint8_t padding[3]; /* Pad to full dword. */
+ uint32_t offset; /* Offset within bar. */
+ uint32_t length; /* Length of the structure, in bytes. */
+};
+
+struct virtio_pci_notify_cap {
+ struct virtio_pci_cap cap;
+ uint32_t notify_off_multiplier; /* Multiplier for queue_notify_off. */
+};
+
+/* Fields in VIRTIO_PCI_CAP_COMMON_CFG: */
+struct virtio_pci_common_cfg {
+ /* About the whole device. */
+ uint32_t device_feature_select; /* read-write */
+ uint32_t device_feature; /* read-only */
+ uint32_t guest_feature_select; /* read-write */
+ uint32_t guest_feature; /* read-write */
+ uint16_t msix_config; /* read-write */
+ uint16_t num_queues; /* read-only */
+ uint8_t device_status; /* read-write */
+ uint8_t config_generation; /* read-only */
+
+ /* About a specific virtqueue. */
+ uint16_t queue_select; /* read-write */
+ uint16_t queue_size; /* read-write, power of 2. */
+ uint16_t queue_msix_vector; /* read-write */
+ uint16_t queue_enable; /* read-write */
+ uint16_t queue_notify_off; /* read-only */
+ uint32_t queue_desc_lo; /* read-write */
+ uint32_t queue_desc_hi; /* read-write */
+ uint32_t queue_avail_lo; /* read-write */
+ uint32_t queue_avail_hi; /* read-write */
+ uint32_t queue_used_lo; /* read-write */
+ uint32_t queue_used_hi; /* read-write */
+};
+
+struct virtio_crypto_hw;
+
+struct virtio_pci_ops {
+ void (*read_dev_cfg)(struct virtio_crypto_hw *hw, size_t offset,
+ void *dst, int len);
+ void (*write_dev_cfg)(struct virtio_crypto_hw *hw, size_t offset,
+ const void *src, int len);
+ void (*reset)(struct virtio_crypto_hw *hw);
+
+ uint8_t (*get_status)(struct virtio_crypto_hw *hw);
+ void (*set_status)(struct virtio_crypto_hw *hw, uint8_t status);
+
+ uint64_t (*get_features)(struct virtio_crypto_hw *hw);
+ void (*set_features)(struct virtio_crypto_hw *hw, uint64_t features);
+
+ uint8_t (*get_isr)(struct virtio_crypto_hw *hw);
+
+ uint16_t (*set_config_irq)(struct virtio_crypto_hw *hw, uint16_t vec);
+
+ uint16_t (*set_queue_irq)(struct virtio_crypto_hw *hw, struct virtqueue *vq,
+ uint16_t vec);
+
+ uint16_t (*get_queue_num)(struct virtio_crypto_hw *hw, uint16_t queue_id);
+ int (*setup_queue)(struct virtio_crypto_hw *hw, struct virtqueue *vq);
+ void (*del_queue)(struct virtio_crypto_hw *hw, struct virtqueue *vq);
+ void (*notify_queue)(struct virtio_crypto_hw *hw, struct virtqueue *vq);
+};
+
+struct virtio_crypto_config;
+
+struct virtio_crypto_hw {
+ /* control queue */
+ struct virtqueue *cvq;
+ uint16_t dev_id;
+ uint16_t max_dataqueues;
+ uint64_t req_guest_features;
+ uint64_t guest_features;
+ uint8_t use_msix;
+ uint8_t modern;
+ uint32_t notify_off_multiplier;
+ uint8_t *isr;
+ uint16_t *notify_base;
+ struct virtio_pci_common_cfg *common_cfg;
+ struct virtio_crypto_config *dev_cfg;
+};
+
+/*
+ * While virtio_crypto_hw is stored in shared memory, this structure stores
+ * some infos that may vary in the multiple process model locally.
+ * For example, the vtpci_ops pointer.
+ */
+struct virtio_hw_internal {
+ const struct virtio_pci_ops *vtpci_ops;
+ struct rte_pci_ioport io;
+};
+
+#define VTPCI_OPS(hw) (virtio_hw_internal[(hw)->dev_id].vtpci_ops)
+#define VTPCI_IO(hw) (&virtio_hw_internal[(hw)->dev_id].io)
+
+extern struct virtio_hw_internal virtio_hw_internal[RTE_MAX_VIRTIO_CRYPTO];
+
+/*
+ * How many bits to shift physical queue address written to QUEUE_PFN.
+ * 12 is historical, and due to x86 page size.
+ */
+#define VIRTIO_PCI_QUEUE_ADDR_SHIFT 12
+
+/* The alignment to use between consumer and producer parts of vring. */
+#define VIRTIO_PCI_VRING_ALIGN 4096
+
+/*
+ * Function declaration from virtio_pci.c
+ */
+int vtpci_init_crypto(struct rte_pci_device *dev, struct virtio_crypto_hw *hw);
+
+void vtpci_reset_crypto(struct virtio_crypto_hw *);
+
+void vtpci_reinit_complete_crypto(struct virtio_crypto_hw *);
+
+uint8_t vtpci_get_status_crypto(struct virtio_crypto_hw *);
+void vtpci_set_status_crypto(struct virtio_crypto_hw *, uint8_t);
+
+uint64_t vtpci_negotiate_features_crypto(struct virtio_crypto_hw *, uint64_t);
+
+void vtpci_write_dev_config_crypto(struct virtio_crypto_hw *, size_t, const void *, int);
+
+void vtpci_read_dev_config_crypto(struct virtio_crypto_hw *, uint64_t, void *, int);
+
+uint8_t vtpci_isr_crypto(struct virtio_crypto_hw *);
+
+uint16_t vtpci_irq_config(struct virtio_crypto_hw *, uint16_t);
+
+#endif /* _VIRTIO_PCI_H_ */
diff --git a/drivers/crypto/virtio/virtio_ring.h b/drivers/crypto/virtio/virtio_ring.h
new file mode 100644
index 0000000..00209d4
--- /dev/null
+++ b/drivers/crypto/virtio/virtio_ring.h
@@ -0,0 +1,169 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTIO_RING_H_
+#define _VIRTIO_RING_H_
+
+#include <stdint.h>
+
+#include <rte_common.h>
+
+/* This marks a buffer as continuing via the next field. */
+#define VRING_DESC_F_NEXT 1
+/* This marks a buffer as write-only (otherwise read-only). */
+#define VRING_DESC_F_WRITE 2
+/* This means the buffer contains a list of buffer descriptors. */
+#define VRING_DESC_F_INDIRECT 4
+
+/*
+ * The Host uses this in used->flags to advise the Guest: don't kick me
+ * when you add a buffer. It's unreliable, so it's simply an
+ * optimization. Guest will still kick if it's out of buffers.
+ */
+#define VRING_USED_F_NO_NOTIFY 1
+/*
+ * The Guest uses this in avail->flags to advise the Host: don't
+ * interrupt me when you consume a buffer. It's unreliable, so it's
+ * simply an optimization.
+ */
+#define VRING_AVAIL_F_NO_INTERRUPT 1
+
+/*
+ * VirtIO ring descriptors: 16 bytes.
+ * These can chain together via "next".
+ */
+struct vring_desc {
+ uint64_t addr; /* Address (guest-physical). */
+ uint32_t len; /* Length. */
+ uint16_t flags; /* The flags as indicated above. */
+ uint16_t next; /* We chain unused descriptors via this. */
+};
+
+struct vring_avail {
+ uint16_t flags;
+ uint16_t idx;
+ uint16_t ring[0];
+};
+
+/* id is a 16bit index. uint32_t is used here for ids for padding reasons. */
+struct vring_used_elem {
+ /* Index of start of used descriptor chain. */
+ uint32_t id;
+ /* Total length of the descriptor chain which was written to. */
+ uint32_t len;
+};
+
+struct vring_used {
+ uint16_t flags;
+ uint16_t idx;
+ struct vring_used_elem ring[0];
+};
+
+struct vring {
+ unsigned int num;
+ struct vring_desc *desc;
+ struct vring_avail *avail;
+ struct vring_used *used;
+};
+
+/* The standard layout for the ring is a continuous chunk of memory which
+ * looks like this. We assume num is a power of 2.
+ *
+ * struct vring {
+ * // The actual descriptors (16 bytes each)
+ * struct vring_desc desc[num];
+ *
+ * // A ring of available descriptor heads with free-running index.
+ * __u16 avail_flags;
+ * __u16 avail_idx;
+ * __u16 available[num];
+ * __u16 used_event_idx;
+ *
+ * // Padding to the next align boundary.
+ * char pad[];
+ *
+ * // A ring of used descriptor heads with free-running index.
+ * __u16 used_flags;
+ * __u16 used_idx;
+ * struct vring_used_elem used[num];
+ * __u16 avail_event_idx;
+ * };
+ *
+ * NOTE: for VirtIO PCI, align is 4096.
+ */
+
+/*
+ * We publish the used event index at the end of the available ring, and vice
+ * versa. They are at the end for backwards compatibility.
+ */
+#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
+#define vring_avail_event(vr) (*(uint16_t *)&(vr)->used->ring[(vr)->num])
+
+static inline size_t
+vring_crypto_size(unsigned int num, unsigned long align)
+{
+ size_t size;
+
+ size = num * sizeof(struct vring_desc);
+ size += sizeof(struct vring_avail) + (num * sizeof(uint16_t));
+ size = RTE_ALIGN_CEIL(size, align);
+ size += sizeof(struct vring_used) +
+ (num * sizeof(struct vring_used_elem));
+ return size;
+}
+
+static inline void
+vring_crypto_init(struct vring *vr, unsigned int num, uint8_t *p,
+ unsigned long align)
+{
+ vr->num = num;
+ vr->desc = (struct vring_desc *) p;
+ vr->avail = (struct vring_avail *) (p +
+ num * sizeof(struct vring_desc));
+ vr->used = (void *)
+ RTE_ALIGN_CEIL((uintptr_t)(&vr->avail->ring[num]), align);
+}
+
+/*
+ * The following is used with VIRTIO_RING_F_EVENT_IDX.
+ * Assuming a given event_idx value from the other size, if we have
+ * just incremented index from old to new_idx, should we trigger an
+ * event?
+ */
+static inline int
+vring_crypto_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
+{
+ return (uint16_t)(new_idx - event_idx - 1) < (uint16_t)(new_idx - old);
+}
+
+#endif /* _VIRTIO_RING_H_ */
diff --git a/drivers/crypto/virtio/virtio_rxtx.c b/drivers/crypto/virtio/virtio_rxtx.c
new file mode 100644
index 0000000..6085a8f
--- /dev/null
+++ b/drivers/crypto/virtio/virtio_rxtx.c
@@ -0,0 +1,569 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include <rte_cycles.h>
+#include <rte_memory.h>
+#include <rte_memcpy.h>
+#include <rte_memzone.h>
+#include <rte_branch_prediction.h>
+#include <rte_mempool.h>
+#include <rte_malloc.h>
+#include <rte_mbuf.h>
+#include <rte_cryptodev.h>
+#include <rte_prefetch.h>
+#include <rte_string_fns.h>
+#include <rte_errno.h>
+#include <rte_byteorder.h>
+#include <rte_cryptodev_pmd.h>
+
+#include "virtio_logs.h"
+#include "virtio_cryptodev.h"
+#include "virtio_pci.h"
+#include "virtqueue.h"
+#include "virtio_crypto_algs.h"
+#include "virtio_crypto.h"
+
+#ifdef RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_DUMP
+#define VIRTIO_DUMP_PACKET(m, len) rte_pktmbuf_dump(stdout, m, len)
+#else
+#define VIRTIO_DUMP_PACKET(m, len) do { } while (0)
+#endif
+
+#define NUM_ENTRY_VIRTIO_CRYPTO_TX 7
+
+enum rte_crypto_op_status status_transfer[VIRTIO_CRYPTO_INVSESS + 1] = {
+ RTE_CRYPTO_OP_STATUS_SUCCESS,
+ RTE_CRYPTO_OP_STATUS_ERROR,
+ RTE_CRYPTO_OP_STATUS_AUTH_FAILED,
+ RTE_CRYPTO_OP_STATUS_INVALID_ARGS,
+ RTE_CRYPTO_OP_STATUS_INVALID_SESSION,
+};
+
+static void
+vq_crypto_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
+{
+ struct vring_desc *dp, *dp_tail;
+ struct vq_desc_extra *dxp;
+ uint16_t desc_idx_last = desc_idx;
+
+ dp = &vq->vq_ring.desc[desc_idx];
+ dxp = &vq->vq_descx[desc_idx];
+ vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt + dxp->ndescs);
+ if ((dp->flags & VRING_DESC_F_INDIRECT) == 0) {
+ while (dp->flags & VRING_DESC_F_NEXT) {
+ desc_idx_last = dp->next;
+ dp = &vq->vq_ring.desc[dp->next];
+ }
+ }
+ dxp->ndescs = 0;
+
+ /*
+ * We must append the existing free chain, if any, to the end of
+ * newly freed chain. If the virtqueue was completely used, then
+ * head would be VQ_RING_DESC_CHAIN_END (ASSERTed above).
+ */
+ if (vq->vq_desc_tail_idx == VQ_RING_DESC_CHAIN_END) {
+ vq->vq_desc_head_idx = desc_idx;
+ } else {
+ dp_tail = &vq->vq_ring.desc[vq->vq_desc_tail_idx];
+ dp_tail->next = desc_idx;
+ }
+
+ vq->vq_desc_tail_idx = desc_idx_last;
+ dp->next = VQ_RING_DESC_CHAIN_END;
+}
+
+static uint16_t
+virtqueue_crypto_dequeue_burst_rx(struct virtqueue *vq,
+ struct rte_crypto_op **rx_pkts, uint16_t num)
+{
+ struct vring_used_elem *uep;
+ struct rte_crypto_op *cop;
+ uint16_t used_idx, desc_idx;
+ uint16_t i;
+ struct virtio_crypto_inhdr *inhdr;
+
+ /* Caller does the check */
+ for (i = 0; i < num ; i++) {
+ used_idx = (uint16_t)(vq->vq_used_cons_idx
+ & (vq->vq_nentries - 1));
+ uep = &vq->vq_ring.used->ring[used_idx];
+ desc_idx = (uint16_t)uep->id;
+ cop = (struct rte_crypto_op *)
+ vq->vq_descx[desc_idx].crypto_op;
+
+ /*
+ * status is saved just after virtio_crypto_op_data_req,
+ * see virtqueue_crypto_sym_enqueue_xmit() for more details
+ */
+ inhdr = (struct virtio_crypto_inhdr *)(
+ (uint8_t *)vq->vq_descx[desc_idx].malloc_addr +
+ sizeof(struct virtio_crypto_op_data_req));
+ if (inhdr->status == VIRTIO_CRYPTO_OK) {
+ cop->status = status_transfer[inhdr->status];
+ } else if (inhdr->status <= VIRTIO_CRYPTO_INVSESS) {
+ cop->status = status_transfer[inhdr->status];
+ vq->packets_received_failed++;
+ } else
+ vq->packets_received_failed++;
+
+ vq->packets_received_total++;
+
+ rx_pkts[i] = cop;
+ vq->vq_used_cons_idx++;
+ vq_crypto_ring_free_chain(vq, desc_idx);
+ vq->vq_descx[desc_idx].crypto_op = NULL;
+ rte_free(vq->vq_descx[desc_idx].malloc_addr);
+ vq->vq_descx[desc_idx].malloc_addr = NULL;
+ }
+
+ return i;
+}
+
+static int
+virtqueue_crypto_sym_pkt_header_arrange(
+ struct rte_crypto_op *cop,
+ struct virtio_crypto_op_data_req *data,
+ struct virtio_crypto_session *session)
+{
+ struct rte_crypto_sym_op *sym_op = cop->sym;
+ struct virtio_crypto_op_data_req *req_data = data;
+ struct virtio_crypto_op_ctrl_req *ctrl = &session->ctrl;
+ struct virtio_crypto_cipher_session_para *para;
+
+ req_data->header.session_id = session->session_id;
+
+ switch (ctrl->u.sym_create_session.op_type) {
+ case VIRTIO_CRYPTO_SYM_OP_CIPHER:
+ req_data->u.sym_req.op_type = VIRTIO_CRYPTO_SYM_OP_CIPHER;
+
+ para = &ctrl->u.sym_create_session.u.cipher.para;
+ if (para->op == VIRTIO_CRYPTO_OP_ENCRYPT)
+ req_data->header.opcode = VIRTIO_CRYPTO_CIPHER_ENCRYPT;
+ else
+ req_data->header.opcode = VIRTIO_CRYPTO_CIPHER_DECRYPT;
+
+ req_data->u.sym_req.u.cipher.para.iv_len
+ = session->iv.length;
+
+ req_data->u.sym_req.u.cipher.para.src_data_len =
+ (sym_op->cipher.data.length + sym_op->cipher.data.offset);
+ req_data->u.sym_req.u.cipher.para.dst_data_len =
+ req_data->u.sym_req.u.cipher.para.src_data_len;
+ break;
+ case VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING:
+ req_data->u.sym_req.op_type = VIRTIO_CRYPTO_SYM_OP_ALGORITHM_CHAINING;
+
+ para = &ctrl->u.sym_create_session.u.chain.para.cipher_param;
+ if (para->op == VIRTIO_CRYPTO_OP_ENCRYPT)
+ req_data->header.opcode = VIRTIO_CRYPTO_CIPHER_ENCRYPT;
+ else
+ req_data->header.opcode = VIRTIO_CRYPTO_CIPHER_DECRYPT;
+
+ req_data->u.sym_req.u.chain.para.iv_len = session->iv.length;
+ req_data->u.sym_req.u.chain.para.aad_len = session->aad.length;
+
+ req_data->u.sym_req.u.chain.para.src_data_len =
+ (sym_op->cipher.data.length + sym_op->cipher.data.offset);
+ req_data->u.sym_req.u.chain.para.dst_data_len =
+ req_data->u.sym_req.u.chain.para.src_data_len;
+ req_data->u.sym_req.u.chain.para.cipher_start_src_offset =
+ sym_op->cipher.data.offset;
+ req_data->u.sym_req.u.chain.para.len_to_cipher =
+ sym_op->cipher.data.length;
+ req_data->u.sym_req.u.chain.para.hash_start_src_offset =
+ sym_op->auth.data.offset;
+ req_data->u.sym_req.u.chain.para.len_to_hash =
+ sym_op->auth.data.length;
+ req_data->u.sym_req.u.chain.para.aad_len =
+ ctrl->u.sym_create_session.u.chain.para.aad_len;
+
+ if (ctrl->u.sym_create_session.u.chain.para.hash_mode ==
+ VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN)
+ req_data->u.sym_req.u.chain.para.hash_result_len =
+ ctrl->u.sym_create_session.u.chain.para.u.hash_param.
+ hash_result_len;
+ if (ctrl->u.sym_create_session.u.chain.para.hash_mode ==
+ VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH)
+ req_data->u.sym_req.u.chain.para.hash_result_len =
+ ctrl->u.sym_create_session.u.chain.para.u.mac_param.
+ hash_result_len;
+ break;
+ default:
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+virtqueue_crypto_sym_enqueue_xmit(
+ struct virtqueue *txvq,
+ struct rte_crypto_op *cop)
+{
+ uint16_t idx = 0;
+ uint16_t num_entry;
+ uint16_t needed = 1;
+ uint16_t head_idx;
+ struct vq_desc_extra *dxp;
+ struct vring_desc *start_dp;
+ struct vring_desc *desc;
+ uint8_t *malloc_addr;
+ uint64_t malloc_phys_addr;
+ uint16_t req_data_len = sizeof(struct virtio_crypto_op_data_req);
+ uint32_t indirect_vring_addr_offset = req_data_len +
+ sizeof(struct virtio_crypto_inhdr);
+ struct rte_crypto_sym_op *sym_op = cop->sym;
+ struct virtio_crypto_session *session =
+ (struct virtio_crypto_session *)get_session_private_data(
+ cop->sym->session, cryptodev_virtio_driver_id);
+ struct virtio_crypto_op_data_req *op_data_req;
+ uint32_t hash_result_len = 0;
+
+ if (unlikely(sym_op->m_src->nb_segs != 1))
+ return -EMSGSIZE;
+ if (unlikely(txvq->vq_free_cnt == 0))
+ return -ENOSPC;
+ if (unlikely(txvq->vq_free_cnt < needed))
+ return -EMSGSIZE;
+ head_idx = txvq->vq_desc_head_idx;
+ if (unlikely(head_idx >= txvq->vq_nentries))
+ return -EFAULT;
+ if (unlikely(session == NULL))
+ return -EFAULT;
+
+ /*
+ * malloc memory to store virtio_crypto_op_data_req, status returned
+ * and indirect vring entries
+ */
+ malloc_addr = rte_malloc(NULL, req_data_len + sizeof(struct virtio_crypto_inhdr)
+ + NUM_ENTRY_VIRTIO_CRYPTO_TX * sizeof(struct vring_desc),
+ RTE_CACHE_LINE_SIZE);
+ if (malloc_addr == NULL) {
+ PMD_TX_LOG(ERR, "not enough heap room");
+ return -ENOSPC;
+ }
+ op_data_req = (struct virtio_crypto_op_data_req *)malloc_addr;
+ malloc_phys_addr = rte_malloc_virt2phy(malloc_addr);
+
+ if (virtqueue_crypto_sym_pkt_header_arrange(cop, op_data_req, session)) {
+ rte_free(malloc_addr);
+ return -EFAULT;
+ }
+
+ /* status is initialized to VIRTIO_CRYPTO_ERR */
+ ((struct virtio_crypto_inhdr *)
+ ((uint8_t *)malloc_addr + req_data_len))->status =
+ VIRTIO_CRYPTO_ERR;
+
+ /* point to indirect vring entry */
+ desc = (struct vring_desc *)
+ ((uint8_t *)malloc_addr + indirect_vring_addr_offset);
+ for (idx = 0; idx < (NUM_ENTRY_VIRTIO_CRYPTO_TX - 1); idx++)
+ desc[idx].next = idx + 1;
+ desc[NUM_ENTRY_VIRTIO_CRYPTO_TX - 1].next = VQ_RING_DESC_CHAIN_END;
+
+ idx = 0;
+
+ /* indirect vring: first part, virtio_crypto_op_data_req */
+ desc[idx].addr = malloc_phys_addr;
+ desc[idx].len = req_data_len;
+ desc[idx++].flags = VRING_DESC_F_NEXT;
+
+ /* indirect vring: iv of cipher */
+ if (session->iv.length) {
+ desc[idx].addr = cop->phys_addr + session->iv.offset;
+ desc[idx].len = session->iv.length;
+ desc[idx++].flags = VRING_DESC_F_NEXT;
+ }
+
+ /* indirect vring: additional auth data */
+ if (session->aad.length) {
+ desc[idx].addr = session->aad.phys_addr;
+ desc[idx].len = session->aad.length;
+ desc[idx++].flags = VRING_DESC_F_NEXT;
+ }
+
+ /* indirect vring: src data */
+ desc[idx].addr = rte_pktmbuf_mtophys_offset(sym_op->m_src, 0);
+ desc[idx].len = (sym_op->cipher.data.offset
+ + sym_op->cipher.data.length);
+ desc[idx++].flags = VRING_DESC_F_NEXT;
+
+ /* indirect vring: dst data */
+ if (sym_op->m_dst) {
+ desc[idx].addr = rte_pktmbuf_mtophys_offset(sym_op->m_dst, 0);
+ desc[idx].len = (sym_op->cipher.data.offset
+ + sym_op->cipher.data.length);
+ } else {
+ desc[idx].addr = rte_pktmbuf_mtophys_offset(sym_op->m_src, 0);
+ desc[idx].len = (sym_op->cipher.data.offset
+ + sym_op->cipher.data.length);
+ }
+ desc[idx++].flags = VRING_DESC_F_WRITE | VRING_DESC_F_NEXT;
+
+ /* indirect vring: digest result */
+ if (session->ctrl.u.sym_create_session.u.chain.para.hash_mode ==
+ VIRTIO_CRYPTO_SYM_HASH_MODE_PLAIN)
+ hash_result_len =
+ session->ctrl.u.sym_create_session.u.chain.para.u.hash_param.
+ hash_result_len;
+ if (session->ctrl.u.sym_create_session.u.chain.para.hash_mode ==
+ VIRTIO_CRYPTO_SYM_HASH_MODE_AUTH)
+ hash_result_len =
+ session->ctrl.u.sym_create_session.u.chain.para.u.mac_param.
+ hash_result_len;
+ if (hash_result_len > 0) {
+ desc[idx].addr = sym_op->auth.digest.phys_addr;
+ desc[idx].len = hash_result_len;
+ desc[idx++].flags = VRING_DESC_F_WRITE | VRING_DESC_F_NEXT;
+ }
+
+ /* indirect vring: last part, status returned */
+ desc[idx].addr = malloc_phys_addr + req_data_len;
+ desc[idx].len = sizeof(struct virtio_crypto_inhdr);
+ desc[idx++].flags = VRING_DESC_F_WRITE;
+
+ num_entry = idx;
+
+ /* save the infos to use when receiving packets */
+ dxp = &txvq->vq_descx[head_idx];
+ dxp->crypto_op = (void *)cop;
+ dxp->malloc_addr = malloc_addr;
+ dxp->ndescs = needed;
+
+ /* use a single buffer */
+ start_dp = txvq->vq_ring.desc;
+ start_dp[head_idx].addr = malloc_phys_addr + indirect_vring_addr_offset;
+ start_dp[head_idx].len = num_entry * sizeof(struct vring_desc);
+ start_dp[head_idx].flags = VRING_DESC_F_INDIRECT;
+
+ idx = start_dp[head_idx].next;
+ txvq->vq_desc_head_idx = idx;
+ if (txvq->vq_desc_head_idx == VQ_RING_DESC_CHAIN_END)
+ txvq->vq_desc_tail_idx = idx;
+ txvq->vq_free_cnt = (uint16_t)(txvq->vq_free_cnt - needed);
+ vq_crypto_update_avail_ring(txvq, head_idx);
+
+ return 0;
+}
+
+static int
+virtqueue_crypto_enqueue_xmit(struct virtqueue *txvq,
+ struct rte_crypto_op *cop)
+{
+ int ret;
+
+ switch (cop->type) {
+ case RTE_CRYPTO_OP_TYPE_SYMMETRIC:
+ ret = virtqueue_crypto_sym_enqueue_xmit(txvq, cop);
+ break;
+ default:
+ PMD_TX_LOG(ERR, "invalid crypto op type %u", cop->type);
+ ret = -EFAULT;
+ break;
+ }
+
+ return ret;
+}
+
+static int
+virtio_crypto_vring_start(struct virtqueue *vq)
+{
+ struct virtio_crypto_hw *hw = vq->hw;
+ int i, size = vq->vq_nentries;
+ struct vring *vr = &vq->vq_ring;
+ uint8_t *ring_mem = vq->vq_ring_virt_mem;
+
+ PMD_INIT_FUNC_TRACE();
+
+ vring_crypto_init(vr, size, ring_mem, VIRTIO_PCI_VRING_ALIGN);
+ vq->vq_desc_tail_idx = (uint16_t)(vq->vq_nentries - 1);
+ vq->vq_free_cnt = vq->vq_nentries;
+
+ /* Chain all the descriptors in the ring with an END */
+ for (i = 0; i < size - 1; i++)
+ vr->desc[i].next = (uint16_t)(i + 1);
+ vr->desc[i].next = VQ_RING_DESC_CHAIN_END;
+
+ /*
+ * Disable device(host) interrupting guest
+ */
+ virtqueue_crypto_disable_intr(vq);
+
+ /*
+ * Set guest physical address of the virtqueue
+ * in VIRTIO_PCI_QUEUE_PFN config register of device
+ * to share with the backend
+ */
+ if (VTPCI_OPS(hw)->setup_queue(hw, vq) < 0) {
+ PMD_INIT_LOG(ERR, "setup_queue failed");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+void
+virtio_crypto_cq_start(struct rte_cryptodev *dev)
+{
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ if (hw->cvq) {
+ virtio_crypto_vring_start(hw->cvq);
+ VIRTQUEUE_DUMP((struct virtqueue *)hw->cvq);
+ }
+}
+
+void
+virtio_crypto_dq_start(struct rte_cryptodev *dev)
+{
+ /*
+ * Start data vrings
+ * - Setup vring structure for data queues
+ */
+ uint32_t i;
+ struct virtio_crypto_hw *hw = dev->data->dev_private;
+
+ PMD_INIT_FUNC_TRACE();
+
+ /* Start data vring. */
+ for (i = 0; i < hw->max_dataqueues; i++) {
+ virtio_crypto_vring_start(dev->data->queue_pairs[i]);
+ VIRTQUEUE_DUMP((struct virtqueue *)dev->data->queue_pairs[i]);
+ }
+}
+
+/* vring size of data queue is 1024 */
+#define VIRTIO_MBUF_BURST_SZ 1024
+
+uint16_t
+virtio_crypto_pkt_rx_burst(void *tx_queue, struct rte_crypto_op **rx_pkts,
+ uint16_t nb_pkts)
+{
+ struct virtqueue *txvq = tx_queue;
+ uint16_t nb_used, num, nb_rx;
+
+ nb_used = VIRTQUEUE_NUSED(txvq);
+
+ virtio_rmb();
+
+ num = (uint16_t)(likely(nb_used <= nb_pkts) ? nb_used : nb_pkts);
+ num = (uint16_t)(likely(num <= VIRTIO_MBUF_BURST_SZ)
+ ? num : VIRTIO_MBUF_BURST_SZ);
+
+ if (num == 0)
+ return 0;
+
+ nb_rx = virtqueue_crypto_dequeue_burst_rx(txvq, rx_pkts, num);
+ PMD_RX_LOG(DEBUG, "used:%d dequeue:%d", nb_used, num);
+
+ return nb_rx;
+}
+
+uint16_t
+virtio_crypto_pkt_tx_burst(void *tx_queue, struct rte_crypto_op **tx_pkts,
+ uint16_t nb_pkts)
+{
+ struct virtqueue *txvq;
+ uint16_t nb_tx;
+ int error;
+
+ if (unlikely(nb_pkts < 1))
+ return nb_pkts;
+ if (unlikely(tx_queue == NULL)) {
+ PMD_TX_LOG(ERR, "tx_queue is NULL");
+ return 0;
+ }
+ txvq = tx_queue;
+
+ PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts);
+
+ for (nb_tx = 0; nb_tx < nb_pkts; nb_tx++) {
+ struct rte_mbuf *txm = tx_pkts[nb_tx]->sym->m_src;
+ /* nb_segs is always 1 at virtio crypto situation */
+ int need = txm->nb_segs - txvq->vq_free_cnt;
+
+ /*
+ * Positive value indicates it hasn't enough space in vring
+ * descriptors
+ */
+ if (unlikely(need > 0)) {
+ /*
+ * try it again because the receive process may be
+ * free some space
+ */
+ need = txm->nb_segs - txvq->vq_free_cnt;
+ if (unlikely(need > 0)) {
+ PMD_TX_LOG(ERR, "No free tx descriptors "
+ "to transmit");
+ break;
+ }
+ }
+
+ txvq->packets_sent_total++;
+
+ /* Enqueue Packet buffers */
+ error = virtqueue_crypto_enqueue_xmit(txvq, tx_pkts[nb_tx]);
+ if (unlikely(error)) {
+ if (error == ENOSPC)
+ PMD_TX_LOG(ERR,
+ "virtqueue_enqueue Free count = 0");
+ else if (error == EMSGSIZE)
+ PMD_TX_LOG(ERR,
+ "virtqueue_enqueue Free count < 1");
+ else
+ PMD_TX_LOG(ERR,
+ "virtqueue_enqueue error: %d", error);
+ txvq->packets_sent_failed++;
+ break;
+ }
+ }
+
+ if (likely(nb_tx)) {
+ vq_crypto_update_avail_idx(txvq);
+
+ if (unlikely(virtqueue_crypto_kick_prepare(txvq))) {
+ virtqueue_crypto_notify(txvq);
+ PMD_TX_LOG(DEBUG, "Notified backend after xmit");
+ }
+ }
+
+ return nb_tx;
+}
diff --git a/drivers/crypto/virtio/virtqueue.c b/drivers/crypto/virtio/virtqueue.c
new file mode 100644
index 0000000..be3a5a6
--- /dev/null
+++ b/drivers/crypto/virtio/virtqueue.c
@@ -0,0 +1,80 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <stdint.h>
+
+#include <rte_mbuf.h>
+#include <rte_crypto.h>
+#include <rte_malloc.h>
+
+#include "virtqueue.h"
+#include "virtio_logs.h"
+#include "virtio_pci.h"
+
+void
+virtqueue_crypto_disable_intr(struct virtqueue *vq)
+{
+ /*
+ * Set VRING_AVAIL_F_NO_INTERRUPT to hint host
+ * not to interrupt when it consumes packets
+ * Note: this is only considered a hint to the host
+ */
+ vq->vq_ring.avail->flags |= VRING_AVAIL_F_NO_INTERRUPT;
+}
+
+void
+virtqueue_crypto_detatch_unused(struct virtqueue *vq)
+{
+ struct rte_crypto_op *cop = NULL;
+ uint8_t *malloc_addr = NULL;
+
+ int idx;
+
+ if (vq != NULL)
+ for (idx = 0; idx < vq->vq_nentries; idx++) {
+ cop = vq->vq_descx[idx].crypto_op;
+ if (cop) {
+ if (cop->sym->m_src)
+ rte_pktmbuf_free(cop->sym->m_src);
+ if (cop->sym->m_dst)
+ rte_pktmbuf_free(cop->sym->m_dst);
+ rte_crypto_op_free(cop);
+ vq->vq_descx[idx].crypto_op = NULL;
+ }
+
+ malloc_addr = vq->vq_descx[idx].malloc_addr;
+ if (malloc_addr) {
+ rte_free(malloc_addr);
+ vq->vq_descx[idx].malloc_addr = NULL;
+ }
+ }
+}
diff --git a/drivers/crypto/virtio/virtqueue.h b/drivers/crypto/virtio/virtqueue.h
new file mode 100644
index 0000000..d666c3a
--- /dev/null
+++ b/drivers/crypto/virtio/virtqueue.h
@@ -0,0 +1,208 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2017 HUAWEI TECHNOLOGIES CO., LTD. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of HUAWEI TECHNOLOGIES CO., LTD nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef _VIRTQUEUE_H_
+#define _VIRTQUEUE_H_
+
+#include <stdint.h>
+
+#include <rte_atomic.h>
+#include <rte_memory.h>
+#include <rte_memzone.h>
+#include <rte_mempool.h>
+
+#include "virtio_pci.h"
+#include "virtio_ring.h"
+#include "virtio_logs.h"
+#include "virtio_crypto.h"
+
+struct rte_mbuf;
+
+/*
+ * Per virtio_config.h in Linux.
+ * For virtio_pci on SMP, we don't need to order with respect to MMIO
+ * accesses through relaxed memory I/O windows, so smp_mb() et al are
+ * sufficient.
+ *
+ */
+#define virtio_mb() rte_smp_mb()
+#define virtio_rmb() rte_smp_rmb()
+#define virtio_wmb() rte_smp_wmb()
+
+#define VIRTQUEUE_MAX_NAME_SZ 32
+
+enum { VTCRYPTO_DATAQ = 0, VTCRYPTO_CTRLQ = 1 };
+
+/**
+ * The maximum virtqueue size is 2^15. Use that value as the end of
+ * descriptor chain terminator since it will never be a valid index
+ * in the descriptor table. This is used to verify we are correctly
+ * handling vq_free_cnt.
+ */
+#define VQ_RING_DESC_CHAIN_END 32768
+
+struct virtqueue {
+ /**< virtio_crypto_hw structure pointer. */
+ struct virtio_crypto_hw *hw;
+ /**< mem zone to populate RX ring. */
+ const struct rte_memzone *mz;
+ /**< memzone to populate hdr. */
+ struct rte_mempool *mpool;
+ uint8_t dev_id; /**< Device identifier. */
+ uint16_t vq_queue_index; /**< PCI queue index */
+
+ void *vq_ring_virt_mem; /**< linear address of vring*/
+ unsigned int vq_ring_size;
+ phys_addr_t vq_ring_mem; /**< physical address of vring */
+
+ struct vring vq_ring; /**< vring keeping desc, used and avail */
+ uint16_t vq_free_cnt; /**< num of desc available */
+ uint16_t vq_nentries; /**< vring desc numbers */
+ uint16_t vq_free_thresh; /**< free threshold */
+ /**
+ * Head of the free chain in the descriptor table. If
+ * there are no free descriptors, this will be set to
+ * VQ_RING_DESC_CHAIN_END.
+ */
+ uint16_t vq_desc_head_idx;
+ uint16_t vq_desc_tail_idx;
+ /**
+ * Last consumed descriptor in the used table,
+ * trails vq_ring.used->idx.
+ */
+ uint16_t vq_used_cons_idx;
+ uint16_t vq_avail_idx;
+
+ /* Statistics */
+ uint64_t packets_sent_total;
+ uint64_t packets_sent_failed;
+ uint64_t packets_received_total;
+ uint64_t packets_received_failed;
+
+ uint16_t *notify_addr;
+
+ struct vq_desc_extra {
+ void *crypto_op;
+ uint8_t *malloc_addr;
+ uint16_t ndescs;
+ } vq_descx[0];
+};
+
+/* If multiqueue is provided by host, then we suppport it. */
+#define VIRTIO_CRYPTO_CTRL_MQ 4
+#define VIRTIO_CRYPTO_CTRL_MQ_VQ_PAIRS_SET 0
+#define VIRTIO_CRYPTO_CTRL_MQ_VQ_PAIRS_MIN 1
+#define VIRTIO_CRYPTO_CTRL_MQ_VQ_PAIRS_MAX 0x8000
+
+/**
+ * Tell the backend not to interrupt us.
+ */
+void virtqueue_crypto_disable_intr(struct virtqueue *vq);
+/**
+ * Dump virtqueue internal structures, for debug purpose only.
+ */
+void virtqueue_crypto_dump(struct virtqueue *vq);
+/**
+ * Get all mbufs to be freed.
+ */
+void virtqueue_crypto_detatch_unused(struct virtqueue *vq);
+
+static inline int
+virtqueue_crypto_full(const struct virtqueue *vq)
+{
+ return vq->vq_free_cnt == 0;
+}
+
+#define VIRTQUEUE_NUSED(vq) \
+ ((uint16_t)((vq)->vq_ring.used->idx - (vq)->vq_used_cons_idx))
+
+static inline void
+vq_crypto_update_avail_idx(struct virtqueue *vq)
+{
+ virtio_wmb();
+ vq->vq_ring.avail->idx = vq->vq_avail_idx;
+}
+
+static inline void
+vq_crypto_update_avail_ring(struct virtqueue *vq, uint16_t desc_idx)
+{
+ uint16_t avail_idx;
+ /*
+ * Place the head of the descriptor chain into the next slot and make
+ * it usable to the host. The chain is made available now rather than
+ * deferring to virtqueue_notify() in the hopes that if the host is
+ * currently running on another CPU, we can keep it processing the new
+ * descriptor.
+ */
+ avail_idx = (uint16_t)(vq->vq_avail_idx & (vq->vq_nentries - 1));
+ vq->vq_ring.avail->ring[avail_idx] = desc_idx;
+ vq->vq_avail_idx++;
+}
+
+static inline int
+virtqueue_crypto_kick_prepare(struct virtqueue *vq)
+{
+ return !(vq->vq_ring.used->flags & VRING_USED_F_NO_NOTIFY);
+}
+
+static inline void
+virtqueue_crypto_notify(struct virtqueue *vq)
+{
+ struct virtio_crypto_hw *hw = vq->hw;
+ /*
+ * Ensure updated avail->idx is visible to host.
+ * For virtio on IA, the notificaiton is through io port operation
+ * which is a serialization instruction itself.
+ */
+ VTPCI_OPS(hw)->notify_queue(hw, vq);
+}
+
+#ifdef RTE_LIBRTE_PMD_VIRTIO_CRYPTO_DEBUG_DUMP
+#define VIRTQUEUE_DUMP(vq) do { \
+ uint16_t used_idx, nused; \
+ used_idx = (vq)->vq_ring.used->idx; \
+ nused = (uint16_t)(used_idx - (vq)->vq_used_cons_idx); \
+ PMD_INIT_LOG(DEBUG, \
+ "VQ: - size=%d; free=%d; used=%d; desc_head_idx=%d;" \
+ " avail.idx=%d; used_cons_idx=%d; used.idx=%d;" \
+ " avail.flags=0x%x; used.flags=0x%x", \
+ (vq)->vq_nentries, (vq)->vq_free_cnt, nused, \
+ (vq)->vq_desc_head_idx, (vq)->vq_ring.avail->idx, \
+ (vq)->vq_used_cons_idx, (vq)->vq_ring.used->idx, \
+ (vq)->vq_ring.avail->flags, (vq)->vq_ring.used->flags); \
+} while (0)
+#else
+#define VIRTQUEUE_DUMP(vq) do { } while (0)
+#endif
+
+#endif /* _VIRTQUEUE_H_ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 047121d..56d7c51 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -169,6 +169,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH)
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_OPENSSL) += -lrte_pmd_openssl -lcrypto
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat -lcrypto
+_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO) += -lrte_pmd_virtio_crypto -lcrypto
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_SNOW3G_PATH)/build -lsso_snow3g
_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_KASUMI) += -lrte_pmd_kasumi
diff --git a/test/test/test_cryptodev.c b/test/test/test_cryptodev.c
index 72988c5..2d03d32 100644
--- a/test/test/test_cryptodev.c
+++ b/test/test/test_cryptodev.c
@@ -1790,6 +1790,25 @@ struct crypto_unittest_params {
}
static int
+test_AES_cipheronly_virtio_all(void)
+{
+ struct crypto_testsuite_params *ts_params = &testsuite_params;
+ int status;
+
+ status = test_blockcipher_all_tests(ts_params->mbuf_pool,
+ ts_params->op_mpool,
+ ts_params->session_mpool,
+ ts_params->valid_devs[0],
+ rte_cryptodev_driver_id_get(
+ RTE_STR(CRYPTODEV_NAME_VIRTIO_SYM_PMD)),
+ BLKCIPHER_AES_CIPHERONLY_TYPE);
+
+ TEST_ASSERT_EQUAL(status, 0, "Test failed");
+
+ return TEST_SUCCESS;
+}
+
+static int
test_AES_chain_dpaa_sec_all(void)
{
struct crypto_testsuite_params *ts_params = &testsuite_params;
@@ -8732,6 +8751,18 @@ struct test_crypto_vector {
}
};
+static struct unit_test_suite cryptodev_virtio_testsuite = {
+ .suite_name = "Crypto VIRTIO Unit Test Suite",
+ .setup = testsuite_setup,
+ .teardown = testsuite_teardown,
+ .unit_test_cases = {
+ TEST_CASE_ST(ut_setup, ut_teardown,
+ test_AES_cipheronly_virtio_all),
+
+ TEST_CASES_END() /**< NULL terminate unit test array */
+ }
+};
+
static struct unit_test_suite cryptodev_aesni_mb_testsuite = {
.suite_name = "Crypto Device AESNI MB Unit Test Suite",
.setup = testsuite_setup,
@@ -9597,6 +9628,23 @@ struct test_crypto_vector {
}
static int
+test_cryptodev_virtio(void /*argv __rte_unused, int argc __rte_unused*/)
+{
+ gbl_driver_id = rte_cryptodev_driver_id_get(
+ RTE_STR(CRYPTODEV_NAME_VIRTIO_SYM_PMD));
+
+ if (gbl_driver_id == -1) {
+ RTE_LOG(ERR, USER1, "VIRTIO PMD must be loaded. Check if "
+ "CONFIG_RTE_LIBRTE_PMD_VIRTIO_CRYPTO is enabled "
+ "in config file to run this testsuite.\n");
+ return TEST_FAILED;
+ }
+
+ return unit_test_suite_runner(&cryptodev_virtio_testsuite);
+}
+
+
+static int
test_cryptodev_aesni_mb(void /*argv __rte_unused, int argc __rte_unused*/)
{
gbl_driver_id = rte_cryptodev_driver_id_get(
@@ -9812,3 +9860,4 @@ struct test_crypto_vector {
REGISTER_TEST_COMMAND(cryptodev_sw_mrvl_autotest, test_cryptodev_mrvl);
REGISTER_TEST_COMMAND(cryptodev_dpaa2_sec_autotest, test_cryptodev_dpaa2_sec);
REGISTER_TEST_COMMAND(cryptodev_dpaa_sec_autotest, test_cryptodev_dpaa_sec);
+REGISTER_TEST_COMMAND(cryptodev_virtio_autotest, test_cryptodev_virtio);
diff --git a/test/test/test_cryptodev.h b/test/test/test_cryptodev.h
index 2e9eb0b..3ca9918 100644
--- a/test/test/test_cryptodev.h
+++ b/test/test/test_cryptodev.h
@@ -89,6 +89,7 @@
#define CRYPTODEV_NAME_DPAA2_SEC_PMD crypto_dpaa2_sec
#define CRYPTODEV_NAME_SCHEDULER_PMD crypto_scheduler
#define CRYPTODEV_NAME_MRVL_PMD crypto_mrvl
+#define CRYPTODEV_NAME_VIRTIO_SYM_PMD crypto_virtio
/**
* Write (spread) data from buffer to mbuf data
diff --git a/test/test/test_cryptodev_aes_test_vectors.h b/test/test/test_cryptodev_aes_test_vectors.h
index 9c13041..e07ca8c 100644
--- a/test/test/test_cryptodev_aes_test_vectors.h
+++ b/test/test/test_cryptodev_aes_test_vectors.h
@@ -1277,7 +1277,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_MRVL
+ BLOCKCIPHER_TEST_TARGET_PMD_MRVL |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-128-CBC HMAC-SHA1 Encryption Digest "
@@ -1541,7 +1542,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_MRVL
+ BLOCKCIPHER_TEST_TARGET_PMD_MRVL |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-128-CBC Decryption",
@@ -1553,7 +1555,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_MRVL
+ BLOCKCIPHER_TEST_TARGET_PMD_MRVL |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-192-CBC Encryption",
@@ -1564,7 +1567,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_MB |
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC
+ BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-192-CBC Encryption Scater gather",
@@ -1583,7 +1587,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_MB |
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC
+ BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-256-CBC Encryption",
@@ -1595,7 +1600,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_MRVL
+ BLOCKCIPHER_TEST_TARGET_PMD_MRVL |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-256-CBC Decryption",
@@ -1607,7 +1613,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_MRVL
+ BLOCKCIPHER_TEST_TARGET_PMD_MRVL |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-256-CBC OOP Encryption",
@@ -1617,7 +1624,8 @@
.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
BLOCKCIPHER_TEST_TARGET_PMD_QAT |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC
+ BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-256-CBC OOP Decryption",
@@ -1627,7 +1635,8 @@
.pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_OPENSSL |
BLOCKCIPHER_TEST_TARGET_PMD_QAT |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC
+ BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-128-CTR Encryption",
@@ -1639,7 +1648,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_MRVL
+ BLOCKCIPHER_TEST_TARGET_PMD_MRVL |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-128-CTR Decryption",
@@ -1651,7 +1661,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_MRVL
+ BLOCKCIPHER_TEST_TARGET_PMD_MRVL |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-192-CTR Encryption",
@@ -1662,7 +1673,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_MB |
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC
+ BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-192-CTR Decryption",
@@ -1673,7 +1685,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_MB |
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC
+ BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-256-CTR Encryption",
@@ -1685,7 +1698,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_MRVL
+ BLOCKCIPHER_TEST_TARGET_PMD_MRVL |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-256-CTR Decryption",
@@ -1697,7 +1711,8 @@
BLOCKCIPHER_TEST_TARGET_PMD_SCHEDULER |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC |
BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC |
- BLOCKCIPHER_TEST_TARGET_PMD_MRVL
+ BLOCKCIPHER_TEST_TARGET_PMD_MRVL |
+ BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO
},
{
.test_descr = "AES-128-CTR Encryption (12-byte IV)",
diff --git a/test/test/test_cryptodev_blockcipher.c b/test/test/test_cryptodev_blockcipher.c
index 9a9fd8b..195180f 100644
--- a/test/test/test_cryptodev_blockcipher.c
+++ b/test/test/test_cryptodev_blockcipher.c
@@ -96,6 +96,8 @@
RTE_STR(CRYPTODEV_NAME_DPAA_SEC_PMD));
int mrvl_pmd = rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_MRVL_PMD));
+ int virtio_pmd = rte_cryptodev_driver_id_get(
+ RTE_STR(CRYPTODEV_NAME_VIRTIO_SYM_PMD));
int nb_segs = 1;
@@ -122,7 +124,8 @@
driver_id == qat_pmd ||
driver_id == openssl_pmd ||
driver_id == armv8_pmd ||
- driver_id == mrvl_pmd) { /* Fall through */
+ driver_id == mrvl_pmd ||
+ driver_id == virtio_pmd) { /* Fall through */
digest_len = tdata->digest.len;
} else if (driver_id == aesni_mb_pmd ||
driver_id == scheduler_pmd) {
@@ -597,6 +600,8 @@
RTE_STR(CRYPTODEV_NAME_QAT_SYM_PMD));
int mrvl_pmd = rte_cryptodev_driver_id_get(
RTE_STR(CRYPTODEV_NAME_MRVL_PMD));
+ int virtio_pmd = rte_cryptodev_driver_id_get(
+ RTE_STR(CRYPTODEV_NAME_VIRTIO_SYM_PMD));
switch (test_type) {
case BLKCIPHER_AES_CHAIN_TYPE:
@@ -659,6 +664,8 @@
target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC;
else if (driver_id == mrvl_pmd)
target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_MRVL;
+ else if (driver_id == virtio_pmd)
+ target_pmd_mask = BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO;
else
TEST_ASSERT(0, "Unrecognized cryptodev type");
diff --git a/test/test/test_cryptodev_blockcipher.h b/test/test/test_cryptodev_blockcipher.h
index 67c78d4..fadb81d 100644
--- a/test/test/test_cryptodev_blockcipher.h
+++ b/test/test/test_cryptodev_blockcipher.h
@@ -55,6 +55,7 @@
#define BLOCKCIPHER_TEST_TARGET_PMD_DPAA2_SEC 0x0020 /* DPAA2_SEC flag */
#define BLOCKCIPHER_TEST_TARGET_PMD_DPAA_SEC 0x0040 /* DPAA_SEC flag */
#define BLOCKCIPHER_TEST_TARGET_PMD_MRVL 0x0080 /* Marvell flag */
+#define BLOCKCIPHER_TEST_TARGET_PMD_VIRTIO 0x0100 /* VIRTIO flag */
#define BLOCKCIPHER_TEST_OP_CIPHER (BLOCKCIPHER_TEST_OP_ENCRYPT | \
BLOCKCIPHER_TEST_OP_DECRYPT)
--
1.8.3.1
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [PATCH v1] doc: add template release notes for 18.02
@ 2017-11-17 22:41 6% John McNamara
2017-11-22 17:38 6% ` [dpdk-dev] [PATCH v2] " John McNamara
0 siblings, 1 reply; 200+ results
From: John McNamara @ 2017-11-17 22:41 UTC (permalink / raw)
To: dev; +Cc: John McNamara
Add template release notes for DPDK 18.02 with inline
comments and explanations of the various sections.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
doc/guides/rel_notes/release_18_02.rst | 214 +++++++++++++++++++++++++++++++++
1 file changed, 214 insertions(+)
create mode 100644 doc/guides/rel_notes/release_18_02.rst
diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst
new file mode 100644
index 0000000..8a513b8
--- /dev/null
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -0,0 +1,214 @@
+DPDK Release 18.02
+==================
+
+.. **Read this first.**
+
+ The text in the sections below explains how to update the release notes.
+
+ Use proper spelling, capitalization and punctuation in all sections.
+
+ Variable and config names should be quoted as fixed width text:
+ ``LIKE_THIS``.
+
+ Build the docs and view the output file to ensure the changes are correct::
+
+ make doc-guides-html
+
+ xdg-open build/doc/html/guides/rel_notes/release_18_02.html
+
+
+New Features
+------------
+
+.. This section should contain new features added in this release. Sample
+ format:
+
+ * **Add a title in the past tense with a full stop.**
+
+ Add a short 1-2 sentence description in the past tense. The description
+ should be enough to allow someone scanning the release notes to
+ understand the new feature.
+
+ If the feature adds a lot of sub-features you can use a bullet list like
+ this:
+
+ * Added feature foo to do something.
+ * Enhanced feature bar to do something else.
+
+ Refer to the previous release notes for examples.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Resolved Issues
+---------------
+
+.. This section should contain bug fixes added to the relevant
+ sections. Sample format:
+
+ * **code/section Fixed issue in the past tense with a full stop.**
+
+ Add a short 1-2 sentence description of the resolved issue in the past
+ tense.
+
+ The title should contain the code/lib section like a commit message.
+
+ Add the entries in alphabetic order in the relevant sections below.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+EAL
+~~~
+
+
+Drivers
+~~~~~~~
+
+
+Libraries
+~~~~~~~~~
+
+
+Examples
+~~~~~~~~
+
+
+Other
+~~~~~
+
+
+Known Issues
+------------
+
+.. This section should contain new known issues in this release. Sample format:
+
+ * **Add title in present tense with full stop.**
+
+ Add a short 1-2 sentence description of the known issue in the present
+ tense. Add information on any known workarounds.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+ * Add a short 1-2 sentence description of the API change. Use fixed width
+ quotes for ``rte_function_names`` or ``rte_struct_names``. Use the past
+ tense.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+ * Add a short 1-2 sentence description of the ABI change that was announced
+ in the previous releases and made in this release. Use fixed width quotes
+ for ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+
+Shared Library Versions
+-----------------------
+
+.. Update any library version updated in this release and prepend with a ``+``
+ sign, like this:
+
+ librte_acl.so.2
+ + librte_cfgfile.so.2
+ librte_cmdline.so.2
+
+ This section is a comment. do not overwrite or remove it.
+ =========================================================
+
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+ librte_acl.so.2
+ librte_bitratestats.so.2
+ librte_bus_dpaa.so.1
+ librte_bus_fslmc.so.1
+ librte_bus_pci.so.1
+ librte_bus_vdev.so.1
+ librte_cfgfile.so.2
+ librte_cmdline.so.2
+ librte_cryptodev.so.4
+ librte_distributor.so.1
+ librte_eal.so.6
+ librte_ethdev.so.8
+ librte_eventdev.so.3
+ librte_flow_classify.so.1
+ librte_gro.so.1
+ librte_gso.so.1
+ librte_hash.so.2
+ librte_ip_frag.so.1
+ librte_jobstats.so.1
+ librte_kni.so.2
+ librte_kvargs.so.1
+ librte_latencystats.so.1
+ librte_lpm.so.2
+ librte_mbuf.so.3
+ librte_mempool.so.3
+ librte_meter.so.1
+ librte_metrics.so.1
+ librte_net.so.1
+ librte_pci.so.1
+ librte_pdump.so.2
+ librte_pipeline.so.3
+ librte_pmd_bnxt.so.2
+ librte_pmd_bond.so.2
+ librte_pmd_i40e.so.2
+ librte_pmd_ixgbe.so.2
+ librte_pmd_ring.so.2
+ librte_pmd_softnic.so.1
+ librte_pmd_vhost.so.2
+ librte_port.so.3
+ librte_power.so.1
+ librte_reorder.so.1
+ librte_ring.so.1
+ librte_sched.so.1
+ librte_security.so.1
+ librte_table.so.3
+ librte_timer.so.1
+ librte_vhost.so.3
+
+
+
+Tested Platforms
+----------------
+
+.. This section should contain a list of platforms that were tested with this
+ release.
+
+ The format is:
+
+ * <vendor> platform with <vendor> <type of devices> combinations
+
+ * List of CPU
+ * List of OS
+ * List of devices
+ * Other relevant details...
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
--
2.7.5
^ permalink raw reply [relevance 6%]
* [dpdk-dev] [PATCH 0/2] ethdev: add GENEVE to flow API
@ 2017-11-20 8:21 3% Andrew Rybchenko
` (3 more replies)
0 siblings, 4 replies; 200+ results
From: Andrew Rybchenko @ 2017-11-20 8:21 UTC (permalink / raw)
To: dev; +Cc: Adrien Mazarguil, Jingjing Wu
enum rte_flow_item_type states that items matching protocol headers
must be stacked in the same order as the protocol layers to match.
As the result the patch changes ABI since Geneve is added just after
VXLAN (the closest protocol).
In fact as far as I can see many items do not follow the requirement
already. May be the comment/requirement should be removed and GENEVE
should be added at the end of the list. If so, should be keep it just
after VXLAN in all other places or move after ESP as well?
Roman Zhukov (2):
ethdev: add GENEVE flow pattern item
app/testpmd: support GENEVE pattern item in flow rules
app/test-pmd/cmdline_flow.c | 31 +++++++++++++++++++++++++++++
app/test-pmd/config.c | 1 +
doc/guides/prog_guide/rte_flow.rst | 12 +++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 5 +++++
lib/librte_ether/rte_flow.c | 1 +
lib/librte_ether/rte_flow.h | 31 +++++++++++++++++++++++++++++
6 files changed, 81 insertions(+)
--
2.7.4
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 1/2] lib/security: add support for get metadata
@ 2017-11-22 13:27 3% ` Neil Horman
2017-11-22 14:13 0% ` Anoob
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2017-11-22 13:27 UTC (permalink / raw)
To: Anoob Joseph
Cc: Akhil Goyal, Declan Doherty, Radu Nicolau,
Sergio Gonzalez Monroy, Jerin Jacob, Narayana Prasad, dev
On Wed, Nov 22, 2017 at 06:55:15AM +0000, Anoob Joseph wrote:
> In case of inline protocol processed ingress traffic, the packet may not
> have enough information to determine the security parameters with which
> the packet was processed. For such cases, application could register a
> 64 bit metadata in security session, which could be retrieved from the
> packet using "rte_security_get_pkt_metadata" API. Application can use
> this metadata to identify the parameters it need.
>
> Application can choose what it should register as the metadata. It can
> register SPI or a pointer to SA.
>
> Signed-off-by: Anoob Joseph <anoob.joseph@caviumnetworks.com>
> ---
> v2:
> * Replaced get_session and get_cookie APIs with get_pkt_metadata API
>
> lib/librte_security/rte_security.c | 13 +++++++++++++
> lib/librte_security/rte_security.h | 19 +++++++++++++++++++
> lib/librte_security/rte_security_driver.h | 16 ++++++++++++++++
> 3 files changed, 48 insertions(+)
>
> diff --git a/lib/librte_security/rte_security.c b/lib/librte_security/rte_security.c
> index 1227fca..804f11f 100644
> --- a/lib/librte_security/rte_security.c
> +++ b/lib/librte_security/rte_security.c
> @@ -108,6 +108,19 @@ rte_security_set_pkt_metadata(struct rte_security_ctx *instance,
> sess, m, params);
> }
>
> +uint64_t
> +rte_security_get_pkt_metadata(struct rte_security_ctx *instance,
> + struct rte_mbuf *pkt)
> +{
> + uint64_t mdata = 0;
> +
> + RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->get_pkt_metadata, 0);
> + if (instance->ops->get_pkt_metadata(instance->device, pkt, &mdata))
> + return 0;
> +
> + return mdata;
> +}
> +
> const struct rte_security_capability *
> rte_security_capabilities_get(struct rte_security_ctx *instance)
> {
> diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
> index 653929b..aa3a471 100644
> --- a/lib/librte_security/rte_security.h
> +++ b/lib/librte_security/rte_security.h
> @@ -274,6 +274,8 @@ struct rte_security_session_conf {
> /**< Configuration parameters for security session */
> struct rte_crypto_sym_xform *crypto_xform;
> /**< Security Session Crypto Transformations */
> + uint64_t metadata;
> + /**< Metadata registered by application */
This is going to break ABI. You need to announce the change so that application
providers can be prepared for it.
> };
>
> struct rte_security_session {
> @@ -346,6 +348,23 @@ rte_security_set_pkt_metadata(struct rte_security_ctx *instance,
> struct rte_mbuf *mb, void *params);
>
> /**
> + * Get metadata from the packet. This is an application registered 64 bit
> + * value, associated with the security session which processed the packet.
> + *
> + * This is valid only for inline processed ingress packets.
> + *
> + * @param instance security instance
> + * @param pkt packet mbuf
> + *
> + * @return
> + * - On success, metadata
> + * - On failure, 0
> + */
> +uint64_t
> +rte_security_get_pkt_metadata(struct rte_security_ctx *instance,
> + struct rte_mbuf *pkt);
> +
> +/**
> * Attach a session to a symmetric crypto operation
> *
> * @param sym_op crypto operation
> diff --git a/lib/librte_security/rte_security_driver.h b/lib/librte_security/rte_security_driver.h
> index 997fbe7..da0ebf4 100644
> --- a/lib/librte_security/rte_security_driver.h
> +++ b/lib/librte_security/rte_security_driver.h
> @@ -122,6 +122,20 @@ typedef int (*security_set_pkt_metadata_t)(void *device,
> void *params);
>
> /**
> + * Get application interpretable metadata from the packet.
> + *
> + * @param device Crypto/eth device pointer
> + * @param pkt Packet mbuf
> + * @param mt Pointer to receive metadata
> + *
> + * @return
> + * - Returns 0 if metadata is retrieved successfully.
> + * - Returns -ve value for errors.
> + */
> +typedef int (*security_get_pkt_metadata_t)(void *device,
> + struct rte_mbuf *pkt, uint64_t *mt);
> +
> +/**
> * Get security capabilities of the device.
> *
> * @param device crypto/eth device pointer
> @@ -145,6 +159,8 @@ struct rte_security_ops {
> /**< Clear a security sessions private data. */
> security_set_pkt_metadata_t set_pkt_metadata;
> /**< Update mbuf metadata. */
> + security_get_pkt_metadata_t get_pkt_metadata;
> + /**< Get metadata from packet. */
> security_capabilities_get_t capabilities_get;
> /**< Get security capabilities. */
> };
> --
> 2.7.4
>
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 2/3] crypto: fix pedentic compilation errors
@ 2017-11-22 13:56 3% ` Neil Horman
2017-11-22 14:31 0% ` Gaëtan Rivet
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2017-11-22 13:56 UTC (permalink / raw)
To: Nelio Laranjeiro
Cc: Akhil Goyal, Declan Doherty, dev, pablo.de.lara.guarch, stable
On Wed, Nov 22, 2017 at 09:10:17AM +0100, Nelio Laranjeiro wrote:
> /root/dpdk/x86_64-native-linuxapp-gcc/include/rte_crypto.h:126:28: error: ISO C forbids zero-size array ‘sym’ [-Werror=pedantic]
> struct rte_crypto_sym_op sym[0];
> ^~~
>
> Fixes: d2a4223c4c6d ("cryptodev: do not store pointer to op specific params")
> Cc: pablo.de.lara.guarch@intel.com
> Cc: stable@dpdk.org
>
> Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> ---
> lib/librte_cryptodev/rte_crypto.h | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/lib/librte_cryptodev/rte_crypto.h b/lib/librte_cryptodev/rte_crypto.h
> index 3d672fe7d..dc6e91d1d 100644
> --- a/lib/librte_cryptodev/rte_crypto.h
> +++ b/lib/librte_cryptodev/rte_crypto.h
> @@ -123,7 +123,7 @@ struct rte_crypto_op {
>
> RTE_STD_C11
> union {
> - struct rte_crypto_sym_op sym[0];
> + struct rte_crypto_sym_op *sym;
> /**< Symmetric operation parameters */
> }; /**< operation specific parameters */
> };
> --
> 2.11.0
>
>
As Laura notes, this isn't the right solution. In addition to adding a 64 bit
pointer, it I think also results in incorrect semantics. That is to say, the
allocation path for this structure allocates the rte_crypto_op and additional
memory for the sym array contiguously, which the sym[0] syntax correctly
interprets to mean the storage for the array is inline with the structure.
Changing to a pointer means you are using the first elements of the array
storage as your pointer, which could be filled with any old value, leading to
corruption.
If you can't use zero length array semantics (which I assume you cant, as I
don't think clang supports that), a better soution might be to remove the sym
variable entirely, and replace it with a macro that access the sym array as an
offset from the start of the pointer. That would seem to be an ABI change, but
if you went through that process you would wind up with the same sized struct,
which would be nice
Neil
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 1/2] lib/security: add support for get metadata
2017-11-22 13:27 3% ` Neil Horman
@ 2017-11-22 14:13 0% ` Anoob
2017-11-27 13:55 0% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Anoob @ 2017-11-22 14:13 UTC (permalink / raw)
To: Neil Horman
Cc: Akhil Goyal, Declan Doherty, Radu Nicolau,
Sergio Gonzalez Monroy, Jerin Jacob, Narayana Prasad, dev
Hi,
Please see inline.
On 11/22/2017 06:57 PM, Neil Horman wrote:
> On Wed, Nov 22, 2017 at 06:55:15AM +0000, Anoob Joseph wrote:
>> In case of inline protocol processed ingress traffic, the packet may not
>> have enough information to determine the security parameters with which
>> the packet was processed. For such cases, application could register a
>> 64 bit metadata in security session, which could be retrieved from the
>> packet using "rte_security_get_pkt_metadata" API. Application can use
>> this metadata to identify the parameters it need.
>>
>> Application can choose what it should register as the metadata. It can
>> register SPI or a pointer to SA.
>>
>> Signed-off-by: Anoob Joseph <anoob.joseph@caviumnetworks.com>
>> ---
>> v2:
>> * Replaced get_session and get_cookie APIs with get_pkt_metadata API
>>
>> lib/librte_security/rte_security.c | 13 +++++++++++++
>> lib/librte_security/rte_security.h | 19 +++++++++++++++++++
>> lib/librte_security/rte_security_driver.h | 16 ++++++++++++++++
>> 3 files changed, 48 insertions(+)
>>
>> diff --git a/lib/librte_security/rte_security.c b/lib/librte_security/rte_security.c
>> index 1227fca..804f11f 100644
>> --- a/lib/librte_security/rte_security.c
>> +++ b/lib/librte_security/rte_security.c
>> @@ -108,6 +108,19 @@ rte_security_set_pkt_metadata(struct rte_security_ctx *instance,
>> sess, m, params);
>> }
>>
>> +uint64_t
>> +rte_security_get_pkt_metadata(struct rte_security_ctx *instance,
>> + struct rte_mbuf *pkt)
>> +{
>> + uint64_t mdata = 0;
>> +
>> + RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->get_pkt_metadata, 0);
>> + if (instance->ops->get_pkt_metadata(instance->device, pkt, &mdata))
>> + return 0;
>> +
>> + return mdata;
>> +}
>> +
>> const struct rte_security_capability *
>> rte_security_capabilities_get(struct rte_security_ctx *instance)
>> {
>> diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
>> index 653929b..aa3a471 100644
>> --- a/lib/librte_security/rte_security.h
>> +++ b/lib/librte_security/rte_security.h
>> @@ -274,6 +274,8 @@ struct rte_security_session_conf {
>> /**< Configuration parameters for security session */
>> struct rte_crypto_sym_xform *crypto_xform;
>> /**< Security Session Crypto Transformations */
>> + uint64_t metadata;
>> + /**< Metadata registered by application */
> This is going to break ABI. You need to announce the change so that application
> providers can be prepared for it.
The security library is under experimental tag. So is the announcement
required?
>
>> };
>>
>> struct rte_security_session {
>> @@ -346,6 +348,23 @@ rte_security_set_pkt_metadata(struct rte_security_ctx *instance,
>> struct rte_mbuf *mb, void *params);
>>
>> /**
>> + * Get metadata from the packet. This is an application registered 64 bit
>> + * value, associated with the security session which processed the packet.
>> + *
>> + * This is valid only for inline processed ingress packets.
>> + *
>> + * @param instance security instance
>> + * @param pkt packet mbuf
>> + *
>> + * @return
>> + * - On success, metadata
>> + * - On failure, 0
>> + */
>> +uint64_t
>> +rte_security_get_pkt_metadata(struct rte_security_ctx *instance,
>> + struct rte_mbuf *pkt);
>> +
>> +/**
>> * Attach a session to a symmetric crypto operation
>> *
>> * @param sym_op crypto operation
>> diff --git a/lib/librte_security/rte_security_driver.h b/lib/librte_security/rte_security_driver.h
>> index 997fbe7..da0ebf4 100644
>> --- a/lib/librte_security/rte_security_driver.h
>> +++ b/lib/librte_security/rte_security_driver.h
>> @@ -122,6 +122,20 @@ typedef int (*security_set_pkt_metadata_t)(void *device,
>> void *params);
>>
>> /**
>> + * Get application interpretable metadata from the packet.
>> + *
>> + * @param device Crypto/eth device pointer
>> + * @param pkt Packet mbuf
>> + * @param mt Pointer to receive metadata
>> + *
>> + * @return
>> + * - Returns 0 if metadata is retrieved successfully.
>> + * - Returns -ve value for errors.
>> + */
>> +typedef int (*security_get_pkt_metadata_t)(void *device,
>> + struct rte_mbuf *pkt, uint64_t *mt);
>> +
>> +/**
>> * Get security capabilities of the device.
>> *
>> * @param device crypto/eth device pointer
>> @@ -145,6 +159,8 @@ struct rte_security_ops {
>> /**< Clear a security sessions private data. */
>> security_set_pkt_metadata_t set_pkt_metadata;
>> /**< Update mbuf metadata. */
>> + security_get_pkt_metadata_t get_pkt_metadata;
>> + /**< Get metadata from packet. */
>> security_capabilities_get_t capabilities_get;
>> /**< Get security capabilities. */
>> };
>> --
>> 2.7.4
>>
>>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 2/3] crypto: fix pedentic compilation errors
2017-11-22 13:56 3% ` Neil Horman
@ 2017-11-22 14:31 0% ` Gaëtan Rivet
2017-11-22 16:50 0% ` De Lara Guarch, Pablo
0 siblings, 1 reply; 200+ results
From: Gaëtan Rivet @ 2017-11-22 14:31 UTC (permalink / raw)
To: Neil Horman
Cc: Nelio Laranjeiro, Akhil Goyal, Declan Doherty, dev,
pablo.de.lara.guarch, stable
On Wed, Nov 22, 2017 at 08:56:14AM -0500, Neil Horman wrote:
> On Wed, Nov 22, 2017 at 09:10:17AM +0100, Nelio Laranjeiro wrote:
> > /root/dpdk/x86_64-native-linuxapp-gcc/include/rte_crypto.h:126:28: error: ISO C forbids zero-size array ‘sym’ [-Werror=pedantic]
> > struct rte_crypto_sym_op sym[0];
> > ^~~
> >
> > Fixes: d2a4223c4c6d ("cryptodev: do not store pointer to op specific params")
> > Cc: pablo.de.lara.guarch@intel.com
> > Cc: stable@dpdk.org
> >
> > Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> > ---
> > lib/librte_cryptodev/rte_crypto.h | 2 +-
> > 1 file changed, 1 insertion(+), 1 deletion(-)
> >
> > diff --git a/lib/librte_cryptodev/rte_crypto.h b/lib/librte_cryptodev/rte_crypto.h
> > index 3d672fe7d..dc6e91d1d 100644
> > --- a/lib/librte_cryptodev/rte_crypto.h
> > +++ b/lib/librte_cryptodev/rte_crypto.h
> > @@ -123,7 +123,7 @@ struct rte_crypto_op {
> >
> > RTE_STD_C11
> > union {
> > - struct rte_crypto_sym_op sym[0];
> > + struct rte_crypto_sym_op *sym;
> > /**< Symmetric operation parameters */
> > }; /**< operation specific parameters */
> > };
> > --
> > 2.11.0
> >
> >
> As Laura notes, this isn't the right solution. In addition to adding a 64 bit
> pointer, it I think also results in incorrect semantics. That is to say, the
> allocation path for this structure allocates the rte_crypto_op and additional
> memory for the sym array contiguously, which the sym[0] syntax correctly
> interprets to mean the storage for the array is inline with the structure.
> Changing to a pointer means you are using the first elements of the array
> storage as your pointer, which could be filled with any old value, leading to
> corruption.
>
> If you can't use zero length array semantics (which I assume you cant, as I
> don't think clang supports that), a better soution might be to remove the sym
> variable entirely, and replace it with a macro that access the sym array as an
> offset from the start of the pointer. That would seem to be an ABI change, but
> if you went through that process you would wind up with the same sized struct,
> which would be nice
>
> Neil
>
ISO C forbids zero-size arrays, but ISO C99 allows flexible arrays.
Why is this symbole within a union? Why not remove the union, change
sym[0] to sym[]?
--
Gaëtan Rivet
6WIND
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 2/3] crypto: fix pedentic compilation errors
2017-11-22 14:31 0% ` Gaëtan Rivet
@ 2017-11-22 16:50 0% ` De Lara Guarch, Pablo
0 siblings, 0 replies; 200+ results
From: De Lara Guarch, Pablo @ 2017-11-22 16:50 UTC (permalink / raw)
To: Gaëtan Rivet, Neil Horman
Cc: Nelio Laranjeiro, Akhil Goyal, Doherty, Declan, dev, stable
> -----Original Message-----
> From: Gaëtan Rivet [mailto:gaetan.rivet@6wind.com]
> Sent: Wednesday, November 22, 2017 2:32 PM
> To: Neil Horman <nhorman@tuxdriver.com>
> Cc: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>; Akhil Goyal
> <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>;
> dev@dpdk.org; De Lara Guarch, Pablo <pablo.de.lara.guarch@intel.com>;
> stable@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/3] crypto: fix pedentic compilation errors
>
> On Wed, Nov 22, 2017 at 08:56:14AM -0500, Neil Horman wrote:
> > On Wed, Nov 22, 2017 at 09:10:17AM +0100, Nelio Laranjeiro wrote:
> > > /root/dpdk/x86_64-native-linuxapp-gcc/include/rte_crypto.h:126:28:
> error: ISO C forbids zero-size array ‘sym’ [-Werror=pedantic]
> > > struct rte_crypto_sym_op sym[0];
> > > ^~~
> > >
> > > Fixes: d2a4223c4c6d ("cryptodev: do not store pointer to op specific
> > > params")
> > > Cc: pablo.de.lara.guarch@intel.com
> > > Cc: stable@dpdk.org
> > >
> > > Signed-off-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
> > > ---
> > > lib/librte_cryptodev/rte_crypto.h | 2 +-
> > > 1 file changed, 1 insertion(+), 1 deletion(-)
> > >
> > > diff --git a/lib/librte_cryptodev/rte_crypto.h
> > > b/lib/librte_cryptodev/rte_crypto.h
> > > index 3d672fe7d..dc6e91d1d 100644
> > > --- a/lib/librte_cryptodev/rte_crypto.h
> > > +++ b/lib/librte_cryptodev/rte_crypto.h
> > > @@ -123,7 +123,7 @@ struct rte_crypto_op {
> > >
> > > RTE_STD_C11
> > > union {
> > > - struct rte_crypto_sym_op sym[0];
> > > + struct rte_crypto_sym_op *sym;
> > > /**< Symmetric operation parameters */
> > > }; /**< operation specific parameters */ };
> > > --
> > > 2.11.0
> > >
> > >
> > As Laura notes, this isn't the right solution. In addition to adding a 64 bit
> > pointer, it I think also results in incorrect semantics. That is to say, the
> > allocation path for this structure allocates the rte_crypto_op and
> additional
> > memory for the sym array contiguously, which the sym[0] syntax
> correctly
> > interprets to mean the storage for the array is inline with the structure.
> > Changing to a pointer means you are using the first elements of the array
> > storage as your pointer, which could be filled with any old value, leading
> to
> > corruption.
> >
> > If you can't use zero length array semantics (which I assume you cant, as I
> > don't think clang supports that), a better soution might be to remove the
> sym
> > variable entirely, and replace it with a macro that access the sym array as
> an
> > offset from the start of the pointer. That would seem to be an ABI
> change, but
> > if you went through that process you would wind up with the same sized
> struct,
> > which would be nice
> >
> > Neil
> >
>
> ISO C forbids zero-size arrays, but ISO C99 allows flexible arrays.
> Why is this symbole within a union? Why not remove the union, change
> sym[0] to sym[]?
It is a union because there were going to be other types of crypto operations (might still happen in the future).
For instance:
union{
struct rte_crypto_sym_op sym[0];
struct rte_crypto_asym_op asym[0];
}
Thanks,
Pablo
>
> --
> Gaëtan Rivet
> 6WIND
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2] doc: add template release notes for 18.02
2017-11-17 22:41 6% [dpdk-dev] [PATCH v1] doc: add template release notes for 18.02 John McNamara
@ 2017-11-22 17:38 6% ` John McNamara
0 siblings, 0 replies; 200+ results
From: John McNamara @ 2017-11-22 17:38 UTC (permalink / raw)
To: dev; +Cc: John McNamara
Add template release notes for DPDK 18.02 with inline
comments and explanations of the various sections.
Signed-off-by: John McNamara <john.mcnamara@intel.com>
---
V2: Added "Removed Items" and removed "Resolved Issues".
doc/guides/rel_notes/release_18_02.rst | 186 +++++++++++++++++++++++++++++++++
1 file changed, 186 insertions(+)
create mode 100644 doc/guides/rel_notes/release_18_02.rst
diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst
new file mode 100644
index 0000000..24b67bb
--- /dev/null
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -0,0 +1,186 @@
+DPDK Release 18.02
+==================
+
+.. **Read this first.**
+
+ The text in the sections below explains how to update the release notes.
+
+ Use proper spelling, capitalization and punctuation in all sections.
+
+ Variable and config names should be quoted as fixed width text:
+ ``LIKE_THIS``.
+
+ Build the docs and view the output file to ensure the changes are correct::
+
+ make doc-guides-html
+
+ xdg-open build/doc/html/guides/rel_notes/release_18_02.html
+
+
+New Features
+------------
+
+.. This section should contain new features added in this release. Sample
+ format:
+
+ * **Add a title in the past tense with a full stop.**
+
+ Add a short 1-2 sentence description in the past tense. The description
+ should be enough to allow someone scanning the release notes to
+ understand the new feature.
+
+ If the feature adds a lot of sub-features you can use a bullet list like
+ this:
+
+ * Added feature foo to do something.
+ * Enhanced feature bar to do something else.
+
+ Refer to the previous release notes for examples.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+API Changes
+-----------
+
+.. This section should contain API changes. Sample format:
+
+ * Add a short 1-2 sentence description of the API change. Use fixed width
+ quotes for ``rte_function_names`` or ``rte_struct_names``. Use the past
+ tense.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+ABI Changes
+-----------
+
+.. This section should contain ABI changes. Sample format:
+
+ * Add a short 1-2 sentence description of the ABI change that was announced
+ in the previous releases and made in this release. Use fixed width quotes
+ for ``rte_function_names`` or ``rte_struct_names``. Use the past tense.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Removed Items
+-------------
+
+.. This section should contain removed items in this release. Sample format:
+
+ * Add a short 1-2 sentence description of the removed item in the past
+ tense.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Known Issues
+------------
+
+.. This section should contain new known issues in this release. Sample format:
+
+ * **Add title in present tense with full stop.**
+
+ Add a short 1-2 sentence description of the known issue in the present
+ tense. Add information on any known workarounds.
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
+
+
+Shared Library Versions
+-----------------------
+
+.. Update any library version updated in this release and prepend with a ``+``
+ sign, like this:
+
+ librte_acl.so.2
+ + librte_cfgfile.so.2
+ librte_cmdline.so.2
+
+ This section is a comment. do not overwrite or remove it.
+ =========================================================
+
+
+The libraries prepended with a plus sign were incremented in this version.
+
+.. code-block:: diff
+
+ librte_acl.so.2
+ librte_bitratestats.so.2
+ librte_bus_dpaa.so.1
+ librte_bus_fslmc.so.1
+ librte_bus_pci.so.1
+ librte_bus_vdev.so.1
+ librte_cfgfile.so.2
+ librte_cmdline.so.2
+ librte_cryptodev.so.4
+ librte_distributor.so.1
+ librte_eal.so.6
+ librte_ethdev.so.8
+ librte_eventdev.so.3
+ librte_flow_classify.so.1
+ librte_gro.so.1
+ librte_gso.so.1
+ librte_hash.so.2
+ librte_ip_frag.so.1
+ librte_jobstats.so.1
+ librte_kni.so.2
+ librte_kvargs.so.1
+ librte_latencystats.so.1
+ librte_lpm.so.2
+ librte_mbuf.so.3
+ librte_mempool.so.3
+ librte_meter.so.1
+ librte_metrics.so.1
+ librte_net.so.1
+ librte_pci.so.1
+ librte_pdump.so.2
+ librte_pipeline.so.3
+ librte_pmd_bnxt.so.2
+ librte_pmd_bond.so.2
+ librte_pmd_i40e.so.2
+ librte_pmd_ixgbe.so.2
+ librte_pmd_ring.so.2
+ librte_pmd_softnic.so.1
+ librte_pmd_vhost.so.2
+ librte_port.so.3
+ librte_power.so.1
+ librte_reorder.so.1
+ librte_ring.so.1
+ librte_sched.so.1
+ librte_security.so.1
+ librte_table.so.3
+ librte_timer.so.1
+ librte_vhost.so.3
+
+
+
+Tested Platforms
+----------------
+
+.. This section should contain a list of platforms that were tested with this
+ release.
+
+ The format is:
+
+ * <vendor> platform with <vendor> <type of devices> combinations
+
+ * List of CPU
+ * List of OS
+ * List of devices
+ * Other relevant details...
+
+ This section is a comment. do not overwrite or remove it.
+ Also, make sure to start the actual text at the margin.
+ =========================================================
--
2.7.5
^ permalink raw reply [relevance 6%]
* Re: [dpdk-dev] [PATCH 0/2] ethdev: add GENEVE to flow API
2017-11-20 8:21 3% [dpdk-dev] [PATCH 0/2] ethdev: add GENEVE to flow API Andrew Rybchenko
@ 2017-11-23 9:39 4% ` Adrien Mazarguil
2017-11-23 10:07 0% ` Andrew Rybchenko
2017-12-01 10:43 3% ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
3 siblings, 1 reply; 200+ results
From: Adrien Mazarguil @ 2017-11-23 9:39 UTC (permalink / raw)
To: Andrew Rybchenko; +Cc: dev, Jingjing Wu
Hi Andrew,
On Mon, Nov 20, 2017 at 08:21:59AM +0000, Andrew Rybchenko wrote:
> enum rte_flow_item_type states that items matching protocol headers
> must be stacked in the same order as the protocol layers to match.
> As the result the patch changes ABI since Geneve is added just after
> VXLAN (the closest protocol).
>
> In fact as far as I can see many items do not follow the requirement
> already. May be the comment/requirement should be removed and GENEVE
> should be added at the end of the list. If so, should be keep it just
> after VXLAN in all other places or move after ESP as well?
Perhaps documentation is unclear, this requirement only applies to
applications when constructing patterns out of those items (e.g. to make
sense, TCP is supposed to come after IPv4, not before).
New item/action definitions must obviously be added at the end of both lists
to avoid ABI breakage, there is no specific order to follow other than that.
What may have confused you is most of them are apparently ordered by
protocol layer, that's because those are here from day one; it's not the
case anymore starting with E_TAG, which was added much later.
Besides addressing the ABI breakage, I don't see any issue with adding
GENEVE to rte_flow, I only have a few more comments on subsequent patches in
the series. Otherwise good job, looks like you didn't miss anything.
--
Adrien Mazarguil
6WIND
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 1/2] ethdev: add GENEVE flow pattern item
@ 2017-11-23 9:39 3% ` Adrien Mazarguil
0 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2017-11-23 9:39 UTC (permalink / raw)
To: Andrew Rybchenko; +Cc: dev, Jingjing Wu, Roman Zhukov
On Mon, Nov 20, 2017 at 08:22:00AM +0000, Andrew Rybchenko wrote:
> From: Roman Zhukov <Roman.Zhukov@oktetlabs.ru>
>
> Add new pattern item RTE_FLOW_ITEM_TYPE_GENEVE in flow API.
> This commit also adds default mask for these item.
>
> Signed-off-by: Roman Zhukov <Roman.Zhukov@oktetlabs.ru>
> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
OK, the main issue in this patch is you're inserting GENEVE in the middle of
everything (enums, documentation, etc). Just append it to the enum to avoid
ABI breakage as described in my previous message and use the same position
everywhere else for consistency.
It must appear after RTE_FLOW_ITEM_TYPE_ESP.
More comments below.
> ---
> doc/guides/prog_guide/rte_flow.rst | 12 ++++++++++++
> lib/librte_ether/rte_flow.c | 1 +
> lib/librte_ether/rte_flow.h | 31 +++++++++++++++++++++++++++++++
> 3 files changed, 44 insertions(+)
>
> diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst
> index d158be5..2f96623 100644
> --- a/doc/guides/prog_guide/rte_flow.rst
> +++ b/doc/guides/prog_guide/rte_flow.rst
> @@ -863,6 +863,18 @@ Matches a VXLAN header (RFC 7348).
> - ``rsvd1``: reserved, normally 0x00.
> - Default ``mask`` matches VNI only.
>
> +Item: ``GENEVE``
> +^^^^^^^^^^^^^^^
> +
> +Matches a GENEVE header.
> +
> +- ``ver_opt_len_o_c_rsvd0``: version (2b), length of the options fields (6b),
> + OAM packet (1b), critical options present (1b), reserved 0 (6b).
> +- ``protocol``: protocol type.
> +- ``vni``: virtual network identifier.
> +- ``rsvd1``: reserved, normally 0x00.
> +- Default ``mask`` matches protocol type and VNI.
> +
I'm not sure about the default mask. It should be the least common
denominator, not necessarily what the first implementation supports. How
about making it like VXLAN, i.e. VNI only? Does that make sense at all?
> Item: ``E_TAG``
> ^^^^^^^^^^^^^^^
>
> diff --git a/lib/librte_ether/rte_flow.c b/lib/librte_ether/rte_flow.c
> index 6659063..bf1b253 100644
> --- a/lib/librte_ether/rte_flow.c
> +++ b/lib/librte_ether/rte_flow.c
> @@ -77,6 +77,7 @@ static const struct rte_flow_desc_data rte_flow_desc_item[] = {
> MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
> MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
> MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
> + MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
You should add it at the end but some items are already missing from that
list. Since I plan to send an overhaul for this function, you can leave this
change out for the time being.
> MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
> MK_FLOW_ITEM(GRE, sizeof(struct rte_flow_item_gre)),
> MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
> diff --git a/lib/librte_ether/rte_flow.h b/lib/librte_ether/rte_flow.h
> index 47c88ea..29d81d4 100644
> --- a/lib/librte_ether/rte_flow.h
> +++ b/lib/librte_ether/rte_flow.h
> @@ -272,6 +272,13 @@ enum rte_flow_item_type {
> RTE_FLOW_ITEM_TYPE_VXLAN,
>
> /**
> + * Matches a GENEVE header.
> + *
> + * See struct rte_flow_item_geneve.
> + */
> + RTE_FLOW_ITEM_TYPE_GENEVE,
> +
> + /**
> * Matches a E_TAG header.
> *
> * See struct rte_flow_item_e_tag.
> @@ -651,6 +658,30 @@ static const struct rte_flow_item_vxlan rte_flow_item_vxlan_mask = {
> #endif
>
> /**
> + * RTE_FLOW_ITEM_TYPE_GENEVE.
> + *
> + * Matches a GENEVE header.
> + */
> +struct rte_flow_item_geneve {
> + /**
> + * Version (2b), length of the options fields (6b), OAM packet (1b),
> + * critical options present (1b), reserved 0 (6b).
> + */
> + rte_be16_t ver_opt_len_o_c_rsvd0;
> + rte_be16_t protocol; /**< Protocol type. */
> + uint8_t vni[3]; /**< Virtual Network Identifier. */
> + uint8_t rsvd1; /**< Reserved, normally 0x00. */
> +};
> +
> +/** Default mask for RTE_FLOW_ITEM_TYPE_GENEVE. */
> +#ifndef __cplusplus
> +static const struct rte_flow_item_geneve rte_flow_item_geneve_mask = {
> + .protocol = RTE_BE16(0xffff),
> + .vni = "\xff\xff\xff",
> +};
> +#endif
So how about removing .protocol from the default mask?
> +
> +/**
> * RTE_FLOW_ITEM_TYPE_E_TAG.
> *
> * Matches a E-tag header.
> --
> 2.7.4
>
--
Adrien Mazarguil
6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 2/2] app/testpmd: support GENEVE pattern item in flow rules
@ 2017-11-23 9:40 3% ` Adrien Mazarguil
0 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2017-11-23 9:40 UTC (permalink / raw)
To: Andrew Rybchenko; +Cc: dev, Jingjing Wu, Roman Zhukov
On Mon, Nov 20, 2017 at 08:22:01AM +0000, Andrew Rybchenko wrote:
> From: Roman Zhukov <Roman.Zhukov@oktetlabs.ru>
>
> Add the ability to match a VNI field of GENEVE protocol header.
>
> Signed-off-by: Roman Zhukov <Roman.Zhukov@oktetlabs.ru>
> Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
Same comments as previously basically, keep the same order as rte_flow.h
after fixing the ABI breakage.
One minor comment below.
> ---
> app/test-pmd/cmdline_flow.c | 31 +++++++++++++++++++++++++++++
> app/test-pmd/config.c | 1 +
> doc/guides/testpmd_app_ug/testpmd_funcs.rst | 5 +++++
> 3 files changed, 37 insertions(+)
>
> diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c
> index df16d2a..cee99f3 100644
> --- a/app/test-pmd/cmdline_flow.c
> +++ b/app/test-pmd/cmdline_flow.c
> @@ -161,6 +161,9 @@ enum index {
> ITEM_SCTP_CKSUM,
> ITEM_VXLAN,
> ITEM_VXLAN_VNI,
> + ITEM_GENEVE,
> + ITEM_GENEVE_VNI,
> + ITEM_GENEVE_PROTO,
> ITEM_E_TAG,
> ITEM_E_TAG_GRP_ECID_B,
> ITEM_NVGRE,
> @@ -452,6 +455,7 @@ static const enum index next_item[] = {
> ITEM_TCP,
> ITEM_SCTP,
> ITEM_VXLAN,
> + ITEM_GENEVE,
> ITEM_E_TAG,
> ITEM_NVGRE,
> ITEM_MPLS,
> @@ -573,6 +577,13 @@ static const enum index item_vxlan[] = {
> ZERO,
> };
>
> +static const enum index item_geneve[] = {
> + ITEM_GENEVE_VNI,
> + ITEM_GENEVE_PROTO,
> + ITEM_NEXT,
> + ZERO,
> +};
> +
> static const enum index item_e_tag[] = {
> ITEM_E_TAG_GRP_ECID_B,
> ITEM_NEXT,
> @@ -1371,6 +1382,26 @@ static const struct token token_list[] = {
> .next = NEXT(item_vxlan, NEXT_ENTRY(UNSIGNED), item_param),
> .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)),
> },
> + [ITEM_GENEVE] = {
> + .name = "geneve",
> + .help = "match GENEVE header",
> + .priv = PRIV_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
> + .next = NEXT(item_geneve),
> + .call = parse_vc,
> + },
> + [ITEM_GENEVE_VNI] = {
> + .name = "vni",
> + .help = "Virtual Network Identifier",
How about "virtual network identifier" (all lower caps)?
> + .next = NEXT(item_geneve, NEXT_ENTRY(UNSIGNED), item_param),
> + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve, vni)),
> + },
> + [ITEM_GENEVE_PROTO] = {
> + .name = "protocol",
> + .help = "GENEVE protocol type",
> + .next = NEXT(item_geneve, NEXT_ENTRY(UNSIGNED), item_param),
> + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_geneve,
> + protocol)),
> + },
> [ITEM_E_TAG] = {
> .name = "e_tag",
> .help = "match E-Tag header",
> diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
> index cd2ac11..4eda37f 100644
> --- a/app/test-pmd/config.c
> +++ b/app/test-pmd/config.c
> @@ -965,6 +965,7 @@ static const struct {
> MK_FLOW_ITEM(TCP, sizeof(struct rte_flow_item_tcp)),
> MK_FLOW_ITEM(SCTP, sizeof(struct rte_flow_item_sctp)),
> MK_FLOW_ITEM(VXLAN, sizeof(struct rte_flow_item_vxlan)),
> + MK_FLOW_ITEM(GENEVE, sizeof(struct rte_flow_item_geneve)),
> MK_FLOW_ITEM(E_TAG, sizeof(struct rte_flow_item_e_tag)),
> MK_FLOW_ITEM(NVGRE, sizeof(struct rte_flow_item_nvgre)),
> MK_FLOW_ITEM(MPLS, sizeof(struct rte_flow_item_mpls)),
> diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> index 9789139..8c2fd12 100644
> --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst
> @@ -3083,6 +3083,11 @@ This section lists supported pattern items and their attributes, if any.
>
> - ``vni {unsigned}``: VXLAN identifier.
>
> +- ``geneve``: match GENEVE header.
> +
> + - ``vni {unsigned}``: virtual network identifier.
> + - ``protocol {unsigned}``: protocol type.
> +
> - ``e_tag``: match IEEE 802.1BR E-Tag header.
>
> - ``grp_ecid_b {unsigned}``: GRP and E-CID base.
> --
> 2.7.4
>
--
Adrien Mazarguil
6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 0/2] ethdev: add GENEVE to flow API
2017-11-23 9:39 4% ` [dpdk-dev] [PATCH 0/2] ethdev: add GENEVE to flow API Adrien Mazarguil
@ 2017-11-23 10:07 0% ` Andrew Rybchenko
0 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2017-11-23 10:07 UTC (permalink / raw)
To: Adrien Mazarguil; +Cc: dev, Jingjing Wu
Hi Adrien,
On 11/23/2017 12:39 PM, Adrien Mazarguil wrote:
> Hi Andrew,
>
> On Mon, Nov 20, 2017 at 08:21:59AM +0000, Andrew Rybchenko wrote:
>> enum rte_flow_item_type states that items matching protocol headers
>> must be stacked in the same order as the protocol layers to match.
>> As the result the patch changes ABI since Geneve is added just after
>> VXLAN (the closest protocol).
>>
>> In fact as far as I can see many items do not follow the requirement
>> already. May be the comment/requirement should be removed and GENEVE
>> should be added at the end of the list. If so, should be keep it just
>> after VXLAN in all other places or move after ESP as well?
> Perhaps documentation is unclear, this requirement only applies to
> applications when constructing patterns out of those items (e.g. to make
> sense, TCP is supposed to come after IPv4, not before).
>
> New item/action definitions must obviously be added at the end of both lists
> to avoid ABI breakage, there is no specific order to follow other than that.
>
> What may have confused you is most of them are apparently ordered by
> protocol layer, that's because those are here from day one; it's not the
> case anymore starting with E_TAG, which was added much later.
>
> Besides addressing the ABI breakage, I don't see any issue with adding
> GENEVE to rte_flow, I only have a few more comments on subsequent patches in
> the series. Otherwise good job, looks like you didn't miss anything.
Many thinks for review and clarification. We'll process review notes and
send v2.
--
Andrew
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [RFC PATCH 0/6] mempool: add bucket mempool driver
@ 2017-11-24 16:06 4% Andrew Rybchenko
2017-12-14 13:36 3% ` Olivier MATZ
0 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2017-11-24 16:06 UTC (permalink / raw)
To: dev; +Cc: Olivier Matz
The patch series adds bucket mempool driver which allows to allocate
(both physically and virtually) contiguous blocks of objects and adds
mempool API to do it. It is still capable to provide separate objects,
but it is definitely more heavy-weight than ring/stack drivers.
The target usecase is dequeue in blocks and enqueue separate objects
back (which are collected in buckets to be dequeued). So, the memory
pool with bucket driver is created by an application and provided to
networking PMD receive queue. The choice of bucket driver is done using
rte_eth_dev_pool_ops_supported(). A PMD that relies upon contiguous
block allocation should report the bucket driver as the only supported
and preferred one.
The number of objects in the contiguous block is a function of bucket
memory size (.config option) and total element size.
As I understand it breaks ABI so it requires 3 acks in accordance with
policy, deprecation notice and mempool shared library version bump.
If there is a way to avoid ABI breakage, please, let us know.
In any case we would like to start from RFC discussion. Comments and
ideas are welcome.
The target DPDK release is 18.05.
Artem V. Andreev (6):
mempool: implement abstract mempool info API
mempool: implement clustered object allocation
mempool/bucket: implement bucket mempool manager
mempool: add a function to flush default cache
mempool: support block dequeue operation
mempool/bucket: implement block dequeue operation
MAINTAINERS | 9 +
config/common_base | 2 +
drivers/mempool/Makefile | 1 +
drivers/mempool/bucket/Makefile | 49 ++
drivers/mempool/bucket/rte_mempool_bucket.c | 559 +++++++++++++++++++++
.../mempool/bucket/rte_mempool_bucket_version.map | 4 +
lib/librte_mempool/rte_mempool.c | 41 +-
lib/librte_mempool/rte_mempool.h | 179 ++++++-
lib/librte_mempool/rte_mempool_ops.c | 16 +
mk/rte.app.mk | 1 +
test/test/test_mempool.c | 2 +-
11 files changed, 857 insertions(+), 6 deletions(-)
create mode 100644 drivers/mempool/bucket/Makefile
create mode 100644 drivers/mempool/bucket/rte_mempool_bucket.c
create mode 100644 drivers/mempool/bucket/rte_mempool_bucket_version.map
--
2.7.4
^ permalink raw reply [relevance 4%]
* [dpdk-dev] 17.08.1 patches review and test
@ 2017-11-27 12:21 2% Yuanhan Liu
2017-11-30 19:09 0% ` Patil, Harish
2017-12-04 20:40 0% ` Patil, Harish
0 siblings, 2 replies; 200+ results
From: Yuanhan Liu @ 2017-11-27 12:21 UTC (permalink / raw)
To: dpdk stable; +Cc: dev, Xu, Qian Q
Hi all,
Here is a list of patches targeted for stable release 17.08.1. Please
help review and test. The planned date for the final release is 7th,
Dec. Before that, please shout if anyone has objections with these
patches being applied.
These patches are located at branch 17.08 of dpdk-stable repo:
http://dpdk.org/browse/dpdk-stable/
Thanks.
--yliu
---
Aaron Conole (1):
net/enic: fix assignment
Ajit Khaparde (28):
net/bnxt: fix HWRM macros and locking
net/bnxt: use 64-bits of address for VLAN table
net/bnxt: fix an issue with group id calculation
net/bnxt: fix calculation of number of pools
net/bnxt: handle multi queue mode properly
net/bnxt: fix Rx handling and buffer allocation logic
net/bnxt: fix an issue with broadcast traffic
net/bnxt: fix usage of VMDq flags
net/bnxt: set checksum offload flags correctly
net/bnxt: update status of Rx IP/L4 CKSUM
net/bnxt: fix config RSS update
net/bnxt: set the hash key size
net/bnxt: fix per queue stats display in xstats
net/bnxt: fix interrupt handler
net/bnxt: fix number of MAC addresses for VMDq
net/bnxt: fix the association of a MACVLAN per VNIC
net/bnxt: fix Tx offload capability
net/bnxt: fix Rx offload capability
net/bnxt: handle Rx multi queue creation properly
net/bnxt: remove redundant code parsing pool map
net/bnxt: fix a bit shift operation
net/bnxt: fix a potential null pointer dereference
net/bnxt: fix a potential null pointer dereference
net/bnxt: fix a pointer deref before null check
net/bnxt: fix an unused value
net/bnxt: check VLANs from pool map only for VMDq
net/bnxt: do not set hash type unnecessarily
net/bnxt: fix VLAN spoof configuration
Akhil Goyal (2):
test/crypto: fix dpaa2 sec macros and definitions
net/dpaa2: set queues after reconfiguration
Alejandro Lucero (2):
net/nfp: fix RSS
net/nfp: fix Rx interrupt when multiqueue
Alok Makhariya (2):
crypto/dpaa2_sec: remove ICV memset on decryption side
crypto/dpaa2_sec: add check for segmented buffer
Anatoly Burakov (1):
vfio: fix secondary process initialization
Andrey Chilikin (1):
net/i40e: fix flexible payload configuration
Aviad Yehezkel (4):
examples/ipsec-secgw: fix crypto device mapping
examples/ipsec-secgw: fix session creation
examples/ipsec-secgw: fix AAD length setting
app/testpmd: fix build without ixgbe and bnxt PMDs
Beilei Xing (1):
net/i40e: fix VF device stop issue
Chas Williams (1):
net/vmxnet3: fix memory leak when releasing queues
Congwen Zhang (1):
net/cxgbe: fix memory leak
Daniel Mrzyglod (3):
net/virtio: fix untrusted scalar value
app/testpmd: fix DDP package filesize detection
net/bonding: fix default aggregator mode to stable
David Harton (2):
net/vmxnet3: fix MAC address set
net/i40e: fix i40evf MAC filter table
Ferruh Yigit (4):
ethdev: fix ABI version
ethdev: revert use port name from device structure
igb_uio: remove device reset in open
net/qede: fix icc build
Gaetan Rivet (1):
net/failsafe: fix errno set on command execution
Gowrishankar Muthukrishnan (1):
net/bonding: support bifurcated driver in eal
Guduri Prathyusha (2):
examples/l3fwd: fix NEON instructions
examples/l3fwd: fix aliasing in port grouping
Harish Patil (2):
net/qede: fix supported packet types
net/qede: fix to re-enable LRO during device start
Hemant Agrawal (3):
net/dpaa2: fix the Tx handling of non HW pool bufs
examples/l2fwd-crypto: fix uninitialized errno value
app/crypto-perf: fix uninitialized errno value
Ian Stokes (1):
cryptodev: fix build with -Ofast
Ivan Malov (2):
net/sfc: specify correct scale table size on Rx start
net/sfc: fix unused variable in RSS-agnostic build
Jacek Piasecki (1):
examples/vhost_scsi: fix product id string termination
Jasvinder Singh (1):
examples/qos_sched: fix uninitialized config
Jerin Jacob (1):
timer: use 64-bit specific code on more platforms
Jianbo Liu (1):
net/i40e: fix Rx packets number for NEON
Jiayu Hu (1):
gro: fix typo in map file
Jingjing Wu (4):
net/i40e: fix interrupt throttling setting in PF
net/i40e: fix memory leak if VF init fails
net/i40e: fix variable assignment
net/i40e: fix VF initialization error
John Daley (3):
net/enic: fix multi-process operation
net/enic: fix packet loss after MTU change
net/enic: fix TSO for packets greater than 9208 bytes
John Miller (1):
net/ark: fix loop counter
Kuba Kozak (2):
vfio: fix close unchecked file descriptor
vhost: check poll error code
Li Han (1):
app/testpmd: fix invalid port id parameters
Lukasz Majczak (1):
eal: fix auxv open check for ARM and PPC
Mark Spender (1):
net/sfc/base: fix default RSS context check on Siena
Matan Azrad (7):
net/failsafe: fix Tx sub device deactivating
net/mlx5: fix locking in xstats functions
net/failsafe: fix parameters parsing
net/mlx5: fix probe failure report
net/failsafe: fix adding MAC error report miss
app/testpmd: fix forward port ids setting
net/failsafe: fix Rx clean race
Maxime Coquelin (1):
vhost: fix dereferencing invalid pointer after realloc
Michal Jastrzebski (1):
net/vmxnet3: fix dereference before null check
Nikhil Rao (1):
eal/x86: fix atomic cmpset
Nirmoy Das (1):
kni: fix SLE version detection
Nélio Laranjeiro (4):
net/mlx5: fix clang build
net/mlx5: fix SSE Rx support verification
net/mlx5: fix clang compilation error
app/testpmd: fix RSS structure initialisation
Olivier Matz (12):
net: fix inner L2 length in packet type parser
net/bnxt: fix compilation with -Og
net/qede: fix compilation with -Og
app/test-crypto-perf: fix memory leak
app/test-crypto-perf: fix compilation with -Og
net/virtio: revert not claiming LRO support
net/virtio: revert not claiming IP checksum offload
net/virtio: fix log levels in configure
net/virtio: fix mbuf port for simple Rx function
net/virtio: fix queue setup consistency
net/virtio: fix compilation with -Og
lpm6: fix compilation with -Og
Ophir Munk (3):
net/tap: fix flow and port commands
net/failsafe: fix VLAN stripping configuration
app/testpmd: fix forwarding between non consecutive ports
Pablo de Lara (8):
hash: fix eviction counter
crypto/aesni_gcm: fix zero data operation
app/crypto-perf: fix packet length check
app/crypto-perf: parse AEAD data from vectors
crypto/openssl: fix AEAD parameters
examples/l2fwd-crypto: fix physical address setting
crypto/qat: fix HMAC supported digest sizes
app/testpmd: fix topology error message
Patrick MacArthur (1):
eal: copy raw strings taken from command line
Phil Yang (1):
app/testpmd: fix quitting in container
Qi Zhang (4):
net/i40e: fix flow control watermark mismatch
net/i40e: fix packet count for PF
net/i40e: fix mbuf free in vector Tx
net/i40e: fix mirror with firmware 6.0
Rami Rosen (1):
net/kni: remove driver struct forward declaration
Rasesh Mody (4):
net/qede/base: fix to use a passed ptt handle
net/qede/base: fix return code to align with FW
net/qede: remove duplicate includes
net/qede/base: fix division by zero
Raslan Darawsheh (2):
net/failsafe: fix failsafe bus uninit return value
net/failsafe: fix PCI devices init
RongQiang Xie (2):
net/enic: fix possible null pointer dereference
net/qede: fix possible null pointer dereference
Sebastian Basierski (3):
net/vmxnet3: fix unintentional integer overflow
net/virtio-user: fix TAP name string termination
net/virtio: check error on setting non block flag
Sergio Gonzalez Monroy (1):
crypto/aesni_mb: fix invalid session error
Shahaf Shuler (5):
net/mlx5: fix num seg assumption in SSE Tx
net/mlx5: fix Tx stats error counter definition
net/mlx5: fix Tx stats error counter logic
net/mlx5: fix TSO segment size verification
net/mlx5: fix packet type flags for Ethernet only frame
Stefan Baranoff (1):
net/pcap: fix memory leak in dumper open
Stephen Hemminger (1):
eal: initialize logging before bus
Tiwei Bie (1):
net/virtio: flush Rx queues on start
Tomasz Duszynski (3):
drivers/crypto: use snprintf return value correctly
examples/ipsec-secgw: fix IP version check
examples/ipsec-secgw: fix IPv6 payload length
Tomasz Kulasek (3):
net/bonding: fix slaves capacity check
net/i40e: fix assignment of enum values
net/bonding: fix check slaves link properties
Vipin Varghese (1):
net/tap: fix unregistering callback with invalid fd
Wei Dai (8):
net/ixgbe: fix mapping of user priority to TC
net/ixgbe: fix adding a mirror rule
net/i40e: fix mirror rule reset when port is closed
net/ixgbe: fix Rx queue interrupt mapping in VF
net/ixgbe: fix VFIO interrupt mapping in VF
net/ixgbe: fix PF DCB info
app/testpmd: fix mapping of user priority to DCB TC
net/i40e: fix VFIO interrupt mapping in VF
Wei Zhao (4):
net/ixgbe: fix MAC VLAN filter fail problem
net/i40e: fix clear xstats bug in VF
app/testpmd: fix packet throughput after stats reset
net/ixgbe: fix filter parser for L2 tunnel
Wenzhuo Lu (7):
net/i40e: fix TM node parameter checking
net/i40e: fix TM level capability getting
net/ixgbe: fix TM node parameter checking
net/ixgbe: fix TM level capability getting
net/i40e: fix not supporting NULL TM profile
net/ixgbe: fix not supporting NULL TM profile
net/i40e: fix parent when adding TM node
Xiaoyun Li (2):
net/i40e: fix PF notify issue when VF is not up
net/igb: fix Rx interrupt with VFIO and MSI-X
Xueming Li (5):
net/mlx5: fix tunnel offload detection
mem: fix malloc debug config
mem: fix malloc element free in debug mode
examples/l2fwd_fork: fix message pool init
examples/multi_process: fix received message length
Yi Yang (1):
service: fix build with gcc 4.9
Yong Wang (4):
net/liquidio: fix uninitialized variable
net/igb: fix memcpy length
net/i40e: fix uninitialized variable
net/ixgbe: fix uninitialized variable
Yongseok Koh (3):
net/mlx5: fix calculating TSO inline size
net/mlx5: fix overflow of Rx SW ring
net/mlx5: fix tunneled TCP/UDP packet type
Zhiyong Yang (2):
test: fix assignment operation
net/virtio: fix Tx packet length stats
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH] ethdev: increase flow type limit from 32 to 64
@ 2017-11-27 12:29 6% Kirill Rybalchenko
2018-01-15 16:58 7% ` [dpdk-dev] [PATCH v2] " Kirill Rybalchenko
0 siblings, 2 replies; 200+ results
From: Kirill Rybalchenko @ 2017-11-27 12:29 UTC (permalink / raw)
To: dev
Cc: jingjing.wu, beilei.xing, johndale, neescoba, adrien.mazarguil,
nelio.laranjeiro, yskoh, wenzhuo.lu, konstantin.ananyev,
kirill.rybalchenko, andrey.chilikin
Increase the internal limit for flow types from 32 to 64
to support future flow type extensions.
Change type of variables from uint32_t[] to uint64_t[]:
rte_eth_fdir_info.flow_types_mask
rte_eth_hash_global_conf.sym_hash_enable_mask
rte_eth_hash_global_conf.valid_bit_mask
This modification affects the following components:
net/i40e
net/enic
net/mlx5
net/ixgbe
app/testpmd
Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
app/test-pmd/cmdline.c | 22 +++++++++++-----------
drivers/net/enic/enic_clsf.c | 6 +++++-
drivers/net/i40e/i40e_ethdev.c | 38 +++++++++++++++++++-------------------
drivers/net/i40e/i40e_fdir.c | 25 ++++++++++++++-----------
drivers/net/ixgbe/ixgbe_fdir.c | 22 ++++++++++++----------
drivers/net/mlx5/mlx5_flow.c | 4 +++-
lib/librte_ether/rte_eth_ctrl.h | 12 ++++++------
7 files changed, 70 insertions(+), 59 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f71d963..3e57715 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10681,7 +10681,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
struct rte_eth_fdir_info fdir_info;
struct rte_eth_fdir_flex_mask flex_mask;
struct rte_port *port;
- uint32_t flow_type_mask;
+ uint64_t flow_type_mask;
uint16_t i;
int ret;
@@ -10734,7 +10734,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
return;
}
for (i = RTE_ETH_FLOW_UNKNOWN; i < RTE_ETH_FLOW_MAX; i++) {
- if (flow_type_mask & (1 << i)) {
+ if (flow_type_mask & (1ULL << i)) {
flex_mask.flow_type = i;
fdir_set_flex_mask(res->port_id, &flex_mask);
}
@@ -10743,7 +10743,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
return;
}
flex_mask.flow_type = str2flowtype(res->flow_type);
- if (!(flow_type_mask & (1 << flex_mask.flow_type))) {
+ if (!(flow_type_mask & (1ULL << flex_mask.flow_type))) {
printf("Flow type %s not supported on port %d\n",
res->flow_type, res->port_id);
return;
@@ -11105,10 +11105,10 @@ cmd_get_hash_global_config_parsed(void *parsed_result,
}
for (i = 0; i < RTE_ETH_FLOW_MAX; i++) {
- idx = i / UINT32_BIT;
- offset = i % UINT32_BIT;
+ idx = i / UINT64_BIT;
+ offset = i % UINT64_BIT;
if (!(info.info.global_conf.valid_bit_mask[idx] &
- (1UL << offset)))
+ (1ULL << offset)))
continue;
str = flowtype_to_str(i);
if (!str)
@@ -11116,7 +11116,7 @@ cmd_get_hash_global_config_parsed(void *parsed_result,
printf("Symmetric hash is %s globally for flow type %s "
"by port %d\n",
((info.info.global_conf.sym_hash_enable_mask[idx] &
- (1UL << offset)) ? "enabled" : "disabled"), str,
+ (1ULL << offset)) ? "enabled" : "disabled"), str,
res->port_id);
}
}
@@ -11177,12 +11177,12 @@ cmd_set_hash_global_config_parsed(void *parsed_result,
RTE_ETH_HASH_FUNCTION_DEFAULT;
ftype = str2flowtype(res->flow_type);
- idx = ftype / (CHAR_BIT * sizeof(uint32_t));
- offset = ftype % (CHAR_BIT * sizeof(uint32_t));
- info.info.global_conf.valid_bit_mask[idx] |= (1UL << offset);
+ idx = ftype / UINT64_BIT;
+ offset = ftype % UINT64_BIT;
+ info.info.global_conf.valid_bit_mask[idx] |= (1ULL << offset);
if (!strcmp(res->enable, "enable"))
info.info.global_conf.sym_hash_enable_mask[idx] |=
- (1UL << offset);
+ (1ULL << offset);
ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
RTE_ETH_FILTER_SET, &info);
if (ret < 0)
diff --git a/drivers/net/enic/enic_clsf.c b/drivers/net/enic/enic_clsf.c
index 9b46142..c5644cb 100644
--- a/drivers/net/enic/enic_clsf.c
+++ b/drivers/net/enic/enic_clsf.c
@@ -74,8 +74,12 @@ void enic_fdir_stats_get(struct enic *enic, struct rte_eth_fdir_stats *stats)
void enic_fdir_info_get(struct enic *enic, struct rte_eth_fdir_info *info)
{
+ uint32_t i;
+
info->mode = (enum rte_fdir_mode)enic->fdir.modes;
- info->flow_types_mask[0] = enic->fdir.types_mask;
+ info->flow_types_mask[0] = (uint64_t)enic->fdir.types_mask;
+ for (i = 1; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
+ info->flow_types_mask[i] = 0ULL;
}
void enic_fdir_info(struct enic *enic)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 811cc9f..78744c2 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -7984,14 +7984,17 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
/*
- * We work only with lowest 32 bits which is not correct, but to work
- * properly the valid_bit_mask size should be increased up to 64 bits
- * and this will brake ABI. This modification will be done in next
- * release
+ * As i40e supports less than 64 flow types, only first 64 bits need to
+ * be checked.
*/
- g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_mask;
+ for (i = 1; i < RTE_SYM_HASH_MASK_ARRAY_SIZE; i++) {
+ g_cfg->valid_bit_mask[i] = 0ULL;
+ g_cfg->sym_hash_enable_mask[i] = 0ULL;
+ }
- for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT32_BIT; i++) {
+ g_cfg->valid_bit_mask[0] = adapter->flow_types_mask;
+
+ for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT64_BIT; i++) {
if (!adapter->pctypes_tbl[i])
continue;
for (j = I40E_FILTER_PCTYPE_INVALID + 1;
@@ -8000,7 +8003,7 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
g_cfg->sym_hash_enable_mask[0] |=
- (1UL << i);
+ (1ULL << i);
}
}
}
@@ -8014,7 +8017,7 @@ i40e_hash_global_config_check(const struct i40e_adapter *adapter,
const struct rte_eth_hash_global_conf *g_cfg)
{
uint32_t i;
- uint32_t mask0, i40e_mask = adapter->flow_types_mask;
+ uint64_t mask0, i40e_mask = adapter->flow_types_mask;
if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR &&
@@ -8025,7 +8028,7 @@ i40e_hash_global_config_check(const struct i40e_adapter *adapter,
}
/*
- * As i40e supports less than 32 flow types, only first 32 bits need to
+ * As i40e supports less than 64 flow types, only first 64 bits need to
* be checked.
*/
mask0 = g_cfg->valid_bit_mask[0];
@@ -8061,23 +8064,20 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
int ret;
uint16_t i, j;
uint32_t reg;
- /*
- * We work only with lowest 32 bits which is not correct, but to work
- * properly the valid_bit_mask size should be increased up to 64 bits
- * and this will brake ABI. This modification will be done in next
- * release
- */
- uint32_t mask0 = g_cfg->valid_bit_mask[0] &
- (uint32_t)adapter->flow_types_mask;
+ uint64_t mask0 = g_cfg->valid_bit_mask[0] & adapter->flow_types_mask;
/* Check the input parameters */
ret = i40e_hash_global_config_check(adapter, g_cfg);
if (ret < 0)
return ret;
- for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT32_BIT; i++) {
+ /*
+ * As i40e supports less than 64 flow types, only first 64 bits need to
+ * be configured.
+ */
+ for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT64_BIT; i++) {
if (mask0 & (1UL << i)) {
- reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
+ reg = (g_cfg->sym_hash_enable_mask[0] & (1ULL << i)) ?
I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
for (j = I40E_FILTER_PCTYPE_INVALID + 1;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 3d7170d..fbc46ee 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -95,17 +95,17 @@
#define I40E_COUNTER_INDEX_FDIR(pf_id) (0 + (pf_id) * I40E_COUNTER_PF)
#define I40E_FDIR_FLOWS ( \
- (1 << RTE_ETH_FLOW_FRAG_IPV4) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
- (1 << RTE_ETH_FLOW_FRAG_IPV6) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) | \
- (1 << RTE_ETH_FLOW_L2_PAYLOAD))
+ (1ULL << RTE_ETH_FLOW_FRAG_IPV4) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
+ (1ULL << RTE_ETH_FLOW_FRAG_IPV6) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) | \
+ (1ULL << RTE_ETH_FLOW_L2_PAYLOAD))
static int i40e_fdir_filter_programming(struct i40e_pf *pf,
enum i40e_filter_pctype pctype,
@@ -2020,6 +2020,7 @@ i40e_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir)
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
uint16_t num_flex_set = 0;
uint16_t num_flex_mask = 0;
+ uint16_t i;
if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT)
fdir->mode = RTE_FDIR_MODE_PERFECT;
@@ -2032,6 +2033,8 @@ i40e_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir)
(uint32_t)hw->func_caps.fd_filters_best_effort;
fdir->max_flexpayload = I40E_FDIR_MAX_FLEX_LEN;
fdir->flow_types_mask[0] = I40E_FDIR_FLOWS;
+ for (i = 1; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
+ fdir->flow_types_mask[i] = 0ULL;
fdir->flex_payload_unit = sizeof(uint16_t);
fdir->flex_bitmask_unit = sizeof(uint16_t);
fdir->max_flex_payload_segment_num = I40E_MAX_FLXPLD_FIED;
diff --git a/drivers/net/ixgbe/ixgbe_fdir.c b/drivers/net/ixgbe/ixgbe_fdir.c
index 9281dc1..6870a57 100644
--- a/drivers/net/ixgbe/ixgbe_fdir.c
+++ b/drivers/net/ixgbe/ixgbe_fdir.c
@@ -70,14 +70,14 @@
#define IXGBE_FDIRCMD_CMD_INTERVAL_US 10
#define IXGBE_FDIR_FLOW_TYPES ( \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER))
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER))
#define IPV6_ADDR_TO_MASK(ipaddr, ipv6m) do { \
uint8_t ipv6_addr[16]; \
@@ -1435,7 +1435,7 @@ ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_hw_fdir_info *info =
IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
- uint32_t fdirctrl, max_num;
+ uint32_t fdirctrl, max_num, i;
uint8_t offset;
fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
@@ -1467,9 +1467,11 @@ ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info
if (fdir_info->mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN ||
fdir_info->mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
- fdir_info->flow_types_mask[0] = 0;
+ fdir_info->flow_types_mask[0] = 0ULL;
else
fdir_info->flow_types_mask[0] = IXGBE_FDIR_FLOW_TYPES;
+ for (i = 1; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
+ fdir_info->flow_types_mask[i] = 0ULL;
fdir_info->flex_payload_unit = sizeof(uint16_t);
fdir_info->max_flex_payload_segment_num = 1;
diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c
index f32dfdd..84927ff 100644
--- a/drivers/net/mlx5/mlx5_flow.c
+++ b/drivers/net/mlx5/mlx5_flow.c
@@ -2987,6 +2987,7 @@ priv_fdir_filter_flush(struct priv *priv)
static void
priv_fdir_info_get(struct priv *priv, struct rte_eth_fdir_info *fdir_info)
{
+ uint32_t i;
struct rte_eth_fdir_masks *mask =
&priv->dev->data->dev_conf.fdir_conf.mask;
@@ -2994,7 +2995,8 @@ priv_fdir_info_get(struct priv *priv, struct rte_eth_fdir_info *fdir_info)
fdir_info->guarant_spc = 0;
rte_memcpy(&fdir_info->mask, mask, sizeof(fdir_info->mask));
fdir_info->max_flexpayload = 0;
- fdir_info->flow_types_mask[0] = 0;
+ for (i = 0; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
+ info->flow_types_mask[i] = 0ULL;
fdir_info->flex_payload_unit = 0;
fdir_info->max_flex_payload_segment_num = 0;
fdir_info->flex_payload_limit = 0;
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 8386904..4f24a93 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -691,9 +691,9 @@ enum rte_fdir_mode {
RTE_FDIR_MODE_PERFECT_TUNNEL, /**< Enable FDIR filter mode - tunnel. */
};
-#define UINT32_BIT (CHAR_BIT * sizeof(uint32_t))
+#define UINT64_BIT (CHAR_BIT * sizeof(uint64_t))
#define RTE_FLOW_MASK_ARRAY_SIZE \
- (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
+ (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
/**
* A structure used to get the information of flow director filter.
@@ -710,7 +710,7 @@ struct rte_eth_fdir_info {
uint32_t guarant_spc; /**< Guaranteed spaces.*/
uint32_t best_spc; /**< Best effort spaces.*/
/** Bit mask for every supported flow type. */
- uint32_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
+ uint64_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
uint32_t max_flexpayload; /**< Total flex payload in bytes. */
/** Flexible payload unit in bytes. Size and alignments of all flex
payload segments should be multiplies of this value. */
@@ -803,7 +803,7 @@ enum rte_eth_hash_function {
};
#define RTE_SYM_HASH_MASK_ARRAY_SIZE \
- (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
+ (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
/**
* A structure used to set or get global hash function configurations which
* include symmetric hash enable per flow type and hash function type.
@@ -816,9 +816,9 @@ enum rte_eth_hash_function {
struct rte_eth_hash_global_conf {
enum rte_eth_hash_function hash_func; /**< Hash function type */
/** Bit mask for symmetric hash enable per flow type */
- uint32_t sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
+ uint64_t sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
/** Bit mask indicates if the corresponding bit is valid */
- uint32_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
+ uint64_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
};
/**
--
2.5.5
^ permalink raw reply [relevance 6%]
* Re: [dpdk-dev] [PATCH v2 1/2] lib/security: add support for get metadata
2017-11-22 14:13 0% ` Anoob
@ 2017-11-27 13:55 0% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2017-11-27 13:55 UTC (permalink / raw)
To: Anoob
Cc: Akhil Goyal, Declan Doherty, Radu Nicolau,
Sergio Gonzalez Monroy, Jerin Jacob, Narayana Prasad, dev
On Wed, Nov 22, 2017 at 07:43:13PM +0530, Anoob wrote:
> Hi,
>
> Please see inline.
>
>
> On 11/22/2017 06:57 PM, Neil Horman wrote:
> > On Wed, Nov 22, 2017 at 06:55:15AM +0000, Anoob Joseph wrote:
> > > In case of inline protocol processed ingress traffic, the packet may not
> > > have enough information to determine the security parameters with which
> > > the packet was processed. For such cases, application could register a
> > > 64 bit metadata in security session, which could be retrieved from the
> > > packet using "rte_security_get_pkt_metadata" API. Application can use
> > > this metadata to identify the parameters it need.
> > >
> > > Application can choose what it should register as the metadata. It can
> > > register SPI or a pointer to SA.
> > >
> > > Signed-off-by: Anoob Joseph <anoob.joseph@caviumnetworks.com>
> > > ---
> > > v2:
> > > * Replaced get_session and get_cookie APIs with get_pkt_metadata API
> > >
> > > lib/librte_security/rte_security.c | 13 +++++++++++++
> > > lib/librte_security/rte_security.h | 19 +++++++++++++++++++
> > > lib/librte_security/rte_security_driver.h | 16 ++++++++++++++++
> > > 3 files changed, 48 insertions(+)
> > >
> > > diff --git a/lib/librte_security/rte_security.c b/lib/librte_security/rte_security.c
> > > index 1227fca..804f11f 100644
> > > --- a/lib/librte_security/rte_security.c
> > > +++ b/lib/librte_security/rte_security.c
> > > @@ -108,6 +108,19 @@ rte_security_set_pkt_metadata(struct rte_security_ctx *instance,
> > > sess, m, params);
> > > }
> > > +uint64_t
> > > +rte_security_get_pkt_metadata(struct rte_security_ctx *instance,
> > > + struct rte_mbuf *pkt)
> > > +{
> > > + uint64_t mdata = 0;
> > > +
> > > + RTE_FUNC_PTR_OR_ERR_RET(*instance->ops->get_pkt_metadata, 0);
> > > + if (instance->ops->get_pkt_metadata(instance->device, pkt, &mdata))
> > > + return 0;
> > > +
> > > + return mdata;
> > > +}
> > > +
> > > const struct rte_security_capability *
> > > rte_security_capabilities_get(struct rte_security_ctx *instance)
> > > {
> > > diff --git a/lib/librte_security/rte_security.h b/lib/librte_security/rte_security.h
> > > index 653929b..aa3a471 100644
> > > --- a/lib/librte_security/rte_security.h
> > > +++ b/lib/librte_security/rte_security.h
> > > @@ -274,6 +274,8 @@ struct rte_security_session_conf {
> > > /**< Configuration parameters for security session */
> > > struct rte_crypto_sym_xform *crypto_xform;
> > > /**< Security Session Crypto Transformations */
> > > + uint64_t metadata;
> > > + /**< Metadata registered by application */
> > This is going to break ABI. You need to announce the change so that application
> > providers can be prepared for it.
> The security library is under experimental tag. So is the announcement
> required?
Ah, thats correct, its not required. That said, thats probably the fourth time
I've reviewed a patch and tripped over the fact that it was experimental. We
should probably look at ways at making that fact more visible at review, compile
and run time
Neil
> >
> > > };
> > > struct rte_security_session {
> > > @@ -346,6 +348,23 @@ rte_security_set_pkt_metadata(struct rte_security_ctx *instance,
> > > struct rte_mbuf *mb, void *params);
> > > /**
> > > + * Get metadata from the packet. This is an application registered 64 bit
> > > + * value, associated with the security session which processed the packet.
> > > + *
> > > + * This is valid only for inline processed ingress packets.
> > > + *
> > > + * @param instance security instance
> > > + * @param pkt packet mbuf
> > > + *
> > > + * @return
> > > + * - On success, metadata
> > > + * - On failure, 0
> > > + */
> > > +uint64_t
> > > +rte_security_get_pkt_metadata(struct rte_security_ctx *instance,
> > > + struct rte_mbuf *pkt);
> > > +
> > > +/**
> > > * Attach a session to a symmetric crypto operation
> > > *
> > > * @param sym_op crypto operation
> > > diff --git a/lib/librte_security/rte_security_driver.h b/lib/librte_security/rte_security_driver.h
> > > index 997fbe7..da0ebf4 100644
> > > --- a/lib/librte_security/rte_security_driver.h
> > > +++ b/lib/librte_security/rte_security_driver.h
> > > @@ -122,6 +122,20 @@ typedef int (*security_set_pkt_metadata_t)(void *device,
> > > void *params);
> > > /**
> > > + * Get application interpretable metadata from the packet.
> > > + *
> > > + * @param device Crypto/eth device pointer
> > > + * @param pkt Packet mbuf
> > > + * @param mt Pointer to receive metadata
> > > + *
> > > + * @return
> > > + * - Returns 0 if metadata is retrieved successfully.
> > > + * - Returns -ve value for errors.
> > > + */
> > > +typedef int (*security_get_pkt_metadata_t)(void *device,
> > > + struct rte_mbuf *pkt, uint64_t *mt);
> > > +
> > > +/**
> > > * Get security capabilities of the device.
> > > *
> > > * @param device crypto/eth device pointer
> > > @@ -145,6 +159,8 @@ struct rte_security_ops {
> > > /**< Clear a security sessions private data. */
> > > security_set_pkt_metadata_t set_pkt_metadata;
> > > /**< Update mbuf metadata. */
> > > + security_get_pkt_metadata_t get_pkt_metadata;
> > > + /**< Get metadata from packet. */
> > > security_capabilities_get_t capabilities_get;
> > > /**< Get security capabilities. */
> > > };
> > > --
> > > 2.7.4
> > >
> > >
>
>
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [RFC 1/2] net/tap: add eBPF to TAP device
@ 2017-11-30 8:01 1% Ophir Munk
2017-11-30 8:01 1% ` [dpdk-dev] [RFC 2/2] net/tap: add eBPF instructions Ophir Munk
2017-12-05 7:53 0% ` [dpdk-dev] [RFC 1/2] net/tap: add eBPF to TAP device Pascal Mazon
0 siblings, 2 replies; 200+ results
From: Ophir Munk @ 2017-11-30 8:01 UTC (permalink / raw)
To: dev; +Cc: Thomas Monjalon, Olga Shern, Pascal Mazon, Ophir Munk
The DPDK traffic classifier is the rte_flow API and the tap PMD
must support it including RSS queue mapping actions.
An example usage for this requirement is failsafe transparent
switching from a PCI device to TAP device while RSS queues are the
same on both devices.
TC was chosen as TAP classifier but TC alone does not support RSS
queue mapping. This commit uses a combination of TC rules and eBPF
actions in order to support TAP RSS.
eBPF requires Linux version 3.19. eBPF is effective only when running
with an appropriate kernel version. It must be compiled with the
appropriate Linux kernel headers. In case the kernel headers do
not include eBPF definitions a warning will be issued during
compilation time and TAP RSS will not be supported.
Signed-off-by: Pascal Mazon <pascal.mazon@6wind.com>
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
---
The DPDK traffic classifier is the rte_flow API and the tap PMD
must support it including RSS queue mapping actions.
An example usage for this requirement is failsafe transparent
switching from a PCI device to TAP device while RSS queues are the
same on both devices.
TC was chosen as TAP classifier but TC alone does not support RSS
queue mapping. This RFC suggests using a combination of TC rules and eBPF
actions in order to support TAP RSS.
eBPF requires Linux version 3.19. eBPF is effective only when running
with an appropriate kernel version. It must be compiled with the
appropriate Linux kernel headers. In case the kernel headers do
not include eBPF definitions a warning will be issued during
compilation time and TAP RSS will not be supported.
The C source file (tap_bpf_insns.c) includes eBPF "assembly
instructions" in the format of an array of struct bpf_insns.
This array is passed to the kernel for execution in BPF system call.
The C language source file (tap_bpf_program.c) from which the
"assembly instructions" were generated is included in TAP source tree,
however it does not take part in dpdk compilation.
TAP documentation will detail the process of eBPF "assembly instructions"
generation.
eBPF programs controlled from tap PMD will be used to match packets, compute a
hash given the configured key, and send packets using the desired queue.
In an eBPF program, it is typically not possible to edit the queue_mapping field
in skb to direct the packet in the correct queue. That part would be addressed by
chaining a ``skbedit queue_mapping`` action.
A packet would go through these TC rules (on the local side of the tap netdevice):
+-----+---------------------------+----------------------------------+----------+
|PRIO | Match | Action 1 | Action 2 |
+=====+===========================+==================================+==========+
| 1 | marked? | skbedit queue 'mark' --> DPDK | |
+-----+---------------------------+----------------------------------+----------+
| 2 | marked? | skbedit queue 'mark' --> DPDK | |
+-----+---------------------------+----------------------------------+----------+
| ... | | | |
+-----+---------------------------+----------------------------------+----------+
| x | ANY | BPF: append NULL 32bits for hash | |
| | | | |
+-----+---------------------------+----------------------------------+----------+
|x + 1| ACTUAL FLOW RULE 1 MATCH | ... | |
| | | | |
+-----+---------------------------+----------------------------------+----------+
|x + 2| ACTUAL FLOW RULE 2 MATCH | ... | |
| | | | |
+-----+---------------------------+----------------------------------+----------+
| ... | | | |
+-----+---------------------------+----------------------------------+----------+
| BPF compute hash into packet |reclassify|
| | | tailroom && set queue in skb->cb | |
+-----+---------------------------+----------------------------------+----------+
| BPF compute hash into packet |reclassify|
| | | tailroom && set queue in skb->cb | |
+-----+---------------------------+----------------------------------+----------+
| ... | | | |
+-----+---------------------------+----------------------------------+----------+
| BPF compute hash into packet |reclassify|
| | | tailroom && set queue in skb->cb | |
+-----+---------------------------+----------------------------------+----------+
| z | ANY (isolate mode) | DROP | |
+-----+---------------------------+----------------------------------+----------+
Rules 1..x will match marked packets and will redirect them to their queues however
on first classification packets are not marked there will not be redirected.
Only when going later through RSS rules y..z BPF computes RSS hash,
sets queue in dkb->cb, and reclassifies packets. Then packets are classified again
through rules 1-x while being marked and will be redirected.
Rules (x+1)..y are non-RSS TC rules already used in dpdk versions prior to 18.02
doc/guides/prog_guide/rte_flow_tap.rst | 962 +++++++++++++++++++++++++++++++++
drivers/net/tap/Makefile | 6 +-
drivers/net/tap/rte_eth_tap.h | 7 +-
drivers/net/tap/tap_bpf_elf.h | 56 ++
drivers/net/tap/tap_flow.c | 336 ++++++++----
5 files changed, 1263 insertions(+), 104 deletions(-)
create mode 100644 doc/guides/prog_guide/rte_flow_tap.rst
create mode 100644 drivers/net/tap/tap_bpf_elf.h
diff --git a/doc/guides/prog_guide/rte_flow_tap.rst b/doc/guides/prog_guide/rte_flow_tap.rst
new file mode 100644
index 0000000..04ddda6
--- /dev/null
+++ b/doc/guides/prog_guide/rte_flow_tap.rst
@@ -0,0 +1,962 @@
+=====================================
+Flow API support in TAP PMD, using TC
+=====================================
+
+.. contents::
+.. sectnum::
+
+.. footer::
+
+ v0.8 - page ###Page###
+
+.. raw:: pdf
+
+ PageBreak
+
+Rationale
+=========
+
+For this project, the tap PMD has to receive selected traffic from a different
+netdevice (refer to *VM migration with Microsoft Hyper-V and Mellanox
+ConnectX-3* document) and only cover the same set of rules as supported by the
+mlx4 PMD.
+
+The DPDK traffic classifier is the rte_flow API, and the tap PMD must therefore
+implement it. For that, TC was chosen for several reasons:
+
+- it happens very early in the kernel stack for ingress (faster than netfilter).
+- it supports dropping packets given a specific flow.
+- it supports redirecting packets to a different netdevice.
+- it has a "flower" classifier type that meets mostly the pattern items in
+ rte_flow.
+- it can be configured through a netlink socket, without an external tool.
+
+Modes of operation
+==================
+
+There should be two modes of operation for the tap PMD regarding rte_flow:
+*local* and *remote*. Only one mode can be in use at a time for a specific tap
+interface.
+
+The *local* mode would be the default one, if no specific parameter is specified
+in the command line. To start the application with tap in *remote* mode, set the
+``remote`` tap parameter to the interface you want to redirect packets from,
+e.g.::
+
+ testpmd -n 4 -c 0xf -m 1024 --vdev=net_tap,iface=tap0,remote=eth3 -- \
+ -i --burst=64 --coremask=0x2
+
+*Local* mode
+------------
+
+In *local* mode, flow rules would be applied as-is, on the tap netdevice itself
+(e.g.: ``tap0``).
+
+The typical use-case is having a linux program (e.g. a webserver) communicating
+with the DPDK app through the tap netdevice::
+
+ +-------------------------+
+ | DPDK application |
+ +-------------------------+
+ | ^
+ | rte_flow rte_flow |
+ v egress ingress |
+ +-------------------------+
+ | Tap PMD |
+ +-------------------------+
+ | ^
+ | TC TC |
+ v ingress egress |
+ +-------------------------+ +-------------------------+
+ | |<-------------| |
+ | Tap netdevice (tap0) | | Linux app (webserver) |
+ | |------------->| |
+ +-------------------------+ +-------------------------+
+
+.. raw:: pdf
+
+ PageBreak
+
+*Remote* mode
+-------------
+
+In *remote* mode, flow rules would be applied on the tap netdevice (e.g.:
+``tap0``), and use a similar match to redirect specific packets from another
+netdevice (e.g.: ``eth3``, a NetVSC netdevice in our project scenario)::
+
+ +-------------------------+
+ | DPDK application |
+ +-------------------------+
+ | ^
+ | rte_flow rte_flow |
+ v egress ingress |
+ +-------------------------+
+ | Tap PMD |
+ +-------------------------+
+ | ^
+ | TC TC |
+ v ingress egress |
+ +-------------------------+ +-------------------------+
+ | |<------------------redirection-------\ |
+ | Tap netdevice (tap0) | | | |
+ | |------------->|-\ eth3 | |
+ +-------------------------+ +--|--------------------|-+
+ | TC TC ^
+ | egress ingress |
+ v |
+
+.. raw:: pdf
+
+ PageBreak
+
+rte_flow rules conversion
+=========================
+
+Netlink
+-------
+
+The only way to create TC rules in the kernel is through netlink messages.
+Two possibilities arise for managing TC rules:
+
+- Using native netlink API calls in the tap PMD
+- Calling the ``tc`` command from iproute2 inside our PMD, via ``system()``.
+
+The former will be done, as library calls are faster than changing context and
+executing an external program from within the tap PMD. Moreover, the kernel TC
+API might propose features not yet implemented in iproute2. Furthermore, a
+custom implementation enables finer tuning and better control.
+
+..
+ Some implementations for TC configuration through Netlink exist already. It's a
+ good source of inspiration on how to do it:
+
+ - iproute2's tc `source code`__
+ - ovs's tc implementation__ (not yet upstream)
+
+ __ https://github.com/shemminger/iproute2/tree/master/tc
+ __ https://mail.openvswitch.org/pipermail/ovs-dev/2016-November/324693.html
+
+Conversion examples
+-------------------
+
+Here are a few examples of rules and how they can be translated from rte_flow
+rules to TC rules. rte_flow rules will be expressed using testpmd's ``flow``
+command syntax, while TC rules will use iproute2 ``tc`` command syntax.
+
+**Notes**:
+ - rte_flow ``ingress`` direction can be translated into a TC ``egress`` rule,
+ and vice versa, when it applies to a tap interface, as TC considers the
+ kernel netdevice standpoint.
+ - in TC, redirecting a packet works by taking a packet from ``ingress`` and
+ sending to another device's ``egress``.
+
+*Local* mode
+~~~~~~~~~~~~
+
+#. Flow rule to give packets coming on the ``tap0`` interface to RX queue 0:
+
+ Using rte_flow::
+
+ flow validate 0 ingress pattern port index is 0 / end \
+ actions queue index 0 / end
+
+ Using ``tc``::
+
+ tc filter add dev tap0 parent 1: flower indev tap0 \
+ action skbedit queue_mapping 0
+
+#. Flow rule to get packets with source mac ``de:ad:ca:fe:00:02`` on RX queue 2:
+
+ Using rte_flow::
+
+ flow create 0 ingress pattern eth src is de:ad:ca:fe:00:02 / end \
+ actions queue 2 / end
+
+ Using ``tc``::
+
+ tc filter add dev tap0 parent 1: flower src_mac de:ad:ca:fe:00:02 \
+ action skbedit queue_mapping 2
+
+#. Flow rule to drop packets matching specific 5-tuple info:
+
+ Using rte_flow::
+
+ flow create 0 ingress pattern eth dst is 3a:80:ce:61:36:54 \
+ src is 52:43:7b:fd:ac:f3 / ipv4 src is 1.1.1.1 dst is 2.2.2.2 \
+ / udp src is 4444 dst is 5555 / end actions drop / end
+
+ Using ``tc``::
+
+ tc filter add dev tap0 parent 1: flower dst_mac 3a:80:ce:61:36:54 \
+ src_mac 52:43:7b:fd:ac:f3 eth_type ip src_ip 1.1.1.1 dst_ip 2.2.2.2 \
+ ip_proto udp src_port 4444 dst_port 5555 action drop
+
+*Remote* mode
+~~~~~~~~~~~~~
+
+In *remote* mode, an additional rule for redirecting packet is systematically
+required. The examples are similar to the previous section (the rte_flow rule
+will thus be omitted).
+
+#. TC rules to give packets coming on the ``eth3`` interface to ``tap0`` RX
+ queue 0::
+
+ # redirection rule
+ tc filter add dev eth3 parent ffff: flower indev eth3 \
+ action mirred egress redirect dev tap0
+ # actual tap rule
+ tc filter add dev tap0 parent 1: flower indev tap0 \
+ action skbedit queue_mapping 0
+
+#. TC rules to get packets with source mac ``de:ad:ca:fe:00:02`` on RX queue 2::
+
+ # redirection rule
+ tc filter add dev eth3 parent ffff: flower src_mac de:ad:ca:fe:00:02 \
+ action mirred egress redirect dev tap0
+ # actual tap rule
+ tc filter add dev tap0 parent 1: flower src_mac de:ad:ca:fe:00:02 \
+ action skbedit queue_mapping 2
+
+#. TC rules to drop packets matching specific 5-tuple info::
+
+ # redirection rule
+ tc filter add dev eth3 parent ffff: flower dst_mac 3a:80:ce:61:36:54 \
+ src_mac 52:43:7b:fd:ac:f3 eth_type ip src_ip 1.1.1.1 dst_ip 2.2.2.2 \
+ ip_proto udp src_port 4444 dst_port 5555 \
+ action mirred egress redirect dev tap0
+ # actual tap rule
+ tc filter add dev tap0 parent 1: flower dst_mac 3a:80:ce:61:36:54 \
+ src_mac 52:43:7b:fd:ac:f3 eth_type ip src_ip 1.1.1.1 dst_ip 2.2.2.2 \
+ ip_proto udp src_port 4444 dst_port 5555 action drop
+
+One last thing, to redirect packets the other way around (from ``tap0`` to
+``eth3``), we would use a similar rule, exchanging interfaces and using an
+appropriate match, e.g.::
+
+ tc filter add dev tap0 parent ffff: flower indev tap0 \
+ action mirred egress redirect dev eth3
+
+..
+ **Note:** ``parent ffff:`` is for TC ``ingress`` while ``parent 1:`` is for TC
+ ``egress``.
+
+Broadcast and promiscuous support
++++++++++++++++++++++++++++++++++
+
+*Remote* mode requirements:
+
+#. When turning the tap netdevice promiscuous, the remote netdevice should
+ implicitly be turned promiscuous too, to get as many packets as possible.
+
+#. Packets matching the destination MAC configured in the tap PMD should be
+ redirected from the remote without being processed by the stack there in the
+ kernel.
+
+#. In promiscuous mode, an incoming packet should be duplicated to be processed
+ both by the tap PMD and the remote netdevice itself.
+
+#. Incoming packets with broadcast destination MAC (i.e.: ``ff:ff:ff:ff:ff:ff``)
+ should be duplicated to be processed both by the tap PMD and the remote
+ netdevice itself.
+
+#. Incoming packets with IPv6 multicast destination MAC (i.e.:
+ ``33:33:00:00:00:00/33:33:00:00:00:00``) should be duplicated to be processed
+ both by the tap PMD and the remote netdevice itself.
+
+#. Incoming packets with broadcast/multicast bit set in the destination MAC
+ (i.e.: ``01:00:00:00:00:00/01:00:00:00:00:00``) should be duplicated to be
+ processed both by the tap PMD and the remote netdevice itself.
+
+Each of these requirements (except the first one) can be directly translated
+into a TC rule, e.g.::
+
+ # local mac (notice the REDIRECT for mirred action):
+ tc filter add dev eth3 parent ffff: prio 1 flower dst_mac de:ad:be:ef:01:02 \
+ action mirred egress redirect dev tap0
+
+ # tap promisc:
+ tc filter add dev eth3 parent ffff: prio 2 basic \
+ action mirred egress mirror dev tap0
+
+ # broadcast:
+ tc filter add dev eth3 parent ffff: prio 3 flower dst_mac ff:ff:ff:ff:ff:ff \
+ action mirred egress mirror dev tap0
+
+ # broadcast v6 (can't express mac_mask with tc, but it works via netlink):
+ tc filter add dev eth3 parent ffff: prio 4 flower dst_mac 33:33:00:00:00:00 \
+ action mirred egress mirror dev tap0
+
+ # all_multi (can't express mac_mask with tc, but it works via netlink):
+ tc filter add dev eth3 parent ffff: prio 5 flower dst_mac 01:00:00:00:00:00 \
+ action mirred egress mirror dev tap0
+
+When promiscuous mode is switched off or on, the first TC rule will be modified
+to have respectively an empty action (``continue``) or the ``mirror`` action.
+
+The first 5 priorities are always reserved, and can only be used for these
+filters.
+
+On top of that, the tap PMD can configure explicit rte_flow rules, translated as
+TC rules on both the remote netdevice and the tap netdevice. On the remote,
+those would need to be processed after the default rules handling promiscuous
+mode, broadcast and all_multi packets.
+
+When using the ``mirror`` action, the packet is duplicated and sent to the tap
+netdevice, while the original packet gets directly processed by the kernel
+without going through later TC rules for the remote. On the tap netdevice, the
+duplicated packet will go through tap TC rules and be classified depending on
+those rules.
+
+**Note:** It is possible to combine a ``mirror`` action and a ``continue``
+action for a single TC rule. Then the original packet would undergo remaining TC
+rules on the remote netdevice side.
+
+When using the ``redirect`` action, the behavior is similar on the tap side, but
+the packet is not duplicated, no further kernel processing is done for the
+remote side.
+
+The following diagram sums it up. A packet that match a TC rule follows the
+associated action (the number in the diamond represents the rule prio as set in
+the above TC rules)::
+
+
+ Incoming packet |
+ on remote (eth3) |
+ | Going through
+ | TC ingress rules
+ v
+ / \
+ / 5 \
+ / \ yes
+ / mac \____________________> tap0
+ \ match?/ duplicated pkt
+ \ /
+ \ /
+ \ /
+ V no, then continue
+ | with TC rules
+ |
+ v
+ / \
+ / 2 \
+ eth3 yes / \ yes
+ kernel <____________________ /promisc\____________________> tap0
+ stack original pkt \ match?/ duplicated pkt
+ \ /
+ \ /
+ \ /
+ V no, then continue
+ | with TC rules
+ |
+ v
+ / \
+ / 3 \
+ eth3 yes / \ yes
+ kernel <____________________ / bcast \____________________> tap0
+ stack original pkt \ match?/ duplicated pkt
+ \ /
+ \ /
+ \ /
+ V no, then continue
+ | with TC rules
+ |
+ v
+ / \
+ / 4 \
+ eth3 yes / \ yes
+ kernel <____________________ / bcast6\____________________> tap0
+ stack original pkt \ match?/ duplicated pkt
+ \ /
+ \ /
+ \ /
+ V no, then continue
+ | with TC rules
+ |
+ v
+ / \
+ / 5 \
+ eth3 yes / all \ yes
+ kernel <____________________ / multi \____________________> tap0
+ stack original pkt \ match?/ duplicated pkt
+ \ /
+ \ /
+ \ /
+ V no, then continue
+ | with TC rules
+ |
+ v
+ |
+ . remaining TC rules
+ .
+ eth3 |
+ kernel <________________________/
+ stack original pkt
+
+.. raw:: pdf
+
+ PageBreak
+
+Associating an rte_flow rule with a TC one
+==========================================
+
+A TC rule is identified by a ``priority`` (16-bit value) and a ``handle``
+(32-bit value). To delete a rule, the priority must be specified, and if several
+rules have the same priority, the handle is needed to select the correct one.
+
+..
+ Specifying an empty priority and handle when requesting a TC rule creation will
+ let the kernel automatically decide what values to set. In fact, the kernel will
+ start with a high priority (i.e. 49152) and subsequent rules will get decreasing
+ priorities (lower priorites get evaluated first).
+
+To avoid further requests to the kernel to identify what priority/handle has
+been automatically allocated, the tap PMD can set priorities and handles
+systematically when creating a rule.
+
+In *local* mode, an rte_flow rule should be translated into a single TC flow
+identified by priority+handle.
+
+In *remote* mode, an rte_flow rule requires two TC rules, one on the tap
+netdevice itself (for the correct action) and another one on the other netdevice
+where packets are redirected from. Both TC rules' priorities+handles must be
+stored for a specific rte_flow rule, and associated with the device they are
+applied on.
+
+.. raw:: pdf
+
+ PageBreak
+
+Considerations regarding Flow API support
+=========================================
+
+Flow rule attributes
+--------------------
+
+Groups and priorities:
+ There is no native support of groups in TC. Instead, the priority field
+ (which is part of the netlink TC msg header) can be adapted. The four MSB
+ would be used to define the group (allowing for 16 groups), while the 12 LSB
+ would be left to define the actual priority (up to 4096).
+
+ Rules with lower priorities are evaluated first. For rules with identical
+ priorities, the one with the highest handle value gets evaluated first.
+
+Direction:
+ Both ingress and egress filtering can be supported.
+
+Meta item types
+---------------
+
+Most applications will use: ``(END | VOID)``
+
+END, VOID:
+ Supported without problem.
+
+INVERT:
+ There is no easy way to support that in TC. It won't be supported
+
+ **mlx4 will not support it either.**
+
+PF, VF, PORT:
+ Not applicable to a tap netdevice.
+
+Data matching item types
+------------------------
+
+Most applications will use:
+``ETH / (IPV4 | IPV6 | END) / (TCP | UDP | END) / END``
+
+ANY:
+ Should be supported.
+
+ **mlx4 will partially support it.**
+
+RAW:
+ It is not planned to support it for now. Matching Raw packets would require
+ using a different classifier than "flower", which is the most simple and
+ applicable for otherwise most other cases. With TC, it's not possible to
+ support in the same rule both "flower" and raw packets.
+
+ **mlx4 will not support it either**.
+
+VLAN:
+ Matching VLAN ID and prio supported.
+ **Note: linux v4.9 required for VLAN support.**
+
+ETH, IPV4, IPV6, UDP, TCP:
+ Matching source/destination MAC/IP/port is supported, with masks.
+
+ **mlx4 does not support partial bit-masks (full or zeroed only).**
+
+ICMP:
+ By specifying the appropriate ether type, ICMP packets can be matched.
+ However, there is no support for ICMP type or code.
+
+ **mlx4 will not support it, however.**
+
+SCTP:
+ By specifying the appropriate IP protocol, SCTP packets can be matched.
+ However, no specific SCTP fields can be matched.
+
+ **mlx4 will not support it, however.**
+
+VXLAN:
+ VXLAN is not recognized by the "flower" classifier. Kernel-managed VXLAN
+ traffic would come through an additional netdevice, which falls outside
+ the scope of this project. VXLAN traffic should occur outside VMs anyway.
+
+Action types
+------------
+
+Most applications will use: ``(VOID | END | QUEUE | DROP) / END``
+
+By default, multiple actions are possible for TC flow rules. However, they are
+ordered in the kernel. The implementation will need to handle actions in a way
+that orders them intelligently when creating them.
+
+VOID, END:
+ Supported.
+
+PASSTHRU:
+ The generic "continue" action can be used.
+
+ **mlx4 will not support it, however**.
+
+MARK / FLAG:
+ The mark is a field inside an skbuff. However, the tap reads messages (mostly
+ packet data), without that info. As an alternative, it may be possible to
+ create a specific queue to pass packets with a specific mark. Further testing
+ are needed to ensure it is feasable.
+
+QUEUE:
+ The ``skbedit`` action with the ``queue_mapping`` option enables directing
+ packets to specific queues.
+
+ Like rte_flow, specifying several ``skbedit queue_mapping`` actions in TC
+ only considers the last one.
+
+DROP:
+ The generic "drop" action can be used. Packets will effectively be dropped,
+ and not left for the kernel to process.
+
+COUNT: Stats are automatically stored in the kernel. The COUNT action will thus
+ be ignored when creating the rule. ``rte_flow_query()`` can be implemented
+ to request a rule's stats from the kernel.
+
+DUP:
+ Duplicating packets is not supported.
+
+RSS:
+ There's no built-in mechanism for RSS in TC.
+
+ By default, incoming packets go to the tap PMD queue 0. To support RSS in
+ software, several additional queues must be set up. Packets coming in on
+ queue 0 can be considered as requiring RSS, and the PMD will apply software
+ rss (using something like ``rte_softrss()``) to select a queue for the
+ packet.
+
+PF, VF:
+ Not applicable to a tap netdevice.
+
+.. raw:: pdf
+
+ PageBreak
+
+TC limitations for flow collision
+=================================
+
+From TC standpoint, filter rules with identical priorities do not collide, if
+they do specify values (at least one different) for the same fields in the TC
+message, with identical fields masks.
+
+Unfortunately, some flows that obviously are not colliding can be considered
+otherwise by the kernel when parsing the TC messages, and thus their creation
+would be rejected.
+
+Here is a table for matching TC fields with their flow API equivalent:
+
++------------------------------+-----------------------------------+-----------+
+| TC message field | rte_flow API | maskable? |
++==============================+===================================+===========+
+| TCA_FLOWER_KEY_ETH_DST | eth dst | yes |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_ETH_SRC | eth src | yes |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_ETH_TYPE | eth type is 0xZZZZ || | no |
+| | eth / {ipv4|ipv6} | |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IP_PROTO | eth / {ipv4|ipv6} / {tcp|udp} | no |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IPV4_SRC | eth / ipv4 src | yes |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IPV4_DST | eth / ipv4 dst | yes |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IPV6_SRC | eth / ipv6 src | yes |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_IPV6_DST | eth / ipv6 dst | yes |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_L4_SRC | eth / {ipv4|ipv6} / {tcp|udp} dst | no |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_L4_DST | eth / {ipv4|ipv6} / {tcp|udp} src | no |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_VLAN_ID | eth / vlan vid | no |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_VLAN_PRIO | eth / vlan pcp | no |
++------------------------------+-----------------------------------+-----------+
+| TCA_FLOWER_KEY_VLAN_ETH_TYPE | eth / vlan tpid | no |
++------------------------------+-----------------------------------+-----------+
+
+When creating rules with identical priorities, one must make sure that they
+would be translated in TC using the same fields as shown in the above table.
+
+The following flow rules can share the same priority, as they use the same
+fields with identical masks under the hood::
+
+ > flow create 0 ingress priority 0 pattern eth / ipv4 / end
+ actions drop / end
+ Flow rule #0 created
+ > flow create 0 ingress priority 0 pattern eth type is 0x86dd / end
+ actions drop / end
+ Flow rule #1 created
+
+**Note:** Both rules use ETH_TYPE (mask 0xffff) in their TC form.
+
+Sadly, the following flow rules cannot share the same priority, since fields for
+matching IPv4 and IPv6 src/dst addresses are different::
+
+ > flow create 0 ingress priority 1 pattern eth / ipv4 src is 1.1.1.1 / end
+ actions drop / end
+ Flow rule #0 created
+ > flow create 0 ingress priority 1 pattern eth / ipv6 src is ::1 / end
+ actions drop / end
+ PMD: Kernel refused TC filter rule creation (22): Invalid argument
+ Caught error type 2 (flow rule (handle)): overlapping rules
+
+**Note:** First rule uses ETH_TYPE and IPV4_SRC, while the second uses ETH_TYPE
+and IPV6_SRC.
+
+It is however possible to match different IPvX addresses with the same
+priority::
+
+ > flow create 0 ingress priority 2 pattern eth / ipv4 src is 1.1.1.1 / end
+ actions drop / end
+ Flow rule #0 created
+ > flow create 0 ingress priority 2 pattern eth / ipv4 src is 2.2.2.2 / end
+ actions drop / end
+ Flow rule #1 created
+
+If the first rule specifies both destination and source addresses, then the
+other rule with the same priority must too (with identical masks)::
+
+ > flow create 0 ingress priority 3 pattern eth / ipv4 src is 1.1.1.1
+ dst is 1.1.1.2 / end actions drop / end
+ Flow rule #0 created
+ > flow create 0 ingress priority 3 pattern eth / ipv4 src is 2.2.2.2 / end
+ actions drop / end
+ PMD: Kernel refused TC filter rule creation (22): Invalid argument
+ Caught error type 2 (flow rule (handle)): overlapping rules
+ > flow create 0 ingress priority 3 pattern eth / ipv4 src is 2.2.2.2
+ dst spec 2.2.2.3 dst mask 255.255.255.0 / end actions drop / end
+ PMD: Kernel refused TC filter rule creation (22): Invalid argument
+ Caught error type 2 (flow rule (handle)): overlapping rules
+ > flow create 0 ingress priority 3 pattern eth / ipv4 src is 2.2.2.2
+ dst is 2.2.2.3 / end actions drop / end
+ Flow rule #1 created
+
+**Note:** First rule uses ETH_TYPE, IPV4_SRC and IPV4_DST (with full masks). The
+two others must also use those to share the same priority.
+
+It is possible to match TCP/UDP packets with different ports whatever the
+underlying L3, if the same fields are used (thus no l3 addresses specification).
+For instance::
+
+ > flow create 0 ingress priority 4 pattern eth / ipv4 / tcp dst is 3333 / end
+ actions drop / end
+ Flow rule #0 created
+ > flow create 0 ingress priority 4 pattern eth / ipv6 / udp dst is 4444 / end
+ actions drop / end
+ Flow rule #1 created
+ > flow create 0 ingress priority 4 pattern eth / ipv6 / udp src is 5555 / end
+ actions drop / end
+ PMD: Kernel refused TC filter rule creation (22): Invalid argument
+ Caught error type 2 (flow rule (handle)): overlapping rules
+
+**Note:** First 2 rules use ETH_TYPE, IP_PROTO and L4_DST with different values
+but identical masks, so they're OK. Last rule used L4_SRC instead of L4_DST.
+
+.. raw:: pdf
+
+ PageBreak
+
+RSS implementation for tap
+==========================
+
+There are several areas of research for a tap RSS implementation:
+
+#. userland implementation in tap PMD
+#. userland implementation in DPDK (generic)
+#. userland implementation using combination of TC rules and BPF filters/actions
+#. kernel-side implementation in tap driver
+#. kernel-side implementation as a BPF classifier/action
+#. kernel-side implementation as a separate TC action
+
++--------------+------------------------------+------------------------------+
+| | Pros | Cons |
++==============+==============================+==============================+
+| tap PMD | - no kernel upstreaming | - tap PMD is supposed to be |
+| | | simple, and would no longer|
+| | | be. |
+| | | |
+| | | - complex rework, with many |
+| | | rings for enqueuing packets|
+| | | to the right queue |
+| | | |
+| | | - slower |
+| | | |
+| | | - won't be accepted as it |
+| | | doesn't make sense to redo |
+| | | what the kernel did |
+| | | previously |
++--------------+------------------------------+------------------------------+
+| generic DPDK | - would be useful to others | - design must be compatible |
+| | | with most PMDs |
+| | | |
+| | | - probably the longest to |
+| | | develop |
+| | | |
+| | | - requires DPDK community |
+| | | approval |
+| | | |
+| | | - requires heavy changes in |
+| | | tap PMD itself anyway |
++--------------+------------------------------+------------------------------+
+| TC rules | - no kernel upstreaming | - BPF is complicated to learn|
+| combination | | |
+| | - fast | - Runtime BPF compilation / |
+| | | or bytecode change, would |
+| | - per-flow RSS | be tricky |
+| | | |
+| | - no change in tap PMD | - much rework in the tap PMD |
+| | datapath | to handle lots of new |
+| | | netlink messages / actions |
++--------------+------------------------------+------------------------------+
+| tap driver | - pretty fast as it | - might not be accepted by |
+| | intervenes early in packet | the kernel community as |
+| | RX | they may cling to their |
+| | | jhash2 hashing function for|
+| | | RX. |
+| | | |
+| | | - only a single RSS context |
++--------------+------------------------------+------------------------------+
+| BPF | - fast | - BPF is complicated to learn|
+| classifier - | | |
+| action | - per-flow RSS | - would require changing the |
+| | | kernel API to support |
+| | | editing queue_mapping in an|
+| | | skb |
+| | | |
+| | | - hashing would be performed |
+| | | for each queue of a |
+| | | specific RSS context |
+| | | |
+| | | - probably difficult to gain |
+| | | community acceptance |
++--------------+------------------------------+------------------------------+
+| TC action | - much more flexibility, with| - needs to be in sync with |
+| | per-flow RSS, multiple | iproute2's tc program |
+| | keys, multiple packet | |
+| | fields for the hash... | - kernel upstreaming is not |
+| | | necessarily easy |
+| | - it's a separate kernel | |
+| | module that can be | - rework in tap PMD to |
+| | maintained out-of-tree and | support new RSS action and |
+| | optionally upstreamed | configuration |
+| | anytime | |
+| | | |
+| | - most logical to be handled | |
+| | in kernel as RSS is | |
+| | supposed to be computed in | |
+| | the "NIC" exactly once. | |
+| | | |
+| | - fastest | |
+| | | |
+| | - no change in tap PMD | |
+| | datapath | |
++--------------+------------------------------+------------------------------+
+
+TC rules using BPF from tap PMD
+-------------------------------
+
+The third solution is the best for userland-based solutions.
+It does the job well, fast (datapath running in kernel), is logically happening
+in the kernel in runtime, supports flow-based RSS, has the best potential to
+be accepted by the community.
+
+Advantages with this solution:
+- hash can be recorded in the packet data and read in tap PMD
+- no kernel customization, everything in DPDK
+- packet gets in tap PMD on the correct queue directly
+
+Drawbacks:
+- complicates tap PMD a lot:
+ - 3 BPF programs
+ - new implicit rules
+ - new action and filter support
+ - packet stripping
+- numerous TC rules required (in proportion with the number of queues)
+- fast (kernel + JIT BPF), but several TC rules must be crossed
+
+BPF programs controlled from tap PMD will be used to match packets, compute a
+hash given the configured key, and send packets to tap using the desired queue.
+
+Design
+~~~~~~
+
+BPF has a limited set of functions for editing the skb in TC. They are listed
+in ``linux/net/core/filter.c:tc_cls_act_func_proto()``:
+
+- skb_store_bytes
+- skb_load_bytes
+- skb_pull_data
+- csum_diff
+- csum_update
+- l3_csum_replace
+- l4_csum_replace
+- clone_redirect
+- get_cgroup_classid
+- skb_vlan_push
+- skb_vlan_pop
+- skb_change_proto
+- skb_change_type
+- skb_change_tail
+- skb_get_tunnel_key
+- skb_set_tunnel_key
+- skb_get_tunnel_opt
+- skb_set_tunnel_opt
+- redirect
+- get_route_realm
+- get_hash_recalc
+- set_hash_invalid
+- perf_event_output
+- get_smp_processor_id
+- skb_under_cgroup
+
+In a BPF program, it is typically not possible to edit the queue_mapping field
+to direct the packet in the correct queue. That part would be done by chaining a
+``skbedit queue_mapping`` action.
+
+It is not possible either to directly prepend data to a packet (appending works,
+though).
+
+A packet would go through these rules (on the local side of the tap netdevice):
+
++-----+---------------------------+----------------------------------+----------+
+|PRIO | Match | Action 1 | Action 2 |
++=====+===========================+==================================+==========+
+| 1 | marked? | skbedit queue 'mark' --> DPDK | |
++-----+---------------------------+----------------------------------+----------+
+| 2 | marked? | skbedit queue 'mark' --> DPDK | |
++-----+---------------------------+----------------------------------+----------+
+| ... | | | |
++-----+---------------------------+----------------------------------+----------+
+| x | ANY | BPF: append NULL 32bits for hash | |
+| | | | |
++-----+---------------------------+----------------------------------+----------+
+|x + 1| ACTUAL FLOW RULE 1 MATCH | ... | |
+| | | | |
++-----+---------------------------+----------------------------------+----------+
+|x + 2| ACTUAL FLOW RULE 2 MATCH | ... | |
+| | | | |
++-----+---------------------------+----------------------------------+----------+
+| ... | | | |
++-----+---------------------------+----------------------------------+----------+
+| y | FLOW RULE RSS 1 MATCH | BPF compute hash into packet |reclassify|
+| | | tailroom && set queue in skb->cb | |
++-----+---------------------------+----------------------------------+----------+
+|y + 1| FLOW RULE RSS 2 MATCH | BPF compute hash into packet |reclassify|
+| | | tailroom && set queue in skb->cb | |
++-----+---------------------------+----------------------------------+----------+
+| ... | | | |
++-----+---------------------------+----------------------------------+----------+
+| z | ANY (default RSS) | BPF compute hash into packet |reclassify|
+| | | tailroom && set queue in skb->cb | |
++-----+---------------------------+----------------------------------+----------+
+| z | ANY (isolate mode) | DROP | |
++-----+---------------------------+----------------------------------+----------+
+
+
+
+TC kernel action
+----------------
+
+The latest solution (implementing a TC action) would probably be the most simple
+to implement. It is also very flexible, opening more possibilities for filtering
+and RSS combined.
+
+For this solution, the following parameters could be used to configure RSS in a
+TC netlink message:
+
+``queues`` (u16 \*):
+ list of queues to spread incoming traffic on. That's actually the reta.
+ **Note:** the queue in an ``skb`` is on 16-bits, hence the type here.
+
+``key`` (u8 \*):
+ key to use for the Toeplitz-hash in this flow.
+
+``hash_fields`` (bitfield):
+ similar to what's in DPDK, the bitfield should determine what fields in the
+ packet header to use for hashing. It is likely another means of configuring
+ which fields to pick would be used actually.
+
+``algo`` (unsigned):
+ an enum value from the kernel act_rss header can be used to determine which
+ algorithm (implemented in the kernel) to use. Possible algos could be
+ toeplitz, xor, symmetric hash...
+
+**Note:** The number of queues to use is automatically deduced from the
+``queues`` netlink attribute length. The ``key`` length can be similarly
+obtained.
+
+.. raw:: pdf
+
+ PageBreak
+
+Appendix: TC netlink message
+============================
+
+**Note:** For deterministic behavior, TC queueing disciplines (QDISC), filters
+and classes must be flushed before starting to apply TC rules. There is a little
+bit of boilerplate (with specific netlink messages) to ensure TC rules can be
+applied. Typically, the TC ``ingress`` QDISC must be created first.
+
+For information, netlink messages regarding TC will look like this::
+
+ 0 8 16 24 32
+ +----------+----------+----------+----------+ ---
+ 0 | Length | \
+ +---------------------+---------------------+ \
+ 4 | Type | Flags | |
+ +----------- ---------+---------------------+ >-- struct
+ 8 | Sequence number | | nlmsghdr
+ +-------------------------------------------+ /
+ 12 | Process Port ID (PID) | /
+ +==========+==========+==========+==========+ ---
+ 16 | Family | Rsvd1 | Reserved2 | \
+ +----------+----------+---------------------+ \
+ 20 | Interface index | |
+ +-------------------------------------------+ |
+ 24 | Handle | |
+ +-------------------------------------------+ >-- struct
+ 28 | Parent handle | | tcmsg
+ | MAJOR + MINOR | |
+ +-------------------------------------------+ |
+ 32 | TCM info | /
+ | priority + protocol | /
+ +===========================================+ ---
+ | |
+ | Payload |
+ | |
+ ........................................
+ | |
+ | |
+ +-------------------------------------------+
diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index 405b49e..9afae5e 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -39,6 +39,9 @@ EXPORT_MAP := rte_pmd_tap_version.map
LIBABIVER := 1
+# TAP_MAX_QUEUES must be a power of 2 as it will be used for masking */
+TAP_MAX_QUEUES = 16
+
CFLAGS += -O3
CFLAGS += -I$(SRCDIR)
CFLAGS += -I.
@@ -47,6 +50,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
LDLIBS += -lrte_bus_vdev
+CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
+
#
# all source are stored in SRCS-y
#
@@ -89,7 +94,6 @@ tap_autoconf.h: tap_autoconf.h.new
mv '$<' '$@'
$(SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP):.c=.o): tap_autoconf.h
-
clean_tap: FORCE
$Q rm -f -- tap_autoconf.h tap_autoconf.h.new
diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
index 829f32f..01ac153 100644
--- a/drivers/net/tap/rte_eth_tap.h
+++ b/drivers/net/tap/rte_eth_tap.h
@@ -45,7 +45,7 @@
#include <rte_ether.h>
#ifdef IFF_MULTI_QUEUE
-#define RTE_PMD_TAP_MAX_QUEUES 16
+#define RTE_PMD_TAP_MAX_QUEUES TAP_MAX_QUEUES
#else
#define RTE_PMD_TAP_MAX_QUEUES 1
#endif
@@ -90,6 +90,11 @@ struct pmd_internals {
int ioctl_sock; /* socket for ioctl calls */
int nlsk_fd; /* Netlink socket fd */
int flow_isolate; /* 1 if flow isolation is enabled */
+ int flower_support; /* 1 if kernel supports, else 0 */
+ int flower_vlan_support; /* 1 if kernel supports, else 0 */
+ int rss_enabled; /* 1 if RSS is enabled, else 0 */
+ /* implicit rules set when RSS is enabled */
+ LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
LIST_HEAD(tap_flows, rte_flow) flows; /* rte_flow rules */
/* implicit rte_flow rules set when a remote device is active */
LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
diff --git a/drivers/net/tap/tap_bpf_elf.h b/drivers/net/tap/tap_bpf_elf.h
new file mode 100644
index 0000000..f3db1bf
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_elf.h
@@ -0,0 +1,56 @@
+/*******************************************************************************
+
+ Copyright (C) 2015 Daniel Borkmann <daniel@iogearbox.net>
+
+ Copied from iproute2's include/bpf_elf.h, available at:
+ https://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git
+
+ This file is licensed under GNU General Public License (GPL) v2.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "LICENSE.GPL".
+
+*******************************************************************************/
+
+
+#ifndef __BPF_ELF__
+#define __BPF_ELF__
+
+#include <asm/types.h>
+
+/* Note:
+ *
+ * Below ELF section names and bpf_elf_map structure definition
+ * are not (!) kernel ABI. It's rather a "contract" between the
+ * application and the BPF loader in tc. For compatibility, the
+ * section names should stay as-is. Introduction of aliases, if
+ * needed, are a possibility, though.
+ */
+
+/* ELF section names, etc */
+#define ELF_SECTION_LICENSE "license"
+#define ELF_SECTION_MAPS "maps"
+#define ELF_SECTION_PROG "prog"
+#define ELF_SECTION_CLASSIFIER "classifier"
+#define ELF_SECTION_ACTION "action"
+
+#define ELF_MAX_MAPS 64
+#define ELF_MAX_LICENSE_LEN 128
+
+/* Object pinning settings */
+#define PIN_NONE 0
+#define PIN_OBJECT_NS 1
+#define PIN_GLOBAL_NS 2
+
+/* ELF map definition */
+struct bpf_elf_map {
+ __u32 type;
+ __u32 size_key;
+ __u32 size_value;
+ __u32 max_elem;
+ __u32 flags;
+ __u32 id;
+ __u32 pinning;
+};
+
+#endif /* __BPF_ELF__ */
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index ffc0b85..43bab7d 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -43,6 +43,9 @@
#include <tap_autoconf.h>
#include <tap_tcmsgs.h>
+#include <linux/bpf.h>
+#include <linux/tc_act/tc_bpf.h>
+
#ifndef HAVE_TC_FLOWER
/*
* For kernels < 4.2, this enum is not defined. Runtime checks will be made to
@@ -104,6 +107,23 @@ struct remote_rule {
int mirred;
};
+struct action_data {
+ char id[16];
+
+ union {
+ struct tc_gact gact;
+ struct tc_mirred mirred;
+ struct skbedit {
+ struct tc_skbedit skbedit;
+ uint16_t queue;
+ } skbedit;
+ struct bpf {
+ int bpf_fd;
+ char *annotation;
+ } bpf;
+ };
+};
+
static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
@@ -134,6 +154,8 @@ struct remote_rule {
int set,
struct rte_flow_error *error);
+static int rss_enable(struct pmd_internals *pmd);
+
static const struct rte_flow_ops tap_flow_ops = {
.validate = tap_flow_validate,
.create = tap_flow_create,
@@ -816,111 +838,64 @@ struct tap_flow_items {
}
/**
- * Transform a DROP/PASSTHRU action item in the provided flow for TC.
- *
- * @param[in, out] flow
- * Flow to be filled.
- * @param[in] action
- * Appropriate action to be set in the TCA_GACT_PARMS structure.
- *
- * @return
- * 0 if checks are alright, -1 otherwise.
+ * FIXME
*/
static int
-add_action_gact(struct rte_flow *flow, int action)
+add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
{
struct nlmsg *msg = &flow->msg;
- size_t act_index = 1;
- struct tc_gact p = {
- .action = action
- };
- if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
- return -1;
- if (nlattr_nested_start(msg, act_index++) < 0)
+ if (nlattr_nested_start(msg, ++(*act_index)) < 0)
return -1;
- nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
- if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
- return -1;
- nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
- nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
- nlattr_nested_finish(msg); /* nested act_index */
- nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
- return 0;
-}
-
-/**
- * Transform a MIRRED action item in the provided flow for TC.
- *
- * @param[in, out] flow
- * Flow to be filled.
- * @param[in] ifindex
- * Netdevice ifindex, where to mirror/redirect packet to.
- * @param[in] action_type
- * Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
- *
- * @return
- * 0 if checks are alright, -1 otherwise.
- */
-static int
-add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
-{
- struct nlmsg *msg = &flow->msg;
- size_t act_index = 1;
- struct tc_mirred p = {
- .eaction = action_type,
- .ifindex = ifindex,
- };
- if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
- return -1;
- if (nlattr_nested_start(msg, act_index++) < 0)
- return -1;
- nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
+ nlattr_add(&msg->nh, TCA_ACT_KIND, strlen(adata->id), adata->id);
if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
return -1;
- if (action_type == TCA_EGRESS_MIRROR)
- p.action = TC_ACT_PIPE;
- else /* REDIRECT */
- p.action = TC_ACT_STOLEN;
- nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
+ if (strcmp("gact", adata->id) == 0) {
+ nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
+ &adata->gact);
+ } else if (strcmp("mirred", adata->id) == 0) {
+ if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
+ adata->mirred.action = TC_ACT_PIPE;
+ else /* REDIRECT */
+ adata->mirred.action = TC_ACT_STOLEN;
+ nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(adata->mirred),
+ &adata->mirred);
+ } else if (strcmp("skbedit", adata->id) == 0) {
+ nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
+ sizeof(adata->skbedit.skbedit),
+ &adata->skbedit.skbedit);
+ nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
+ adata->skbedit.queue);
+ } else if (strcmp("bpf", adata->id) == 0) {
+ nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
+ nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
+ strlen(adata->bpf.annotation),
+ adata->bpf.annotation);
+ } else {
+ return -1;
+ }
nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
nlattr_nested_finish(msg); /* nested act_index */
- nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
return 0;
}
/**
- * Transform a QUEUE action item in the provided flow for TC.
- *
- * @param[in, out] flow
- * Flow to be filled.
- * @param[in] queue
- * Queue id to use.
- *
- * @return
- * 0 if checks are alright, -1 otherwise.
+ * FIXME
*/
static int
-add_action_skbedit(struct rte_flow *flow, uint16_t queue)
+add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
+ int classifier_action)
{
struct nlmsg *msg = &flow->msg;
- size_t act_index = 1;
- struct tc_skbedit p = {
- .action = TC_ACT_PIPE
- };
+ size_t act_index = 0;
+ int i;
- if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
- return -1;
- if (nlattr_nested_start(msg, act_index++) < 0)
+ if (nlattr_nested_start(msg, classifier_action) < 0)
return -1;
- nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
- if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
- return -1;
- nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
- nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
- nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
- nlattr_nested_finish(msg); /* nested act_index */
+ for (i = 0; i < nb_actions; i++)
+ if (add_action(flow, &act_index, data + i) < 0)
+ return -1;
nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
return 0;
}
@@ -1053,7 +1028,12 @@ struct tap_flow_items {
}
}
if (mirred && flow) {
- uint16_t if_index = pmd->if_index;
+ struct action_data adata = {
+ .id = "mirred",
+ .mirred = {
+ .eaction = mirred,
+ },
+ };
/*
* If attr->egress && mirred, then this is a special
@@ -1061,9 +1041,13 @@ struct tap_flow_items {
* redirect packets coming from the DPDK App, out
* through the remote netdevice.
*/
- if (attr->egress)
- if_index = pmd->remote_if_index;
- if (add_action_mirred(flow, if_index, mirred) < 0)
+ adata.mirred.ifindex = attr->ingress ? pmd->if_index :
+ pmd->remote_if_index;
+ if (mirred == TCA_EGRESS_MIRROR)
+ adata.mirred.action = TC_ACT_PIPE;
+ else
+ adata.mirred.action = TC_ACT_STOLEN;
+ if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
goto exit_action_not_supported;
else
goto end;
@@ -1077,14 +1061,33 @@ struct tap_flow_items {
if (action)
goto exit_action_not_supported;
action = 1;
- if (flow)
- err = add_action_gact(flow, TC_ACT_SHOT);
+ if (flow) {
+ struct action_data adata = {
+ .id = "gact",
+ .gact = {
+ .action = TC_ACT_SHOT,
+ },
+ };
+
+ err = add_actions(flow, 1, &adata,
+ TCA_FLOWER_ACT);
+ }
} else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
if (action)
goto exit_action_not_supported;
action = 1;
- if (flow)
- err = add_action_gact(flow, TC_ACT_UNSPEC);
+ if (flow) {
+ struct action_data adata = {
+ .id = "gact",
+ .gact = {
+ /* continue */
+ .action = TC_ACT_UNSPEC,
+ },
+ };
+
+ err = add_actions(flow, 1, &adata,
+ TCA_FLOWER_ACT);
+ }
} else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
const struct rte_flow_action_queue *queue =
(const struct rte_flow_action_queue *)
@@ -1096,22 +1099,30 @@ struct tap_flow_items {
if (!queue ||
(queue->index > pmd->dev->data->nb_rx_queues - 1))
goto exit_action_not_supported;
- if (flow)
- err = add_action_skbedit(flow, queue->index);
+ if (flow) {
+ struct action_data adata = {
+ .id = "skbedit",
+ .skbedit = {
+ .skbedit = {
+ .action = TC_ACT_PIPE,
+ },
+ .queue = queue->index,
+ },
+ };
+
+ err = add_actions(flow, 1, &adata,
+ TCA_FLOWER_ACT);
+ }
} else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
- /* Fake RSS support. */
const struct rte_flow_action_rss *rss =
(const struct rte_flow_action_rss *)
actions->conf;
- if (action)
- goto exit_action_not_supported;
- action = 1;
- if (!rss || rss->num < 1 ||
- (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
+ if (action++)
goto exit_action_not_supported;
- if (flow)
- err = add_action_skbedit(flow, rss->queue[0]);
+ if (!pmd->rss_enabled)
+ err = rss_enable(pmd);
+ (void)rss;
} else {
goto exit_action_not_supported;
}
@@ -1632,6 +1643,127 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
return 0;
}
+#define BPF_PROGRAM "tap_bpf_program.o"
+
+/**
+ * Enable RSS on tap: create leading TC rules for queuing.
+ */
+static int rss_enable(struct pmd_internals *pmd)
+{
+ struct rte_flow *rss_flow = NULL;
+ char section[64];
+ struct nlmsg *msg = NULL;
+ /* 4096 is the maximum number of instructions for a BPF program */
+ char annotation[256];
+ int bpf_fd;
+ int i;
+
+ /*
+ * Add a rule per queue to match reclassified packets and direct them to
+ * the correct queue.
+ */
+ for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
+ struct action_data adata = {
+ .id = "skbedit",
+ .skbedit = {
+ .skbedit = {
+ .action = TC_ACT_PIPE,
+ },
+ .queue = i,
+ },
+ };
+
+ bpf_fd = 0;
+
+ rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+ if (!rss_flow) {
+ RTE_LOG(ERR, PMD,
+ "Cannot allocate memory for rte_flow");
+ return -1;
+ }
+ msg = &rss_flow->msg;
+ tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
+ NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
+ msg->t.tcm_info = TC_H_MAKE((i + PRIORITY_OFFSET) << 16,
+ htons(ETH_P_ALL));
+ msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
+ tap_flow_set_handle(rss_flow);
+ nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
+ if (nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+ return -1;
+ nlattr_add32(&msg->nh, TCA_BPF_FD, bpf_fd);
+ snprintf(annotation, sizeof(annotation), "%s:[%s]",
+ BPF_PROGRAM, section);
+ nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation),
+ annotation);
+
+ if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
+ return -1;
+ nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
+ /* Netlink message is now ready to be sent */
+ if (nl_send(pmd->nlsk_fd, &msg->nh) < 0)
+ return -1;
+ if (nl_recv_ack(pmd->nlsk_fd) < 0)
+ return -1;
+ LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+ }
+
+ snprintf(annotation, sizeof(annotation), "%s:[%s]", BPF_PROGRAM,
+ section);
+ rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
+ if (!rss_flow) {
+ RTE_LOG(ERR, PMD,
+ "Cannot allocate memory for rte_flow");
+ return -1;
+ }
+ msg = &rss_flow->msg;
+ tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER,
+ NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
+ msg->t.tcm_info =
+ TC_H_MAKE((RTE_PMD_TAP_MAX_QUEUES + PRIORITY_OFFSET) << 16,
+ htons(ETH_P_ALL));
+ msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
+ tap_flow_set_handle(rss_flow);
+ nlattr_add(&msg->nh, TCA_KIND, sizeof("flower"), "flower");
+ if (nlattr_nested_start(msg, TCA_OPTIONS) < 0)
+ return -1;
+
+ /* no fields for matching: all packets must match */
+ {
+ /* Actions */
+ struct action_data data[2] = {
+ [0] = {
+ .id = "bpf",
+ .bpf = {
+ .bpf_fd = bpf_fd,
+ .annotation = annotation,
+ },
+ },
+ [1] = {
+ .id = "gact",
+ .gact = {
+ /* continue */
+ .action = TC_ACT_UNSPEC,
+ },
+ },
+ };
+
+ if (add_actions(rss_flow, 2, data, TCA_FLOWER_ACT) < 0)
+ return -1;
+ }
+ nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
+ nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
+ /* Netlink message is now ready to be sent */
+ if (nl_send(pmd->nlsk_fd, &msg->nh) < 0)
+ return -1;
+ if (nl_recv_ack(pmd->nlsk_fd) < 0)
+ return -1;
+ LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
+
+ pmd->rss_enabled = 1;
+ return 0;
+}
+
/**
* Manage filter operations.
*
--
1.8.3.1
^ permalink raw reply [relevance 1%]
* [dpdk-dev] [RFC 2/2] net/tap: add eBPF instructions
2017-11-30 8:01 1% [dpdk-dev] [RFC 1/2] net/tap: add eBPF to TAP device Ophir Munk
@ 2017-11-30 8:01 1% ` Ophir Munk
2017-12-05 7:53 0% ` [dpdk-dev] [RFC 1/2] net/tap: add eBPF to TAP device Pascal Mazon
1 sibling, 0 replies; 200+ results
From: Ophir Munk @ 2017-11-30 8:01 UTC (permalink / raw)
To: dev; +Cc: Thomas Monjalon, Olga Shern, Pascal Mazon, Ophir Munk
The C source file (tap_bpf_insns.c) includes eBPF "assembly
instructions" in the format of an array of struct bpf_insns.
This array is passed to the kernel for execution in BPF system call.
The C language source file (tap_bpf_program.c) from which the
"assembly instructions" were generated is included in TAP source tree,
however it does not take part in dpdk compilation.
TAP documentation details the process of eBPF "assembly instructions"
generation.
Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
Signed-off-by: Pascal Mazon <pascal.mazon@6wind.com>
---
drivers/net/tap/Makefile | 1 +
drivers/net/tap/tap_bpf_api.h | 276 ++
drivers/net/tap/tap_bpf_insns.c | 5427 +++++++++++++++++++++++++++++++++++++
drivers/net/tap/tap_bpf_program.c | 321 +++
drivers/net/tap/tap_bpf_shared.h | 40 +
drivers/net/tap/tap_flow.c | 11 +-
6 files changed, 6075 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/tap/tap_bpf_api.h
create mode 100644 drivers/net/tap/tap_bpf_insns.c
create mode 100644 drivers/net/tap/tap_bpf_program.c
create mode 100644 drivers/net/tap/tap_bpf_shared.h
diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
index 9afae5e..c334d90 100644
--- a/drivers/net/tap/Makefile
+++ b/drivers/net/tap/Makefile
@@ -59,6 +59,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += rte_eth_tap.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_flow.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_netlink.c
SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_tcmsgs.c
+SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP) += tap_bpf_insns.c
include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/tap/tap_bpf_api.h b/drivers/net/tap/tap_bpf_api.h
new file mode 100644
index 0000000..0328dd8
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_api.h
@@ -0,0 +1,276 @@
+/*******************************************************************************
+
+ Copyright (C) 2015 Daniel Borkmann <daniel@iogearbox.net>
+
+ Copied from iproute2's include/bpf_api.h, available at:
+ https://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git
+
+ This file is licensed under GNU General Public License (GPL) v2.
+
+ The full GNU General Public License is included in this distribution in
+ the file called "LICENSE.GPL".
+
+*******************************************************************************/
+
+
+#ifndef __BPF_API__
+#define __BPF_API__
+
+/* Note:
+ *
+ * This file can be included into eBPF kernel programs. It contains
+ * a couple of useful helper functions, map/section ABI (bpf_elf.h),
+ * misc macros and some eBPF specific LLVM built-ins.
+ */
+
+#include <stdint.h>
+
+#include <linux/pkt_cls.h>
+#include <linux/bpf.h>
+#include <linux/filter.h>
+
+#include <asm/byteorder.h>
+
+#include "tap_bpf_elf.h"
+
+/** Misc macros. */
+
+#ifndef __stringify
+# define __stringify(X) #X
+#endif
+
+#ifndef __maybe_unused
+# define __maybe_unused __attribute__((__unused__))
+#endif
+
+#ifndef offsetof
+# define offsetof(TYPE, MEMBER) __builtin_offsetof(TYPE, MEMBER)
+#endif
+
+#ifndef likely
+# define likely(X) __builtin_expect(!!(X), 1)
+#endif
+
+#ifndef unlikely
+# define unlikely(X) __builtin_expect(!!(X), 0)
+#endif
+
+#ifndef htons
+# define htons(X) __constant_htons((X))
+#endif
+
+#ifndef ntohs
+# define ntohs(X) __constant_ntohs((X))
+#endif
+
+#ifndef htonl
+# define htonl(X) __constant_htonl((X))
+#endif
+
+#ifndef ntohl
+# define ntohl(X) __constant_ntohl((X))
+#endif
+
+#ifndef __inline__
+# define __inline__ __attribute__((always_inline))
+#endif
+
+/** Section helper macros. */
+
+#ifndef __section
+# define __section(NAME) \
+ __attribute__((section(NAME), used))
+#endif
+
+#ifndef __section_tail
+# define __section_tail(ID, KEY) \
+ __section(__stringify(ID) "/" __stringify(KEY))
+#endif
+
+#ifndef __section_xdp_entry
+# define __section_xdp_entry \
+ __section(ELF_SECTION_PROG)
+#endif
+
+#ifndef __section_cls_entry
+# define __section_cls_entry \
+ __section(ELF_SECTION_CLASSIFIER)
+#endif
+
+#ifndef __section_act_entry
+# define __section_act_entry \
+ __section(ELF_SECTION_ACTION)
+#endif
+
+#ifndef __section_lwt_entry
+# define __section_lwt_entry \
+ __section(ELF_SECTION_PROG)
+#endif
+
+#ifndef __section_license
+# define __section_license \
+ __section(ELF_SECTION_LICENSE)
+#endif
+
+#ifndef __section_maps
+# define __section_maps \
+ __section(ELF_SECTION_MAPS)
+#endif
+
+/** Declaration helper macros. */
+
+#ifndef BPF_LICENSE
+# define BPF_LICENSE(NAME) \
+ char ____license[] __section_license = NAME
+#endif
+
+/** Classifier helper */
+
+#ifndef BPF_H_DEFAULT
+# define BPF_H_DEFAULT -1
+#endif
+
+/** BPF helper functions for tc. Individual flags are in linux/bpf.h */
+
+#ifndef __BPF_FUNC
+# define __BPF_FUNC(NAME, ...) \
+ (* NAME)(__VA_ARGS__)__maybe_unused
+#endif
+
+#ifndef BPF_FUNC
+# define BPF_FUNC(NAME, ...) \
+ __BPF_FUNC(NAME, __VA_ARGS__) = (void *)BPF_FUNC_##NAME
+#endif
+
+/* Map access/manipulation */
+static void *BPF_FUNC(map_lookup_elem, void *map, const void *key);
+static int BPF_FUNC(map_update_elem, void *map, const void *key,
+ const void *value, uint32_t flags);
+static int BPF_FUNC(map_delete_elem, void *map, const void *key);
+
+/* Time access */
+static uint64_t BPF_FUNC(ktime_get_ns);
+
+/* Debugging */
+
+/* FIXME: __attribute__ ((format(printf, 1, 3))) not possible unless
+ * llvm bug https://llvm.org/bugs/show_bug.cgi?id=26243 gets resolved.
+ * It would require ____fmt to be made const, which generates a reloc
+ * entry (non-map).
+ */
+static void BPF_FUNC(trace_printk, const char *fmt, int fmt_size, ...);
+
+#ifndef printt
+# define printt(fmt, ...) \
+ ({ \
+ char ____fmt[] = fmt; \
+ trace_printk(____fmt, sizeof(____fmt), ##__VA_ARGS__); \
+ })
+#endif
+
+/* Random numbers */
+static uint32_t BPF_FUNC(get_prandom_u32);
+
+/* Tail calls */
+static void BPF_FUNC(tail_call, struct __sk_buff *skb, void *map,
+ uint32_t index);
+
+/* System helpers */
+static uint32_t BPF_FUNC(get_smp_processor_id);
+static uint32_t BPF_FUNC(get_numa_node_id);
+
+/* Packet misc meta data */
+static uint32_t BPF_FUNC(get_cgroup_classid, struct __sk_buff *skb);
+static int BPF_FUNC(skb_under_cgroup, void *map, uint32_t index);
+
+static uint32_t BPF_FUNC(get_route_realm, struct __sk_buff *skb);
+static uint32_t BPF_FUNC(get_hash_recalc, struct __sk_buff *skb);
+static uint32_t BPF_FUNC(set_hash_invalid, struct __sk_buff *skb);
+
+/* Packet redirection */
+static int BPF_FUNC(redirect, int ifindex, uint32_t flags);
+static int BPF_FUNC(clone_redirect, struct __sk_buff *skb, int ifindex,
+ uint32_t flags);
+
+/* Packet manipulation */
+static int BPF_FUNC(skb_load_bytes, struct __sk_buff *skb, uint32_t off,
+ void *to, uint32_t len);
+static int BPF_FUNC(skb_store_bytes, struct __sk_buff *skb, uint32_t off,
+ const void *from, uint32_t len, uint32_t flags);
+
+static int BPF_FUNC(l3_csum_replace, struct __sk_buff *skb, uint32_t off,
+ uint32_t from, uint32_t to, uint32_t flags);
+static int BPF_FUNC(l4_csum_replace, struct __sk_buff *skb, uint32_t off,
+ uint32_t from, uint32_t to, uint32_t flags);
+static int BPF_FUNC(csum_diff, const void *from, uint32_t from_size,
+ const void *to, uint32_t to_size, uint32_t seed);
+static int BPF_FUNC(csum_update, struct __sk_buff *skb, uint32_t wsum);
+
+static int BPF_FUNC(skb_change_type, struct __sk_buff *skb, uint32_t type);
+static int BPF_FUNC(skb_change_proto, struct __sk_buff *skb, uint32_t proto,
+ uint32_t flags);
+static int BPF_FUNC(skb_change_tail, struct __sk_buff *skb, uint32_t nlen,
+ uint32_t flags);
+
+static int BPF_FUNC(skb_pull_data, struct __sk_buff *skb, uint32_t len);
+
+/* Event notification */
+static int __BPF_FUNC(skb_event_output, struct __sk_buff *skb, void *map,
+ uint64_t index, const void *data, uint32_t size) =
+ (void *) BPF_FUNC_perf_event_output;
+
+/* Packet vlan encap/decap */
+static int BPF_FUNC(skb_vlan_push, struct __sk_buff *skb, uint16_t proto,
+ uint16_t vlan_tci);
+static int BPF_FUNC(skb_vlan_pop, struct __sk_buff *skb);
+
+/* Packet tunnel encap/decap */
+static int BPF_FUNC(skb_get_tunnel_key, struct __sk_buff *skb,
+ struct bpf_tunnel_key *to, uint32_t size, uint32_t flags);
+static int BPF_FUNC(skb_set_tunnel_key, struct __sk_buff *skb,
+ const struct bpf_tunnel_key *from, uint32_t size,
+ uint32_t flags);
+
+static int BPF_FUNC(skb_get_tunnel_opt, struct __sk_buff *skb,
+ void *to, uint32_t size);
+static int BPF_FUNC(skb_set_tunnel_opt, struct __sk_buff *skb,
+ const void *from, uint32_t size);
+
+/** LLVM built-ins, mem*() routines work for constant size */
+
+#ifndef lock_xadd
+# define lock_xadd(ptr, val) ((void) __sync_fetch_and_add(ptr, val))
+#endif
+
+#ifndef memset
+# define memset(s, c, n) __builtin_memset((s), (c), (n))
+#endif
+
+#ifndef memcpy
+# define memcpy(d, s, n) __builtin_memcpy((d), (s), (n))
+#endif
+
+#ifndef memmove
+# define memmove(d, s, n) __builtin_memmove((d), (s), (n))
+#endif
+
+/* FIXME: __builtin_memcmp() is not yet fully useable unless llvm bug
+ * https://llvm.org/bugs/show_bug.cgi?id=26218 gets resolved. Also
+ * this one would generate a reloc entry (non-map), otherwise.
+ */
+#if 0
+#ifndef memcmp
+# define memcmp(a, b, n) __builtin_memcmp((a), (b), (n))
+#endif
+#endif
+
+unsigned long long load_byte(void *skb, unsigned long long off)
+ asm ("llvm.bpf.load.byte");
+
+unsigned long long load_half(void *skb, unsigned long long off)
+ asm ("llvm.bpf.load.half");
+
+unsigned long long load_word(void *skb, unsigned long long off)
+ asm ("llvm.bpf.load.word");
+
+#endif /* __BPF_API__ */
diff --git a/drivers/net/tap/tap_bpf_insns.c b/drivers/net/tap/tap_bpf_insns.c
new file mode 100644
index 0000000..951d037
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_insns.c
@@ -0,0 +1,5427 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright 2017 6WIND S.A.
+ * Copyright 2017 Mellanox.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of 6WIND S.A. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_tunnel.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+
+#include "tap_bpf_shared.h"
+
+#define ERROR 0
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET 1
+
+#define INV_KEY_IDX 0xdeadbeef
+
+/*
+ *
+ * __section("maps")
+ * struct bpf_elf_map map_keys = {
+ * .type = BPF_MAP_TYPE_HASH,
+ * .id = BPF_MAP_ID_KEY,
+ * .size_key = sizeof(__u32),
+ * .size_value = sizeof(struct rss_key),
+ * .max_elem = 256,
+ * .pinning = PIN_GLOBAL_NS,
+ * };
+ */
+
+/*
+ * struct bpf_insn {
+ * __u8 code; opcode
+ * __u8 dst_reg:4; dest register
+ * __u8 src_reg:4; source register
+ * __s16 off; signed offset
+ * __s32 imm; signed immediate constant
+ * };
+ */
+
+/*
+ * The next bpf_insn array matches cls_q section
+ * see tap_bpf_program.c file
+ *
+ * __section("cls_q") int
+ * match_q (struct __sk_buff *skb)
+ * {
+ * __u32 queue = skb->cb[1];
+ * volatile __u32 q = INV_KEY_IDX;
+ * __u32 match_queue = QUEUE_OFFSET + q;
+ *
+ * if (queue != match_queue)
+ * return TC_ACT_OK;
+ * return TC_ACT_UNSPEC;
+ *
+ * }
+ */
+
+static struct bpf_insn cls_q_insns[] = {
+ {0x61, 1, 1, 52, 0x00000000},
+ {0x18, 2, 0, 0, 0xdeadbeef},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x63, 10, 2, -4, 0x00000000},
+ {0x61, 2, 10, -4, 0x00000000},
+ {0x07, 2, 0, 0, 0x00000001},
+ {0x67, 2, 0, 0, 0x00000020},
+ {0x77, 2, 0, 0, 0x00000020},
+ {0xb7, 0, 0, 0, 0xffffffff},
+ {0x1d, 1, 2, 1, 0x00000000},
+ {0xb7, 0, 0, 0, 0x00000000},
+ {0x95, 0, 0, 0, 0x00000000},
+};
+
+#define CLS_Q_INSNS_CNT \
+ (sizeof(cls_q_insns) / sizeof(cls_q_insns[0]))
+
+/**
+ * Load BPF program (section cls_q) into the kernel and return a bpf fd
+ *
+ * @param queue_idx
+ * Queue index matching packet cb
+ *
+ * @return
+ * -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_cls_q_insns(__u32 queue_idx)
+{
+ cls_q_insns[1].imm = queue_idx;
+
+ return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+ (struct bpf_insn *)cls_q_insns,
+ CLS_Q_INSNS_CNT,
+ "GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches tailing section
+ * see tap_bpf_program.c file
+ *
+ * __section("tailing") int
+ * tail(struct __sk_buff *skb)
+ * {
+ * skb_change_tail(skb, skb->len + sizeof(__u32), 0);
+ *
+ * return TC_ACT_UNSPEC;
+ * }
+ */
+
+static struct bpf_insn tailing_insns[] = {
+ {0x61, 2, 1, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0x00000004},
+ {0xb7, 3, 0, 0, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000026},
+ {0x18, 0, 0, 0, 0xffffffff},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x95, 0, 0, 0, 0x00000000},
+};
+
+#define TAILING_INSNS_CNT \
+ (sizeof(tailing_insns) / sizeof(tailing_insns[0]))
+
+/**
+ * Load BPF program (section tailing) into the kernel and return a bpf fd.
+ *
+ * @return
+ * -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_tailing_insns(void)
+{
+ return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+ (struct bpf_insn *)tailing_insns,
+ TAILING_INSNS_CNT,
+ "GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches hash_pending section
+ * see tap_bpf_program.c file
+ *
+ * __section("hash_appending") int
+ * append_hash(struct __sk_buff *skb)
+ * {
+ * __u32 hash = skb->cb[0];
+ *
+ * skb_store_bytes(skb, skb->len - sizeof(hash), &hash, sizeof(hash), 0);
+ *
+ * return TC_ACT_PIPE;
+ * }
+ */
+
+static struct bpf_insn hash_appending_insns[] = {
+ {0x61, 2, 1, 48, 0x00000000},
+ {0x63, 10, 2, -4, 0x00000000},
+ {0x61, 2, 1, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0xfffffffc},
+ {0xbf, 3, 10, 0, 0x00000000},
+ {0x07, 3, 0, 0, 0xfffffffc},
+ {0xb7, 4, 0, 0, 0x00000004},
+ {0xb7, 5, 0, 0, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000009},
+ {0xb7, 0, 0, 0, 0x00000003},
+ {0x95, 0, 0, 0, 0x00000000},
+};
+
+#define HASH_APPENDING_INSNS_CNT \
+ (sizeof(hash_appending_insns) / sizeof(hash_appending_insns[0]))
+
+/**
+ * Load BPF program into the kernel and return a bpf fd.
+ *
+ * @return
+ * -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_hash_appending_insns(void)
+{
+ return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+ (struct bpf_insn *)hash_appending_insns,
+ HASH_APPENDING_INSNS_CNT,
+ "GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches queue_setting section
+ * see tap_bpf_program.c file
+ *
+ * static void __attribute__((always_inline))
+ * __section("queue_setting") int
+ * set_queue(struct __sk_buff *skb)
+ * {
+ * __u32 key_idx = INV_KEY_IDX;
+ * __u64 hash = skb->cb[0];
+ * struct rss_key *rsskey;
+ * __u32 queue = 0;
+ *
+ * rsskey = map_lookup_elem(&map_keys, &key_idx);
+ * if (rsskey && rsskey->nb_queues <= TAP_MAX_QUEUES)
+ * queue = rsskey->queues[(hash % rsskey->nb_queues) &
+ * (TAP_MAX_QUEUES - 1)];
+ *
+ * skb->cb[1] = QUEUE_OFFSET + queue;
+ *
+ * return TC_ACT_RECLASSIFY;
+ * }
+ */
+
+static struct bpf_insn queue_setting_insns[] = {
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0x18, 1, 0, 0, 0xdeadbeef},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x63, 10, 1, -4, 0x00000000},
+ {0x61, 7, 6, 48, 0x00000000},
+ {0xbf, 2, 10, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0xfffffffc},
+ {0x18, 1, 1, 0, 0xffffffff},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000001},
+ {0xb7, 1, 0, 0, 0x00000001},
+ {0x15, 0, 0, 13, 0x00000000},
+ {0x61, 2, 0, 200, 0x00000000},
+ {0x25, 2, 0, 11, 0x00000010},
+ {0x67, 7, 0, 0, 0x00000020},
+ {0x77, 7, 0, 0, 0x00000020},
+ {0xbf, 1, 7, 0, 0x00000000},
+ {0x3f, 1, 2, 0, 0x00000000},
+ {0x2f, 1, 2, 0, 0x00000000},
+ {0x1f, 7, 1, 0, 0x00000000},
+ {0x57, 7, 0, 0, 0x0000000f},
+ {0x67, 7, 0, 0, 0x00000002},
+ {0x0f, 0, 7, 0, 0x00000000},
+ {0x61, 1, 0, 136, 0x00000000},
+ {0x07, 1, 0, 0, 0x00000001},
+ {0x63, 6, 1, 52, 0x00000000},
+ {0xb7, 0, 0, 0, 0x00000001},
+ {0x95, 0, 0, 0, 0x00000000},
+};
+
+#define QUEUE_SETTING_INSNS_CNT \
+ (sizeof(queue_setting_insns) / sizeof(queue_setting_insns[0]))
+
+/**
+ * Load BPF program (section queue_setting) into the kernel and return a bpf fd
+ *
+ * @param queue_idx
+ * Queue index matching packet cb
+ *
+ * @return
+ * -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_queue_setting_insns(__u32 queue_idx)
+{
+ queue_setting_insns[1].imm = queue_idx;
+
+ return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+ (struct bpf_insn *)queue_setting_insns,
+ QUEUE_SETTING_INSNS_CNT,
+ "GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l2_src_hash section
+ * see tap_bpf_program.c file
+ *
+ * #define HASH(L) \
+ * __section(#L) int \
+ * L ## _hash(struct __sk_buff *skb) \
+ * { \
+ * return hash(skb, HASH_FIELD_ ## L); \
+ * }
+ *
+ * HASH(L2_SRC)
+ */
+
+
+static struct bpf_insn l2_src_hash_insns[] = {
+ {0xbf, 7, 1, 0, 0x00000000},
+ {0x61, 6, 7, 16, 0x00000000},
+ {0x61, 9, 7, 76, 0x00000000},
+ {0x61, 8, 7, 80, 0x00000000},
+ {0x18, 1, 0, 0, 0xdeadbeef},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x63, 10, 1, -4, 0x00000000},
+ {0x61, 1, 7, 48, 0x00000000},
+ {0x7b, 10, 1, -56, 0x00000000},
+ {0xbf, 2, 10, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0xfffffffc},
+ {0x18, 1, 1, 0, 0xffffffff},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000001},
+ {0x55, 0, 0, 21, 0x00000000},
+ {0xb7, 1, 0, 0, 0x00000a64},
+ {0x6b, 10, 1, -16, 0x00000000},
+ {0x18, 1, 0, 0, 0x69666e6f},
+ {0x00, 0, 0, 0, 0x65727567},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x6e207369},
+ {0x00, 0, 0, 0, 0x6320746f},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x20737372},
+ {0x00, 0, 0, 0, 0x2079656b},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x203a2928},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0x73, 10, 7, -14, 0x00000000},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 2, 0, 0, 0x00000023},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0x05, 0, 0, 543, 0x00000000},
+ {0xb7, 1, 0, 0, 0x0000000e},
+ {0x61, 2, 7, 20, 0x00000000},
+ {0x15, 2, 0, 10, 0x00000000},
+ {0x61, 2, 7, 28, 0x00000000},
+ {0x55, 2, 0, 8, 0x0000a888},
+ {0xbf, 2, 7, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0x00000012},
+ {0x2d, 1, 8, 533, 0x00000000},
+ {0xb7, 1, 0, 0, 0x00000012},
+ {0x69, 6, 9, 16, 0x00000000},
+ {0xbf, 7, 2, 0, 0x00000000},
+ {0x61, 2, 0, 128, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0xb7, 4, 0, 0, 0x00000000},
+ {0x1d, 3, 4, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000006},
+ {0x57, 2, 0, 0, 0x00000002},
+ {0x15, 2, 0, 508, 0x00000000},
+ {0x7b, 10, 7, -64, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0x0000000c},
+ {0x2d, 1, 8, 517, 0x00000000},
+ {0x71, 1, 0, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000018},
+ {0x71, 6, 0, 1, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000010},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 2, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000008},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 3, 0x00000000},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 5, 9, 6, 0x00000000},
+ {0x67, 5, 0, 0, 0x00000038},
+ {0xc7, 5, 0, 0, 0x00000038},
+ {0xb7, 2, 0, 0, 0x00000000},
+ {0xb7, 3, 0, 0, 0xffffffff},
+ {0xb7, 4, 0, 0, 0x00000000},
+ {0x6d, 5, 3, 1, 0x00000000},
+ {0xbf, 4, 6, 0, 0x00000000},
+ {0x79, 1, 10, -56, 0x00000000},
+ {0xaf, 4, 1, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000001},
+ {0x71, 7, 0, 4, 0x00000000},
+ {0xbf, 1, 7, 0, 0x00000000},
+ {0x77, 1, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003f},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x57, 7, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 7, 0, 0x00000000},
+ {0x71, 5, 9, 7, 0x00000000},
+ {0x67, 5, 0, 0, 0x00000038},
+ {0xc7, 5, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 5, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 7, 0, 5, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003f},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x57, 7, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 7, 0, 0x00000000},
+ {0x71, 5, 9, 8, 0x00000000},
+ {0x67, 5, 0, 0, 0x00000038},
+ {0xc7, 5, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 5, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 7, 0, 6, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003f},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x57, 7, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 7, 0, 0x00000000},
+ {0x71, 5, 9, 9, 0x00000000},
+ {0x67, 5, 0, 0, 0x00000038},
+ {0xc7, 5, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 5, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 7, 0, 7, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003f},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x57, 7, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 7, 0, 0x00000000},
+ {0x71, 5, 9, 10, 0x00000000},
+ {0x67, 5, 0, 0, 0x00000038},
+ {0xc7, 5, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 5, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 7, 0, 8, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003f},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x57, 7, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 7, 0, 0x00000000},
+ {0x71, 5, 9, 11, 0x00000000},
+ {0x67, 5, 0, 0, 0x00000038},
+ {0xc7, 5, 0, 0, 0x00000038},
+ {0x6d, 5, 3, 1, 0x00000000},
+ {0xbf, 2, 1, 0, 0x00000000},
+ {0xaf, 4, 2, 0, 0x00000000},
+ {0x71, 2, 0, 9, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000007},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 5, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000039},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000006},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 5, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003a},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000005},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 5, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003b},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000004},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 5, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003c},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000003},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 5, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003d},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000002},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 5, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003e},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x77, 2, 0, 0, 0x00000001},
+ {0x57, 2, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 2, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003f},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x79, 1, 10, -64, 0x00000000},
+ {0x63, 1, 4, 48, 0x00000000},
+ {0x18, 1, 0, 0, 0x25203d20},
+ {0x00, 0, 0, 0, 0x000a2964},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x20782520},
+ {0x00, 0, 0, 0, 0x66666f28},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x6168203a},
+ {0x00, 0, 0, 0, 0x3d206873},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x29642528},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 2, 0, 0, 0x00000020},
+ {0xb7, 3, 0, 0, 0x00000001},
+ {0xb7, 5, 0, 0, 0x00000006},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0x05, 0, 0, 13, 0x00000000},
+ {0x57, 6, 0, 0, 0x0000ffff},
+ {0x15, 6, 0, 7, 0x0000dd86},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x55, 6, 0, 10, 0x00000008},
+ {0x0f, 9, 1, 0, 0x00000000},
+ {0x07, 9, 0, 0, 0x00000014},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0x2d, 9, 8, 6, 0x00000000},
+ {0x05, 0, 0, 4, 0x00000000},
+ {0x0f, 9, 1, 0, 0x00000000},
+ {0x07, 9, 0, 0, 0x00000028},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0x2d, 9, 8, 1, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0xbf, 0, 7, 0, 0x00000000},
+ {0x95, 0, 0, 0, 0x00000000},
+};
+
+#define L2_SRC_HASH_INSNS_CNT \
+ (sizeof(l2_src_hash_insns) / sizeof(l2_src_hash_insns[0]))
+
+/**
+ * Load BPF program (section l2_src_hash) into the kernel and return a bpf fd.
+ *
+ * @param key_idx
+ * RSS MAP key index
+ *
+ * @return
+ * -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l2_src_hash_insns(__u32 key_idx)
+{
+ l2_src_hash_insns[4].imm = key_idx;
+
+ return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+ (struct bpf_insn *)l2_src_hash_insns,
+ L2_SRC_HASH_INSNS_CNT,
+ "GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l2_dst_hash section
+ * see tap_bpf_program.c file
+ *
+ * HASH(L2_DST)
+ */
+
+static struct bpf_insn l2_dst_hash_insns[] = {
+ {0xbf, 7, 1, 0, 0x00000000},
+ {0x61, 6, 7, 16, 0x00000000},
+ {0x61, 9, 7, 76, 0x00000000},
+ {0x61, 8, 7, 80, 0x00000000},
+ {0x18, 1, 0, 0, 0xdeadbeef},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x63, 10, 1, -4, 0x00000000},
+ {0x61, 1, 7, 48, 0x00000000},
+ {0x7b, 10, 1, -56, 0x00000000},
+ {0xbf, 2, 10, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0xfffffffc},
+ {0x18, 1, 1, 0, 0xffffffff},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000001},
+ {0x55, 0, 0, 21, 0x00000000},
+ {0xb7, 1, 0, 0, 0x00000a64},
+ {0x6b, 10, 1, -16, 0x00000000},
+ {0x18, 1, 0, 0, 0x69666e6f},
+ {0x00, 0, 0, 0, 0x65727567},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x6e207369},
+ {0x00, 0, 0, 0, 0x6320746f},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x20737372},
+ {0x00, 0, 0, 0, 0x2079656b},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x203a2928},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0x73, 10, 7, -14, 0x00000000},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 2, 0, 0, 0x00000023},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0x05, 0, 0, 538, 0x00000000},
+ {0xb7, 1, 0, 0, 0x0000000e},
+ {0x61, 2, 7, 20, 0x00000000},
+ {0x15, 2, 0, 10, 0x00000000},
+ {0x61, 2, 7, 28, 0x00000000},
+ {0x55, 2, 0, 8, 0x0000a888},
+ {0xbf, 2, 7, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0x00000012},
+ {0x2d, 1, 8, 528, 0x00000000},
+ {0xb7, 1, 0, 0, 0x00000012},
+ {0x69, 6, 9, 16, 0x00000000},
+ {0xbf, 7, 2, 0, 0x00000000},
+ {0x71, 2, 0, 128, 0x00000000},
+ {0x57, 2, 0, 0, 0x00000001},
+ {0x15, 2, 0, 508, 0x00000000},
+ {0xbf, 5, 7, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0x00000006},
+ {0x2d, 1, 8, 517, 0x00000000},
+ {0x71, 1, 0, 1, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000010},
+ {0x71, 6, 0, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000018},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 2, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000008},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 3, 0x00000000},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 3, 9, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000038},
+ {0xc7, 3, 0, 0, 0x00000038},
+ {0xb7, 2, 0, 0, 0xffffffff},
+ {0xb7, 4, 0, 0, 0x00000000},
+ {0xbf, 7, 5, 0, 0x00000000},
+ {0x6d, 3, 2, 1, 0x00000000},
+ {0xbf, 4, 6, 0, 0x00000000},
+ {0x79, 1, 10, -56, 0x00000000},
+ {0xaf, 4, 1, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000001},
+ {0x71, 5, 0, 4, 0x00000000},
+ {0xbf, 1, 5, 0, 0x00000000},
+ {0x77, 1, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003f},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0x71, 3, 9, 1, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000038},
+ {0xc7, 3, 0, 0, 0x00000038},
+ {0xb7, 5, 0, 0, 0x00000000},
+ {0x6d, 3, 2, 1, 0x00000000},
+ {0xbf, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 5, 0, 5, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003f},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0x71, 3, 9, 2, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000038},
+ {0xc7, 3, 0, 0, 0x00000038},
+ {0xb7, 5, 0, 0, 0x00000000},
+ {0x6d, 3, 2, 1, 0x00000000},
+ {0xbf, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 5, 0, 6, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003f},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0x71, 3, 9, 3, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000038},
+ {0xc7, 3, 0, 0, 0x00000038},
+ {0xb7, 5, 0, 0, 0x00000000},
+ {0x6d, 3, 2, 1, 0x00000000},
+ {0xbf, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 5, 0, 7, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003f},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0x71, 3, 9, 4, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000038},
+ {0xc7, 3, 0, 0, 0x00000038},
+ {0xb7, 5, 0, 0, 0x00000000},
+ {0x6d, 3, 2, 1, 0x00000000},
+ {0xbf, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 5, 0, 8, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 3, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 5, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003f},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0x71, 3, 9, 5, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000038},
+ {0xc7, 3, 0, 0, 0x00000038},
+ {0xb7, 5, 0, 0, 0x00000000},
+ {0x6d, 3, 2, 1, 0x00000000},
+ {0xbf, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x71, 2, 0, 9, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 5, 2, 0, 0x00000000},
+ {0x77, 5, 0, 0, 0x00000007},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0xbf, 5, 3, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x00000039},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0xbf, 5, 2, 0, 0x00000000},
+ {0x77, 5, 0, 0, 0x00000006},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0xbf, 5, 3, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003a},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0xbf, 5, 2, 0, 0x00000000},
+ {0x77, 5, 0, 0, 0x00000005},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0xbf, 5, 3, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003b},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0xbf, 5, 2, 0, 0x00000000},
+ {0x77, 5, 0, 0, 0x00000004},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0xbf, 5, 3, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003c},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0xbf, 5, 2, 0, 0x00000000},
+ {0x77, 5, 0, 0, 0x00000003},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0xbf, 5, 3, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003d},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0xbf, 5, 2, 0, 0x00000000},
+ {0x77, 5, 0, 0, 0x00000002},
+ {0x57, 5, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 5, 0, 0x00000000},
+ {0xbf, 5, 3, 0, 0x00000000},
+ {0x67, 5, 0, 0, 0x0000003e},
+ {0xc7, 5, 0, 0, 0x0000003f},
+ {0x5f, 5, 1, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x77, 2, 0, 0, 0x00000001},
+ {0x57, 2, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 2, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003f},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x63, 7, 4, 48, 0x00000000},
+ {0x18, 1, 0, 0, 0x25203d20},
+ {0x00, 0, 0, 0, 0x000a2964},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x20782520},
+ {0x00, 0, 0, 0, 0x66666f28},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x6168203a},
+ {0x00, 0, 0, 0, 0x3d206873},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x29642528},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 2, 0, 0, 0x00000020},
+ {0xb7, 3, 0, 0, 0x00000000},
+ {0xb7, 5, 0, 0, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0x05, 0, 0, 13, 0x00000000},
+ {0x57, 6, 0, 0, 0x0000ffff},
+ {0x15, 6, 0, 7, 0x0000dd86},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x55, 6, 0, 10, 0x00000008},
+ {0x0f, 9, 1, 0, 0x00000000},
+ {0x07, 9, 0, 0, 0x00000014},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0x2d, 9, 8, 6, 0x00000000},
+ {0x05, 0, 0, 4, 0x00000000},
+ {0x0f, 9, 1, 0, 0x00000000},
+ {0x07, 9, 0, 0, 0x00000028},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0x2d, 9, 8, 1, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0xbf, 0, 7, 0, 0x00000000},
+ {0x95, 0, 0, 0, 0x00000000},
+};
+#define L2_DST_HASH_INSNS_CNT \
+ (sizeof(l2_dst_hash_insns) / sizeof(l2_dst_hash_insns[0]))
+
+/**
+ * Load BPF program (section l2_dst_hash) into the kernel and return a bpf fd.
+ *
+ * @param key_idx
+ * RSS MAP key index
+ *
+ * @return
+ * -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l2_dst_hash_insns(__u32 key_idx)
+{
+ l2_dst_hash_insns[4].imm = key_idx;
+
+ return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+ (struct bpf_insn *)l2_dst_hash_insns,
+ L2_DST_HASH_INSNS_CNT,
+ "GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l3_dst_hash section
+ * see tap_bpf_program.c file
+ *
+ * HASH(L3_DST)
+ */
+
+
+static struct bpf_insn l3_dst_hash_insns[] = {
+ {0xbf, 7, 1, 0, 0x00000000},
+ {0x61, 6, 7, 16, 0x00000000},
+ {0x61, 9, 7, 76, 0x00000000},
+ {0x61, 8, 7, 80, 0x00000000},
+ {0x18, 1, 0, 0, 0xdeadbeef},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x63, 10, 1, -4, 0x00000000},
+ {0x61, 1, 7, 48, 0x00000000},
+ {0x7b, 10, 1, -56, 0x00000000},
+ {0xbf, 2, 10, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0xfffffffc},
+ {0x18, 1, 1, 0, 0xffffffff},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000001},
+ {0x55, 0, 0, 21, 0x00000000},
+ {0xb7, 1, 0, 0, 0x00000a64},
+ {0x6b, 10, 1, -16, 0x00000000},
+ {0x18, 1, 0, 0, 0x69666e6f},
+ {0x00, 0, 0, 0, 0x65727567},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x6e207369},
+ {0x00, 0, 0, 0, 0x6320746f},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x20737372},
+ {0x00, 0, 0, 0, 0x2079656b},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x203a2928},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0x73, 10, 7, -14, 0x00000000},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 2, 0, 0, 0x00000023},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0x05, 0, 0, 1689, 0x00000000},
+ {0xb7, 5, 0, 0, 0x0000000e},
+ {0x61, 1, 7, 20, 0x00000000},
+ {0x15, 1, 0, 10, 0x00000000},
+ {0x61, 1, 7, 28, 0x00000000},
+ {0x55, 1, 0, 8, 0x0000a888},
+ {0xbf, 2, 7, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0x00000012},
+ {0x2d, 1, 8, 1679, 0x00000000},
+ {0xb7, 5, 0, 0, 0x00000012},
+ {0x69, 6, 9, 16, 0x00000000},
+ {0xbf, 7, 2, 0, 0x00000000},
+ {0x61, 1, 0, 128, 0x00000000},
+ {0xbf, 3, 1, 0, 0x00000000},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0xb7, 2, 0, 0, 0x00000000},
+ {0x1d, 3, 2, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000006},
+ {0x7b, 10, 7, -64, 0x00000000},
+ {0xbf, 3, 1, 0, 0x00000000},
+ {0x57, 3, 0, 0, 0x00000002},
+ {0x1d, 3, 2, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000006},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x0000ffff},
+ {0x15, 6, 0, 355, 0x0000dd86},
+ {0x55, 6, 0, 1661, 0x00000008},
+ {0x0f, 9, 5, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 2, 9, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0x00000014},
+ {0x2d, 2, 8, 1656, 0x00000000},
+ {0xbf, 2, 1, 0, 0x00000000},
+ {0x57, 2, 0, 0, 0x00000004},
+ {0xb7, 3, 0, 0, 0x00000000},
+ {0x1d, 2, 3, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000004},
+ {0x57, 1, 0, 0, 0x00000008},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x15, 1, 0, 1648, 0x00000000},
+ {0x71, 1, 0, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000018},
+ {0x71, 6, 0, 1, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000010},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 2, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000008},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 3, 0x00000000},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x71, 7, 8, 16, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 2, 0, 0, 0x00000000},
+ {0xb7, 3, 0, 0, 0xffffffff},
+ {0xb7, 4, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 4, 6, 0, 0x00000000},
+ {0x79, 1, 10, -56, 0x00000000},
+ {0xaf, 4, 1, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000001},
+ {0x71, 9, 0, 4, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x77, 1, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 17, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 5, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 18, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 6, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 19, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 2, 1, 0, 0x00000000},
+ {0xaf, 4, 2, 0, 0x00000000},
+ {0x71, 2, 0, 7, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000007},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000039},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000006},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003a},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000005},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003b},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000004},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003c},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000003},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003d},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000002},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003e},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x77, 2, 0, 0, 0x00000001},
+ {0x57, 2, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 2, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x79, 1, 10, -64, 0x00000000},
+ {0x63, 1, 4, 48, 0x00000000},
+ {0x18, 1, 0, 0, 0x25203d20},
+ {0x00, 0, 0, 0, 0x000a2964},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x20782520},
+ {0x00, 0, 0, 0, 0x66666f28},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x6168203a},
+ {0x00, 0, 0, 0, 0x3d206873},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x29642528},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0x07, 5, 0, 0, 0x00000010},
+ {0x05, 0, 0, 1301, 0x00000000},
+ {0x0f, 9, 5, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 2, 9, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0x00000028},
+ {0x2d, 2, 8, 1302, 0x00000000},
+ {0xbf, 2, 1, 0, 0x00000000},
+ {0x57, 2, 0, 0, 0x00000004},
+ {0xb7, 3, 0, 0, 0x00000000},
+ {0x1d, 2, 3, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000010},
+ {0x57, 1, 0, 0, 0x00000008},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x15, 1, 0, 1294, 0x00000000},
+ {0x71, 1, 0, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000018},
+ {0x71, 6, 0, 1, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000010},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 2, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000008},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 3, 0x00000000},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x71, 7, 8, 24, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 2, 0, 0, 0x00000000},
+ {0xb7, 3, 0, 0, 0xffffffff},
+ {0xb7, 4, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 4, 6, 0, 0x00000000},
+ {0x79, 1, 10, -56, 0x00000000},
+ {0xaf, 4, 1, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000001},
+ {0x71, 9, 0, 4, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x77, 1, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 25, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 5, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 26, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 6, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 27, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 7, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 28, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 8, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 29, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 9, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 30, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 10, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 31, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 11, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 32, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 12, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 33, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 13, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 34, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 14, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 35, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 15, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 36, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 16, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 37, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 17, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 38, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 18, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 39, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 2, 1, 0, 0x00000000},
+ {0xaf, 4, 2, 0, 0x00000000},
+ {0x71, 2, 0, 19, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000007},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000039},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000006},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003a},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000005},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003b},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000004},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003c},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000003},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003d},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000002},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003e},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x77, 2, 0, 0, 0x00000001},
+ {0x57, 2, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 2, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x79, 1, 10, -64, 0x00000000},
+ {0x63, 1, 4, 48, 0x00000000},
+ {0x18, 1, 0, 0, 0x25203d20},
+ {0x00, 0, 0, 0, 0x000a2964},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x20782520},
+ {0x00, 0, 0, 0, 0x66666f28},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x6168203a},
+ {0x00, 0, 0, 0, 0x3d206873},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x29642528},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0x07, 5, 0, 0, 0x00000018},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0xb7, 2, 0, 0, 0x00000020},
+ {0xb7, 3, 0, 0, 0x00000003},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0xbf, 0, 7, 0, 0x00000000},
+ {0x95, 0, 0, 0, 0x00000000},
+};
+
+#define L3_DST_HASH_INSNS_CNT \
+ (sizeof(l3_dst_hash_insns) / sizeof(l3_dst_hash_insns[0]))
+
+/**
+ * Load BPF program (section l3_dst_hash) into the kernel and return a bpf fd.
+ *
+ * @param queue_idx
+ * RSS MAP key index
+ *
+ * @return
+ * -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l3_dst_hash_insns(__u32 key_idx)
+{
+ l3_dst_hash_insns[4].imm = key_idx;
+
+ return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+ (struct bpf_insn *)l3_dst_hash_insns,
+ L3_DST_HASH_INSNS_CNT,
+ "GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l3_src_hash section
+ * see tap_bpf_program.c file
+ *
+ * HASH(L3_SRC)
+ */
+
+static struct bpf_insn l3_src_hash_insns[] = {
+ {0xbf, 7, 1, 0, 0x00000000},
+ {0x61, 6, 7, 16, 0x00000000},
+ {0x61, 9, 7, 76, 0x00000000},
+ {0x61, 8, 7, 80, 0x00000000},
+ {0x18, 1, 0, 0, 0xdeadbeef},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x63, 10, 1, -4, 0x00000000},
+ {0x61, 1, 7, 48, 0x00000000},
+ {0x7b, 10, 1, -56, 0x00000000},
+ {0xbf, 2, 10, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0xfffffffc},
+ {0x18, 1, 1, 0, 0xffffffff},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000001},
+ {0x55, 0, 0, 21, 0x00000000},
+ {0xb7, 1, 0, 0, 0x00000a64},
+ {0x6b, 10, 1, -16, 0x00000000},
+ {0x18, 1, 0, 0, 0x69666e6f},
+ {0x00, 0, 0, 0, 0x65727567},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x6e207369},
+ {0x00, 0, 0, 0, 0x6320746f},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x20737372},
+ {0x00, 0, 0, 0, 0x2079656b},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x203a2928},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0x73, 10, 7, -14, 0x00000000},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 2, 0, 0, 0x00000023},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0x05, 0, 0, 1679, 0x00000000},
+ {0xb7, 5, 0, 0, 0x0000000e},
+ {0x61, 1, 7, 20, 0x00000000},
+ {0x15, 1, 0, 10, 0x00000000},
+ {0x61, 1, 7, 28, 0x00000000},
+ {0x55, 1, 0, 8, 0x0000a888},
+ {0xbf, 2, 7, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0x00000012},
+ {0x2d, 1, 8, 1669, 0x00000000},
+ {0xb7, 5, 0, 0, 0x00000012},
+ {0x69, 6, 9, 16, 0x00000000},
+ {0xbf, 7, 2, 0, 0x00000000},
+ {0x61, 1, 0, 128, 0x00000000},
+ {0xbf, 3, 1, 0, 0x00000000},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0xb7, 2, 0, 0, 0x00000000},
+ {0x1d, 3, 2, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000006},
+ {0xbf, 3, 1, 0, 0x00000000},
+ {0x57, 3, 0, 0, 0x00000002},
+ {0x1d, 3, 2, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000006},
+ {0x7b, 10, 7, -64, 0x00000000},
+ {0x57, 6, 0, 0, 0x0000ffff},
+ {0x15, 6, 0, 351, 0x0000dd86},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x55, 6, 0, 1651, 0x00000008},
+ {0x0f, 9, 5, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 2, 9, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0x00000014},
+ {0x2d, 2, 8, 1646, 0x00000000},
+ {0x57, 1, 0, 0, 0x00000004},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x15, 1, 0, 1643, 0x00000000},
+ {0x71, 1, 0, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000018},
+ {0x71, 6, 0, 1, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000010},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 2, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000008},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 3, 0x00000000},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x71, 7, 8, 12, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 2, 0, 0, 0x00000000},
+ {0xb7, 3, 0, 0, 0xffffffff},
+ {0xb7, 4, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 4, 6, 0, 0x00000000},
+ {0x79, 1, 10, -56, 0x00000000},
+ {0xaf, 4, 1, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000001},
+ {0x71, 9, 0, 4, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x77, 1, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 13, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 5, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 14, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 6, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 15, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 2, 1, 0, 0x00000000},
+ {0xaf, 4, 2, 0, 0x00000000},
+ {0x71, 2, 0, 7, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000007},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000039},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000006},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003a},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000005},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003b},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000004},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003c},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000003},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003d},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000002},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003e},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x77, 2, 0, 0, 0x00000001},
+ {0x57, 2, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 2, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x79, 1, 10, -64, 0x00000000},
+ {0x63, 1, 4, 48, 0x00000000},
+ {0x18, 1, 0, 0, 0x25203d20},
+ {0x00, 0, 0, 0, 0x000a2964},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x20782520},
+ {0x00, 0, 0, 0, 0x66666f28},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x6168203a},
+ {0x00, 0, 0, 0, 0x3d206873},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x29642528},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0x07, 5, 0, 0, 0x0000000c},
+ {0x05, 0, 0, 1296, 0x00000000},
+ {0x0f, 9, 5, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 2, 9, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0x00000028},
+ {0x2d, 2, 8, 1297, 0x00000000},
+ {0x57, 1, 0, 0, 0x00000004},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x15, 1, 0, 1294, 0x00000000},
+ {0x71, 1, 0, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000018},
+ {0x71, 6, 0, 1, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000010},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 2, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000008},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0x71, 1, 0, 3, 0x00000000},
+ {0x4f, 6, 1, 0, 0x00000000},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x71, 7, 8, 8, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 2, 0, 0, 0x00000000},
+ {0xb7, 3, 0, 0, 0xffffffff},
+ {0xb7, 4, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 4, 6, 0, 0x00000000},
+ {0x79, 1, 10, -56, 0x00000000},
+ {0xaf, 4, 1, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000001},
+ {0x71, 9, 0, 4, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x77, 1, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 9, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 5, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 10, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 6, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 11, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 7, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 12, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 8, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 13, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 9, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 14, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 10, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 15, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 11, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 16, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 12, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 17, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 13, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 18, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 14, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 19, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 15, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 20, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 16, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 21, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 17, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 22, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 6, 0, 0, 0x00000000},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x71, 9, 0, 18, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000007},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x00000039},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000006},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003a},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000005},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003b},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000004},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003c},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000003},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003d},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000002},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0xbf, 6, 7, 0, 0x00000000},
+ {0x67, 6, 0, 0, 0x0000003e},
+ {0xc7, 6, 0, 0, 0x0000003f},
+ {0x5f, 6, 1, 0, 0x00000000},
+ {0xaf, 4, 6, 0, 0x00000000},
+ {0xbf, 6, 9, 0, 0x00000000},
+ {0x77, 6, 0, 0, 0x00000001},
+ {0x57, 6, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 6, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 8, 23, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 2, 1, 0, 0x00000000},
+ {0xaf, 4, 2, 0, 0x00000000},
+ {0x71, 2, 0, 19, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000007},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000039},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000006},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003a},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000005},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003b},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000004},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003c},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000003},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003d},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000002},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003e},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x77, 2, 0, 0, 0x00000001},
+ {0x57, 2, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 2, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x79, 1, 10, -64, 0x00000000},
+ {0x63, 1, 4, 48, 0x00000000},
+ {0x18, 1, 0, 0, 0x25203d20},
+ {0x00, 0, 0, 0, 0x000a2964},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x20782520},
+ {0x00, 0, 0, 0, 0x66666f28},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x6168203a},
+ {0x00, 0, 0, 0, 0x3d206873},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x29642528},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0x07, 5, 0, 0, 0x00000008},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 2, 0, 0, 0x00000020},
+ {0xb7, 3, 0, 0, 0x00000002},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0xbf, 0, 7, 0, 0x00000000},
+ {0x95, 0, 0, 0, 0x00000000},
+};
+
+#define L3_SRC_HASH_INSNS_CNT \
+ (sizeof(l3_src_hash_insns) / sizeof(l3_src_hash_insns[0]))
+
+/**
+ * Load BPF program (section l3_src_hash) into the kernel and return a bpf fd.
+ *
+ * @param queue_idx
+ * RSS MAP key index
+ *
+ * @return
+ * -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l3_src_hash_insns(__u32 key_idx)
+{
+ l3_src_hash_insns[4].imm = key_idx;
+
+ return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+ (struct bpf_insn *)l3_src_hash_insns,
+ L3_SRC_HASH_INSNS_CNT,
+ "GPL", 0);
+}
+
+/*
+ * The next bpf_insn array matches l4_src_hash section
+ * see tap_bpf_program.c file
+ *
+ * HASH(L4_SRC)
+ */
+
+static struct bpf_insn l4_src_hash_insns[] = {
+ {0xbf, 6, 1, 0, 0x00000000},
+ {0x61, 8, 6, 16, 0x00000000},
+ {0x61, 9, 6, 76, 0x00000000},
+ {0x61, 1, 6, 80, 0x00000000},
+ {0x7b, 10, 1, -56, 0x00000000},
+ {0x18, 1, 0, 0, 0xdeadbeef},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x63, 10, 1, -4, 0x00000000},
+ {0x61, 7, 6, 48, 0x00000000},
+ {0xbf, 2, 10, 0, 0x00000000},
+ {0x07, 2, 0, 0, 0xfffffffc},
+ {0x18, 1, 1, 0, 0xffffffff},
+ {0x00, 0, 0, 0, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000001},
+ {0x55, 0, 0, 21, 0x00000000},
+ {0xb7, 1, 0, 0, 0x00000a64},
+ {0x6b, 10, 1, -16, 0x00000000},
+ {0x18, 1, 0, 0, 0x69666e6f},
+ {0x00, 0, 0, 0, 0x65727567},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x6e207369},
+ {0x00, 0, 0, 0, 0x6320746f},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x20737372},
+ {0x00, 0, 0, 0, 0x2079656b},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x203a2928},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0x73, 10, 7, -14, 0x00000000},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 2, 0, 0, 0x00000023},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0x05, 0, 0, 272, 0x00000000},
+ {0xb7, 4, 0, 0, 0x0000000e},
+ {0x61, 1, 6, 20, 0x00000000},
+ {0x15, 1, 0, 11, 0x00000000},
+ {0x61, 1, 6, 28, 0x00000000},
+ {0x55, 1, 0, 9, 0x0000a888},
+ {0xbf, 2, 7, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0x00000012},
+ {0x79, 3, 10, -56, 0x00000000},
+ {0x2d, 1, 3, 261, 0x00000000},
+ {0xb7, 4, 0, 0, 0x00000012},
+ {0x69, 8, 9, 16, 0x00000000},
+ {0xbf, 7, 2, 0, 0x00000000},
+ {0x61, 1, 0, 128, 0x00000000},
+ {0xbf, 3, 1, 0, 0x00000000},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0xb7, 2, 0, 0, 0x00000000},
+ {0x1d, 3, 2, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000006},
+ {0xbf, 3, 1, 0, 0x00000000},
+ {0x57, 3, 0, 0, 0x00000002},
+ {0x1d, 3, 2, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000006},
+ {0x57, 8, 0, 0, 0x0000ffff},
+ {0x15, 8, 0, 24, 0x0000dd86},
+ {0xbf, 5, 7, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x55, 8, 0, 243, 0x00000008},
+ {0xbf, 2, 9, 0, 0x00000000},
+ {0x0f, 2, 4, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x07, 3, 0, 0, 0x00000014},
+ {0x79, 8, 10, -56, 0x00000000},
+ {0x2d, 3, 8, 236, 0x00000000},
+ {0xbf, 7, 4, 0, 0x00000000},
+ {0xbf, 4, 1, 0, 0x00000000},
+ {0x57, 4, 0, 0, 0x00000004},
+ {0xb7, 3, 0, 0, 0x00000000},
+ {0x1d, 4, 3, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000004},
+ {0xbf, 4, 1, 0, 0x00000000},
+ {0x57, 4, 0, 0, 0x00000008},
+ {0x1d, 4, 3, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000004},
+ {0xbf, 4, 7, 0, 0x00000000},
+ {0x07, 4, 0, 0, 0x00000014},
+ {0x07, 2, 0, 0, 0x00000009},
+ {0x05, 0, 0, 21, 0x00000000},
+ {0xbf, 5, 7, 0, 0x00000000},
+ {0xbf, 2, 9, 0, 0x00000000},
+ {0x0f, 2, 4, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x07, 3, 0, 0, 0x00000028},
+ {0x79, 8, 10, -56, 0x00000000},
+ {0x2d, 3, 8, 214, 0x00000000},
+ {0xbf, 7, 4, 0, 0x00000000},
+ {0xbf, 4, 1, 0, 0x00000000},
+ {0x57, 4, 0, 0, 0x00000004},
+ {0xb7, 3, 0, 0, 0x00000000},
+ {0x1d, 4, 3, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000010},
+ {0xbf, 4, 1, 0, 0x00000000},
+ {0x57, 4, 0, 0, 0x00000008},
+ {0x1d, 4, 3, 1, 0x00000000},
+ {0x07, 0, 0, 0, 0x00000010},
+ {0xbf, 4, 7, 0, 0x00000000},
+ {0x07, 4, 0, 0, 0x00000028},
+ {0x07, 2, 0, 0, 0x00000006},
+ {0x71, 2, 2, 0, 0x00000000},
+ {0x15, 2, 0, 2, 0x00000011},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x55, 2, 0, 197, 0x00000006},
+ {0x57, 1, 0, 0, 0x00000010},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0x15, 1, 0, 194, 0x00000000},
+ {0xbf, 3, 9, 0, 0x00000000},
+ {0x0f, 3, 4, 0, 0x00000000},
+ {0xb7, 7, 0, 0, 0x00000000},
+ {0xbf, 1, 3, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0x00000002},
+ {0x79, 2, 10, -56, 0x00000000},
+ {0x2d, 1, 2, 187, 0x00000000},
+ {0x7b, 10, 4, -56, 0x00000000},
+ {0x71, 1, 0, 1, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000010},
+ {0x71, 8, 0, 0, 0x00000000},
+ {0x67, 8, 0, 0, 0x00000018},
+ {0x4f, 8, 1, 0, 0x00000000},
+ {0x71, 1, 0, 2, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000008},
+ {0x4f, 8, 1, 0, 0x00000000},
+ {0x71, 1, 0, 3, 0x00000000},
+ {0x4f, 8, 1, 0, 0x00000000},
+ {0x71, 7, 3, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 2, 0, 0, 0x00000000},
+ {0xb7, 1, 0, 0, 0xffffffff},
+ {0xb7, 4, 0, 0, 0x00000000},
+ {0x6d, 7, 1, 1, 0x00000000},
+ {0xbf, 4, 8, 0, 0x00000000},
+ {0xaf, 4, 5, 0, 0x00000000},
+ {0x67, 8, 0, 0, 0x00000001},
+ {0x71, 9, 0, 4, 0x00000000},
+ {0xbf, 1, 9, 0, 0x00000000},
+ {0x77, 1, 0, 0, 0x00000007},
+ {0x4f, 1, 8, 0, 0x00000000},
+ {0xbf, 8, 7, 0, 0x00000000},
+ {0x67, 8, 0, 0, 0x00000039},
+ {0xc7, 8, 0, 0, 0x0000003f},
+ {0x5f, 8, 1, 0, 0x00000000},
+ {0xaf, 4, 8, 0, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x77, 8, 0, 0, 0x00000006},
+ {0x57, 8, 0, 0, 0x00000001},
+ {0x4f, 1, 8, 0, 0x00000000},
+ {0xbf, 8, 7, 0, 0x00000000},
+ {0x67, 8, 0, 0, 0x0000003a},
+ {0xc7, 8, 0, 0, 0x0000003f},
+ {0x5f, 8, 1, 0, 0x00000000},
+ {0xaf, 4, 8, 0, 0x00000000},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x77, 8, 0, 0, 0x00000005},
+ {0x57, 8, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 8, 0, 0x00000000},
+ {0xbf, 8, 7, 0, 0x00000000},
+ {0x67, 8, 0, 0, 0x0000003b},
+ {0xc7, 8, 0, 0, 0x0000003f},
+ {0x5f, 8, 1, 0, 0x00000000},
+ {0xaf, 4, 8, 0, 0x00000000},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x77, 8, 0, 0, 0x00000004},
+ {0x57, 8, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 8, 0, 0x00000000},
+ {0xbf, 8, 7, 0, 0x00000000},
+ {0x67, 8, 0, 0, 0x0000003c},
+ {0xc7, 8, 0, 0, 0x0000003f},
+ {0x5f, 8, 1, 0, 0x00000000},
+ {0xaf, 4, 8, 0, 0x00000000},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x77, 8, 0, 0, 0x00000003},
+ {0x57, 8, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 8, 0, 0x00000000},
+ {0xbf, 8, 7, 0, 0x00000000},
+ {0x67, 8, 0, 0, 0x0000003d},
+ {0xc7, 8, 0, 0, 0x0000003f},
+ {0x5f, 8, 1, 0, 0x00000000},
+ {0xaf, 4, 8, 0, 0x00000000},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x77, 8, 0, 0, 0x00000002},
+ {0x57, 8, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 8, 0, 0x00000000},
+ {0xbf, 8, 7, 0, 0x00000000},
+ {0x67, 8, 0, 0, 0x0000003e},
+ {0xc7, 8, 0, 0, 0x0000003f},
+ {0x5f, 8, 1, 0, 0x00000000},
+ {0xaf, 4, 8, 0, 0x00000000},
+ {0xbf, 8, 9, 0, 0x00000000},
+ {0x77, 8, 0, 0, 0x00000001},
+ {0x57, 8, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 8, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x57, 9, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 9, 0, 0x00000000},
+ {0x71, 7, 3, 1, 0x00000000},
+ {0x67, 7, 0, 0, 0x00000038},
+ {0xc7, 7, 0, 0, 0x00000038},
+ {0xb7, 3, 0, 0, 0xffffffff},
+ {0x6d, 7, 3, 1, 0x00000000},
+ {0xbf, 2, 1, 0, 0x00000000},
+ {0xaf, 4, 2, 0, 0x00000000},
+ {0x71, 2, 0, 5, 0x00000000},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000007},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x00000039},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000006},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003a},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000005},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003b},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000004},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003c},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000003},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003d},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0xbf, 3, 2, 0, 0x00000000},
+ {0x77, 3, 0, 0, 0x00000002},
+ {0x57, 3, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 3, 0, 0x00000000},
+ {0xbf, 3, 7, 0, 0x00000000},
+ {0x67, 3, 0, 0, 0x0000003e},
+ {0xc7, 3, 0, 0, 0x0000003f},
+ {0x5f, 3, 1, 0, 0x00000000},
+ {0xaf, 4, 3, 0, 0x00000000},
+ {0x77, 2, 0, 0, 0x00000001},
+ {0x57, 2, 0, 0, 0x00000001},
+ {0x67, 1, 0, 0, 0x00000001},
+ {0x4f, 1, 2, 0, 0x00000000},
+ {0x67, 7, 0, 0, 0x0000003f},
+ {0xc7, 7, 0, 0, 0x0000003f},
+ {0x5f, 7, 1, 0, 0x00000000},
+ {0xaf, 4, 7, 0, 0x00000000},
+ {0x63, 6, 4, 48, 0x00000000},
+ {0x18, 1, 0, 0, 0x25203d20},
+ {0x00, 0, 0, 0, 0x000a2964},
+ {0x7b, 10, 1, -24, 0x00000000},
+ {0x18, 1, 0, 0, 0x20782520},
+ {0x00, 0, 0, 0, 0x66666f28},
+ {0x7b, 10, 1, -32, 0x00000000},
+ {0x18, 1, 0, 0, 0x6168203a},
+ {0x00, 0, 0, 0, 0x3d206873},
+ {0x7b, 10, 1, -40, 0x00000000},
+ {0x18, 1, 0, 0, 0x68736168},
+ {0x00, 0, 0, 0, 0x29642528},
+ {0x7b, 10, 1, -48, 0x00000000},
+ {0xbf, 1, 10, 0, 0x00000000},
+ {0x07, 1, 0, 0, 0xffffffd0},
+ {0xb7, 2, 0, 0, 0x00000020},
+ {0xb7, 3, 0, 0, 0x00000004},
+ {0x79, 5, 10, -56, 0x00000000},
+ {0x85, 0, 0, 0, 0x00000006},
+ {0xb7, 7, 0, 0, 0x00000003},
+ {0xbf, 0, 7, 0, 0x00000000},
+ {0x95, 0, 0, 0, 0x00000000},
+};
+
+#define L4_SRC_HASH_INSNS_CNT \
+ (sizeof(l4_src_hash_insns) / sizeof(l4_src_hash_insns[0]))
+
+/**
+ * Load BPF program (section l4_src_hash) into the kernel and return a bpf fd.
+ *
+ * @param queue_idx
+ * RSS MAP key index
+ *
+ * @return
+ * -1 if the BPF program couldn't be loaded. An fd (int) otherwise.
+ */
+int bpf_load_l4_src_hash_insns(__u32 key_idx)
+{
+ l4_src_hash_insns[4].imm = key_idx;
+
+ return bpf_load(BPF_PROG_TYPE_SCHED_ACT,
+ (struct bpf_insn *)l4_src_hash_insns,
+ L4_SRC_HASH_INSNS_CNT,
+ "GPL", 0);
+}
+
+#ifndef __NR_bpf
+# if defined(__i386__)
+# define __NR_bpf 357
+# elif defined(__x86_64__)
+# define __NR_bpf 321
+# elif defined(__aarch64__)
+# define __NR_bpf 280
+# elif defined(__sparc__)
+# define __NR_bpf 349
+# elif defined(__s390__)
+# define __NR_bpf 351
+# else
+# error __NR_bpf not defined. libbpf does not support your arch.
+# endif
+#endif
+
+static inline __u64 ptr_to_u64(const void *ptr)
+{
+ return (__u64)(unsigned long)ptr;
+}
+
+static inline int sys_bpf(enum bpf_cmd cmd, union bpf_attr *attr,
+ unsigned int size)
+{
+ return syscall(__NR_bpf, cmd, attr, size);
+}
+
+int bpf_load(enum bpf_prog_type type,
+ const struct bpf_insn *insns,
+ size_t insns_cnt,
+ const char *license,
+ __u32 kern_version)
+{
+ union bpf_attr attr;
+
+ bzero(&attr, sizeof(attr));
+ attr.prog_type = type;
+ attr.insn_cnt = (__u32)insns_cnt;
+ attr.insns = ptr_to_u64(insns);
+ attr.license = ptr_to_u64(license);
+ attr.log_buf = ptr_to_u64(NULL);
+ attr.log_level = 0;
+ attr.kern_version = kern_version;
+
+ return sys_bpf(BPF_PROG_LOAD, &attr, sizeof(attr));
+}
diff --git a/drivers/net/tap/tap_bpf_program.c b/drivers/net/tap/tap_bpf_program.c
new file mode 100644
index 0000000..e1ae0c5
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_program.c
@@ -0,0 +1,321 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright 2017 6WIND S.A.
+ * Copyright 2017 Mellanox.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of 6WIND S.A. nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <asm/types.h>
+#include <linux/in.h>
+#include <linux/if.h>
+#include <linux/if_ether.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <linux/if_tunnel.h>
+#include <linux/filter.h>
+#include <linux/bpf.h>
+
+/* BPF helper functions for our example. */
+#include "tap_bpf_api.h"
+#include "tap_bpf_shared.h"
+
+#define ERROR 0
+
+/*
+ * The queue number is offset by 1, to distinguish packets that have
+ * gone through this rule (skb->cb[1] != 0) from others.
+ */
+#define QUEUE_OFFSET 1
+
+#define INV_KEY_IDX 0xdeadbeef
+
+struct vlan_hdr {
+ __be16 proto;
+ __be16 tci;
+};
+
+__section("maps")
+struct bpf_elf_map map_keys = {
+ .type = BPF_MAP_TYPE_HASH,
+ .id = BPF_MAP_ID_KEY,
+ .size_key = sizeof(__u32),
+ .size_value = sizeof(struct rss_key),
+ .max_elem = 256,
+ .pinning = PIN_GLOBAL_NS,
+};
+
+__section("cls_q") int
+match_q(struct __sk_buff *skb)
+{
+ __u32 queue = skb->cb[1];
+ volatile __u32 q = INV_KEY_IDX;
+ __u32 match_queue = QUEUE_OFFSET + q;
+
+ /* printt("match_q$i() queue = %d\n", queue); */
+
+ if (queue != match_queue)
+ return TC_ACT_OK;
+ return TC_ACT_UNSPEC;
+}
+
+__section("tailing") int
+tail(struct __sk_buff *skb)
+{
+ skb_change_tail(skb, skb->len + sizeof(__u32), 0);
+
+ return TC_ACT_UNSPEC;
+}
+
+static void __attribute__((always_inline))
+toeplitz_hash(__u32 *hash, __u8 *key, __u32 *v, __u8 *data, __u8 data_len)
+{
+ u_int i, b;
+
+#pragma unroll
+ for (i = 0; i < data_len; i++) {
+#pragma unroll
+ for (b = 0; b < 8; b++) {
+ if (data[i] & (1 << (7 - b)))
+ *hash ^= *v;
+ *v <<= 1;
+ if (key[i + 4] & (1 << (7 - b)))
+ *v |= 1;
+ }
+ }
+}
+
+static int __attribute__((always_inline))
+hash(struct __sk_buff *skb, enum hash_field f)
+{
+ void *data_end = (void *)(long)skb->data_end;
+ void *data = (void *)(long)skb->data;
+ __u16 proto = (__u16)skb->protocol;
+ __u32 key_idx = INV_KEY_IDX;
+ __u32 hash = skb->cb[0];
+ struct rss_key *rsskey;
+ __u64 off = ETH_HLEN;
+ __u8 ip_proto = 0;
+ __u8 *key = 0;
+ __u32 v, len;
+
+ rsskey = map_lookup_elem(&map_keys, &key_idx);
+ if (!rsskey) {
+ printt("hash(): rss key is not configured\n");
+ return TC_ACT_OK;
+ }
+ key = (__u8 *)rsskey->key;
+
+ /* Get correct proto for 802.1ad */
+ if (skb->vlan_present && skb->vlan_proto == htons(ETH_P_8021AD)) {
+ if (data + ETH_ALEN * 2 + sizeof(struct vlan_hdr) +
+ sizeof(proto) > data_end)
+ return TC_ACT_OK;
+ proto = *(__u16 *)(data + ETH_ALEN * 2 +
+ sizeof(struct vlan_hdr));
+ off += sizeof(struct vlan_hdr);
+ }
+
+ if (rsskey->hash_fields & (1 << HASH_FIELD_L2_DST)) {
+ if (f == HASH_FIELD_L2_DST) {
+ v = (key[0] << 24) + (key[1] << 16) + (key[2] << 8) + key[3];
+ if (data + ETH_ALEN > data_end)
+ return TC_ACT_OK;
+ toeplitz_hash(&hash, key, &v, data, ETH_ALEN);
+ skb->cb[0] = hash;
+ printt("hash(%d): hash = %x (off = %d)\n",
+ f, skb->cb[0], 0);
+ return TC_ACT_PIPE;
+ }
+ key += ETH_ALEN;
+ }
+ if (rsskey->hash_fields & (1 << HASH_FIELD_L2_SRC)) {
+ if (f == HASH_FIELD_L2_SRC) {
+ v = (key[0] << 24) + (key[1] << 16) + (key[2] << 8) + key[3];
+ if (data + ETH_ALEN * 2 > data_end)
+ return TC_ACT_OK;
+ toeplitz_hash(&hash, key, &v, data + ETH_ALEN, ETH_ALEN);
+ skb->cb[0] = hash;
+ printt("hash(%d): hash = %x (off = %d)\n",
+ f, skb->cb[0], ETH_ALEN);
+ return TC_ACT_PIPE;
+ }
+ key += ETH_ALEN;
+ }
+
+ if (proto == htons(ETH_P_IP)) {
+ struct iphdr *ip;
+
+ if (data + off + sizeof(struct iphdr) > data_end)
+ return TC_ACT_OK;
+ ip = data + off;
+ ip_proto = ip->protocol;
+
+ if (rsskey->hash_fields & (1 << HASH_FIELD_L3_SRC)) {
+ if (f == HASH_FIELD_L3_SRC) {
+ v = (key[0] << 24) + (key[1] << 16) +
+ (key[2] << 8) + key[3];
+ toeplitz_hash(&hash, key, &v, data + off +
+ offsetof(struct iphdr, saddr),
+ sizeof(__u32));
+ skb->cb[0] = hash;
+ printt("hash(%d): hash = %x (off = %d)\n",
+ f, skb->cb[0],
+ off + offsetof(struct iphdr, saddr));
+ return TC_ACT_PIPE;
+ }
+ key += sizeof(__u32);
+ }
+ if (rsskey->hash_fields & (1 << HASH_FIELD_L3_DST)) {
+ if (f == HASH_FIELD_L3_DST) {
+ v = (key[0] << 24) + (key[1] << 16) +
+ (key[2] << 8) + key[3];
+ toeplitz_hash(&hash, key, &v, data + off +
+ offsetof(struct iphdr, daddr),
+ sizeof(__u32));
+ skb->cb[0] = hash;
+ printt("hash(%d): hash = %x (off = %d)\n",
+ f, skb->cb[0],
+ off + offsetof(struct iphdr, daddr));
+ return TC_ACT_PIPE;
+ }
+ key += sizeof(__u32);
+ }
+ off += sizeof(struct iphdr);
+ } else if (proto == htons(ETH_P_IPV6)) {
+ struct ipv6hdr *ip;
+
+ if (data + off + sizeof(struct ipv6hdr) > data_end)
+ return TC_ACT_OK;
+ ip = data + off;
+ ip_proto = ip->nexthdr;
+
+ if (rsskey->hash_fields & (1 << HASH_FIELD_L3_SRC)) {
+ if (f == HASH_FIELD_L3_SRC) {
+ v = (key[0] << 24) + (key[1] << 16) +
+ (key[2] << 8) + key[3];
+ toeplitz_hash(&hash, key, &v, data + off +
+ offsetof(struct ipv6hdr, saddr),
+ sizeof(struct in6_addr));
+ skb->cb[0] = hash;
+ printt("hash(%d): hash = %x (off = %d)\n",
+ f, skb->cb[0],
+ off + offsetof(struct ipv6hdr, saddr));
+ return TC_ACT_PIPE;
+ }
+ key += sizeof(struct in6_addr);
+ }
+ if (rsskey->hash_fields & (1 << HASH_FIELD_L3_DST)) {
+ if (f == HASH_FIELD_L3_DST) {
+ v = (key[0] << 24) + (key[1] << 16) +
+ (key[2] << 8) + key[3];
+ toeplitz_hash(&hash, key, &v, data + off +
+ offsetof(struct ipv6hdr, daddr),
+ sizeof(struct in6_addr));
+ skb->cb[0] = hash;
+ printt("hash(%d): hash = %x (off = %d)\n",
+ f, skb->cb[0],
+ off + offsetof(struct ipv6hdr, daddr));
+ return TC_ACT_PIPE;
+ }
+ key += sizeof(struct in6_addr);
+ }
+ off += sizeof(struct ipv6hdr);
+ } else {
+ /* Unknown protocol: stop hashing there */
+ return TC_ACT_PIPE;
+ }
+
+ /* Unknown ip_proto: stop hashing there */
+ if ((ip_proto == IPPROTO_TCP || ip_proto == IPPROTO_UDP) &&
+ (rsskey->hash_fields & (1 << HASH_FIELD_L4_SRC)) &&
+ (f == HASH_FIELD_L4_SRC)) {
+ v = (key[0] << 24) + (key[1] << 16) + (key[2] << 8) + key[3];
+ if (data + off + sizeof(__u16) > data_end)
+ return TC_ACT_OK;
+ toeplitz_hash(&hash, key, &v, data + off,
+ sizeof(__u16));
+ skb->cb[0] = hash;
+ printt("hash(%d): hash = %x (off = %d)\n",
+ f, skb->cb[0], off);
+ return TC_ACT_PIPE;
+ }
+
+ return TC_ACT_PIPE;
+}
+
+#define HASH(L) \
+ __section(#L) int \
+ L ## _hash(struct __sk_buff *skb) \
+ { \
+ return hash(skb, HASH_FIELD_ ## L); \
+ }
+
+HASH(L2_DST)
+
+HASH(L2_SRC)
+
+HASH(L3_SRC)
+
+HASH(L3_DST)
+
+HASH(L4_SRC)
+
+__section("hash_appending") int
+append_hash(struct __sk_buff *skb)
+{
+ __u32 hash = skb->cb[0];
+
+ skb_store_bytes(skb, skb->len - sizeof(hash), &hash, sizeof(hash), 0);
+
+ return TC_ACT_PIPE;
+}
+
+__section("queue_setting") int
+set_queue(struct __sk_buff *skb)
+{
+ __u32 key_idx = INV_KEY_IDX;
+ __u64 hash = skb->cb[0];
+ struct rss_key *rsskey;
+ __u32 queue = 0;
+
+ rsskey = map_lookup_elem(&map_keys, &key_idx);
+ if (rsskey && rsskey->nb_queues <= TAP_MAX_QUEUES)
+ queue = rsskey->queues[(hash % rsskey->nb_queues) &
+ (TAP_MAX_QUEUES - 1)];
+
+ skb->cb[1] = QUEUE_OFFSET + queue;
+
+ return TC_ACT_RECLASSIFY;
+}
+
+BPF_LICENSE("GPL");
diff --git a/drivers/net/tap/tap_bpf_shared.h b/drivers/net/tap/tap_bpf_shared.h
new file mode 100644
index 0000000..6895cf4
--- /dev/null
+++ b/drivers/net/tap/tap_bpf_shared.h
@@ -0,0 +1,40 @@
+#ifndef __BPF_SHARED__
+#define __BPF_SHARED__
+
+#define TAP_MAX_QUEUES 16
+
+enum hash_field {
+ HASH_FIELD_L2_DST,
+ HASH_FIELD_L2_SRC,
+ HASH_FIELD_L3_SRC,
+ HASH_FIELD_L3_DST,
+ HASH_FIELD_L4_SRC,
+};
+
+enum {
+ BPF_MAP_ID_KEY,
+ BPF_MAP_ID_SIMPLE,
+};
+
+struct rss_key {
+ __u32 key[32];
+ __u32 hash_fields;
+ __u32 key_size;
+ __u32 queues[TAP_MAX_QUEUES];
+ __u32 nb_queues;
+};
+
+int bpf_load_cls_q_insns(__u32 queue_idx);
+int bpf_load_tailing_insns(void);
+int bpf_load_hash_appending_insns(void);
+int bpf_load_queue_setting_insns(__u32 queue_idx);
+int bpf_load_l2_src_hash_insns(__u32 key_idx);
+int bpf_load_l2_dst_hash_insns(__u32 key_idx);
+int bpf_load_l3_dst_hash_insns(__u32 key_idx);
+int bpf_load_l3_src_hash_insns(__u32 key_idx);
+int bpf_load_l4_src_hash_insns(__u32 key_idx);
+
+int bpf_load(enum bpf_prog_type type, const struct bpf_insn *insns,
+ size_t insns_cnt, const char *license, __u32 kern_version);
+
+#endif /* __BPF_SHARED__ */
diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
index 43bab7d..355f493 100644
--- a/drivers/net/tap/tap_flow.c
+++ b/drivers/net/tap/tap_flow.c
@@ -46,6 +46,8 @@
#include <linux/bpf.h>
#include <linux/tc_act/tc_bpf.h>
+#include <tap_bpf_shared.h>
+
#ifndef HAVE_TC_FLOWER
/*
* For kernels < 4.2, this enum is not defined. Runtime checks will be made to
@@ -1673,7 +1675,9 @@ static int rss_enable(struct pmd_internals *pmd)
},
};
- bpf_fd = 0;
+ bpf_fd = bpf_load_cls_q_insns(i);
+ if (bpf_fd == -1)
+ return -1;
rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
if (!rss_flow) {
@@ -1708,6 +1712,11 @@ static int rss_enable(struct pmd_internals *pmd)
LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
}
+ /* Add a rule that adds 4 bytes at packet's end to hold the hash */
+ bpf_fd = bpf_load_tailing_insns();
+ if (bpf_fd == -1)
+ return -1;
+
snprintf(annotation, sizeof(annotation), "%s:[%s]", BPF_PROGRAM,
section);
rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
--
1.8.3.1
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH 2/5] ethdev: add port ownership
@ 2017-11-30 14:30 3% ` Matan Azrad
2017-11-30 15:09 3% ` Gaëtan Rivet
0 siblings, 1 reply; 200+ results
From: Matan Azrad @ 2017-11-30 14:30 UTC (permalink / raw)
To: Gaëtan Rivet, Neil Horman; +Cc: Thomas Monjalon, Jingjing Wu, dev
Hi all
> -----Original Message-----
> From: Gaëtan Rivet [mailto:gaetan.rivet@6wind.com]
> Sent: Thursday, November 30, 2017 3:25 PM
> To: Neil Horman <nhorman@tuxdriver.com>
> Cc: Matan Azrad <matan@mellanox.com>; Thomas Monjalon
> <thomas@monjalon.net>; Jingjing Wu <jingjing.wu@intel.com>;
> dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/5] ethdev: add port ownership
>
> Hello Matan, Neil,
>
> I like the port ownership concept. I think it is needed to clarify some
> operations and should be useful to several subsystems.
>
> This patch could certainly be sub-divided however, and your current 1/5
> should probably come after this one.
Can you suggest how to divide it?
1/5 could be actually outside of this series, it is just better behavior to use the right function to do release port :)
>
> Some comments inline.
>
> On Thu, Nov 30, 2017 at 07:36:11AM -0500, Neil Horman wrote:
> > On Tue, Nov 28, 2017 at 11:57:58AM +0000, Matan Azrad wrote:
> > > The ownership of a port is implicit in DPDK.
> > > Making it explicit is better from the next reasons:
> > > 1. It may be convenient for multi-process applications to know which
> > > process is in charge of a port.
> > > 2. A library could work on top of a port.
> > > 3. A port can work on top of another port.
> > >
> > > Also in the fail-safe case, an issue has been met in testpmd.
> > > We need to check that the user is not trying to use a port which is
> > > already managed by fail-safe.
> > >
> > > Add ownership mechanism to DPDK Ethernet devices to avoid multiple
> > > management of a device by different DPDK entities.
> > >
> > > A port owner is built from owner id(number) and owner name(string)
> > > while the owner id must be unique to distinguish between two
> > > identical entity instances and the owner name can be any name.
> > > The name helps to logically recognize the owner by different DPDK
> > > entities and allows easy debug.
> > > Each DPDK entity can allocate an owner unique identifier and can use
> > > it and its preferred name to owns valid ethdev ports.
> > > Each DPDK entity can get any port owner status to decide if it can
> > > manage the port or not.
> > >
> > > The current ethdev internal port management is not affected by this
> > > feature.
> > >
>
> The internal port management is not affected, but the external interface is,
> however. In order to respect port ownership, applications are forced to
> modify their port iterator, as shown by your testpmd patch.
>
> I think it would be better to modify the current RTE_ETH_FOREACH_DEV to
> call RTE_FOREACH_DEV_OWNED_BY, and introduce a default owner that
> would represent the application itself (probably with the ID 0 and an owner
> string ""). Only with specific additional configuration should this default
> subset of ethdev be divided.
>
> This would make this evolution seamless for applications, at no cost to the
> complexity of the design.
As you can see in patch code and in testpmd example I added option to iterate over all valid ownerless ports which should be more relevant by owner_id = 0.
So maybe the RTE_ETH_FOREACH_DEV should be changed to run this by the new iterator.
By this way current applications don't need to build their owners but the ABI will be broken.
Actually, I think the old iterator RTE_ETH_FOREACH_DEV should be unexposed or just removed,
also the DEFFERED state should be removed,
I don't really see any usage to iterate over all valid ports by DPDK entities different from ethdev itself.
I just don't want to break it now.
>
> > > Signed-off-by: Matan Azrad <matan@mellanox.com>
> >
> >
> > This seems fairly racy. What if one thread attempts to set ownership
> > on a port, while another is checking it on another cpu in parallel.
> > It doesn't seem like it will protect against that at all. It also
> > doesn't protect against the possibility of multiple threads attempting
> > to poll for rx in parallel, which I think was part of Thomas's
> > origional statement regarding port ownership (he noted that the
> > lockless design implied only a single thread should be allowed to poll for
> receive or make configuration changes at a time.
> >
> > Neil
> >
>
> Isn't this race already there for any configuration operation / polling
> function? The DPDK arch is expecting applications to solve it. Why should port
> ownership be designed differently from other DPDK components?
>
> Embedding checks for port ownership within operations will force everyone
> to bear their costs, even those not interested in using this API. These checks
> should be kept outside, within the entity claiming ownership of the port, in
> the form of using the proper port iterator IMO.
As Gaetan said, there is a race in ethdev in many places, think about new port creation in parallel.
If one day ethdev will be race safe than the port ownership should be too.
>
> > > ---
> > > doc/guides/prog_guide/poll_mode_drv.rst | 12 +++-
> > > lib/librte_ether/rte_ethdev.c | 121
> ++++++++++++++++++++++++++++++++
> > > lib/librte_ether/rte_ethdev.h | 86 +++++++++++++++++++++++
> > > lib/librte_ether/rte_ethdev_version.map | 12 ++++
> > > 4 files changed, 230 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/doc/guides/prog_guide/poll_mode_drv.rst
> > > b/doc/guides/prog_guide/poll_mode_drv.rst
> > > index 6a0c9f9..af639a1 100644
> > > --- a/doc/guides/prog_guide/poll_mode_drv.rst
> > > +++ b/doc/guides/prog_guide/poll_mode_drv.rst
> > > @@ -156,7 +156,7 @@ concurrently on the same tx queue without SW
> > > lock. This PMD feature found in som
> > >
> > > See `Hardware Offload`_ for ``DEV_TX_OFFLOAD_MT_LOCKFREE``
> capability probing details.
> > >
> > > -Device Identification and Configuration
> > > +Device Identification, Ownership and Configuration
> > > ---------------------------------------
> > >
> > > Device Identification
> > > @@ -171,6 +171,16 @@ Based on their PCI identifier, NIC ports are
> assigned two other identifiers:
> > > * A port name used to designate the port in console messages, for
> administration or debugging purposes.
> > > For ease of use, the port name includes the port index.
> > >
> > > +Port Ownership
> > > +~~~~~~~~~~~~~
> > > +The Ethernet devices ports can be owned by a single DPDK entity
> (application, library, PMD, process, etc).
> > > +The ownership mechanism is controlled by ethdev APIs and allows to
> set/remove/get a port owner by DPDK entities.
> > > +Allowing this should prevent any multiple management of Ethernet port
> by different entities.
> > > +
> > > +.. note::
> > > +
> > > + It is the DPDK entity responsibility either to check the port owner
> before using it or to set the port owner to prevent others from using it.
> > > +
> > > Device Configuration
> > > ~~~~~~~~~~~~~~~~~~~~
> > >
> > > diff --git a/lib/librte_ether/rte_ethdev.c
> > > b/lib/librte_ether/rte_ethdev.c index 2d754d9..836991e 100644
> > > --- a/lib/librte_ether/rte_ethdev.c
> > > +++ b/lib/librte_ether/rte_ethdev.c
> > > @@ -71,6 +71,7 @@
> > > static const char *MZ_RTE_ETH_DEV_DATA = "rte_eth_dev_data";
> > > struct rte_eth_dev rte_eth_devices[RTE_MAX_ETHPORTS];
> > > static struct rte_eth_dev_data *rte_eth_dev_data;
> > > +static uint16_t rte_eth_next_owner_id = RTE_ETH_DEV_NO_OWNER +
> 1;
> > > static uint8_t eth_dev_last_created_port;
> > >
> > > /* spinlock for eth device callbacks */ @@ -278,6 +279,7 @@ struct
> > > rte_eth_dev *
> > > if (eth_dev == NULL)
> > > return -EINVAL;
> > >
> > > + memset(ð_dev->data->owner, 0, sizeof(struct
> > > +rte_eth_dev_owner));
> > > eth_dev->state = RTE_ETH_DEV_UNUSED;
> > > return 0;
> > > }
> > > @@ -293,6 +295,125 @@ struct rte_eth_dev *
> > > return 1;
> > > }
> > >
> > > +static int
> > > +rte_eth_is_valid_owner_id(uint16_t owner_id) {
> > > + if (owner_id == RTE_ETH_DEV_NO_OWNER ||
> > > + (rte_eth_next_owner_id != RTE_ETH_DEV_NO_OWNER &&
> > > + rte_eth_next_owner_id <= owner_id)) {
> > > + RTE_LOG(ERR, EAL, "Invalid owner_id=%d.\n", owner_id);
> > > + return 0;
> > > + }
> > > + return 1;
> > > +}
> > > +
> > > +uint16_t
> > > +rte_eth_find_next_owned_by(uint16_t port_id, const uint16_t
> > > +owner_id) {
> > > + while (port_id < RTE_MAX_ETHPORTS &&
> > > + (rte_eth_devices[port_id].state != RTE_ETH_DEV_ATTACHED ||
> > > + rte_eth_devices[port_id].data->owner.id != owner_id))
> > > + port_id++;
> > > +
> > > + if (port_id >= RTE_MAX_ETHPORTS)
> > > + return RTE_MAX_ETHPORTS;
> > > +
> > > + return port_id;
> > > +}
> > > +
> > > +int
> > > +rte_eth_dev_owner_new(uint16_t *owner_id) {
> > > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> > > + RTE_PMD_DEBUG_TRACE("Not primary process cannot own
> ports.\n");
> > > + return -EPERM;
> > > + }
> > > + if (rte_eth_next_owner_id == RTE_ETH_DEV_NO_OWNER) {
> > > + RTE_PMD_DEBUG_TRACE("Reached maximum number of
> Ethernet port owners.\n");
> > > + return -EUSERS;
> > > + }
> > > + *owner_id = rte_eth_next_owner_id++;
> > > + return 0;
> > > +}
> > > +
> > > +int
> > > +rte_eth_dev_owner_set(const uint16_t port_id,
> > > + const struct rte_eth_dev_owner *owner) {
> > > + struct rte_eth_dev_owner *port_owner;
> > > + int ret;
> > > +
> > > + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> > > + if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
> > > + RTE_PMD_DEBUG_TRACE("Not primary process cannot own
> ports.\n");
> > > + return -EPERM;
> > > + }
> > > + if (!rte_eth_is_valid_owner_id(owner->id))
> > > + return -EINVAL;
> > > + port_owner = &rte_eth_devices[port_id].data->owner;
> > > + if (port_owner->id != RTE_ETH_DEV_NO_OWNER &&
> > > + port_owner->id != owner->id) {
> > > + RTE_LOG(ERR, EAL,
> > > + "Cannot set owner to port %d already owned by
> %s_%05d.\n",
> > > + port_id, port_owner->name, port_owner->id);
> > > + return -EPERM;
> > > + }
> > > + ret = snprintf(port_owner->name,
> RTE_ETH_MAX_OWNER_NAME_LEN, "%s",
> > > + owner->name);
> > > + if (ret < 0 || ret >= RTE_ETH_MAX_OWNER_NAME_LEN) {
> > > + memset(port_owner->name, 0,
> RTE_ETH_MAX_OWNER_NAME_LEN);
> > > + RTE_LOG(ERR, EAL, "Invalid owner name.\n");
> > > + return -EINVAL;
> > > + }
> > > + port_owner->id = owner->id;
> > > + RTE_PMD_DEBUG_TRACE("Port %d owner is %s_%05d.\n", port_id,
> > > + owner->name, owner->id);
> > > + return 0;
> > > +}
> > > +
> > > +int
> > > +rte_eth_dev_owner_remove(const uint16_t port_id, const uint16_t
> > > +owner_id) {
> > > + struct rte_eth_dev_owner *port_owner;
> > > + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
> > > + if (!rte_eth_is_valid_owner_id(owner_id))
> > > + return -EINVAL;
> > > + port_owner = &rte_eth_devices[port_id].data->owner;
> > > + if (port_owner->id != owner_id) {
> > > + RTE_LOG(ERR, EAL,
> > > + "Cannot remove port %d owner %s_%05d by
> different owner id %5d.\n",
> > > + port_id, port_owner->name, port_owner->id,
> owner_id);
> > > + return -EPERM;
> > > + }
> > > + RTE_PMD_DEBUG_TRACE("Port %d owner %s_%05d has
> removed.\n", port_id,
> > > + port_owner->name, port_owner->id);
> > > + memset(port_owner, 0, sizeof(struct rte_eth_dev_owner));
> > > + return 0;
> > > +}
> > > +
> > > +void
> > > +rte_eth_dev_owner_delete(const uint16_t owner_id) {
> > > + uint16_t p;
> > > +
> > > + if (!rte_eth_is_valid_owner_id(owner_id))
> > > + return;
> > > + RTE_ETH_FOREACH_DEV_OWNED_BY(p, owner_id)
> > > + memset(&rte_eth_devices[p].data->owner, 0,
> > > + sizeof(struct rte_eth_dev_owner));
> > > + RTE_PMD_DEBUG_TRACE("All port owners owned by "
> > > + "%05d identifier has removed.\n", owner_id); }
> > > +
> > > +const struct rte_eth_dev_owner *
> > > +rte_eth_dev_owner_get(const uint16_t port_id) {
> > > + RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, NULL);
> > > + if (rte_eth_devices[port_id].data->owner.id ==
> RTE_ETH_DEV_NO_OWNER)
> > > + return NULL;
> > > + return &rte_eth_devices[port_id].data->owner;
> > > +}
> > > +
> > > int
> > > rte_eth_dev_socket_id(uint16_t port_id) { diff --git
> > > a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> > > index 341c2d6..f54c26d 100644
> > > --- a/lib/librte_ether/rte_ethdev.h
> > > +++ b/lib/librte_ether/rte_ethdev.h
> > > @@ -1760,6 +1760,15 @@ struct rte_eth_dev_sriov {
> > >
> > > #define RTE_ETH_NAME_MAX_LEN RTE_DEV_NAME_MAX_LEN
> > >
> > > +#define RTE_ETH_DEV_NO_OWNER 0
> > > +
> > > +#define RTE_ETH_MAX_OWNER_NAME_LEN 64
> > > +
> > > +struct rte_eth_dev_owner {
> > > + uint16_t id; /**< The owner unique identifier. */
> > > + char name[RTE_ETH_MAX_OWNER_NAME_LEN]; /**< The owner
> name. */ };
> > > +
> > > /**
> > > * @internal
> > > * The data part, with no function pointers, associated with each
> ethernet device.
> > > @@ -1810,6 +1819,7 @@ struct rte_eth_dev_data {
> > > int numa_node; /**< NUMA node connection */
> > > struct rte_vlan_filter_conf vlan_filter_conf;
> > > /**< VLAN filter configuration. */
> > > + struct rte_eth_dev_owner owner; /**< The port owner. */
> > > };
> > >
> > > /** Device supports link state interrupt */ @@ -1846,6 +1856,82 @@
> > > struct rte_eth_dev_data {
> > >
> > >
> > > /**
> > > + * Iterates over valid ethdev ports owned by a specific owner.
> > > + *
> > > + * @param port_id
> > > + * The id of the next possible valid owned port.
> > > + * @param owner_id
> > > + * The owner identifier.
> > > + * RTE_ETH_DEV_NO_OWNER means iterate over all valid ownerless
> ports.
> > > + * @return
> > > + * Next valid port id owned by owner_id, RTE_MAX_ETHPORTS if there
> is none.
> > > + */
> > > +uint16_t rte_eth_find_next_owned_by(uint16_t port_id, const
> > > +uint16_t owner_id);
> > > +
> > > +/**
> > > + * Macro to iterate over all enabled ethdev ports owned by a specific
> owner.
> > > + */
> > > +#define RTE_ETH_FOREACH_DEV_OWNED_BY(p, o) \
> > > + for (p = rte_eth_find_next_owned_by(0, o); \
> > > + (unsigned int)p < (unsigned int)RTE_MAX_ETHPORTS; \
> > > + p = rte_eth_find_next_owned_by(p + 1, o))
> > > +
> > > +/**
> > > + * Get a new unique owner identifier.
> > > + * An owner identifier is used to owns Ethernet devices by only one
> > > +DPDK entity
> > > + * to avoid multiple management of device by different entities.
> > > + *
> > > + * @param owner_id
> > > + * Owner identifier pointer.
> > > + * @return
> > > + * Negative errno value on error, 0 on success.
> > > + */
> > > +int rte_eth_dev_owner_new(uint16_t *owner_id);
> > > +
> > > +/**
> > > + * Set an Ethernet device owner.
> > > + *
> > > + * @param port_id
> > > + * The identifier of the port to own.
> > > + * @param owner
> > > + * The owner pointer.
> > > + * @return
> > > + * Negative errno value on error, 0 on success.
> > > + */
> > > +int rte_eth_dev_owner_set(const uint16_t port_id,
> > > + const struct rte_eth_dev_owner *owner);
> > > +
> > > +/**
> > > + * Remove Ethernet device owner to make the device ownerless.
> > > + *
> > > + * @param port_id
> > > + * The identifier of port to make ownerless.
> > > + * @param owner
> > > + * The owner identifier.
> > > + * @return
> > > + * 0 on success, negative errno value on error.
> > > + */
> > > +int rte_eth_dev_owner_remove(const uint16_t port_id, const uint16_t
> > > +owner_id);
> > > +
> > > +/**
> > > + * Remove owner from all Ethernet devices owned by a specific owner.
> > > + *
> > > + * @param owner
> > > + * The owner identifier.
> > > + */
> > > +void rte_eth_dev_owner_delete(const uint16_t owner_id);
> > > +
> > > +/**
> > > + * Get the owner of an Ethernet device.
> > > + *
> > > + * @param port_id
> > > + * The port identifier.
> > > + * @return
> > > + * NULL when the device is ownerless, else the device owner pointer.
> > > + */
> > > +const struct rte_eth_dev_owner *rte_eth_dev_owner_get(const
> > > +uint16_t port_id);
> > > +
> > > +/**
> > > * Get the total number of Ethernet devices that have been successfully
> > > * initialized by the matching Ethernet driver during the PCI probing
> phase
> > > * and that are available for applications to use. These devices
> > > must be diff --git a/lib/librte_ether/rte_ethdev_version.map
> > > b/lib/librte_ether/rte_ethdev_version.map
> > > index e9681ac..7d07edb 100644
> > > --- a/lib/librte_ether/rte_ethdev_version.map
> > > +++ b/lib/librte_ether/rte_ethdev_version.map
> > > @@ -198,6 +198,18 @@ DPDK_17.11 {
> > >
> > > } DPDK_17.08;
> > >
> > > +DPDK_18.02 {
> > > + global:
> > > +
> > > + rte_eth_find_next_owned_by;
> > > + rte_eth_dev_owner_new;
> > > + rte_eth_dev_owner_set;
> > > + rte_eth_dev_owner_remove;
> > > + rte_eth_dev_owner_delete;
> > > + rte_eth_dev_owner_get;
> > > +
> > > +} DPDK_17.11;
> > > +
> > > EXPERIMENTAL {
> > > global:
> > >
> > > --
> > > 1.8.3.1
> > >
> > >
>
> --
> Gaëtan Rivet
> 6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 2/5] ethdev: add port ownership
2017-11-30 14:30 3% ` Matan Azrad
@ 2017-11-30 15:09 3% ` Gaëtan Rivet
2017-11-30 15:43 3% ` Matan Azrad
0 siblings, 1 reply; 200+ results
From: Gaëtan Rivet @ 2017-11-30 15:09 UTC (permalink / raw)
To: Matan Azrad; +Cc: Neil Horman, Thomas Monjalon, Jingjing Wu, dev
On Thu, Nov 30, 2017 at 02:30:20PM +0000, Matan Azrad wrote:
> Hi all
>
> > -----Original Message-----
> > From: Gaëtan Rivet [mailto:gaetan.rivet@6wind.com]
> > Sent: Thursday, November 30, 2017 3:25 PM
> > To: Neil Horman <nhorman@tuxdriver.com>
> > Cc: Matan Azrad <matan@mellanox.com>; Thomas Monjalon
> > <thomas@monjalon.net>; Jingjing Wu <jingjing.wu@intel.com>;
> > dev@dpdk.org
> > Subject: Re: [dpdk-dev] [PATCH 2/5] ethdev: add port ownership
> >
> > Hello Matan, Neil,
> >
> > I like the port ownership concept. I think it is needed to clarify some
> > operations and should be useful to several subsystems.
> >
> > This patch could certainly be sub-divided however, and your current 1/5
> > should probably come after this one.
>
> Can you suggest how to divide it?
>
Adding first the API to add / remove owners, then in a second patch
set / get / unset. (by the way, remove / delete is pretty confusing, I'd
suggest renaming those.) You can also separate the introduction of the
new owner-wise iterator.
Ultimately, you are the author, it's your job to help us review your
work.
> 1/5 could be actually outside of this series, it is just better behavior to use the right function to do release port :)
>
> >
> > Some comments inline.
> >
> > On Thu, Nov 30, 2017 at 07:36:11AM -0500, Neil Horman wrote:
> > > On Tue, Nov 28, 2017 at 11:57:58AM +0000, Matan Azrad wrote:
> > > > The ownership of a port is implicit in DPDK.
> > > > Making it explicit is better from the next reasons:
> > > > 1. It may be convenient for multi-process applications to know which
> > > > process is in charge of a port.
> > > > 2. A library could work on top of a port.
> > > > 3. A port can work on top of another port.
> > > >
> > > > Also in the fail-safe case, an issue has been met in testpmd.
> > > > We need to check that the user is not trying to use a port which is
> > > > already managed by fail-safe.
> > > >
> > > > Add ownership mechanism to DPDK Ethernet devices to avoid multiple
> > > > management of a device by different DPDK entities.
> > > >
> > > > A port owner is built from owner id(number) and owner name(string)
> > > > while the owner id must be unique to distinguish between two
> > > > identical entity instances and the owner name can be any name.
> > > > The name helps to logically recognize the owner by different DPDK
> > > > entities and allows easy debug.
> > > > Each DPDK entity can allocate an owner unique identifier and can use
> > > > it and its preferred name to owns valid ethdev ports.
> > > > Each DPDK entity can get any port owner status to decide if it can
> > > > manage the port or not.
> > > >
> > > > The current ethdev internal port management is not affected by this
> > > > feature.
> > > >
> >
> > The internal port management is not affected, but the external interface is,
> > however. In order to respect port ownership, applications are forced to
> > modify their port iterator, as shown by your testpmd patch.
> >
> > I think it would be better to modify the current RTE_ETH_FOREACH_DEV to
> > call RTE_FOREACH_DEV_OWNED_BY, and introduce a default owner that
> > would represent the application itself (probably with the ID 0 and an owner
> > string ""). Only with specific additional configuration should this default
> > subset of ethdev be divided.
> >
> > This would make this evolution seamless for applications, at no cost to the
> > complexity of the design.
>
> As you can see in patch code and in testpmd example I added option to iterate
> over all valid ownerless ports which should be more relevant by owner_id = 0.
> So maybe the RTE_ETH_FOREACH_DEV should be changed to run this by the new iterator.
That is precisely what I am suggesting.
Ideally, you should not have to change anything in testpmd, beside some
bug fixing regarding port iteration to avoid those with a specific
owner.
RTE_ETH_FOREACH_DEV must stay valid, and should iterate over ownerless
ports (read: port owned by the default owner).
> By this way current applications don't need to build their owners but the ABI will be broken.
>
ABI is broken anyway as you will add the owner to rte_eth_dev_data.
> Actually, I think the old iterator RTE_ETH_FOREACH_DEV should be unexposed or just removed,
I don't think so. Using RTE_ETH_FOREACH_DEV should allow keeping the
current behavior of iterating over ownerless ports. Applications that do
not care for this API should not have to change anything to their code.
> also the DEFFERED state should be removed,
Of course.
> I don't really see any usage to iterate over all valid ports by DPDK entities different from ethdev itself.
> I just don't want to break it now.
>
[snip]
--
Gaëtan Rivet
6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 2/5] ethdev: add port ownership
2017-11-30 15:09 3% ` Gaëtan Rivet
@ 2017-11-30 15:43 3% ` Matan Azrad
0 siblings, 0 replies; 200+ results
From: Matan Azrad @ 2017-11-30 15:43 UTC (permalink / raw)
To: Gaëtan Rivet; +Cc: Neil Horman, Thomas Monjalon, Jingjing Wu, dev
Hi Gaetan
> -----Original Message-----
> From: Gaëtan Rivet [mailto:gaetan.rivet@6wind.com]
> Sent: Thursday, November 30, 2017 5:10 PM
> To: Matan Azrad <matan@mellanox.com>
> Cc: Neil Horman <nhorman@tuxdriver.com>; Thomas Monjalon
> <thomas@monjalon.net>; Jingjing Wu <jingjing.wu@intel.com>;
> dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 2/5] ethdev: add port ownership
>
> On Thu, Nov 30, 2017 at 02:30:20PM +0000, Matan Azrad wrote:
> > Hi all
> >
> > > -----Original Message-----
> > > From: Gaëtan Rivet [mailto:gaetan.rivet@6wind.com]
> > > Sent: Thursday, November 30, 2017 3:25 PM
> > > To: Neil Horman <nhorman@tuxdriver.com>
> > > Cc: Matan Azrad <matan@mellanox.com>; Thomas Monjalon
> > > <thomas@monjalon.net>; Jingjing Wu <jingjing.wu@intel.com>;
> > > dev@dpdk.org
> > > Subject: Re: [dpdk-dev] [PATCH 2/5] ethdev: add port ownership
> > >
> > > Hello Matan, Neil,
> > >
> > > I like the port ownership concept. I think it is needed to clarify
> > > some operations and should be useful to several subsystems.
> > >
> > > This patch could certainly be sub-divided however, and your current
> > > 1/5 should probably come after this one.
> >
> > Can you suggest how to divide it?
> >
>
> Adding first the API to add / remove owners, then in a second patch set / get
> / unset. (by the way, remove / delete is pretty confusing, I'd suggest
> renaming those.) You can also separate the introduction of the new owner-
> wise iterator.
>
> Ultimately, you are the author, it's your job to help us review your work.
>
When you suggest improvement I think you need to propose another method\idea.
The author probably thought about it and arrived to his conclusions.
Exactly as you are doing now in naming.
If you have a specific question, I'm here to answer :)
I agree with unset name instead of remove, will change it in V2.
> > 1/5 could be actually outside of this series, it is just better
> > behavior to use the right function to do release port :)
> >
> > >
> > > Some comments inline.
> > >
> > > On Thu, Nov 30, 2017 at 07:36:11AM -0500, Neil Horman wrote:
> > > > On Tue, Nov 28, 2017 at 11:57:58AM +0000, Matan Azrad wrote:
> > > > > The ownership of a port is implicit in DPDK.
> > > > > Making it explicit is better from the next reasons:
> > > > > 1. It may be convenient for multi-process applications to know which
> > > > > process is in charge of a port.
> > > > > 2. A library could work on top of a port.
> > > > > 3. A port can work on top of another port.
> > > > >
> > > > > Also in the fail-safe case, an issue has been met in testpmd.
> > > > > We need to check that the user is not trying to use a port which
> > > > > is already managed by fail-safe.
> > > > >
> > > > > Add ownership mechanism to DPDK Ethernet devices to avoid
> > > > > multiple management of a device by different DPDK entities.
> > > > >
> > > > > A port owner is built from owner id(number) and owner
> > > > > name(string) while the owner id must be unique to distinguish
> > > > > between two identical entity instances and the owner name can be
> any name.
> > > > > The name helps to logically recognize the owner by different
> > > > > DPDK entities and allows easy debug.
> > > > > Each DPDK entity can allocate an owner unique identifier and can
> > > > > use it and its preferred name to owns valid ethdev ports.
> > > > > Each DPDK entity can get any port owner status to decide if it
> > > > > can manage the port or not.
> > > > >
> > > > > The current ethdev internal port management is not affected by
> > > > > this feature.
> > > > >
> > >
> > > The internal port management is not affected, but the external
> > > interface is, however. In order to respect port ownership,
> > > applications are forced to modify their port iterator, as shown by your
> testpmd patch.
> > >
> > > I think it would be better to modify the current RTE_ETH_FOREACH_DEV
> > > to call RTE_FOREACH_DEV_OWNED_BY, and introduce a default owner
> that
> > > would represent the application itself (probably with the ID 0 and
> > > an owner string ""). Only with specific additional configuration
> > > should this default subset of ethdev be divided.
> > >
> > > This would make this evolution seamless for applications, at no cost
> > > to the complexity of the design.
> >
> > As you can see in patch code and in testpmd example I added option to
> > iterate over all valid ownerless ports which should be more relevant by
> owner_id = 0.
> > So maybe the RTE_ETH_FOREACH_DEV should be changed to run this by
> the new iterator.
>
> That is precisely what I am suggesting.
> Ideally, you should not have to change anything in testpmd, beside some bug
> fixing regarding port iteration to avoid those with a specific owner.
>
> RTE_ETH_FOREACH_DEV must stay valid, and should iterate over ownerless
> ports (read: port owned by the default owner).
>
> > By this way current applications don't need to build their owners but the
> ABI will be broken.
> >
>
> ABI is broken anyway as you will add the owner to rte_eth_dev_data.
>
It is not, rte_eth_dev_data is internal.
> > Actually, I think the old iterator RTE_ETH_FOREACH_DEV should be
> > unexposed or just removed,
>
> I don't think so. Using RTE_ETH_FOREACH_DEV should allow keeping the
> current behavior of iterating over ownerless ports. Applications that do not
> care for this API should not have to change anything to their code.
>
If we will break the ABI later users can use RTE_ETH_FOREACH_DEV_OWNED_BY(p,0)
to do it. RTE_ETH_FOREACH_DEV will be unnecessary anymore but maybe is too much to applications to change also the API.
I can agree with it.
> > also the DEFFERED state should be removed,
>
> Of course.
>
> > I don't really see any usage to iterate over all valid ports by DPDK entities
> different from ethdev itself.
> > I just don't want to break it now.
> >
>
> [snip]
>
> --
> Gaëtan Rivet
> 6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] 17.08.1 patches review and test
2017-11-27 12:21 2% [dpdk-dev] 17.08.1 patches review and test Yuanhan Liu
@ 2017-11-30 19:09 0% ` Patil, Harish
2017-12-04 20:40 0% ` Patil, Harish
1 sibling, 0 replies; 200+ results
From: Patil, Harish @ 2017-11-30 19:09 UTC (permalink / raw)
To: Yuanhan Liu, dpdk stable; +Cc: dev, Xu, Qian Q, Dept-Eng DPDK Dev
-----Original Message-----
From: dev <dev-bounces@dpdk.org> on behalf of Yuanhan Liu
<yliu@fridaylinux.org>
Date: Monday, November 27, 2017 at 4:21 AM
To: dpdk stable <stable@dpdk.org>
Cc: "dev@dpdk.org" <dev@dpdk.org>, "Xu, Qian Q" <qian.q.xu@intel.com>
Subject: [dpdk-dev] 17.08.1 patches review and test
>Hi all,
>
>Here is a list of patches targeted for stable release 17.08.1. Please
>help review and test. The planned date for the final release is 7th,
>Dec. Before that, please shout if anyone has objections with these
>patches being applied.
>
>These patches are located at branch 17.08 of dpdk-stable repo:
> http://dpdk.org/browse/dpdk-stable/
>
>Thanks.
>
> --yliu
>
>---
>Aaron Conole (1):
> net/enic: fix assignment
>
>Ajit Khaparde (28):
> net/bnxt: fix HWRM macros and locking
> net/bnxt: use 64-bits of address for VLAN table
> net/bnxt: fix an issue with group id calculation
> net/bnxt: fix calculation of number of pools
> net/bnxt: handle multi queue mode properly
> net/bnxt: fix Rx handling and buffer allocation logic
> net/bnxt: fix an issue with broadcast traffic
> net/bnxt: fix usage of VMDq flags
> net/bnxt: set checksum offload flags correctly
> net/bnxt: update status of Rx IP/L4 CKSUM
> net/bnxt: fix config RSS update
> net/bnxt: set the hash key size
> net/bnxt: fix per queue stats display in xstats
> net/bnxt: fix interrupt handler
> net/bnxt: fix number of MAC addresses for VMDq
> net/bnxt: fix the association of a MACVLAN per VNIC
> net/bnxt: fix Tx offload capability
> net/bnxt: fix Rx offload capability
> net/bnxt: handle Rx multi queue creation properly
> net/bnxt: remove redundant code parsing pool map
> net/bnxt: fix a bit shift operation
> net/bnxt: fix a potential null pointer dereference
> net/bnxt: fix a potential null pointer dereference
> net/bnxt: fix a pointer deref before null check
> net/bnxt: fix an unused value
> net/bnxt: check VLANs from pool map only for VMDq
> net/bnxt: do not set hash type unnecessarily
> net/bnxt: fix VLAN spoof configuration
>
>Akhil Goyal (2):
> test/crypto: fix dpaa2 sec macros and definitions
> net/dpaa2: set queues after reconfiguration
>
>Alejandro Lucero (2):
> net/nfp: fix RSS
> net/nfp: fix Rx interrupt when multiqueue
>
>Alok Makhariya (2):
> crypto/dpaa2_sec: remove ICV memset on decryption side
> crypto/dpaa2_sec: add check for segmented buffer
>
>Anatoly Burakov (1):
> vfio: fix secondary process initialization
>
>Andrey Chilikin (1):
> net/i40e: fix flexible payload configuration
>
>Aviad Yehezkel (4):
> examples/ipsec-secgw: fix crypto device mapping
> examples/ipsec-secgw: fix session creation
> examples/ipsec-secgw: fix AAD length setting
> app/testpmd: fix build without ixgbe and bnxt PMDs
>
>Beilei Xing (1):
> net/i40e: fix VF device stop issue
>
>Chas Williams (1):
> net/vmxnet3: fix memory leak when releasing queues
>
>Congwen Zhang (1):
> net/cxgbe: fix memory leak
>
>Daniel Mrzyglod (3):
> net/virtio: fix untrusted scalar value
> app/testpmd: fix DDP package filesize detection
> net/bonding: fix default aggregator mode to stable
>
>David Harton (2):
> net/vmxnet3: fix MAC address set
> net/i40e: fix i40evf MAC filter table
>
>Ferruh Yigit (4):
> ethdev: fix ABI version
> ethdev: revert use port name from device structure
> igb_uio: remove device reset in open
> net/qede: fix icc build
>
>Gaetan Rivet (1):
> net/failsafe: fix errno set on command execution
>
>Gowrishankar Muthukrishnan (1):
> net/bonding: support bifurcated driver in eal
>
>Guduri Prathyusha (2):
> examples/l3fwd: fix NEON instructions
> examples/l3fwd: fix aliasing in port grouping
>
>Harish Patil (2):
> net/qede: fix supported packet types
> net/qede: fix to re-enable LRO during device start
>
>Hemant Agrawal (3):
> net/dpaa2: fix the Tx handling of non HW pool bufs
> examples/l2fwd-crypto: fix uninitialized errno value
> app/crypto-perf: fix uninitialized errno value
>
>Ian Stokes (1):
> cryptodev: fix build with -Ofast
>
>Ivan Malov (2):
> net/sfc: specify correct scale table size on Rx start
> net/sfc: fix unused variable in RSS-agnostic build
>
>Jacek Piasecki (1):
> examples/vhost_scsi: fix product id string termination
>
>Jasvinder Singh (1):
> examples/qos_sched: fix uninitialized config
>
>Jerin Jacob (1):
> timer: use 64-bit specific code on more platforms
>
>Jianbo Liu (1):
> net/i40e: fix Rx packets number for NEON
>
>Jiayu Hu (1):
> gro: fix typo in map file
>
>Jingjing Wu (4):
> net/i40e: fix interrupt throttling setting in PF
> net/i40e: fix memory leak if VF init fails
> net/i40e: fix variable assignment
> net/i40e: fix VF initialization error
>
>John Daley (3):
> net/enic: fix multi-process operation
> net/enic: fix packet loss after MTU change
> net/enic: fix TSO for packets greater than 9208 bytes
>
>John Miller (1):
> net/ark: fix loop counter
>
>Kuba Kozak (2):
> vfio: fix close unchecked file descriptor
> vhost: check poll error code
>
>Li Han (1):
> app/testpmd: fix invalid port id parameters
>
>Lukasz Majczak (1):
> eal: fix auxv open check for ARM and PPC
>
>Mark Spender (1):
> net/sfc/base: fix default RSS context check on Siena
>
>Matan Azrad (7):
> net/failsafe: fix Tx sub device deactivating
> net/mlx5: fix locking in xstats functions
> net/failsafe: fix parameters parsing
> net/mlx5: fix probe failure report
> net/failsafe: fix adding MAC error report miss
> app/testpmd: fix forward port ids setting
> net/failsafe: fix Rx clean race
>
>Maxime Coquelin (1):
> vhost: fix dereferencing invalid pointer after realloc
>
>Michal Jastrzebski (1):
> net/vmxnet3: fix dereference before null check
>
>Nikhil Rao (1):
> eal/x86: fix atomic cmpset
>
>Nirmoy Das (1):
> kni: fix SLE version detection
>
>Nélio Laranjeiro (4):
> net/mlx5: fix clang build
> net/mlx5: fix SSE Rx support verification
> net/mlx5: fix clang compilation error
> app/testpmd: fix RSS structure initialisation
>
>Olivier Matz (12):
> net: fix inner L2 length in packet type parser
> net/bnxt: fix compilation with -Og
> net/qede: fix compilation with -Og
> app/test-crypto-perf: fix memory leak
> app/test-crypto-perf: fix compilation with -Og
> net/virtio: revert not claiming LRO support
> net/virtio: revert not claiming IP checksum offload
> net/virtio: fix log levels in configure
> net/virtio: fix mbuf port for simple Rx function
> net/virtio: fix queue setup consistency
> net/virtio: fix compilation with -Og
> lpm6: fix compilation with -Og
>
>Ophir Munk (3):
> net/tap: fix flow and port commands
> net/failsafe: fix VLAN stripping configuration
> app/testpmd: fix forwarding between non consecutive ports
>
>Pablo de Lara (8):
> hash: fix eviction counter
> crypto/aesni_gcm: fix zero data operation
> app/crypto-perf: fix packet length check
> app/crypto-perf: parse AEAD data from vectors
> crypto/openssl: fix AEAD parameters
> examples/l2fwd-crypto: fix physical address setting
> crypto/qat: fix HMAC supported digest sizes
> app/testpmd: fix topology error message
>
>Patrick MacArthur (1):
> eal: copy raw strings taken from command line
>
>Phil Yang (1):
> app/testpmd: fix quitting in container
>
>Qi Zhang (4):
> net/i40e: fix flow control watermark mismatch
> net/i40e: fix packet count for PF
> net/i40e: fix mbuf free in vector Tx
> net/i40e: fix mirror with firmware 6.0
>
>Rami Rosen (1):
> net/kni: remove driver struct forward declaration
>
>Rasesh Mody (4):
> net/qede/base: fix to use a passed ptt handle
> net/qede/base: fix return code to align with FW
> net/qede: remove duplicate includes
> net/qede/base: fix division by zero
>
>Raslan Darawsheh (2):
> net/failsafe: fix failsafe bus uninit return value
> net/failsafe: fix PCI devices init
>
>RongQiang Xie (2):
> net/enic: fix possible null pointer dereference
> net/qede: fix possible null pointer dereference
>
>Sebastian Basierski (3):
> net/vmxnet3: fix unintentional integer overflow
> net/virtio-user: fix TAP name string termination
> net/virtio: check error on setting non block flag
>
>Sergio Gonzalez Monroy (1):
> crypto/aesni_mb: fix invalid session error
>
>Shahaf Shuler (5):
> net/mlx5: fix num seg assumption in SSE Tx
> net/mlx5: fix Tx stats error counter definition
> net/mlx5: fix Tx stats error counter logic
> net/mlx5: fix TSO segment size verification
> net/mlx5: fix packet type flags for Ethernet only frame
>
>Stefan Baranoff (1):
> net/pcap: fix memory leak in dumper open
>
>Stephen Hemminger (1):
> eal: initialize logging before bus
>
>Tiwei Bie (1):
> net/virtio: flush Rx queues on start
>
>Tomasz Duszynski (3):
> drivers/crypto: use snprintf return value correctly
> examples/ipsec-secgw: fix IP version check
> examples/ipsec-secgw: fix IPv6 payload length
>
>Tomasz Kulasek (3):
> net/bonding: fix slaves capacity check
> net/i40e: fix assignment of enum values
> net/bonding: fix check slaves link properties
>
>Vipin Varghese (1):
> net/tap: fix unregistering callback with invalid fd
>
>Wei Dai (8):
> net/ixgbe: fix mapping of user priority to TC
> net/ixgbe: fix adding a mirror rule
> net/i40e: fix mirror rule reset when port is closed
> net/ixgbe: fix Rx queue interrupt mapping in VF
> net/ixgbe: fix VFIO interrupt mapping in VF
> net/ixgbe: fix PF DCB info
> app/testpmd: fix mapping of user priority to DCB TC
> net/i40e: fix VFIO interrupt mapping in VF
>
>Wei Zhao (4):
> net/ixgbe: fix MAC VLAN filter fail problem
> net/i40e: fix clear xstats bug in VF
> app/testpmd: fix packet throughput after stats reset
> net/ixgbe: fix filter parser for L2 tunnel
>
>Wenzhuo Lu (7):
> net/i40e: fix TM node parameter checking
> net/i40e: fix TM level capability getting
> net/ixgbe: fix TM node parameter checking
> net/ixgbe: fix TM level capability getting
> net/i40e: fix not supporting NULL TM profile
> net/ixgbe: fix not supporting NULL TM profile
> net/i40e: fix parent when adding TM node
>
>Xiaoyun Li (2):
> net/i40e: fix PF notify issue when VF is not up
> net/igb: fix Rx interrupt with VFIO and MSI-X
>
>Xueming Li (5):
> net/mlx5: fix tunnel offload detection
> mem: fix malloc debug config
> mem: fix malloc element free in debug mode
> examples/l2fwd_fork: fix message pool init
> examples/multi_process: fix received message length
>
>Yi Yang (1):
> service: fix build with gcc 4.9
>
>Yong Wang (4):
> net/liquidio: fix uninitialized variable
> net/igb: fix memcpy length
> net/i40e: fix uninitialized variable
> net/ixgbe: fix uninitialized variable
>
>Yongseok Koh (3):
> net/mlx5: fix calculating TSO inline size
> net/mlx5: fix overflow of Rx SW ring
> net/mlx5: fix tunneled TCP/UDP packet type
>
>Zhiyong Yang (2):
> test: fix assignment operation
> net/virtio: fix Tx packet length stats
Hi Yuanhan,
Thanks for the queuing the patches for stable release.
Could you please provide ETA?
I was on PTO for last several days, so we need some time to do review and
sanity etc.
Thanks.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2 0/2] ethdev: add GENEVE to flow API
2017-11-20 8:21 3% [dpdk-dev] [PATCH 0/2] ethdev: add GENEVE to flow API Andrew Rybchenko
` (2 preceding siblings ...)
2017-11-23 9:39 4% ` [dpdk-dev] [PATCH 0/2] ethdev: add GENEVE to flow API Adrien Mazarguil
@ 2017-12-01 10:43 3% ` Andrew Rybchenko
3 siblings, 0 replies; 200+ results
From: Andrew Rybchenko @ 2017-12-01 10:43 UTC (permalink / raw)
To: dev; +Cc: Adrien Mazarguil, Jingjing Wu
v2:
- add after ESP to avoid ABI breakage
- make default mask to include VNI only
- minor style fixes
Roman Zhukov (2):
ethdev: add GENEVE flow pattern item
app/testpmd: support GENEVE pattern item in flow rules
app/test-pmd/cmdline_flow.c | 31 +++++++++++++++++++++++++++++
app/test-pmd/config.c | 1 +
doc/guides/prog_guide/rte_flow.rst | 12 +++++++++++
doc/guides/testpmd_app_ug/testpmd_funcs.rst | 5 +++++
lib/librte_ether/rte_flow.c | 1 +
lib/librte_ether/rte_flow.h | 30 ++++++++++++++++++++++++++++
6 files changed, 80 insertions(+)
--
2.7.4
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [RFC PATCH 0/3] *** SUBJECT HERE ***
@ 2017-12-01 14:47 4% Konstantin Ananyev
2017-12-01 14:48 19% ` [dpdk-dev] [RFC PATCH 3/3] doc: ethdev ABI change deprecation notice Konstantin Ananyev
2017-12-01 14:56 0% ` [dpdk-dev] [RFC PATCH 0/3] *** SUBJECT HERE *** Ananyev, Konstantin
0 siblings, 2 replies; 200+ results
From: Konstantin Ananyev @ 2017-12-01 14:47 UTC (permalink / raw)
To: dev, dev; +Cc: Konstantin Ananyev
The series introduces 2 main changes:
1.Introduce a separate data structure (rte_eth_queue_local)
to store local to given process (i.e. no-shareable) information
for each configured rx/tx queue.
Memory for that structure is allocated/freed dynamically during
rte_eth_dev_configure().
Reserve a space for queue specific (rx|tx)_pkt_burst(),
tx_pkt_prepare() function pointers inside that structure.
Move rx/tx callback related information inside that structure.
That introduces a change in current behavior: all callbacks for
un-configured queues will be automatically removed.
Also as size of struct rte_eth_dev changes that patch is an ABI breakage,
so deprecation notice for 18.05 is filled.
Further suggestions how to introduce the same functionality
without ABI breakage are welcome.
2. Make it safe to remove rx/tx callback at runtime.
Right now it is not possible for the application to figure out
when it is safe to free removed callback handle and
associated with it resources(unless the queue is stopped).
That's probably not a big problem if all callbacks are static
hange through whole application lifetime)
and/or application doesn't allocate any resources for the callback handler.
Though if callbacks have to be added/removed dynamically and
callback handler would require more resources to operate properly -
then it might become an issue.
So patch #2 fixes that problem - now as soon as
rte_eth_remove_(rx|tx)_callback() completes successfully, application
can safely free all associated with the removed callback resources.
Performance impact:
If application doesn't use RX/TX callbacks, then the tests I run didn't
reveal any performance degradation.
Though if application do use RX/TX callbacks - patch #2 does introduce
some slowdown.
To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
1) testpmd ... --latencystats=1 - slowdown < 1%
2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
3) examples/rxtx_callbacks - slowdown ~8%
All that in terms of packet throughput (Mpps).
Ability to safely remove callbacks at runtime implies
some sort of synchronization.
Even I tried to make it as light as possible,
probably some slowdown is unavoidable.
Of course instead of introducing these changes at rte_ethdev layer
similar technique could be applied on individual callback basis.
In that case it would be up to callback writer/installer to decide
does he/she need a removable at runtime callback or not.
Though in that case, each installed callback might introduce extra
synchronization overhead and slowdown.
Konstantin Ananyev (3):
ethdev: introduce eth_queue_local
ethdev: make it safe to remove rx/tx callback at runtime
doc: ethdev ABI change deprecation notice
doc/guides/rel_notes/deprecation.rst | 5 +
lib/librte_ether/rte_ethdev.c | 390 ++++++++++++++++++++++-------------
lib/librte_ether/rte_ethdev.h | 174 ++++++++++++----
3 files changed, 387 insertions(+), 182 deletions(-)
--
2.13.5
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [RFC PATCH 3/3] doc: ethdev ABI change deprecation notice
2017-12-01 14:47 4% [dpdk-dev] [RFC PATCH 0/3] *** SUBJECT HERE *** Konstantin Ananyev
@ 2017-12-01 14:48 19% ` Konstantin Ananyev
2017-12-12 14:55 4% ` Kovacevic, Marko
2017-12-01 14:56 0% ` [dpdk-dev] [RFC PATCH 0/3] *** SUBJECT HERE *** Ananyev, Konstantin
1 sibling, 1 reply; 200+ results
From: Konstantin Ananyev @ 2017-12-01 14:48 UTC (permalink / raw)
To: dev, dev; +Cc: Konstantin Ananyev
Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e85432f..038b55fd5 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -8,6 +8,11 @@ API and ABI deprecation notices are to be posted here.
Deprecation Notices
-------------------
+* ethdev: an ABI changes for ``rte_ethdev`` are planned in v18.05.
+ The size and layout of struct rte_eth_dev will change.
+ Mainly to accommodate queue specific RX/TX function pointers, plus
+ reorganize RX/TX callback related information.
+
* eal: several API and ABI changes are planned for ``rte_devargs`` in v18.02.
The format of device command line parameters will change. The bus will need
to be explicitly stated in the device declaration. The enum ``rte_devtype``
--
2.13.5
^ permalink raw reply [relevance 19%]
* [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer
@ 2017-12-01 14:55 4% Konstantin Ananyev
2017-12-14 4:54 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Konstantin Ananyev @ 2017-12-01 14:55 UTC (permalink / raw)
To: dev, dev; +Cc: Konstantin Ananyev
The series introduces 2 main changes:
1.Introduce a separate data structure (rte_eth_queue_local)
to store local to given process (i.e. no-shareable) information
for each configured rx/tx queue.
Memory for that structure is allocated/freed dynamically during
rte_eth_dev_configure().
Reserve a space for queue specific (rx|tx)_pkt_burst(),
tx_pkt_prepare() function pointers inside that structure.
Move rx/tx callback related information inside that structure.
That introduces a change in current behavior: all callbacks for
un-configured queues will be automatically removed.
Also as size of struct rte_eth_dev changes that patch is an ABI breakage,
so deprecation notice for 18.05 is filled.
Further suggestions how to introduce the same functionality
without ABI breakage are welcome.
2. Make it safe to remove rx/tx callback at runtime.
Right now it is not possible for the application to figure out
when it is safe to free removed callback handle and
associated with it resources(unless the queue is stopped).
That's probably not a big problem if all callbacks are static
hange through whole application lifetime)
and/or application doesn't allocate any resources for the callback handler.
Though if callbacks have to be added/removed dynamically and
callback handler would require more resources to operate properly -
then it might become an issue.
So patch #2 fixes that problem - now as soon as
rte_eth_remove_(rx|tx)_callback() completes successfully, application
can safely free all associated with the removed callback resources.
Performance impact:
If application doesn't use RX/TX callbacks, then the tests I run didn't
reveal any performance degradation.
Though if application do use RX/TX callbacks - patch #2 does introduce
some slowdown.
To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
1) testpmd ... --latencystats=1 - slowdown < 1%
2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
3) examples/rxtx_callbacks - slowdown ~8%
All that in terms of packet throughput (Mpps).
Ability to safely remove callbacks at runtime implies
some sort of synchronization.
Even I tried to make it as light as possible,
probably some slowdown is unavoidable.
Of course instead of introducing these changes at rte_ethdev layer
similar technique could be applied on individual callback basis.
In that case it would be up to callback writer/installer to decide
does he/she need a removable at runtime callback or not.
Though in that case, each installed callback might introduce extra
synchronization overhead and slowdown.
Konstantin Ananyev (3):
ethdev: introduce eth_queue_local
ethdev: make it safe to remove rx/tx callback at runtime
doc: ethdev ABI change deprecation notice
doc/guides/rel_notes/deprecation.rst | 5 +
lib/librte_ether/rte_ethdev.c | 390 ++++++++++++++++++++++-------------
lib/librte_ether/rte_ethdev.h | 174 ++++++++++++----
3 files changed, 387 insertions(+), 182 deletions(-)
--
2.13.5
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [RFC PATCH 0/3] *** SUBJECT HERE ***
2017-12-01 14:47 4% [dpdk-dev] [RFC PATCH 0/3] *** SUBJECT HERE *** Konstantin Ananyev
2017-12-01 14:48 19% ` [dpdk-dev] [RFC PATCH 3/3] doc: ethdev ABI change deprecation notice Konstantin Ananyev
@ 2017-12-01 14:56 0% ` Ananyev, Konstantin
1 sibling, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2017-12-01 14:56 UTC (permalink / raw)
To: dev
Oops sorry, resending with proper subject.
> -----Original Message-----
> From: Ananyev, Konstantin
> Sent: Friday, December 1, 2017 2:48 PM
> To: dev@dpdk.org; dev@dpdk.org
> Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Subject: [RFC PATCH 0/3] *** SUBJECT HERE ***
>
> The series introduces 2 main changes:
>
> 1.Introduce a separate data structure (rte_eth_queue_local)
> to store local to given process (i.e. no-shareable) information
> for each configured rx/tx queue.
> Memory for that structure is allocated/freed dynamically during
> rte_eth_dev_configure().
> Reserve a space for queue specific (rx|tx)_pkt_burst(),
> tx_pkt_prepare() function pointers inside that structure.
> Move rx/tx callback related information inside that structure.
> That introduces a change in current behavior: all callbacks for
> un-configured queues will be automatically removed.
> Also as size of struct rte_eth_dev changes that patch is an ABI breakage,
> so deprecation notice for 18.05 is filled.
> Further suggestions how to introduce the same functionality
> without ABI breakage are welcome.
>
> 2. Make it safe to remove rx/tx callback at runtime.
> Right now it is not possible for the application to figure out
> when it is safe to free removed callback handle and
> associated with it resources(unless the queue is stopped).
> That's probably not a big problem if all callbacks are static
> hange through whole application lifetime)
> and/or application doesn't allocate any resources for the callback handler.
> Though if callbacks have to be added/removed dynamically and
> callback handler would require more resources to operate properly -
> then it might become an issue.
> So patch #2 fixes that problem - now as soon as
> rte_eth_remove_(rx|tx)_callback() completes successfully, application
> can safely free all associated with the removed callback resources.
>
> Performance impact:
> If application doesn't use RX/TX callbacks, then the tests I run didn't
> reveal any performance degradation.
> Though if application do use RX/TX callbacks - patch #2 does introduce
> some slowdown.
>
> To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
> with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
> 1) testpmd ... --latencystats=1 - slowdown < 1%
> 2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
> 3) examples/rxtx_callbacks - slowdown ~8%
> All that in terms of packet throughput (Mpps).
>
> Ability to safely remove callbacks at runtime implies
> some sort of synchronization.
> Even I tried to make it as light as possible,
> probably some slowdown is unavoidable.
> Of course instead of introducing these changes at rte_ethdev layer
> similar technique could be applied on individual callback basis.
> In that case it would be up to callback writer/installer to decide
> does he/she need a removable at runtime callback or not.
> Though in that case, each installed callback might introduce extra
> synchronization overhead and slowdown.
>
> Konstantin Ananyev (3):
> ethdev: introduce eth_queue_local
> ethdev: make it safe to remove rx/tx callback at runtime
> doc: ethdev ABI change deprecation notice
>
> doc/guides/rel_notes/deprecation.rst | 5 +
> lib/librte_ether/rte_ethdev.c | 390 ++++++++++++++++++++++-------------
> lib/librte_ether/rte_ethdev.h | 174 ++++++++++++----
> 3 files changed, 387 insertions(+), 182 deletions(-)
>
> --
> 2.13.5
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH 0/4] dpdk: enhance EXPERIMENTAL api tagging
@ 2017-12-01 18:56 4% Neil Horman
2017-12-01 18:56 5% ` [dpdk-dev] [PATCH 2/4] compat: Add __experimental macro Neil Horman
` (3 more replies)
0 siblings, 4 replies; 200+ results
From: Neil Horman @ 2017-12-01 18:56 UTC (permalink / raw)
To: dev
Hey all-
A few days ago, I was lamenting the fact that, when reviewing patches I
would frequently complain about ABI changes that were actually considered safe
because they were part of the EXPERIMENTAL api set. John M. asked me then what
I might do to improve the situation, and the following patch set is a proposal
that I've come up with.
In thinking about the problem I identified two issues that I think we
can improve on in this area:
1) Make experimental api calls more visible in the source code. That is to say,
when reviewing patches, it would be nice to have some sort of visual reference
that indicates that the changes being made are part of an experimental API and
therefore ABI concerns need not be addressed
2) Make experimenal api usage more visible to consumers of the DPDK, so that
they can make a more informed decision about the API's they consume in their
application. We make an effort to document all the experimental API's, but
there is no guarantee that a user will check the documentation before making use
of a new library.
This patch set attempts to achieve both of the above goals. To do this I've
added an __experimental macro tag, suitable for inserting into api forward
declarations and definitions.
The presence of the tag in the header and c files where the api code resides
increases the likelyhood that any patch submitted against them will include the
tag in the context, making it clear to reviewers that ABI stability isn't a
concern here.
Also, This tag marks each function it is used on with an attibute causing any
use of the fuction to emit a warning during the build
with a message indicating that the API call in question is not yet part of the
stable interface. Developers can then make an informed decision to suppress
that warning or not.
Because there is internal use of several experimental API's, this set also
includes a new override macro ALLOW_EXPERIMENTAL_FUNCTIONS to automatically
suprress these warnings. I think its fair to assume that, for internal use, we
almost always want to suppress these warnings, as by definition any change to
the apis (even their removal) must be done in parallel with an appropriate
change in the calling locations, lest the dpdk build itself break.
Neil
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH 2/4] compat: Add __experimental macro
2017-12-01 18:56 4% [dpdk-dev] [PATCH 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
@ 2017-12-01 18:56 5% ` Neil Horman
2017-12-08 17:14 4% ` [dpdk-dev] [PATCHv2 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
` (2 subsequent siblings)
3 siblings, 0 replies; 200+ results
From: Neil Horman @ 2017-12-01 18:56 UTC (permalink / raw)
To: dev; +Cc: Neil Horman, Thomas Monjalon, Mcnamara, John
The __experimental macro tags a given exported function as being part of
the EXPERIMENTAL api. Use of this tag will cause any caller of the
function (that isn't removed by dead code elimination) to emit a warning
that the user is making use of an API whos stabilty isn't guaranteed.
It also places the function in the .text.experimental section, which is
used to validate the tag against the corresponding library version map
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Thomas Monjalon <thomas@monjalon.net>
CC: "Mcnamara, John" <john.mcnamara@intel.com>
---
lib/librte_compat/rte_compat.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/lib/librte_compat/rte_compat.h b/lib/librte_compat/rte_compat.h
index 41e8032ba..c7c967d86 100644
--- a/lib/librte_compat/rte_compat.h
+++ b/lib/librte_compat/rte_compat.h
@@ -101,5 +101,7 @@
*/
#endif
+#define __experimental \
+__attribute__(( deprecated("Symbol is not yet part of stable abi"), section(".text.experimental") ))
#endif /* _RTE_COMPAT_H_ */
--
2.14.3
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH 7/7] ethdev: use opaque user callback object
@ 2017-12-04 10:31 3% ` Bruce Richardson
2017-12-04 17:49 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2017-12-04 10:31 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: Ananyev, Konstantin, Thomas Monjalon, dev, vladz
On Fri, Dec 01, 2017 at 03:51:52PM -0800, Ferruh Yigit wrote:
> On 12/1/2017 5:17 AM, Bruce Richardson wrote:
> > On Fri, Dec 01, 2017 at 11:22:12AM +0000, Ananyev, Konstantin wrote:
> >>
> >>
> >>> -----Original Message-----
> >>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bruce Richardson
> >>> Sent: Friday, December 1, 2017 10:33 AM
> >>> To: Yigit, Ferruh <ferruh.yigit@intel.com>
> >>> Cc: Thomas Monjalon <thomas@monjalon.net>; dev@dpdk.org; vladz@cloudius-systems.com
> >>> Subject: Re: [dpdk-dev] [PATCH 7/7] ethdev: use opaque user callback object
> >>>
> >>> On Fri, Dec 01, 2017 at 02:29:57AM +0000, Ferruh Yigit wrote:
> >>>> "struct rte_eth_rxtx_callback" is defined as internal data structure but
> >>>> used in public APIs.
> >>>>
> >>>> Checking the API documentation shows that intention was using this
> >>>> object as opaque object. Data structure only used in delete APIs which
> >>>> doesn't require to know the internals of the data structure.
> >>>>
> >>>> Converting callback parameter in API to void pointer should not require
> >>>> any modification in user application because this data structure was
> >>>> already marked as internal and only should be used as pointer in
> >>>> application.
> >>>>
> >>>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
> >>>> ---
> >>>
> >>> I disagree on this patch. The structure itself is not exposed, only the
> >>> name, since it is only passed around as a pointer, so there is no need
> >>> to change the parameters to void pointer. It's a named opaque type.
> >>
> >> Personally I think it would be better to do visa-versa:
> >> make rte_eth_add_(rx|tx)_callback() to return struct rte_eth_rxtx_callback *
> >> instead of void *.
> >> Konstantin
> >>
> > I didn't realise that it did, so definite +1 to that suggestion.
>
> No issue on having a named opaque type, but unfortunately struct is exposed
> because of inline functions again.
> It has been moved into rte_ethdev_core.h but accessible by applications.
>
> And since intention is an opaque type, because of "void *" return types, I
> thought it is better to hide type completely so that application can't access
> details.
I wouldn't be worried about applications being able to get into the
structure. The only compelling reason for me to make the type opaque
would be for ABI compatibility, and since that is not a factor here, I
don't see the point in changing it to a void *.
/Bruce
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH] relicense various bits of the dpdk
@ 2017-12-04 15:55 8% Neil Horman
2017-12-05 10:44 0% ` Hemant Agrawal
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2017-12-04 15:55 UTC (permalink / raw)
To: dev; +Cc: Neil Horman, Hemant Agrawal, Thomas Monjalon
Received a note the other day from the Linux Foundation governance board
for DPDK indicating that several files I have copyright on need to be
relicensed to be compliant with the DPDK licensing guidelines. I have
some concerns with some parts of the request, but am not opposed to
other parts. So, for those pieces that we are in consensus on, I'm
proposing that we change their license from BSD 2 clause to 3 clause.
I'm also updating the files to use the SPDX licensing scheme
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Hemant Agrawal <hemant.agrawal@nxp.com>
CC: Thomas Monjalon <thomas@monjalon.net>
---
devtools/validate-abi.sh | 32 ++++----------------------------
lib/librte_compat/rte_compat.h | 24 +-----------------------
2 files changed, 5 insertions(+), 51 deletions(-)
diff --git a/devtools/validate-abi.sh b/devtools/validate-abi.sh
index 8caf43e83..26f3f9d0d 100755
--- a/devtools/validate-abi.sh
+++ b/devtools/validate-abi.sh
@@ -1,32 +1,8 @@
#!/usr/bin/env bash
-# BSD LICENSE
-#
-# Copyright(c) 2015 Neil Horman. All rights reserved.
-# Copyright(c) 2017 6WIND S.A.
-# All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions
-# are met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above copyright
-# notice, this list of conditions and the following disclaimer in
-# the documentation and/or other materials provided with the
-# distribution.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# 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
diff --git a/lib/librte_compat/rte_compat.h b/lib/librte_compat/rte_compat.h
index 41e8032ba..2f8a0e2a6 100644
--- a/lib/librte_compat/rte_compat.h
+++ b/lib/librte_compat/rte_compat.h
@@ -1,31 +1,9 @@
/*-
- * BSD LICENSE
+ * SPDX-License-Identifier: BSD-3-Clause
*
* Copyright(c) 2015 Neil Horman <nhorman@tuxdriver.com>.
* All rights reserved.
*
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _RTE_COMPAT_H_
--
2.14.3
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH 7/7] ethdev: use opaque user callback object
2017-12-04 10:31 3% ` Bruce Richardson
@ 2017-12-04 17:49 0% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2017-12-04 17:49 UTC (permalink / raw)
To: Bruce Richardson; +Cc: Ananyev, Konstantin, Thomas Monjalon, dev, vladz
On 12/4/2017 2:31 AM, Bruce Richardson wrote:
> On Fri, Dec 01, 2017 at 03:51:52PM -0800, Ferruh Yigit wrote:
>> On 12/1/2017 5:17 AM, Bruce Richardson wrote:
>>> On Fri, Dec 01, 2017 at 11:22:12AM +0000, Ananyev, Konstantin wrote:
>>>>
>>>>
>>>>> -----Original Message-----
>>>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Bruce Richardson
>>>>> Sent: Friday, December 1, 2017 10:33 AM
>>>>> To: Yigit, Ferruh <ferruh.yigit@intel.com>
>>>>> Cc: Thomas Monjalon <thomas@monjalon.net>; dev@dpdk.org; vladz@cloudius-systems.com
>>>>> Subject: Re: [dpdk-dev] [PATCH 7/7] ethdev: use opaque user callback object
>>>>>
>>>>> On Fri, Dec 01, 2017 at 02:29:57AM +0000, Ferruh Yigit wrote:
>>>>>> "struct rte_eth_rxtx_callback" is defined as internal data structure but
>>>>>> used in public APIs.
>>>>>>
>>>>>> Checking the API documentation shows that intention was using this
>>>>>> object as opaque object. Data structure only used in delete APIs which
>>>>>> doesn't require to know the internals of the data structure.
>>>>>>
>>>>>> Converting callback parameter in API to void pointer should not require
>>>>>> any modification in user application because this data structure was
>>>>>> already marked as internal and only should be used as pointer in
>>>>>> application.
>>>>>>
>>>>>> Signed-off-by: Ferruh Yigit <ferruh.yigit@intel.com>
>>>>>> ---
>>>>>
>>>>> I disagree on this patch. The structure itself is not exposed, only the
>>>>> name, since it is only passed around as a pointer, so there is no need
>>>>> to change the parameters to void pointer. It's a named opaque type.
>>>>
>>>> Personally I think it would be better to do visa-versa:
>>>> make rte_eth_add_(rx|tx)_callback() to return struct rte_eth_rxtx_callback *
>>>> instead of void *.
>>>> Konstantin
>>>>
>>> I didn't realise that it did, so definite +1 to that suggestion.
>>
>> No issue on having a named opaque type, but unfortunately struct is exposed
>> because of inline functions again.
>> It has been moved into rte_ethdev_core.h but accessible by applications.
>>
>> And since intention is an opaque type, because of "void *" return types, I
>> thought it is better to hide type completely so that application can't access
>> details.
>
> I wouldn't be worried about applications being able to get into the
> structure. The only compelling reason for me to make the type opaque
> would be for ABI compatibility, and since that is not a factor here, I
> don't see the point in changing it to a void *.
OK, I will update as suggested.
>
> /Bruce
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] 17.08.1 patches review and test
2017-11-27 12:21 2% [dpdk-dev] 17.08.1 patches review and test Yuanhan Liu
2017-11-30 19:09 0% ` Patil, Harish
@ 2017-12-04 20:40 0% ` Patil, Harish
2017-12-07 13:46 0% ` Yuanhan Liu
1 sibling, 1 reply; 200+ results
From: Patil, Harish @ 2017-12-04 20:40 UTC (permalink / raw)
To: Yuanhan Liu, dpdk stable; +Cc: dev, Xu, Qian Q
-----Original Message-----
From: dev <dev-bounces@dpdk.org> on behalf of Yuanhan Liu
<yliu@fridaylinux.org>
Date: Monday, November 27, 2017 at 4:21 AM
To: dpdk stable <stable@dpdk.org>
Cc: "dev@dpdk.org" <dev@dpdk.org>, "Xu, Qian Q" <qian.q.xu@intel.com>
Subject: [dpdk-dev] 17.08.1 patches review and test
>Hi all,
>
>Here is a list of patches targeted for stable release 17.08.1. Please
>help review and test. The planned date for the final release is 7th,
>Dec. Before that, please shout if anyone has objections with these
>patches being applied.
>
>These patches are located at branch 17.08 of dpdk-stable repo:
> http://dpdk.org/browse/dpdk-stable/
>
>Thanks.
>
> --yliu
>
>---
>Aaron Conole (1):
> net/enic: fix assignment
>
>Ajit Khaparde (28):
> net/bnxt: fix HWRM macros and locking
> net/bnxt: use 64-bits of address for VLAN table
> net/bnxt: fix an issue with group id calculation
> net/bnxt: fix calculation of number of pools
> net/bnxt: handle multi queue mode properly
> net/bnxt: fix Rx handling and buffer allocation logic
> net/bnxt: fix an issue with broadcast traffic
> net/bnxt: fix usage of VMDq flags
> net/bnxt: set checksum offload flags correctly
> net/bnxt: update status of Rx IP/L4 CKSUM
> net/bnxt: fix config RSS update
> net/bnxt: set the hash key size
> net/bnxt: fix per queue stats display in xstats
> net/bnxt: fix interrupt handler
> net/bnxt: fix number of MAC addresses for VMDq
> net/bnxt: fix the association of a MACVLAN per VNIC
> net/bnxt: fix Tx offload capability
> net/bnxt: fix Rx offload capability
> net/bnxt: handle Rx multi queue creation properly
> net/bnxt: remove redundant code parsing pool map
> net/bnxt: fix a bit shift operation
> net/bnxt: fix a potential null pointer dereference
> net/bnxt: fix a potential null pointer dereference
> net/bnxt: fix a pointer deref before null check
> net/bnxt: fix an unused value
> net/bnxt: check VLANs from pool map only for VMDq
> net/bnxt: do not set hash type unnecessarily
> net/bnxt: fix VLAN spoof configuration
>
>Akhil Goyal (2):
> test/crypto: fix dpaa2 sec macros and definitions
> net/dpaa2: set queues after reconfiguration
>
>Alejandro Lucero (2):
> net/nfp: fix RSS
> net/nfp: fix Rx interrupt when multiqueue
>
>Alok Makhariya (2):
> crypto/dpaa2_sec: remove ICV memset on decryption side
> crypto/dpaa2_sec: add check for segmented buffer
>
>Anatoly Burakov (1):
> vfio: fix secondary process initialization
>
>Andrey Chilikin (1):
> net/i40e: fix flexible payload configuration
>
>Aviad Yehezkel (4):
> examples/ipsec-secgw: fix crypto device mapping
> examples/ipsec-secgw: fix session creation
> examples/ipsec-secgw: fix AAD length setting
> app/testpmd: fix build without ixgbe and bnxt PMDs
>
>Beilei Xing (1):
> net/i40e: fix VF device stop issue
>
>Chas Williams (1):
> net/vmxnet3: fix memory leak when releasing queues
>
>Congwen Zhang (1):
> net/cxgbe: fix memory leak
>
>Daniel Mrzyglod (3):
> net/virtio: fix untrusted scalar value
> app/testpmd: fix DDP package filesize detection
> net/bonding: fix default aggregator mode to stable
>
>David Harton (2):
> net/vmxnet3: fix MAC address set
> net/i40e: fix i40evf MAC filter table
>
>Ferruh Yigit (4):
> ethdev: fix ABI version
> ethdev: revert use port name from device structure
> igb_uio: remove device reset in open
> net/qede: fix icc build
>
>Gaetan Rivet (1):
> net/failsafe: fix errno set on command execution
>
>Gowrishankar Muthukrishnan (1):
> net/bonding: support bifurcated driver in eal
>
>Guduri Prathyusha (2):
> examples/l3fwd: fix NEON instructions
> examples/l3fwd: fix aliasing in port grouping
>
>Harish Patil (2):
> net/qede: fix supported packet types
> net/qede: fix to re-enable LRO during device start
>
>Hemant Agrawal (3):
> net/dpaa2: fix the Tx handling of non HW pool bufs
> examples/l2fwd-crypto: fix uninitialized errno value
> app/crypto-perf: fix uninitialized errno value
>
>Ian Stokes (1):
> cryptodev: fix build with -Ofast
>
>Ivan Malov (2):
> net/sfc: specify correct scale table size on Rx start
> net/sfc: fix unused variable in RSS-agnostic build
>
>Jacek Piasecki (1):
> examples/vhost_scsi: fix product id string termination
>
>Jasvinder Singh (1):
> examples/qos_sched: fix uninitialized config
>
>Jerin Jacob (1):
> timer: use 64-bit specific code on more platforms
>
>Jianbo Liu (1):
> net/i40e: fix Rx packets number for NEON
>
>Jiayu Hu (1):
> gro: fix typo in map file
>
>Jingjing Wu (4):
> net/i40e: fix interrupt throttling setting in PF
> net/i40e: fix memory leak if VF init fails
> net/i40e: fix variable assignment
> net/i40e: fix VF initialization error
>
>John Daley (3):
> net/enic: fix multi-process operation
> net/enic: fix packet loss after MTU change
> net/enic: fix TSO for packets greater than 9208 bytes
>
>John Miller (1):
> net/ark: fix loop counter
>
>Kuba Kozak (2):
> vfio: fix close unchecked file descriptor
> vhost: check poll error code
>
>Li Han (1):
> app/testpmd: fix invalid port id parameters
>
>Lukasz Majczak (1):
> eal: fix auxv open check for ARM and PPC
>
>Mark Spender (1):
> net/sfc/base: fix default RSS context check on Siena
>
>Matan Azrad (7):
> net/failsafe: fix Tx sub device deactivating
> net/mlx5: fix locking in xstats functions
> net/failsafe: fix parameters parsing
> net/mlx5: fix probe failure report
> net/failsafe: fix adding MAC error report miss
> app/testpmd: fix forward port ids setting
> net/failsafe: fix Rx clean race
>
>Maxime Coquelin (1):
> vhost: fix dereferencing invalid pointer after realloc
>
>Michal Jastrzebski (1):
> net/vmxnet3: fix dereference before null check
>
>Nikhil Rao (1):
> eal/x86: fix atomic cmpset
>
>Nirmoy Das (1):
> kni: fix SLE version detection
>
>Nélio Laranjeiro (4):
> net/mlx5: fix clang build
> net/mlx5: fix SSE Rx support verification
> net/mlx5: fix clang compilation error
> app/testpmd: fix RSS structure initialisation
>
>Olivier Matz (12):
> net: fix inner L2 length in packet type parser
> net/bnxt: fix compilation with -Og
> net/qede: fix compilation with -Og
> app/test-crypto-perf: fix memory leak
> app/test-crypto-perf: fix compilation with -Og
> net/virtio: revert not claiming LRO support
> net/virtio: revert not claiming IP checksum offload
> net/virtio: fix log levels in configure
> net/virtio: fix mbuf port for simple Rx function
> net/virtio: fix queue setup consistency
> net/virtio: fix compilation with -Og
> lpm6: fix compilation with -Og
>
>Ophir Munk (3):
> net/tap: fix flow and port commands
> net/failsafe: fix VLAN stripping configuration
> app/testpmd: fix forwarding between non consecutive ports
>
>Pablo de Lara (8):
> hash: fix eviction counter
> crypto/aesni_gcm: fix zero data operation
> app/crypto-perf: fix packet length check
> app/crypto-perf: parse AEAD data from vectors
> crypto/openssl: fix AEAD parameters
> examples/l2fwd-crypto: fix physical address setting
> crypto/qat: fix HMAC supported digest sizes
> app/testpmd: fix topology error message
>
>Patrick MacArthur (1):
> eal: copy raw strings taken from command line
>
>Phil Yang (1):
> app/testpmd: fix quitting in container
>
>Qi Zhang (4):
> net/i40e: fix flow control watermark mismatch
> net/i40e: fix packet count for PF
> net/i40e: fix mbuf free in vector Tx
> net/i40e: fix mirror with firmware 6.0
>
>Rami Rosen (1):
> net/kni: remove driver struct forward declaration
>
>Rasesh Mody (4):
> net/qede/base: fix to use a passed ptt handle
> net/qede/base: fix return code to align with FW
> net/qede: remove duplicate includes
> net/qede/base: fix division by zero
>
>Raslan Darawsheh (2):
> net/failsafe: fix failsafe bus uninit return value
> net/failsafe: fix PCI devices init
>
>RongQiang Xie (2):
> net/enic: fix possible null pointer dereference
> net/qede: fix possible null pointer dereference
>
>Sebastian Basierski (3):
> net/vmxnet3: fix unintentional integer overflow
> net/virtio-user: fix TAP name string termination
> net/virtio: check error on setting non block flag
>
>Sergio Gonzalez Monroy (1):
> crypto/aesni_mb: fix invalid session error
>
>Shahaf Shuler (5):
> net/mlx5: fix num seg assumption in SSE Tx
> net/mlx5: fix Tx stats error counter definition
> net/mlx5: fix Tx stats error counter logic
> net/mlx5: fix TSO segment size verification
> net/mlx5: fix packet type flags for Ethernet only frame
>
>Stefan Baranoff (1):
> net/pcap: fix memory leak in dumper open
>
>Stephen Hemminger (1):
> eal: initialize logging before bus
>
>Tiwei Bie (1):
> net/virtio: flush Rx queues on start
>
>Tomasz Duszynski (3):
> drivers/crypto: use snprintf return value correctly
> examples/ipsec-secgw: fix IP version check
> examples/ipsec-secgw: fix IPv6 payload length
>
>Tomasz Kulasek (3):
> net/bonding: fix slaves capacity check
> net/i40e: fix assignment of enum values
> net/bonding: fix check slaves link properties
>
>Vipin Varghese (1):
> net/tap: fix unregistering callback with invalid fd
>
>Wei Dai (8):
> net/ixgbe: fix mapping of user priority to TC
> net/ixgbe: fix adding a mirror rule
> net/i40e: fix mirror rule reset when port is closed
> net/ixgbe: fix Rx queue interrupt mapping in VF
> net/ixgbe: fix VFIO interrupt mapping in VF
> net/ixgbe: fix PF DCB info
> app/testpmd: fix mapping of user priority to DCB TC
> net/i40e: fix VFIO interrupt mapping in VF
>
>Wei Zhao (4):
> net/ixgbe: fix MAC VLAN filter fail problem
> net/i40e: fix clear xstats bug in VF
> app/testpmd: fix packet throughput after stats reset
> net/ixgbe: fix filter parser for L2 tunnel
>
>Wenzhuo Lu (7):
> net/i40e: fix TM node parameter checking
> net/i40e: fix TM level capability getting
> net/ixgbe: fix TM node parameter checking
> net/ixgbe: fix TM level capability getting
> net/i40e: fix not supporting NULL TM profile
> net/ixgbe: fix not supporting NULL TM profile
> net/i40e: fix parent when adding TM node
>
>Xiaoyun Li (2):
> net/i40e: fix PF notify issue when VF is not up
> net/igb: fix Rx interrupt with VFIO and MSI-X
>
>Xueming Li (5):
> net/mlx5: fix tunnel offload detection
> mem: fix malloc debug config
> mem: fix malloc element free in debug mode
> examples/l2fwd_fork: fix message pool init
> examples/multi_process: fix received message length
>
>Yi Yang (1):
> service: fix build with gcc 4.9
>
>Yong Wang (4):
> net/liquidio: fix uninitialized variable
> net/igb: fix memcpy length
> net/i40e: fix uninitialized variable
> net/ixgbe: fix uninitialized variable
>
>Yongseok Koh (3):
> net/mlx5: fix calculating TSO inline size
> net/mlx5: fix overflow of Rx SW ring
> net/mlx5: fix tunneled TCP/UDP packet type
>
>Zhiyong Yang (2):
> test: fix assignment operation
> net/virtio: fix Tx packet length stats
Hi Yuanhan,
I found the following two patches marked for stable release is not picked
up here.
commit f07aa795c92ac6a9460d25ab2e9d74379ed8e5eb
Author: Harish Patil <harish.patil@cavium.com>
Date: Tue Nov 7 00:34:18 2017 -0800
net/qede: disable per-VF Tx switching feature
Provide a knob to control per-VF Tx switching feature by adding a
config
option, CONFIG_RTE_LIBRTE_QEDE_VF_TX_SWITCH. By default, it will be
kept
in disabled state for better performance with small sized frames.
Fixes: 2ea6f76aff40 ("qede: add core driver")
Cc: stable@dpdk.org
Signed-off-by: Harish Patil <harish.patil@cavium.com>
commit 1282943aa05b2f211bd1b831b9d2962859323063
Author: Harish Patil <harish.patil@cavium.com>
Date: Wed Nov 8 22:52:20 2017 -0800
net/qede: fix default config option
Restore the default configuration as in previous releases and
add a debug msg.
Fixes: f07aa795c92a ("net/qede: disable per-VF Tx switching feature")
Cc: stable@dpdk.org
Signed-off-by: Harish Patil <harish.patil@cavium.com>
Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
We need to include these two patches as well.
Thanks,
Harish
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC 1/2] net/tap: add eBPF to TAP device
2017-11-30 8:01 1% [dpdk-dev] [RFC 1/2] net/tap: add eBPF to TAP device Ophir Munk
2017-11-30 8:01 1% ` [dpdk-dev] [RFC 2/2] net/tap: add eBPF instructions Ophir Munk
@ 2017-12-05 7:53 0% ` Pascal Mazon
1 sibling, 0 replies; 200+ results
From: Pascal Mazon @ 2017-12-05 7:53 UTC (permalink / raw)
To: Ophir Munk, dev; +Cc: Thomas Monjalon, Olga Shern
Hi Ophir,
I wrote that doc (rte_flow_tap) a while ago (10 months+), it is no
longer accurate and would very much need updating.
I might have written some of the code you propose, but I definitely
didn't see this patch before you sent it, you shouldn't use my sign-off.
That goes for the second patch in the series, too.
On 30/11/2017 09:01, Ophir Munk wrote:
> The DPDK traffic classifier is the rte_flow API and the tap PMD
> must support it including RSS queue mapping actions.
> An example usage for this requirement is failsafe transparent
> switching from a PCI device to TAP device while RSS queues are the
> same on both devices.
>
> TC was chosen as TAP classifier but TC alone does not support RSS
> queue mapping. This commit uses a combination of TC rules and eBPF
> actions in order to support TAP RSS.
>
> eBPF requires Linux version 3.19. eBPF is effective only when running
> with an appropriate kernel version. It must be compiled with the
> appropriate Linux kernel headers. In case the kernel headers do
> not include eBPF definitions a warning will be issued during
> compilation time and TAP RSS will not be supported.
>
> Signed-off-by: Pascal Mazon <pascal.mazon@6wind.com>
> Signed-off-by: Ophir Munk <ophirmu@mellanox.com>
> ---
>
> The DPDK traffic classifier is the rte_flow API and the tap PMD
> must support it including RSS queue mapping actions.
> An example usage for this requirement is failsafe transparent
> switching from a PCI device to TAP device while RSS queues are the
> same on both devices.
> TC was chosen as TAP classifier but TC alone does not support RSS
> queue mapping. This RFC suggests using a combination of TC rules and eBPF
> actions in order to support TAP RSS.
> eBPF requires Linux version 3.19. eBPF is effective only when running
> with an appropriate kernel version. It must be compiled with the
> appropriate Linux kernel headers. In case the kernel headers do
> not include eBPF definitions a warning will be issued during
> compilation time and TAP RSS will not be supported.
> The C source file (tap_bpf_insns.c) includes eBPF "assembly
> instructions" in the format of an array of struct bpf_insns.
> This array is passed to the kernel for execution in BPF system call.
> The C language source file (tap_bpf_program.c) from which the
> "assembly instructions" were generated is included in TAP source tree,
> however it does not take part in dpdk compilation.
> TAP documentation will detail the process of eBPF "assembly instructions"
> generation.
>
> eBPF programs controlled from tap PMD will be used to match packets, compute a
> hash given the configured key, and send packets using the desired queue.
> In an eBPF program, it is typically not possible to edit the queue_mapping field
> in skb to direct the packet in the correct queue. That part would be addressed by
> chaining a ``skbedit queue_mapping`` action.
>
> A packet would go through these TC rules (on the local side of the tap netdevice):
>
> +-----+---------------------------+----------------------------------+----------+
> |PRIO | Match | Action 1 | Action 2 |
> +=====+===========================+==================================+==========+
> | 1 | marked? | skbedit queue 'mark' --> DPDK | |
> +-----+---------------------------+----------------------------------+----------+
> | 2 | marked? | skbedit queue 'mark' --> DPDK | |
> +-----+---------------------------+----------------------------------+----------+
> | ... | | | |
> +-----+---------------------------+----------------------------------+----------+
> | x | ANY | BPF: append NULL 32bits for hash | |
> | | | | |
> +-----+---------------------------+----------------------------------+----------+
> |x + 1| ACTUAL FLOW RULE 1 MATCH | ... | |
> | | | | |
> +-----+---------------------------+----------------------------------+----------+
> |x + 2| ACTUAL FLOW RULE 2 MATCH | ... | |
> | | | | |
> +-----+---------------------------+----------------------------------+----------+
> | ... | | | |
> +-----+---------------------------+----------------------------------+----------+
> | y | FLOW RULE RSS 1 MATCH | BPF compute hash into packet |reclassify|
> | | | tailroom && set queue in skb->cb | |
> +-----+---------------------------+----------------------------------+----------+
> |y + 1| FLOW RULE RSS 2 MATCH | BPF compute hash into packet |reclassify|
> | | | tailroom && set queue in skb->cb | |
> +-----+---------------------------+----------------------------------+----------+
> | ... | | | |
> +-----+---------------------------+----------------------------------+----------+
> | z | ANY (default RSS) | BPF compute hash into packet |reclassify|
> | | | tailroom && set queue in skb->cb | |
> +-----+---------------------------+----------------------------------+----------+
> | z | ANY (isolate mode) | DROP | |
> +-----+---------------------------+----------------------------------+----------+
>
> Rules 1..x will match marked packets and will redirect them to their queues however
> on first classification packets are not marked there will not be redirected.
> Only when going later through RSS rules y..z BPF computes RSS hash,
> sets queue in dkb->cb, and reclassifies packets. Then packets are classified again
> through rules 1-x while being marked and will be redirected.
> Rules (x+1)..y are non-RSS TC rules already used in dpdk versions prior to 18.02
>
> doc/guides/prog_guide/rte_flow_tap.rst | 962 +++++++++++++++++++++++++++++++++
> drivers/net/tap/Makefile | 6 +-
> drivers/net/tap/rte_eth_tap.h | 7 +-
> drivers/net/tap/tap_bpf_elf.h | 56 ++
> drivers/net/tap/tap_flow.c | 336 ++++++++----
> 5 files changed, 1263 insertions(+), 104 deletions(-)
> create mode 100644 doc/guides/prog_guide/rte_flow_tap.rst
> create mode 100644 drivers/net/tap/tap_bpf_elf.h
>
> diff --git a/doc/guides/prog_guide/rte_flow_tap.rst b/doc/guides/prog_guide/rte_flow_tap.rst
> new file mode 100644
> index 0000000..04ddda6
> --- /dev/null
> +++ b/doc/guides/prog_guide/rte_flow_tap.rst
> @@ -0,0 +1,962 @@
> +=====================================
> +Flow API support in TAP PMD, using TC
> +=====================================
> +
> +.. contents::
> +.. sectnum::
> +
> +.. footer::
> +
> + v0.8 - page ###Page###
> +
> +.. raw:: pdf
> +
> + PageBreak
> +
> +Rationale
> +=========
> +
> +For this project, the tap PMD has to receive selected traffic from a different
> +netdevice (refer to *VM migration with Microsoft Hyper-V and Mellanox
> +ConnectX-3* document) and only cover the same set of rules as supported by the
> +mlx4 PMD.
> +
> +The DPDK traffic classifier is the rte_flow API, and the tap PMD must therefore
> +implement it. For that, TC was chosen for several reasons:
> +
> +- it happens very early in the kernel stack for ingress (faster than netfilter).
> +- it supports dropping packets given a specific flow.
> +- it supports redirecting packets to a different netdevice.
> +- it has a "flower" classifier type that meets mostly the pattern items in
> + rte_flow.
> +- it can be configured through a netlink socket, without an external tool.
> +
> +Modes of operation
> +==================
> +
> +There should be two modes of operation for the tap PMD regarding rte_flow:
> +*local* and *remote*. Only one mode can be in use at a time for a specific tap
> +interface.
> +
> +The *local* mode would be the default one, if no specific parameter is specified
> +in the command line. To start the application with tap in *remote* mode, set the
> +``remote`` tap parameter to the interface you want to redirect packets from,
> +e.g.::
> +
> + testpmd -n 4 -c 0xf -m 1024 --vdev=net_tap,iface=tap0,remote=eth3 -- \
> + -i --burst=64 --coremask=0x2
> +
> +*Local* mode
> +------------
> +
> +In *local* mode, flow rules would be applied as-is, on the tap netdevice itself
> +(e.g.: ``tap0``).
> +
> +The typical use-case is having a linux program (e.g. a webserver) communicating
> +with the DPDK app through the tap netdevice::
> +
> + +-------------------------+
> + | DPDK application |
> + +-------------------------+
> + | ^
> + | rte_flow rte_flow |
> + v egress ingress |
> + +-------------------------+
> + | Tap PMD |
> + +-------------------------+
> + | ^
> + | TC TC |
> + v ingress egress |
> + +-------------------------+ +-------------------------+
> + | |<-------------| |
> + | Tap netdevice (tap0) | | Linux app (webserver) |
> + | |------------->| |
> + +-------------------------+ +-------------------------+
> +
> +.. raw:: pdf
> +
> + PageBreak
> +
> +*Remote* mode
> +-------------
> +
> +In *remote* mode, flow rules would be applied on the tap netdevice (e.g.:
> +``tap0``), and use a similar match to redirect specific packets from another
> +netdevice (e.g.: ``eth3``, a NetVSC netdevice in our project scenario)::
> +
> + +-------------------------+
> + | DPDK application |
> + +-------------------------+
> + | ^
> + | rte_flow rte_flow |
> + v egress ingress |
> + +-------------------------+
> + | Tap PMD |
> + +-------------------------+
> + | ^
> + | TC TC |
> + v ingress egress |
> + +-------------------------+ +-------------------------+
> + | |<------------------redirection-------\ |
> + | Tap netdevice (tap0) | | | |
> + | |------------->|-\ eth3 | |
> + +-------------------------+ +--|--------------------|-+
> + | TC TC ^
> + | egress ingress |
> + v |
> +
> +.. raw:: pdf
> +
> + PageBreak
> +
> +rte_flow rules conversion
> +=========================
> +
> +Netlink
> +-------
> +
> +The only way to create TC rules in the kernel is through netlink messages.
> +Two possibilities arise for managing TC rules:
> +
> +- Using native netlink API calls in the tap PMD
> +- Calling the ``tc`` command from iproute2 inside our PMD, via ``system()``.
> +
> +The former will be done, as library calls are faster than changing context and
> +executing an external program from within the tap PMD. Moreover, the kernel TC
> +API might propose features not yet implemented in iproute2. Furthermore, a
> +custom implementation enables finer tuning and better control.
> +
> +..
> + Some implementations for TC configuration through Netlink exist already. It's a
> + good source of inspiration on how to do it:
> +
> + - iproute2's tc `source code`__
> + - ovs's tc implementation__ (not yet upstream)
> +
> + __ https://github.com/shemminger/iproute2/tree/master/tc
> + __ https://mail.openvswitch.org/pipermail/ovs-dev/2016-November/324693.html
> +
> +Conversion examples
> +-------------------
> +
> +Here are a few examples of rules and how they can be translated from rte_flow
> +rules to TC rules. rte_flow rules will be expressed using testpmd's ``flow``
> +command syntax, while TC rules will use iproute2 ``tc`` command syntax.
> +
> +**Notes**:
> + - rte_flow ``ingress`` direction can be translated into a TC ``egress`` rule,
> + and vice versa, when it applies to a tap interface, as TC considers the
> + kernel netdevice standpoint.
> + - in TC, redirecting a packet works by taking a packet from ``ingress`` and
> + sending to another device's ``egress``.
> +
> +*Local* mode
> +~~~~~~~~~~~~
> +
> +#. Flow rule to give packets coming on the ``tap0`` interface to RX queue 0:
> +
> + Using rte_flow::
> +
> + flow validate 0 ingress pattern port index is 0 / end \
> + actions queue index 0 / end
> +
> + Using ``tc``::
> +
> + tc filter add dev tap0 parent 1: flower indev tap0 \
> + action skbedit queue_mapping 0
> +
> +#. Flow rule to get packets with source mac ``de:ad:ca:fe:00:02`` on RX queue 2:
> +
> + Using rte_flow::
> +
> + flow create 0 ingress pattern eth src is de:ad:ca:fe:00:02 / end \
> + actions queue 2 / end
> +
> + Using ``tc``::
> +
> + tc filter add dev tap0 parent 1: flower src_mac de:ad:ca:fe:00:02 \
> + action skbedit queue_mapping 2
> +
> +#. Flow rule to drop packets matching specific 5-tuple info:
> +
> + Using rte_flow::
> +
> + flow create 0 ingress pattern eth dst is 3a:80:ce:61:36:54 \
> + src is 52:43:7b:fd:ac:f3 / ipv4 src is 1.1.1.1 dst is 2.2.2.2 \
> + / udp src is 4444 dst is 5555 / end actions drop / end
> +
> + Using ``tc``::
> +
> + tc filter add dev tap0 parent 1: flower dst_mac 3a:80:ce:61:36:54 \
> + src_mac 52:43:7b:fd:ac:f3 eth_type ip src_ip 1.1.1.1 dst_ip 2.2.2.2 \
> + ip_proto udp src_port 4444 dst_port 5555 action drop
> +
> +*Remote* mode
> +~~~~~~~~~~~~~
> +
> +In *remote* mode, an additional rule for redirecting packet is systematically
> +required. The examples are similar to the previous section (the rte_flow rule
> +will thus be omitted).
> +
> +#. TC rules to give packets coming on the ``eth3`` interface to ``tap0`` RX
> + queue 0::
> +
> + # redirection rule
> + tc filter add dev eth3 parent ffff: flower indev eth3 \
> + action mirred egress redirect dev tap0
> + # actual tap rule
> + tc filter add dev tap0 parent 1: flower indev tap0 \
> + action skbedit queue_mapping 0
> +
> +#. TC rules to get packets with source mac ``de:ad:ca:fe:00:02`` on RX queue 2::
> +
> + # redirection rule
> + tc filter add dev eth3 parent ffff: flower src_mac de:ad:ca:fe:00:02 \
> + action mirred egress redirect dev tap0
> + # actual tap rule
> + tc filter add dev tap0 parent 1: flower src_mac de:ad:ca:fe:00:02 \
> + action skbedit queue_mapping 2
> +
> +#. TC rules to drop packets matching specific 5-tuple info::
> +
> + # redirection rule
> + tc filter add dev eth3 parent ffff: flower dst_mac 3a:80:ce:61:36:54 \
> + src_mac 52:43:7b:fd:ac:f3 eth_type ip src_ip 1.1.1.1 dst_ip 2.2.2.2 \
> + ip_proto udp src_port 4444 dst_port 5555 \
> + action mirred egress redirect dev tap0
> + # actual tap rule
> + tc filter add dev tap0 parent 1: flower dst_mac 3a:80:ce:61:36:54 \
> + src_mac 52:43:7b:fd:ac:f3 eth_type ip src_ip 1.1.1.1 dst_ip 2.2.2.2 \
> + ip_proto udp src_port 4444 dst_port 5555 action drop
> +
> +One last thing, to redirect packets the other way around (from ``tap0`` to
> +``eth3``), we would use a similar rule, exchanging interfaces and using an
> +appropriate match, e.g.::
> +
> + tc filter add dev tap0 parent ffff: flower indev tap0 \
> + action mirred egress redirect dev eth3
> +
> +..
> + **Note:** ``parent ffff:`` is for TC ``ingress`` while ``parent 1:`` is for TC
> + ``egress``.
> +
> +Broadcast and promiscuous support
> ++++++++++++++++++++++++++++++++++
> +
> +*Remote* mode requirements:
> +
> +#. When turning the tap netdevice promiscuous, the remote netdevice should
> + implicitly be turned promiscuous too, to get as many packets as possible.
> +
> +#. Packets matching the destination MAC configured in the tap PMD should be
> + redirected from the remote without being processed by the stack there in the
> + kernel.
> +
> +#. In promiscuous mode, an incoming packet should be duplicated to be processed
> + both by the tap PMD and the remote netdevice itself.
> +
> +#. Incoming packets with broadcast destination MAC (i.e.: ``ff:ff:ff:ff:ff:ff``)
> + should be duplicated to be processed both by the tap PMD and the remote
> + netdevice itself.
> +
> +#. Incoming packets with IPv6 multicast destination MAC (i.e.:
> + ``33:33:00:00:00:00/33:33:00:00:00:00``) should be duplicated to be processed
> + both by the tap PMD and the remote netdevice itself.
> +
> +#. Incoming packets with broadcast/multicast bit set in the destination MAC
> + (i.e.: ``01:00:00:00:00:00/01:00:00:00:00:00``) should be duplicated to be
> + processed both by the tap PMD and the remote netdevice itself.
> +
> +Each of these requirements (except the first one) can be directly translated
> +into a TC rule, e.g.::
> +
> + # local mac (notice the REDIRECT for mirred action):
> + tc filter add dev eth3 parent ffff: prio 1 flower dst_mac de:ad:be:ef:01:02 \
> + action mirred egress redirect dev tap0
> +
> + # tap promisc:
> + tc filter add dev eth3 parent ffff: prio 2 basic \
> + action mirred egress mirror dev tap0
> +
> + # broadcast:
> + tc filter add dev eth3 parent ffff: prio 3 flower dst_mac ff:ff:ff:ff:ff:ff \
> + action mirred egress mirror dev tap0
> +
> + # broadcast v6 (can't express mac_mask with tc, but it works via netlink):
> + tc filter add dev eth3 parent ffff: prio 4 flower dst_mac 33:33:00:00:00:00 \
> + action mirred egress mirror dev tap0
> +
> + # all_multi (can't express mac_mask with tc, but it works via netlink):
> + tc filter add dev eth3 parent ffff: prio 5 flower dst_mac 01:00:00:00:00:00 \
> + action mirred egress mirror dev tap0
> +
> +When promiscuous mode is switched off or on, the first TC rule will be modified
> +to have respectively an empty action (``continue``) or the ``mirror`` action.
> +
> +The first 5 priorities are always reserved, and can only be used for these
> +filters.
> +
> +On top of that, the tap PMD can configure explicit rte_flow rules, translated as
> +TC rules on both the remote netdevice and the tap netdevice. On the remote,
> +those would need to be processed after the default rules handling promiscuous
> +mode, broadcast and all_multi packets.
> +
> +When using the ``mirror`` action, the packet is duplicated and sent to the tap
> +netdevice, while the original packet gets directly processed by the kernel
> +without going through later TC rules for the remote. On the tap netdevice, the
> +duplicated packet will go through tap TC rules and be classified depending on
> +those rules.
> +
> +**Note:** It is possible to combine a ``mirror`` action and a ``continue``
> +action for a single TC rule. Then the original packet would undergo remaining TC
> +rules on the remote netdevice side.
> +
> +When using the ``redirect`` action, the behavior is similar on the tap side, but
> +the packet is not duplicated, no further kernel processing is done for the
> +remote side.
> +
> +The following diagram sums it up. A packet that match a TC rule follows the
> +associated action (the number in the diamond represents the rule prio as set in
> +the above TC rules)::
> +
> +
> + Incoming packet |
> + on remote (eth3) |
> + | Going through
> + | TC ingress rules
> + v
> + / \
> + / 5 \
> + / \ yes
> + / mac \____________________> tap0
> + \ match?/ duplicated pkt
> + \ /
> + \ /
> + \ /
> + V no, then continue
> + | with TC rules
> + |
> + v
> + / \
> + / 2 \
> + eth3 yes / \ yes
> + kernel <____________________ /promisc\____________________> tap0
> + stack original pkt \ match?/ duplicated pkt
> + \ /
> + \ /
> + \ /
> + V no, then continue
> + | with TC rules
> + |
> + v
> + / \
> + / 3 \
> + eth3 yes / \ yes
> + kernel <____________________ / bcast \____________________> tap0
> + stack original pkt \ match?/ duplicated pkt
> + \ /
> + \ /
> + \ /
> + V no, then continue
> + | with TC rules
> + |
> + v
> + / \
> + / 4 \
> + eth3 yes / \ yes
> + kernel <____________________ / bcast6\____________________> tap0
> + stack original pkt \ match?/ duplicated pkt
> + \ /
> + \ /
> + \ /
> + V no, then continue
> + | with TC rules
> + |
> + v
> + / \
> + / 5 \
> + eth3 yes / all \ yes
> + kernel <____________________ / multi \____________________> tap0
> + stack original pkt \ match?/ duplicated pkt
> + \ /
> + \ /
> + \ /
> + V no, then continue
> + | with TC rules
> + |
> + v
> + |
> + . remaining TC rules
> + .
> + eth3 |
> + kernel <________________________/
> + stack original pkt
> +
> +.. raw:: pdf
> +
> + PageBreak
> +
> +Associating an rte_flow rule with a TC one
> +==========================================
> +
> +A TC rule is identified by a ``priority`` (16-bit value) and a ``handle``
> +(32-bit value). To delete a rule, the priority must be specified, and if several
> +rules have the same priority, the handle is needed to select the correct one.
> +
> +..
> + Specifying an empty priority and handle when requesting a TC rule creation will
> + let the kernel automatically decide what values to set. In fact, the kernel will
> + start with a high priority (i.e. 49152) and subsequent rules will get decreasing
> + priorities (lower priorites get evaluated first).
> +
> +To avoid further requests to the kernel to identify what priority/handle has
> +been automatically allocated, the tap PMD can set priorities and handles
> +systematically when creating a rule.
> +
> +In *local* mode, an rte_flow rule should be translated into a single TC flow
> +identified by priority+handle.
> +
> +In *remote* mode, an rte_flow rule requires two TC rules, one on the tap
> +netdevice itself (for the correct action) and another one on the other netdevice
> +where packets are redirected from. Both TC rules' priorities+handles must be
> +stored for a specific rte_flow rule, and associated with the device they are
> +applied on.
> +
> +.. raw:: pdf
> +
> + PageBreak
> +
> +Considerations regarding Flow API support
> +=========================================
> +
> +Flow rule attributes
> +--------------------
> +
> +Groups and priorities:
> + There is no native support of groups in TC. Instead, the priority field
> + (which is part of the netlink TC msg header) can be adapted. The four MSB
> + would be used to define the group (allowing for 16 groups), while the 12 LSB
> + would be left to define the actual priority (up to 4096).
> +
> + Rules with lower priorities are evaluated first. For rules with identical
> + priorities, the one with the highest handle value gets evaluated first.
> +
> +Direction:
> + Both ingress and egress filtering can be supported.
> +
> +Meta item types
> +---------------
> +
> +Most applications will use: ``(END | VOID)``
> +
> +END, VOID:
> + Supported without problem.
> +
> +INVERT:
> + There is no easy way to support that in TC. It won't be supported
> +
> + **mlx4 will not support it either.**
> +
> +PF, VF, PORT:
> + Not applicable to a tap netdevice.
> +
> +Data matching item types
> +------------------------
> +
> +Most applications will use:
> +``ETH / (IPV4 | IPV6 | END) / (TCP | UDP | END) / END``
> +
> +ANY:
> + Should be supported.
> +
> + **mlx4 will partially support it.**
> +
> +RAW:
> + It is not planned to support it for now. Matching Raw packets would require
> + using a different classifier than "flower", which is the most simple and
> + applicable for otherwise most other cases. With TC, it's not possible to
> + support in the same rule both "flower" and raw packets.
> +
> + **mlx4 will not support it either**.
> +
> +VLAN:
> + Matching VLAN ID and prio supported.
> + **Note: linux v4.9 required for VLAN support.**
> +
> +ETH, IPV4, IPV6, UDP, TCP:
> + Matching source/destination MAC/IP/port is supported, with masks.
> +
> + **mlx4 does not support partial bit-masks (full or zeroed only).**
> +
> +ICMP:
> + By specifying the appropriate ether type, ICMP packets can be matched.
> + However, there is no support for ICMP type or code.
> +
> + **mlx4 will not support it, however.**
> +
> +SCTP:
> + By specifying the appropriate IP protocol, SCTP packets can be matched.
> + However, no specific SCTP fields can be matched.
> +
> + **mlx4 will not support it, however.**
> +
> +VXLAN:
> + VXLAN is not recognized by the "flower" classifier. Kernel-managed VXLAN
> + traffic would come through an additional netdevice, which falls outside
> + the scope of this project. VXLAN traffic should occur outside VMs anyway.
> +
> +Action types
> +------------
> +
> +Most applications will use: ``(VOID | END | QUEUE | DROP) / END``
> +
> +By default, multiple actions are possible for TC flow rules. However, they are
> +ordered in the kernel. The implementation will need to handle actions in a way
> +that orders them intelligently when creating them.
> +
> +VOID, END:
> + Supported.
> +
> +PASSTHRU:
> + The generic "continue" action can be used.
> +
> + **mlx4 will not support it, however**.
> +
> +MARK / FLAG:
> + The mark is a field inside an skbuff. However, the tap reads messages (mostly
> + packet data), without that info. As an alternative, it may be possible to
> + create a specific queue to pass packets with a specific mark. Further testing
> + are needed to ensure it is feasable.
> +
> +QUEUE:
> + The ``skbedit`` action with the ``queue_mapping`` option enables directing
> + packets to specific queues.
> +
> + Like rte_flow, specifying several ``skbedit queue_mapping`` actions in TC
> + only considers the last one.
> +
> +DROP:
> + The generic "drop" action can be used. Packets will effectively be dropped,
> + and not left for the kernel to process.
> +
> +COUNT: Stats are automatically stored in the kernel. The COUNT action will thus
> + be ignored when creating the rule. ``rte_flow_query()`` can be implemented
> + to request a rule's stats from the kernel.
> +
> +DUP:
> + Duplicating packets is not supported.
> +
> +RSS:
> + There's no built-in mechanism for RSS in TC.
> +
> + By default, incoming packets go to the tap PMD queue 0. To support RSS in
> + software, several additional queues must be set up. Packets coming in on
> + queue 0 can be considered as requiring RSS, and the PMD will apply software
> + rss (using something like ``rte_softrss()``) to select a queue for the
> + packet.
> +
> +PF, VF:
> + Not applicable to a tap netdevice.
> +
> +.. raw:: pdf
> +
> + PageBreak
> +
> +TC limitations for flow collision
> +=================================
> +
> +From TC standpoint, filter rules with identical priorities do not collide, if
> +they do specify values (at least one different) for the same fields in the TC
> +message, with identical fields masks.
> +
> +Unfortunately, some flows that obviously are not colliding can be considered
> +otherwise by the kernel when parsing the TC messages, and thus their creation
> +would be rejected.
> +
> +Here is a table for matching TC fields with their flow API equivalent:
> +
> ++------------------------------+-----------------------------------+-----------+
> +| TC message field | rte_flow API | maskable? |
> ++==============================+===================================+===========+
> +| TCA_FLOWER_KEY_ETH_DST | eth dst | yes |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_ETH_SRC | eth src | yes |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_ETH_TYPE | eth type is 0xZZZZ || | no |
> +| | eth / {ipv4|ipv6} | |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_IP_PROTO | eth / {ipv4|ipv6} / {tcp|udp} | no |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_IPV4_SRC | eth / ipv4 src | yes |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_IPV4_DST | eth / ipv4 dst | yes |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_IPV6_SRC | eth / ipv6 src | yes |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_IPV6_DST | eth / ipv6 dst | yes |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_L4_SRC | eth / {ipv4|ipv6} / {tcp|udp} dst | no |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_L4_DST | eth / {ipv4|ipv6} / {tcp|udp} src | no |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_VLAN_ID | eth / vlan vid | no |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_VLAN_PRIO | eth / vlan pcp | no |
> ++------------------------------+-----------------------------------+-----------+
> +| TCA_FLOWER_KEY_VLAN_ETH_TYPE | eth / vlan tpid | no |
> ++------------------------------+-----------------------------------+-----------+
> +
> +When creating rules with identical priorities, one must make sure that they
> +would be translated in TC using the same fields as shown in the above table.
> +
> +The following flow rules can share the same priority, as they use the same
> +fields with identical masks under the hood::
> +
> + > flow create 0 ingress priority 0 pattern eth / ipv4 / end
> + actions drop / end
> + Flow rule #0 created
> + > flow create 0 ingress priority 0 pattern eth type is 0x86dd / end
> + actions drop / end
> + Flow rule #1 created
> +
> +**Note:** Both rules use ETH_TYPE (mask 0xffff) in their TC form.
> +
> +Sadly, the following flow rules cannot share the same priority, since fields for
> +matching IPv4 and IPv6 src/dst addresses are different::
> +
> + > flow create 0 ingress priority 1 pattern eth / ipv4 src is 1.1.1.1 / end
> + actions drop / end
> + Flow rule #0 created
> + > flow create 0 ingress priority 1 pattern eth / ipv6 src is ::1 / end
> + actions drop / end
> + PMD: Kernel refused TC filter rule creation (22): Invalid argument
> + Caught error type 2 (flow rule (handle)): overlapping rules
> +
> +**Note:** First rule uses ETH_TYPE and IPV4_SRC, while the second uses ETH_TYPE
> +and IPV6_SRC.
> +
> +It is however possible to match different IPvX addresses with the same
> +priority::
> +
> + > flow create 0 ingress priority 2 pattern eth / ipv4 src is 1.1.1.1 / end
> + actions drop / end
> + Flow rule #0 created
> + > flow create 0 ingress priority 2 pattern eth / ipv4 src is 2.2.2.2 / end
> + actions drop / end
> + Flow rule #1 created
> +
> +If the first rule specifies both destination and source addresses, then the
> +other rule with the same priority must too (with identical masks)::
> +
> + > flow create 0 ingress priority 3 pattern eth / ipv4 src is 1.1.1.1
> + dst is 1.1.1.2 / end actions drop / end
> + Flow rule #0 created
> + > flow create 0 ingress priority 3 pattern eth / ipv4 src is 2.2.2.2 / end
> + actions drop / end
> + PMD: Kernel refused TC filter rule creation (22): Invalid argument
> + Caught error type 2 (flow rule (handle)): overlapping rules
> + > flow create 0 ingress priority 3 pattern eth / ipv4 src is 2.2.2.2
> + dst spec 2.2.2.3 dst mask 255.255.255.0 / end actions drop / end
> + PMD: Kernel refused TC filter rule creation (22): Invalid argument
> + Caught error type 2 (flow rule (handle)): overlapping rules
> + > flow create 0 ingress priority 3 pattern eth / ipv4 src is 2.2.2.2
> + dst is 2.2.2.3 / end actions drop / end
> + Flow rule #1 created
> +
> +**Note:** First rule uses ETH_TYPE, IPV4_SRC and IPV4_DST (with full masks). The
> +two others must also use those to share the same priority.
> +
> +It is possible to match TCP/UDP packets with different ports whatever the
> +underlying L3, if the same fields are used (thus no l3 addresses specification).
> +For instance::
> +
> + > flow create 0 ingress priority 4 pattern eth / ipv4 / tcp dst is 3333 / end
> + actions drop / end
> + Flow rule #0 created
> + > flow create 0 ingress priority 4 pattern eth / ipv6 / udp dst is 4444 / end
> + actions drop / end
> + Flow rule #1 created
> + > flow create 0 ingress priority 4 pattern eth / ipv6 / udp src is 5555 / end
> + actions drop / end
> + PMD: Kernel refused TC filter rule creation (22): Invalid argument
> + Caught error type 2 (flow rule (handle)): overlapping rules
> +
> +**Note:** First 2 rules use ETH_TYPE, IP_PROTO and L4_DST with different values
> +but identical masks, so they're OK. Last rule used L4_SRC instead of L4_DST.
> +
> +.. raw:: pdf
> +
> + PageBreak
> +
> +RSS implementation for tap
> +==========================
> +
> +There are several areas of research for a tap RSS implementation:
> +
> +#. userland implementation in tap PMD
> +#. userland implementation in DPDK (generic)
> +#. userland implementation using combination of TC rules and BPF filters/actions
> +#. kernel-side implementation in tap driver
> +#. kernel-side implementation as a BPF classifier/action
> +#. kernel-side implementation as a separate TC action
> +
> ++--------------+------------------------------+------------------------------+
> +| | Pros | Cons |
> ++==============+==============================+==============================+
> +| tap PMD | - no kernel upstreaming | - tap PMD is supposed to be |
> +| | | simple, and would no longer|
> +| | | be. |
> +| | | |
> +| | | - complex rework, with many |
> +| | | rings for enqueuing packets|
> +| | | to the right queue |
> +| | | |
> +| | | - slower |
> +| | | |
> +| | | - won't be accepted as it |
> +| | | doesn't make sense to redo |
> +| | | what the kernel did |
> +| | | previously |
> ++--------------+------------------------------+------------------------------+
> +| generic DPDK | - would be useful to others | - design must be compatible |
> +| | | with most PMDs |
> +| | | |
> +| | | - probably the longest to |
> +| | | develop |
> +| | | |
> +| | | - requires DPDK community |
> +| | | approval |
> +| | | |
> +| | | - requires heavy changes in |
> +| | | tap PMD itself anyway |
> ++--------------+------------------------------+------------------------------+
> +| TC rules | - no kernel upstreaming | - BPF is complicated to learn|
> +| combination | | |
> +| | - fast | - Runtime BPF compilation / |
> +| | | or bytecode change, would |
> +| | - per-flow RSS | be tricky |
> +| | | |
> +| | - no change in tap PMD | - much rework in the tap PMD |
> +| | datapath | to handle lots of new |
> +| | | netlink messages / actions |
> ++--------------+------------------------------+------------------------------+
> +| tap driver | - pretty fast as it | - might not be accepted by |
> +| | intervenes early in packet | the kernel community as |
> +| | RX | they may cling to their |
> +| | | jhash2 hashing function for|
> +| | | RX. |
> +| | | |
> +| | | - only a single RSS context |
> ++--------------+------------------------------+------------------------------+
> +| BPF | - fast | - BPF is complicated to learn|
> +| classifier - | | |
> +| action | - per-flow RSS | - would require changing the |
> +| | | kernel API to support |
> +| | | editing queue_mapping in an|
> +| | | skb |
> +| | | |
> +| | | - hashing would be performed |
> +| | | for each queue of a |
> +| | | specific RSS context |
> +| | | |
> +| | | - probably difficult to gain |
> +| | | community acceptance |
> ++--------------+------------------------------+------------------------------+
> +| TC action | - much more flexibility, with| - needs to be in sync with |
> +| | per-flow RSS, multiple | iproute2's tc program |
> +| | keys, multiple packet | |
> +| | fields for the hash... | - kernel upstreaming is not |
> +| | | necessarily easy |
> +| | - it's a separate kernel | |
> +| | module that can be | - rework in tap PMD to |
> +| | maintained out-of-tree and | support new RSS action and |
> +| | optionally upstreamed | configuration |
> +| | anytime | |
> +| | | |
> +| | - most logical to be handled | |
> +| | in kernel as RSS is | |
> +| | supposed to be computed in | |
> +| | the "NIC" exactly once. | |
> +| | | |
> +| | - fastest | |
> +| | | |
> +| | - no change in tap PMD | |
> +| | datapath | |
> ++--------------+------------------------------+------------------------------+
> +
> +TC rules using BPF from tap PMD
> +-------------------------------
> +
> +The third solution is the best for userland-based solutions.
> +It does the job well, fast (datapath running in kernel), is logically happening
> +in the kernel in runtime, supports flow-based RSS, has the best potential to
> +be accepted by the community.
> +
> +Advantages with this solution:
> +- hash can be recorded in the packet data and read in tap PMD
> +- no kernel customization, everything in DPDK
> +- packet gets in tap PMD on the correct queue directly
> +
> +Drawbacks:
> +- complicates tap PMD a lot:
> + - 3 BPF programs
> + - new implicit rules
> + - new action and filter support
> + - packet stripping
> +- numerous TC rules required (in proportion with the number of queues)
> +- fast (kernel + JIT BPF), but several TC rules must be crossed
> +
> +BPF programs controlled from tap PMD will be used to match packets, compute a
> +hash given the configured key, and send packets to tap using the desired queue.
> +
> +Design
> +~~~~~~
> +
> +BPF has a limited set of functions for editing the skb in TC. They are listed
> +in ``linux/net/core/filter.c:tc_cls_act_func_proto()``:
> +
> +- skb_store_bytes
> +- skb_load_bytes
> +- skb_pull_data
> +- csum_diff
> +- csum_update
> +- l3_csum_replace
> +- l4_csum_replace
> +- clone_redirect
> +- get_cgroup_classid
> +- skb_vlan_push
> +- skb_vlan_pop
> +- skb_change_proto
> +- skb_change_type
> +- skb_change_tail
> +- skb_get_tunnel_key
> +- skb_set_tunnel_key
> +- skb_get_tunnel_opt
> +- skb_set_tunnel_opt
> +- redirect
> +- get_route_realm
> +- get_hash_recalc
> +- set_hash_invalid
> +- perf_event_output
> +- get_smp_processor_id
> +- skb_under_cgroup
> +
> +In a BPF program, it is typically not possible to edit the queue_mapping field
> +to direct the packet in the correct queue. That part would be done by chaining a
> +``skbedit queue_mapping`` action.
> +
> +It is not possible either to directly prepend data to a packet (appending works,
> +though).
> +
> +A packet would go through these rules (on the local side of the tap netdevice):
> +
> ++-----+---------------------------+----------------------------------+----------+
> +|PRIO | Match | Action 1 | Action 2 |
> ++=====+===========================+==================================+==========+
> +| 1 | marked? | skbedit queue 'mark' --> DPDK | |
> ++-----+---------------------------+----------------------------------+----------+
> +| 2 | marked? | skbedit queue 'mark' --> DPDK | |
> ++-----+---------------------------+----------------------------------+----------+
> +| ... | | | |
> ++-----+---------------------------+----------------------------------+----------+
> +| x | ANY | BPF: append NULL 32bits for hash | |
> +| | | | |
> ++-----+---------------------------+----------------------------------+----------+
> +|x + 1| ACTUAL FLOW RULE 1 MATCH | ... | |
> +| | | | |
> ++-----+---------------------------+----------------------------------+----------+
> +|x + 2| ACTUAL FLOW RULE 2 MATCH | ... | |
> +| | | | |
> ++-----+---------------------------+----------------------------------+----------+
> +| ... | | | |
> ++-----+---------------------------+----------------------------------+----------+
> +| y | FLOW RULE RSS 1 MATCH | BPF compute hash into packet |reclassify|
> +| | | tailroom && set queue in skb->cb | |
> ++-----+---------------------------+----------------------------------+----------+
> +|y + 1| FLOW RULE RSS 2 MATCH | BPF compute hash into packet |reclassify|
> +| | | tailroom && set queue in skb->cb | |
> ++-----+---------------------------+----------------------------------+----------+
> +| ... | | | |
> ++-----+---------------------------+----------------------------------+----------+
> +| z | ANY (default RSS) | BPF compute hash into packet |reclassify|
> +| | | tailroom && set queue in skb->cb | |
> ++-----+---------------------------+----------------------------------+----------+
> +| z | ANY (isolate mode) | DROP | |
> ++-----+---------------------------+----------------------------------+----------+
> +
> +
> +
> +TC kernel action
> +----------------
> +
> +The latest solution (implementing a TC action) would probably be the most simple
> +to implement. It is also very flexible, opening more possibilities for filtering
> +and RSS combined.
> +
> +For this solution, the following parameters could be used to configure RSS in a
> +TC netlink message:
> +
> +``queues`` (u16 \*):
> + list of queues to spread incoming traffic on. That's actually the reta.
> + **Note:** the queue in an ``skb`` is on 16-bits, hence the type here.
> +
> +``key`` (u8 \*):
> + key to use for the Toeplitz-hash in this flow.
> +
> +``hash_fields`` (bitfield):
> + similar to what's in DPDK, the bitfield should determine what fields in the
> + packet header to use for hashing. It is likely another means of configuring
> + which fields to pick would be used actually.
> +
> +``algo`` (unsigned):
> + an enum value from the kernel act_rss header can be used to determine which
> + algorithm (implemented in the kernel) to use. Possible algos could be
> + toeplitz, xor, symmetric hash...
> +
> +**Note:** The number of queues to use is automatically deduced from the
> +``queues`` netlink attribute length. The ``key`` length can be similarly
> +obtained.
> +
> +.. raw:: pdf
> +
> + PageBreak
> +
> +Appendix: TC netlink message
> +============================
> +
> +**Note:** For deterministic behavior, TC queueing disciplines (QDISC), filters
> +and classes must be flushed before starting to apply TC rules. There is a little
> +bit of boilerplate (with specific netlink messages) to ensure TC rules can be
> +applied. Typically, the TC ``ingress`` QDISC must be created first.
> +
> +For information, netlink messages regarding TC will look like this::
> +
> + 0 8 16 24 32
> + +----------+----------+----------+----------+ ---
> + 0 | Length | \
> + +---------------------+---------------------+ \
> + 4 | Type | Flags | |
> + +----------- ---------+---------------------+ >-- struct
> + 8 | Sequence number | | nlmsghdr
> + +-------------------------------------------+ /
> + 12 | Process Port ID (PID) | /
> + +==========+==========+==========+==========+ ---
> + 16 | Family | Rsvd1 | Reserved2 | \
> + +----------+----------+---------------------+ \
> + 20 | Interface index | |
> + +-------------------------------------------+ |
> + 24 | Handle | |
> + +-------------------------------------------+ >-- struct
> + 28 | Parent handle | | tcmsg
> + | MAJOR + MINOR | |
> + +-------------------------------------------+ |
> + 32 | TCM info | /
> + | priority + protocol | /
> + +===========================================+ ---
> + | |
> + | Payload |
> + | |
> + ........................................
> + | |
> + | |
> + +-------------------------------------------+
> diff --git a/drivers/net/tap/Makefile b/drivers/net/tap/Makefile
> index 405b49e..9afae5e 100644
> --- a/drivers/net/tap/Makefile
> +++ b/drivers/net/tap/Makefile
> @@ -39,6 +39,9 @@ EXPORT_MAP := rte_pmd_tap_version.map
>
> LIBABIVER := 1
>
> +# TAP_MAX_QUEUES must be a power of 2 as it will be used for masking */
> +TAP_MAX_QUEUES = 16
> +
> CFLAGS += -O3
> CFLAGS += -I$(SRCDIR)
> CFLAGS += -I.
> @@ -47,6 +50,8 @@ LDLIBS += -lrte_eal -lrte_mbuf -lrte_mempool -lrte_ring
> LDLIBS += -lrte_ethdev -lrte_net -lrte_kvargs -lrte_hash
> LDLIBS += -lrte_bus_vdev
>
> +CFLAGS += -DTAP_MAX_QUEUES=$(TAP_MAX_QUEUES)
> +
> #
> # all source are stored in SRCS-y
> #
> @@ -89,7 +94,6 @@ tap_autoconf.h: tap_autoconf.h.new
> mv '$<' '$@'
>
> $(SRCS-$(CONFIG_RTE_LIBRTE_PMD_TAP):.c=.o): tap_autoconf.h
> -
> clean_tap: FORCE
> $Q rm -f -- tap_autoconf.h tap_autoconf.h.new
>
> diff --git a/drivers/net/tap/rte_eth_tap.h b/drivers/net/tap/rte_eth_tap.h
> index 829f32f..01ac153 100644
> --- a/drivers/net/tap/rte_eth_tap.h
> +++ b/drivers/net/tap/rte_eth_tap.h
> @@ -45,7 +45,7 @@
> #include <rte_ether.h>
>
> #ifdef IFF_MULTI_QUEUE
> -#define RTE_PMD_TAP_MAX_QUEUES 16
> +#define RTE_PMD_TAP_MAX_QUEUES TAP_MAX_QUEUES
> #else
> #define RTE_PMD_TAP_MAX_QUEUES 1
> #endif
> @@ -90,6 +90,11 @@ struct pmd_internals {
> int ioctl_sock; /* socket for ioctl calls */
> int nlsk_fd; /* Netlink socket fd */
> int flow_isolate; /* 1 if flow isolation is enabled */
> + int flower_support; /* 1 if kernel supports, else 0 */
> + int flower_vlan_support; /* 1 if kernel supports, else 0 */
> + int rss_enabled; /* 1 if RSS is enabled, else 0 */
> + /* implicit rules set when RSS is enabled */
> + LIST_HEAD(tap_rss_flows, rte_flow) rss_flows;
> LIST_HEAD(tap_flows, rte_flow) flows; /* rte_flow rules */
> /* implicit rte_flow rules set when a remote device is active */
> LIST_HEAD(tap_implicit_flows, rte_flow) implicit_flows;
> diff --git a/drivers/net/tap/tap_bpf_elf.h b/drivers/net/tap/tap_bpf_elf.h
> new file mode 100644
> index 0000000..f3db1bf
> --- /dev/null
> +++ b/drivers/net/tap/tap_bpf_elf.h
> @@ -0,0 +1,56 @@
> +/*******************************************************************************
> +
> + Copyright (C) 2015 Daniel Borkmann <daniel@iogearbox.net>
> +
> + Copied from iproute2's include/bpf_elf.h, available at:
> + https://git.kernel.org/pub/scm/linux/kernel/git/shemminger/iproute2.git
> +
> + This file is licensed under GNU General Public License (GPL) v2.
> +
> + The full GNU General Public License is included in this distribution in
> + the file called "LICENSE.GPL".
> +
> +*******************************************************************************/
> +
> +
> +#ifndef __BPF_ELF__
> +#define __BPF_ELF__
> +
> +#include <asm/types.h>
> +
> +/* Note:
> + *
> + * Below ELF section names and bpf_elf_map structure definition
> + * are not (!) kernel ABI. It's rather a "contract" between the
> + * application and the BPF loader in tc. For compatibility, the
> + * section names should stay as-is. Introduction of aliases, if
> + * needed, are a possibility, though.
> + */
> +
> +/* ELF section names, etc */
> +#define ELF_SECTION_LICENSE "license"
> +#define ELF_SECTION_MAPS "maps"
> +#define ELF_SECTION_PROG "prog"
> +#define ELF_SECTION_CLASSIFIER "classifier"
> +#define ELF_SECTION_ACTION "action"
> +
> +#define ELF_MAX_MAPS 64
> +#define ELF_MAX_LICENSE_LEN 128
> +
> +/* Object pinning settings */
> +#define PIN_NONE 0
> +#define PIN_OBJECT_NS 1
> +#define PIN_GLOBAL_NS 2
> +
> +/* ELF map definition */
> +struct bpf_elf_map {
> + __u32 type;
> + __u32 size_key;
> + __u32 size_value;
> + __u32 max_elem;
> + __u32 flags;
> + __u32 id;
> + __u32 pinning;
> +};
> +
> +#endif /* __BPF_ELF__ */
> diff --git a/drivers/net/tap/tap_flow.c b/drivers/net/tap/tap_flow.c
> index ffc0b85..43bab7d 100644
> --- a/drivers/net/tap/tap_flow.c
> +++ b/drivers/net/tap/tap_flow.c
> @@ -43,6 +43,9 @@
> #include <tap_autoconf.h>
> #include <tap_tcmsgs.h>
>
> +#include <linux/bpf.h>
> +#include <linux/tc_act/tc_bpf.h>
> +
> #ifndef HAVE_TC_FLOWER
> /*
> * For kernels < 4.2, this enum is not defined. Runtime checks will be made to
> @@ -104,6 +107,23 @@ struct remote_rule {
> int mirred;
> };
>
> +struct action_data {
> + char id[16];
> +
> + union {
> + struct tc_gact gact;
> + struct tc_mirred mirred;
> + struct skbedit {
> + struct tc_skbedit skbedit;
> + uint16_t queue;
> + } skbedit;
> + struct bpf {
> + int bpf_fd;
> + char *annotation;
> + } bpf;
> + };
> +};
> +
> static int tap_flow_create_eth(const struct rte_flow_item *item, void *data);
> static int tap_flow_create_vlan(const struct rte_flow_item *item, void *data);
> static int tap_flow_create_ipv4(const struct rte_flow_item *item, void *data);
> @@ -134,6 +154,8 @@ struct remote_rule {
> int set,
> struct rte_flow_error *error);
>
> +static int rss_enable(struct pmd_internals *pmd);
> +
> static const struct rte_flow_ops tap_flow_ops = {
> .validate = tap_flow_validate,
> .create = tap_flow_create,
> @@ -816,111 +838,64 @@ struct tap_flow_items {
> }
>
> /**
> - * Transform a DROP/PASSTHRU action item in the provided flow for TC.
> - *
> - * @param[in, out] flow
> - * Flow to be filled.
> - * @param[in] action
> - * Appropriate action to be set in the TCA_GACT_PARMS structure.
> - *
> - * @return
> - * 0 if checks are alright, -1 otherwise.
> + * FIXME
> */
> static int
> -add_action_gact(struct rte_flow *flow, int action)
> +add_action(struct rte_flow *flow, size_t *act_index, struct action_data *adata)
> {
> struct nlmsg *msg = &flow->msg;
> - size_t act_index = 1;
> - struct tc_gact p = {
> - .action = action
> - };
>
> - if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
> - return -1;
> - if (nlattr_nested_start(msg, act_index++) < 0)
> + if (nlattr_nested_start(msg, ++(*act_index)) < 0)
> return -1;
> - nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("gact"), "gact");
> - if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
> - return -1;
> - nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(p), &p);
> - nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> - nlattr_nested_finish(msg); /* nested act_index */
> - nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
> - return 0;
> -}
> -
> -/**
> - * Transform a MIRRED action item in the provided flow for TC.
> - *
> - * @param[in, out] flow
> - * Flow to be filled.
> - * @param[in] ifindex
> - * Netdevice ifindex, where to mirror/redirect packet to.
> - * @param[in] action_type
> - * Either TCA_EGRESS_REDIR for redirection or TCA_EGRESS_MIRROR for mirroring.
> - *
> - * @return
> - * 0 if checks are alright, -1 otherwise.
> - */
> -static int
> -add_action_mirred(struct rte_flow *flow, uint16_t ifindex, uint16_t action_type)
> -{
> - struct nlmsg *msg = &flow->msg;
> - size_t act_index = 1;
> - struct tc_mirred p = {
> - .eaction = action_type,
> - .ifindex = ifindex,
> - };
>
> - if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
> - return -1;
> - if (nlattr_nested_start(msg, act_index++) < 0)
> - return -1;
> - nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("mirred"), "mirred");
> + nlattr_add(&msg->nh, TCA_ACT_KIND, strlen(adata->id), adata->id);
> if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
> return -1;
> - if (action_type == TCA_EGRESS_MIRROR)
> - p.action = TC_ACT_PIPE;
> - else /* REDIRECT */
> - p.action = TC_ACT_STOLEN;
> - nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(p), &p);
> + if (strcmp("gact", adata->id) == 0) {
> + nlattr_add(&msg->nh, TCA_GACT_PARMS, sizeof(adata->gact),
> + &adata->gact);
> + } else if (strcmp("mirred", adata->id) == 0) {
> + if (adata->mirred.eaction == TCA_EGRESS_MIRROR)
> + adata->mirred.action = TC_ACT_PIPE;
> + else /* REDIRECT */
> + adata->mirred.action = TC_ACT_STOLEN;
> + nlattr_add(&msg->nh, TCA_MIRRED_PARMS, sizeof(adata->mirred),
> + &adata->mirred);
> + } else if (strcmp("skbedit", adata->id) == 0) {
> + nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS,
> + sizeof(adata->skbedit.skbedit),
> + &adata->skbedit.skbedit);
> + nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING,
> + adata->skbedit.queue);
> + } else if (strcmp("bpf", adata->id) == 0) {
> + nlattr_add32(&msg->nh, TCA_ACT_BPF_FD, adata->bpf.bpf_fd);
> + nlattr_add(&msg->nh, TCA_ACT_BPF_NAME,
> + strlen(adata->bpf.annotation),
> + adata->bpf.annotation);
> + } else {
> + return -1;
> + }
> nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> nlattr_nested_finish(msg); /* nested act_index */
> - nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
> return 0;
> }
>
> /**
> - * Transform a QUEUE action item in the provided flow for TC.
> - *
> - * @param[in, out] flow
> - * Flow to be filled.
> - * @param[in] queue
> - * Queue id to use.
> - *
> - * @return
> - * 0 if checks are alright, -1 otherwise.
> + * FIXME
> */
> static int
> -add_action_skbedit(struct rte_flow *flow, uint16_t queue)
> +add_actions(struct rte_flow *flow, int nb_actions, struct action_data *data,
> + int classifier_action)
> {
> struct nlmsg *msg = &flow->msg;
> - size_t act_index = 1;
> - struct tc_skbedit p = {
> - .action = TC_ACT_PIPE
> - };
> + size_t act_index = 0;
> + int i;
>
> - if (nlattr_nested_start(msg, TCA_FLOWER_ACT) < 0)
> - return -1;
> - if (nlattr_nested_start(msg, act_index++) < 0)
> + if (nlattr_nested_start(msg, classifier_action) < 0)
> return -1;
> - nlattr_add(&msg->nh, TCA_ACT_KIND, sizeof("skbedit"), "skbedit");
> - if (nlattr_nested_start(msg, TCA_ACT_OPTIONS) < 0)
> - return -1;
> - nlattr_add(&msg->nh, TCA_SKBEDIT_PARMS, sizeof(p), &p);
> - nlattr_add16(&msg->nh, TCA_SKBEDIT_QUEUE_MAPPING, queue);
> - nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> - nlattr_nested_finish(msg); /* nested act_index */
> + for (i = 0; i < nb_actions; i++)
> + if (add_action(flow, &act_index, data + i) < 0)
> + return -1;
> nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
> return 0;
> }
> @@ -1053,7 +1028,12 @@ struct tap_flow_items {
> }
> }
> if (mirred && flow) {
> - uint16_t if_index = pmd->if_index;
> + struct action_data adata = {
> + .id = "mirred",
> + .mirred = {
> + .eaction = mirred,
> + },
> + };
>
> /*
> * If attr->egress && mirred, then this is a special
> @@ -1061,9 +1041,13 @@ struct tap_flow_items {
> * redirect packets coming from the DPDK App, out
> * through the remote netdevice.
> */
> - if (attr->egress)
> - if_index = pmd->remote_if_index;
> - if (add_action_mirred(flow, if_index, mirred) < 0)
> + adata.mirred.ifindex = attr->ingress ? pmd->if_index :
> + pmd->remote_if_index;
> + if (mirred == TCA_EGRESS_MIRROR)
> + adata.mirred.action = TC_ACT_PIPE;
> + else
> + adata.mirred.action = TC_ACT_STOLEN;
> + if (add_actions(flow, 1, &adata, TCA_FLOWER_ACT) < 0)
> goto exit_action_not_supported;
> else
> goto end;
> @@ -1077,14 +1061,33 @@ struct tap_flow_items {
> if (action)
> goto exit_action_not_supported;
> action = 1;
> - if (flow)
> - err = add_action_gact(flow, TC_ACT_SHOT);
> + if (flow) {
> + struct action_data adata = {
> + .id = "gact",
> + .gact = {
> + .action = TC_ACT_SHOT,
> + },
> + };
> +
> + err = add_actions(flow, 1, &adata,
> + TCA_FLOWER_ACT);
> + }
> } else if (actions->type == RTE_FLOW_ACTION_TYPE_PASSTHRU) {
> if (action)
> goto exit_action_not_supported;
> action = 1;
> - if (flow)
> - err = add_action_gact(flow, TC_ACT_UNSPEC);
> + if (flow) {
> + struct action_data adata = {
> + .id = "gact",
> + .gact = {
> + /* continue */
> + .action = TC_ACT_UNSPEC,
> + },
> + };
> +
> + err = add_actions(flow, 1, &adata,
> + TCA_FLOWER_ACT);
> + }
> } else if (actions->type == RTE_FLOW_ACTION_TYPE_QUEUE) {
> const struct rte_flow_action_queue *queue =
> (const struct rte_flow_action_queue *)
> @@ -1096,22 +1099,30 @@ struct tap_flow_items {
> if (!queue ||
> (queue->index > pmd->dev->data->nb_rx_queues - 1))
> goto exit_action_not_supported;
> - if (flow)
> - err = add_action_skbedit(flow, queue->index);
> + if (flow) {
> + struct action_data adata = {
> + .id = "skbedit",
> + .skbedit = {
> + .skbedit = {
> + .action = TC_ACT_PIPE,
> + },
> + .queue = queue->index,
> + },
> + };
> +
> + err = add_actions(flow, 1, &adata,
> + TCA_FLOWER_ACT);
> + }
> } else if (actions->type == RTE_FLOW_ACTION_TYPE_RSS) {
> - /* Fake RSS support. */
> const struct rte_flow_action_rss *rss =
> (const struct rte_flow_action_rss *)
> actions->conf;
>
> - if (action)
> - goto exit_action_not_supported;
> - action = 1;
> - if (!rss || rss->num < 1 ||
> - (rss->queue[0] > pmd->dev->data->nb_rx_queues - 1))
> + if (action++)
> goto exit_action_not_supported;
> - if (flow)
> - err = add_action_skbedit(flow, rss->queue[0]);
> + if (!pmd->rss_enabled)
> + err = rss_enable(pmd);
> + (void)rss;
> } else {
> goto exit_action_not_supported;
> }
> @@ -1632,6 +1643,127 @@ int tap_flow_implicit_destroy(struct pmd_internals *pmd,
> return 0;
> }
>
> +#define BPF_PROGRAM "tap_bpf_program.o"
> +
> +/**
> + * Enable RSS on tap: create leading TC rules for queuing.
> + */
> +static int rss_enable(struct pmd_internals *pmd)
> +{
> + struct rte_flow *rss_flow = NULL;
> + char section[64];
> + struct nlmsg *msg = NULL;
> + /* 4096 is the maximum number of instructions for a BPF program */
> + char annotation[256];
> + int bpf_fd;
> + int i;
> +
> + /*
> + * Add a rule per queue to match reclassified packets and direct them to
> + * the correct queue.
> + */
> + for (i = 0; i < pmd->dev->data->nb_rx_queues; i++) {
> + struct action_data adata = {
> + .id = "skbedit",
> + .skbedit = {
> + .skbedit = {
> + .action = TC_ACT_PIPE,
> + },
> + .queue = i,
> + },
> + };
> +
> + bpf_fd = 0;
> +
> + rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
> + if (!rss_flow) {
> + RTE_LOG(ERR, PMD,
> + "Cannot allocate memory for rte_flow");
> + return -1;
> + }
> + msg = &rss_flow->msg;
> + tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER, NLM_F_REQUEST |
> + NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
> + msg->t.tcm_info = TC_H_MAKE((i + PRIORITY_OFFSET) << 16,
> + htons(ETH_P_ALL));
> + msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
> + tap_flow_set_handle(rss_flow);
> + nlattr_add(&msg->nh, TCA_KIND, sizeof("bpf"), "bpf");
> + if (nlattr_nested_start(msg, TCA_OPTIONS) < 0)
> + return -1;
> + nlattr_add32(&msg->nh, TCA_BPF_FD, bpf_fd);
> + snprintf(annotation, sizeof(annotation), "%s:[%s]",
> + BPF_PROGRAM, section);
> + nlattr_add(&msg->nh, TCA_BPF_NAME, strlen(annotation),
> + annotation);
> +
> + if (add_actions(rss_flow, 1, &adata, TCA_BPF_ACT) < 0)
> + return -1;
> + nlattr_nested_finish(msg); /* nested TCA_ACT_OPTIONS */
> + /* Netlink message is now ready to be sent */
> + if (nl_send(pmd->nlsk_fd, &msg->nh) < 0)
> + return -1;
> + if (nl_recv_ack(pmd->nlsk_fd) < 0)
> + return -1;
> + LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
> + }
> +
> + snprintf(annotation, sizeof(annotation), "%s:[%s]", BPF_PROGRAM,
> + section);
> + rss_flow = rte_malloc(__func__, sizeof(struct rte_flow), 0);
> + if (!rss_flow) {
> + RTE_LOG(ERR, PMD,
> + "Cannot allocate memory for rte_flow");
> + return -1;
> + }
> + msg = &rss_flow->msg;
> + tc_init_msg(msg, pmd->if_index, RTM_NEWTFILTER,
> + NLM_F_REQUEST | NLM_F_ACK | NLM_F_EXCL | NLM_F_CREATE);
> + msg->t.tcm_info =
> + TC_H_MAKE((RTE_PMD_TAP_MAX_QUEUES + PRIORITY_OFFSET) << 16,
> + htons(ETH_P_ALL));
> + msg->t.tcm_parent = TC_H_MAKE(MULTIQ_MAJOR_HANDLE, 0);
> + tap_flow_set_handle(rss_flow);
> + nlattr_add(&msg->nh, TCA_KIND, sizeof("flower"), "flower");
> + if (nlattr_nested_start(msg, TCA_OPTIONS) < 0)
> + return -1;
> +
> + /* no fields for matching: all packets must match */
> + {
> + /* Actions */
> + struct action_data data[2] = {
> + [0] = {
> + .id = "bpf",
> + .bpf = {
> + .bpf_fd = bpf_fd,
> + .annotation = annotation,
> + },
> + },
> + [1] = {
> + .id = "gact",
> + .gact = {
> + /* continue */
> + .action = TC_ACT_UNSPEC,
> + },
> + },
> + };
> +
> + if (add_actions(rss_flow, 2, data, TCA_FLOWER_ACT) < 0)
> + return -1;
> + }
> + nlattr_nested_finish(msg); /* nested TCA_FLOWER_ACT */
> + nlattr_nested_finish(msg); /* nested TCA_OPTIONS */
> + /* Netlink message is now ready to be sent */
> + if (nl_send(pmd->nlsk_fd, &msg->nh) < 0)
> + return -1;
> + if (nl_recv_ack(pmd->nlsk_fd) < 0)
> + return -1;
> + LIST_INSERT_HEAD(&pmd->rss_flows, rss_flow, next);
> +
> + pmd->rss_enabled = 1;
> + return 0;
> +}
> +
> /**
> * Manage filter operations.
> *
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] relicense various bits of the dpdk
2017-12-04 15:55 8% [dpdk-dev] [PATCH] relicense various bits of the dpdk Neil Horman
@ 2017-12-05 10:44 0% ` Hemant Agrawal
0 siblings, 0 replies; 200+ results
From: Hemant Agrawal @ 2017-12-05 10:44 UTC (permalink / raw)
To: Neil Horman, dev; +Cc: Thomas Monjalon
On 12/4/2017 9:25 PM, Neil Horman wrote:
> Received a note the other day from the Linux Foundation governance board
> for DPDK indicating that several files I have copyright on need to be
> relicensed to be compliant with the DPDK licensing guidelines. I have
> some concerns with some parts of the request, but am not opposed to
> other parts. So, for those pieces that we are in consensus on, I'm
> proposing that we change their license from BSD 2 clause to 3 clause.
> I'm also updating the files to use the SPDX licensing scheme
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Hemant Agrawal <hemant.agrawal@nxp.com>
> CC: Thomas Monjalon <thomas@monjalon.net>
> ---
> devtools/validate-abi.sh | 32 ++++----------------------------
> lib/librte_compat/rte_compat.h | 24 +-----------------------
> 2 files changed, 5 insertions(+), 51 deletions(-)
Acked-by: Hemant Agrawal <hemant.agrawal@nxp.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] examples/ipsec-secgw: fix usage of incorrect port
@ 2017-12-06 11:08 3% ` Anoob
2017-12-11 10:26 0% ` Radu Nicolau
0 siblings, 1 reply; 200+ results
From: Anoob @ 2017-12-06 11:08 UTC (permalink / raw)
To: Akhil Goyal, Declan Doherty, Sergio Gonzalez Monroy,
Radu Nicolau, Bruce Richardson
Cc: Narayana Prasad, Jerin Jacob, dev
Hi Akhil,
On 12/04/2017 01:19 PM, Akhil Goyal wrote:
> Hi Anoob,
> On 11/29/2017 9:51 AM, Anoob Joseph wrote:
>> Hi Akhil,
>>
>>
>> On 24-11-2017 16:19, Akhil Goyal wrote:
>>> Hi Anoob,
>>>
>>> On 11/24/2017 3:28 PM, Anoob wrote:
>>>>>> static inline void
>>>>>> route4_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[],
>>>>>> uint8_t nb_pkts)
>>>>>> {
>>>>>> uint32_t hop[MAX_PKT_BURST * 2];
>>>>>> uint32_t dst_ip[MAX_PKT_BURST * 2];
>>>>>> + int32_t pkt_hop = 0;
>>>>>> uint16_t i, offset;
>>>>>> + uint16_t lpm_pkts = 0;
>>>>>> if (nb_pkts == 0)
>>>>>> return;
>>>>>> + /* Need to do an LPM lookup for non-offload packets.
>>>>>> Offload packets
>>>>>> + * will have port ID in the SA
>>>>>> + */
>>>>>> +
>>>>>> for (i = 0; i < nb_pkts; i++) {
>>>>>> - offset = offsetof(struct ip, ip_dst);
>>>>>> - dst_ip[i] = *rte_pktmbuf_mtod_offset(pkts[i],
>>>>>> - uint32_t *, offset);
>>>>>> - dst_ip[i] = rte_be_to_cpu_32(dst_ip[i]);
>>>>>> + if (!(pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD)) {
>>>>>> + /* Security offload not enabled. So an LPM lookup is
>>>>>> + * required to get the hop
>>>>>> + */
>>>>>> + offset = offsetof(struct ip, ip_dst);
>>>>>> + dst_ip[lpm_pkts] = *rte_pktmbuf_mtod_offset(pkts[i],
>>>>>> + uint32_t *, offset);
>>>>>> + dst_ip[lpm_pkts] = rte_be_to_cpu_32(dst_ip[lpm_pkts]);
>>>>>> + lpm_pkts++;
>>>>>> + }
>>>>>> }
>>>>>> - rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip, hop,
>>>>>> nb_pkts);
>>>>>> + rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip, hop,
>>>>>> lpm_pkts);
>>>>>> +
>>>>>> + lpm_pkts = 0;
>>>>>> for (i = 0; i < nb_pkts; i++) {
>>>>>> - if ((hop[i] & RTE_LPM_LOOKUP_SUCCESS) == 0) {
>>>>>> + if (pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD) {
>>>>>> + /* Read hop from the SA */
>>>>>> + pkt_hop = get_hop_for_offload_pkt(pkts[i]);
>>>>>> + } else {
>>>>>> + /* Need to use hop returned by lookup */
>>>>>> + pkt_hop = hop[lpm_pkts++];
>>>>>> + if ((pkt_hop & RTE_LPM_LOOKUP_SUCCESS) == 0)
>>>>>> + pkt_hop = -1;
>>>>>> + }
>>>>>> +
>>>>> I believe the following check is redundant for non inline case. I
>>>>> believe get_hop_for_offload_pkt can also set the
>>>>> RTE_LPM_LOOKUP_SUCCESS if route is success and take the (pkt_hop &
>>>>> RTE_LPM_LOOKUP_SUCCESS) == 0 check outside the if else block and
>>>>> free the packet if it is unsuccessful.
>>>>>
>>>>> Same comment for route6_pkts. Checking with -1 may not be a good
>>>>> idea if we have a flag available for the same.
>>>>> Others can comment.
>>>> The problem is ipv4 & ipv6 LPM lookups return different error
>>>> values, but we are using a single routine to get the hop for
>>>> offload packets. The flag(RTE_LPM_LOOKUP_SUCCESS) is only for ipv4
>>>> lookups. For ipv6, error is -1. If we need a cleaner solution, we
>>>> can have ipv4 & ipv6 variants of "get_hop_for_offload_pkt". But
>>>> that would be repetition of some code.
>>>
>>> my concern over this patch is that there is an addition of an extra
>>> check in the non inline case and we can get rid of that with some
>>> changes in the code(lib/app). Regarding route6_pkts, the code looks
>>> cleaner than route4_pkts
>> If we have ipv4 and ipv6 variants of the "get_hop_for_offload_packet"
>> function, the code would look much cleaner. Shall I update the patch
>> with such a change and send v4?
>
> I believe we shall get rid of "RTE_LPM_LOOKUP_SUCCESS" from the
> rte_lpm_lookup_bulk(), we shall have similar error flags for v4 and v6
> APIs. Either we can have RTE_LPM_LOOKUP_SUCCESS or -1 as check for
> errors.
This will call for an ABI change. And LPM library has multiple variants
for v4 & v6 lookups. We will need to modify all such instances. I've
CCed Bruce for his opinion on this matter. If maintainers can decide on
how to address this properly, I can plan my next steps accordingly.
> Sergio can comment on this.
>
> Duplicating code for get_hop_for_offload_packet may not be a good idea.
>
> -Akhil
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] 17.08.1 patches review and test
2017-12-04 20:40 0% ` Patil, Harish
@ 2017-12-07 13:46 0% ` Yuanhan Liu
0 siblings, 0 replies; 200+ results
From: Yuanhan Liu @ 2017-12-07 13:46 UTC (permalink / raw)
To: Patil, Harish; +Cc: dpdk stable, dev, Xu, Qian Q
On Mon, Dec 04, 2017 at 08:40:03PM +0000, Patil, Harish wrote:
>
>
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> on behalf of Yuanhan Liu
> <yliu@fridaylinux.org>
> Date: Monday, November 27, 2017 at 4:21 AM
> To: dpdk stable <stable@dpdk.org>
> Cc: "dev@dpdk.org" <dev@dpdk.org>, "Xu, Qian Q" <qian.q.xu@intel.com>
> Subject: [dpdk-dev] 17.08.1 patches review and test
>
> >Hi all,
> >
> >Here is a list of patches targeted for stable release 17.08.1. Please
> >help review and test. The planned date for the final release is 7th,
> >Dec. Before that, please shout if anyone has objections with these
> >patches being applied.
> >
> >These patches are located at branch 17.08 of dpdk-stable repo:
> > http://dpdk.org/browse/dpdk-stable/
> >
> >Thanks.
> >
> > --yliu
> >
> >---
> >Aaron Conole (1):
> > net/enic: fix assignment
> >
> >Ajit Khaparde (28):
> > net/bnxt: fix HWRM macros and locking
> > net/bnxt: use 64-bits of address for VLAN table
> > net/bnxt: fix an issue with group id calculation
> > net/bnxt: fix calculation of number of pools
> > net/bnxt: handle multi queue mode properly
> > net/bnxt: fix Rx handling and buffer allocation logic
> > net/bnxt: fix an issue with broadcast traffic
> > net/bnxt: fix usage of VMDq flags
> > net/bnxt: set checksum offload flags correctly
> > net/bnxt: update status of Rx IP/L4 CKSUM
> > net/bnxt: fix config RSS update
> > net/bnxt: set the hash key size
> > net/bnxt: fix per queue stats display in xstats
> > net/bnxt: fix interrupt handler
> > net/bnxt: fix number of MAC addresses for VMDq
> > net/bnxt: fix the association of a MACVLAN per VNIC
> > net/bnxt: fix Tx offload capability
> > net/bnxt: fix Rx offload capability
> > net/bnxt: handle Rx multi queue creation properly
> > net/bnxt: remove redundant code parsing pool map
> > net/bnxt: fix a bit shift operation
> > net/bnxt: fix a potential null pointer dereference
> > net/bnxt: fix a potential null pointer dereference
> > net/bnxt: fix a pointer deref before null check
> > net/bnxt: fix an unused value
> > net/bnxt: check VLANs from pool map only for VMDq
> > net/bnxt: do not set hash type unnecessarily
> > net/bnxt: fix VLAN spoof configuration
> >
> >Akhil Goyal (2):
> > test/crypto: fix dpaa2 sec macros and definitions
> > net/dpaa2: set queues after reconfiguration
> >
> >Alejandro Lucero (2):
> > net/nfp: fix RSS
> > net/nfp: fix Rx interrupt when multiqueue
> >
> >Alok Makhariya (2):
> > crypto/dpaa2_sec: remove ICV memset on decryption side
> > crypto/dpaa2_sec: add check for segmented buffer
> >
> >Anatoly Burakov (1):
> > vfio: fix secondary process initialization
> >
> >Andrey Chilikin (1):
> > net/i40e: fix flexible payload configuration
> >
> >Aviad Yehezkel (4):
> > examples/ipsec-secgw: fix crypto device mapping
> > examples/ipsec-secgw: fix session creation
> > examples/ipsec-secgw: fix AAD length setting
> > app/testpmd: fix build without ixgbe and bnxt PMDs
> >
> >Beilei Xing (1):
> > net/i40e: fix VF device stop issue
> >
> >Chas Williams (1):
> > net/vmxnet3: fix memory leak when releasing queues
> >
> >Congwen Zhang (1):
> > net/cxgbe: fix memory leak
> >
> >Daniel Mrzyglod (3):
> > net/virtio: fix untrusted scalar value
> > app/testpmd: fix DDP package filesize detection
> > net/bonding: fix default aggregator mode to stable
> >
> >David Harton (2):
> > net/vmxnet3: fix MAC address set
> > net/i40e: fix i40evf MAC filter table
> >
> >Ferruh Yigit (4):
> > ethdev: fix ABI version
> > ethdev: revert use port name from device structure
> > igb_uio: remove device reset in open
> > net/qede: fix icc build
> >
> >Gaetan Rivet (1):
> > net/failsafe: fix errno set on command execution
> >
> >Gowrishankar Muthukrishnan (1):
> > net/bonding: support bifurcated driver in eal
> >
> >Guduri Prathyusha (2):
> > examples/l3fwd: fix NEON instructions
> > examples/l3fwd: fix aliasing in port grouping
> >
> >Harish Patil (2):
> > net/qede: fix supported packet types
> > net/qede: fix to re-enable LRO during device start
> >
> >Hemant Agrawal (3):
> > net/dpaa2: fix the Tx handling of non HW pool bufs
> > examples/l2fwd-crypto: fix uninitialized errno value
> > app/crypto-perf: fix uninitialized errno value
> >
> >Ian Stokes (1):
> > cryptodev: fix build with -Ofast
> >
> >Ivan Malov (2):
> > net/sfc: specify correct scale table size on Rx start
> > net/sfc: fix unused variable in RSS-agnostic build
> >
> >Jacek Piasecki (1):
> > examples/vhost_scsi: fix product id string termination
> >
> >Jasvinder Singh (1):
> > examples/qos_sched: fix uninitialized config
> >
> >Jerin Jacob (1):
> > timer: use 64-bit specific code on more platforms
> >
> >Jianbo Liu (1):
> > net/i40e: fix Rx packets number for NEON
> >
> >Jiayu Hu (1):
> > gro: fix typo in map file
> >
> >Jingjing Wu (4):
> > net/i40e: fix interrupt throttling setting in PF
> > net/i40e: fix memory leak if VF init fails
> > net/i40e: fix variable assignment
> > net/i40e: fix VF initialization error
> >
> >John Daley (3):
> > net/enic: fix multi-process operation
> > net/enic: fix packet loss after MTU change
> > net/enic: fix TSO for packets greater than 9208 bytes
> >
> >John Miller (1):
> > net/ark: fix loop counter
> >
> >Kuba Kozak (2):
> > vfio: fix close unchecked file descriptor
> > vhost: check poll error code
> >
> >Li Han (1):
> > app/testpmd: fix invalid port id parameters
> >
> >Lukasz Majczak (1):
> > eal: fix auxv open check for ARM and PPC
> >
> >Mark Spender (1):
> > net/sfc/base: fix default RSS context check on Siena
> >
> >Matan Azrad (7):
> > net/failsafe: fix Tx sub device deactivating
> > net/mlx5: fix locking in xstats functions
> > net/failsafe: fix parameters parsing
> > net/mlx5: fix probe failure report
> > net/failsafe: fix adding MAC error report miss
> > app/testpmd: fix forward port ids setting
> > net/failsafe: fix Rx clean race
> >
> >Maxime Coquelin (1):
> > vhost: fix dereferencing invalid pointer after realloc
> >
> >Michal Jastrzebski (1):
> > net/vmxnet3: fix dereference before null check
> >
> >Nikhil Rao (1):
> > eal/x86: fix atomic cmpset
> >
> >Nirmoy Das (1):
> > kni: fix SLE version detection
> >
> >Nélio Laranjeiro (4):
> > net/mlx5: fix clang build
> > net/mlx5: fix SSE Rx support verification
> > net/mlx5: fix clang compilation error
> > app/testpmd: fix RSS structure initialisation
> >
> >Olivier Matz (12):
> > net: fix inner L2 length in packet type parser
> > net/bnxt: fix compilation with -Og
> > net/qede: fix compilation with -Og
> > app/test-crypto-perf: fix memory leak
> > app/test-crypto-perf: fix compilation with -Og
> > net/virtio: revert not claiming LRO support
> > net/virtio: revert not claiming IP checksum offload
> > net/virtio: fix log levels in configure
> > net/virtio: fix mbuf port for simple Rx function
> > net/virtio: fix queue setup consistency
> > net/virtio: fix compilation with -Og
> > lpm6: fix compilation with -Og
> >
> >Ophir Munk (3):
> > net/tap: fix flow and port commands
> > net/failsafe: fix VLAN stripping configuration
> > app/testpmd: fix forwarding between non consecutive ports
> >
> >Pablo de Lara (8):
> > hash: fix eviction counter
> > crypto/aesni_gcm: fix zero data operation
> > app/crypto-perf: fix packet length check
> > app/crypto-perf: parse AEAD data from vectors
> > crypto/openssl: fix AEAD parameters
> > examples/l2fwd-crypto: fix physical address setting
> > crypto/qat: fix HMAC supported digest sizes
> > app/testpmd: fix topology error message
> >
> >Patrick MacArthur (1):
> > eal: copy raw strings taken from command line
> >
> >Phil Yang (1):
> > app/testpmd: fix quitting in container
> >
> >Qi Zhang (4):
> > net/i40e: fix flow control watermark mismatch
> > net/i40e: fix packet count for PF
> > net/i40e: fix mbuf free in vector Tx
> > net/i40e: fix mirror with firmware 6.0
> >
> >Rami Rosen (1):
> > net/kni: remove driver struct forward declaration
> >
> >Rasesh Mody (4):
> > net/qede/base: fix to use a passed ptt handle
> > net/qede/base: fix return code to align with FW
> > net/qede: remove duplicate includes
> > net/qede/base: fix division by zero
> >
> >Raslan Darawsheh (2):
> > net/failsafe: fix failsafe bus uninit return value
> > net/failsafe: fix PCI devices init
> >
> >RongQiang Xie (2):
> > net/enic: fix possible null pointer dereference
> > net/qede: fix possible null pointer dereference
> >
> >Sebastian Basierski (3):
> > net/vmxnet3: fix unintentional integer overflow
> > net/virtio-user: fix TAP name string termination
> > net/virtio: check error on setting non block flag
> >
> >Sergio Gonzalez Monroy (1):
> > crypto/aesni_mb: fix invalid session error
> >
> >Shahaf Shuler (5):
> > net/mlx5: fix num seg assumption in SSE Tx
> > net/mlx5: fix Tx stats error counter definition
> > net/mlx5: fix Tx stats error counter logic
> > net/mlx5: fix TSO segment size verification
> > net/mlx5: fix packet type flags for Ethernet only frame
> >
> >Stefan Baranoff (1):
> > net/pcap: fix memory leak in dumper open
> >
> >Stephen Hemminger (1):
> > eal: initialize logging before bus
> >
> >Tiwei Bie (1):
> > net/virtio: flush Rx queues on start
> >
> >Tomasz Duszynski (3):
> > drivers/crypto: use snprintf return value correctly
> > examples/ipsec-secgw: fix IP version check
> > examples/ipsec-secgw: fix IPv6 payload length
> >
> >Tomasz Kulasek (3):
> > net/bonding: fix slaves capacity check
> > net/i40e: fix assignment of enum values
> > net/bonding: fix check slaves link properties
> >
> >Vipin Varghese (1):
> > net/tap: fix unregistering callback with invalid fd
> >
> >Wei Dai (8):
> > net/ixgbe: fix mapping of user priority to TC
> > net/ixgbe: fix adding a mirror rule
> > net/i40e: fix mirror rule reset when port is closed
> > net/ixgbe: fix Rx queue interrupt mapping in VF
> > net/ixgbe: fix VFIO interrupt mapping in VF
> > net/ixgbe: fix PF DCB info
> > app/testpmd: fix mapping of user priority to DCB TC
> > net/i40e: fix VFIO interrupt mapping in VF
> >
> >Wei Zhao (4):
> > net/ixgbe: fix MAC VLAN filter fail problem
> > net/i40e: fix clear xstats bug in VF
> > app/testpmd: fix packet throughput after stats reset
> > net/ixgbe: fix filter parser for L2 tunnel
> >
> >Wenzhuo Lu (7):
> > net/i40e: fix TM node parameter checking
> > net/i40e: fix TM level capability getting
> > net/ixgbe: fix TM node parameter checking
> > net/ixgbe: fix TM level capability getting
> > net/i40e: fix not supporting NULL TM profile
> > net/ixgbe: fix not supporting NULL TM profile
> > net/i40e: fix parent when adding TM node
> >
> >Xiaoyun Li (2):
> > net/i40e: fix PF notify issue when VF is not up
> > net/igb: fix Rx interrupt with VFIO and MSI-X
> >
> >Xueming Li (5):
> > net/mlx5: fix tunnel offload detection
> > mem: fix malloc debug config
> > mem: fix malloc element free in debug mode
> > examples/l2fwd_fork: fix message pool init
> > examples/multi_process: fix received message length
> >
> >Yi Yang (1):
> > service: fix build with gcc 4.9
> >
> >Yong Wang (4):
> > net/liquidio: fix uninitialized variable
> > net/igb: fix memcpy length
> > net/i40e: fix uninitialized variable
> > net/ixgbe: fix uninitialized variable
> >
> >Yongseok Koh (3):
> > net/mlx5: fix calculating TSO inline size
> > net/mlx5: fix overflow of Rx SW ring
> > net/mlx5: fix tunneled TCP/UDP packet type
> >
> >Zhiyong Yang (2):
> > test: fix assignment operation
> > net/virtio: fix Tx packet length stats
>
>
> Hi Yuanhan,
> I found the following two patches marked for stable release is not picked
> up here.
>
> commit f07aa795c92ac6a9460d25ab2e9d74379ed8e5eb
> Author: Harish Patil <harish.patil@cavium.com>
> Date: Tue Nov 7 00:34:18 2017 -0800
>
> net/qede: disable per-VF Tx switching feature
>
> Provide a knob to control per-VF Tx switching feature by adding a
> config
> option, CONFIG_RTE_LIBRTE_QEDE_VF_TX_SWITCH. By default, it will be
> kept
> in disabled state for better performance with small sized frames.
>
> Fixes: 2ea6f76aff40 ("qede: add core driver")
> Cc: stable@dpdk.org
>
> Signed-off-by: Harish Patil <harish.patil@cavium.com>
>
> commit 1282943aa05b2f211bd1b831b9d2962859323063
> Author: Harish Patil <harish.patil@cavium.com>
> Date: Wed Nov 8 22:52:20 2017 -0800
>
> net/qede: fix default config option
>
> Restore the default configuration as in previous releases and
> add a debug msg.
>
> Fixes: f07aa795c92a ("net/qede: disable per-VF Tx switching feature")
> Cc: stable@dpdk.org
>
> Signed-off-by: Harish Patil <harish.patil@cavium.com>
> Signed-off-by: Rasesh Mody <rasesh.mody@cavium.com>
>
>
>
> We need to include these two patches as well.
Now they were included. Thanks!
--yliu
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [dpdk-announce] DPDK 17.08.1 released
@ 2017-12-07 15:47 1% Yuanhan Liu
0 siblings, 0 replies; 200+ results
From: Yuanhan Liu @ 2017-12-07 15:47 UTC (permalink / raw)
To: announce
Hi all,
Here is a new stable release:
http://fast.dpdk.org/rel/dpdk-17.08.1.tar.xz
The git tree is at:
http://dpdk.org/browse/dpdk-stable/
Thanks.
--yliu
---
app/test-crypto-perf/cperf_options_parsing.c | 20 +-
app/test-crypto-perf/cperf_test_vector_parsing.c | 55 +++
app/test-crypto-perf/cperf_test_verify.c | 5 +
app/test-pmd/cmdline.c | 4 +-
app/test-pmd/config.c | 53 ++-
app/test-pmd/parameters.c | 18 +-
app/test-pmd/testpmd.c | 22 +-
config/common_base | 1 +
doc/guides/nics/features/enic.ini | 1 +
doc/guides/rel_notes/release_17_08.rst | 201 ++++++++
drivers/crypto/aesni_gcm/aesni_gcm_pmd.c | 2 +-
drivers/crypto/aesni_gcm/aesni_gcm_pmd_ops.c | 2 +-
drivers/crypto/aesni_mb/rte_aesni_mb_pmd.c | 7 +-
drivers/crypto/aesni_mb/rte_aesni_mb_pmd_ops.c | 4 +-
drivers/crypto/armv8/rte_armv8_pmd_ops.c | 2 +-
drivers/crypto/dpaa2_sec/dpaa2_sec_dpseci.c | 11 +-
drivers/crypto/kasumi/rte_kasumi_pmd_ops.c | 2 +-
drivers/crypto/null/null_crypto_pmd_ops.c | 2 +-
drivers/crypto/openssl/rte_openssl_pmd.c | 15 +-
drivers/crypto/openssl/rte_openssl_pmd_ops.c | 2 +-
drivers/crypto/qat/qat_crypto_capabilities.h | 24 +-
drivers/crypto/snow3g/rte_snow3g_pmd_ops.c | 2 +-
drivers/crypto/zuc/rte_zuc_pmd_ops.c | 2 +-
drivers/net/ark/ark_ethdev.c | 2 +-
drivers/net/bnxt/bnxt.h | 4 +-
drivers/net/bnxt/bnxt_cpr.c | 2 +
drivers/net/bnxt/bnxt_ethdev.c | 41 +-
drivers/net/bnxt/bnxt_hwrm.c | 525 +++++++++++++--------
drivers/net/bnxt/bnxt_hwrm.h | 2 +-
drivers/net/bnxt/bnxt_irq.c | 11 +-
drivers/net/bnxt/bnxt_ring.c | 4 +-
drivers/net/bnxt/bnxt_rxq.c | 199 ++++----
drivers/net/bnxt/bnxt_rxr.c | 47 +-
drivers/net/bnxt/bnxt_rxr.h | 16 +
drivers/net/bnxt/bnxt_stats.c | 6 +-
drivers/net/bnxt/bnxt_txr.c | 32 +-
drivers/net/bnxt/bnxt_txr.h | 21 +
drivers/net/bnxt/rte_pmd_bnxt.c | 18 +-
drivers/net/bonding/rte_eth_bond_api.c | 9 +-
drivers/net/bonding/rte_eth_bond_args.c | 35 +-
drivers/net/bonding/rte_eth_bond_pmd.c | 46 +-
drivers/net/cxgbe/base/t4_hw.c | 3 +
drivers/net/dpaa2/dpaa2_ethdev.c | 4 +-
drivers/net/dpaa2/dpaa2_rxtx.c | 41 +-
drivers/net/e1000/igb_ethdev.c | 18 +-
drivers/net/enic/base/vnic_dev.c | 10 +-
drivers/net/enic/enic_ethdev.c | 43 ++
drivers/net/enic/enic_main.c | 13 +-
drivers/net/enic/enic_rxtx.c | 25 +-
drivers/net/failsafe/failsafe_args.c | 32 +-
drivers/net/failsafe/failsafe_eal.c | 28 +-
drivers/net/failsafe/failsafe_ether.c | 1 +
drivers/net/failsafe/failsafe_ops.c | 118 -----
drivers/net/failsafe/failsafe_private.h | 9 +-
drivers/net/failsafe/failsafe_rxtx.c | 3 +-
drivers/net/i40e/i40e_ethdev.c | 117 +++--
drivers/net/i40e/i40e_ethdev.h | 4 +-
drivers/net/i40e/i40e_ethdev_vf.c | 151 +++++-
drivers/net/i40e/i40e_pf.c | 19 +-
drivers/net/i40e/i40e_rxtx.c | 110 +++--
drivers/net/i40e/i40e_rxtx_vec_neon.c | 19 +-
drivers/net/i40e/i40e_tm.c | 102 ++--
drivers/net/ixgbe/ixgbe_ethdev.c | 69 ++-
drivers/net/ixgbe/ixgbe_fdir.c | 3 +-
drivers/net/ixgbe/ixgbe_flow.c | 29 +-
drivers/net/ixgbe/ixgbe_rxtx.c | 41 +-
drivers/net/ixgbe/ixgbe_tm.c | 91 ++--
drivers/net/kni/rte_eth_kni.c | 2 -
drivers/net/liquidio/lio_ethdev.c | 1 +
drivers/net/mlx5/mlx5.c | 10 +-
drivers/net/mlx5/mlx5_ethdev.c | 28 +-
drivers/net/mlx5/mlx5_rxq.c | 6 +-
drivers/net/mlx5/mlx5_rxtx.c | 68 +--
drivers/net/mlx5/mlx5_rxtx.h | 2 +-
drivers/net/mlx5/mlx5_rxtx_vec_sse.c | 21 +-
drivers/net/mlx5/mlx5_stats.c | 11 +-
drivers/net/nfp/nfp_net.c | 25 +-
drivers/net/pcap/rte_eth_pcap.c | 2 +
drivers/net/qede/Makefile | 5 +-
drivers/net/qede/base/ecore.h | 1 +
drivers/net/qede/base/ecore_cxt.c | 32 +-
drivers/net/qede/base/ecore_dev.c | 5 +-
drivers/net/qede/base/ecore_int.c | 1 -
drivers/net/qede/base/ecore_mcp.c | 2 +-
drivers/net/qede/base/ecore_sriov.c | 9 +-
drivers/net/qede/qede_ethdev.c | 57 ++-
drivers/net/qede/qede_ethdev.h | 4 -
drivers/net/qede/qede_rxtx.c | 225 +++++++--
drivers/net/qede/qede_rxtx.h | 23 +-
drivers/net/sfc/base/efx_filter.c | 4 +-
drivers/net/sfc/sfc.c | 8 +-
drivers/net/sfc/sfc_rx.c | 26 +-
drivers/net/tap/rte_eth_tap.c | 146 ++++--
drivers/net/tap/rte_eth_tap.h | 2 +-
drivers/net/tap/tap_flow.c | 3 +-
drivers/net/virtio/virtio_ethdev.c | 54 ++-
drivers/net/virtio/virtio_ethdev.h | 6 +
drivers/net/virtio/virtio_rxtx.c | 46 +-
drivers/net/virtio/virtio_rxtx_simple.c | 2 +
drivers/net/virtio/virtio_user/vhost_kernel_tap.c | 4 +-
drivers/net/virtio/virtio_user/vhost_user.c | 4 +
drivers/net/virtio/virtio_user_ethdev.c | 6 +-
drivers/net/vmxnet3/vmxnet3_ethdev.c | 6 +-
drivers/net/vmxnet3/vmxnet3_rxtx.c | 18 +-
examples/ipsec-secgw/esp.c | 8 +-
examples/ipsec-secgw/ipip.h | 3 +-
examples/ipsec-secgw/ipsec-secgw.c | 13 +-
examples/ipsec-secgw/ipsec.c | 8 +-
examples/ipsec-secgw/ipsec.h | 1 +
examples/ipsec-secgw/sa.c | 3 +-
examples/l2fwd-crypto/main.c | 3 +-
examples/l3fwd/l3fwd_neon.h | 3 +-
examples/multi_process/l2fwd_fork/main.c | 5 +-
examples/multi_process/simple_mp/main.c | 4 +-
examples/multi_process/simple_mp/mp_commands.c | 2 +-
examples/multi_process/simple_mp/mp_commands.h | 1 -
examples/qos_sched/init.c | 2 +
examples/vhost_scsi/scsi.c | 4 +-
lib/librte_cryptodev/rte_crypto.h | 1 +
lib/librte_eal/common/arch/arm/rte_cpuflags.c | 2 +-
lib/librte_eal/common/arch/ppc_64/rte_cpuflags.c | 2 +-
lib/librte_eal/common/eal_common_log.c | 3 +-
.../common/include/arch/x86/rte_atomic_32.h | 2 +-
lib/librte_eal/common/include/rte_bus.h | 2 +-
lib/librte_eal/common/include/rte_version.h | 2 +-
lib/librte_eal/common/malloc_elem.c | 8 +-
lib/librte_eal/common/malloc_elem.h | 4 +-
lib/librte_eal/common/rte_service.c | 2 +-
lib/librte_eal/linuxapp/eal/eal.c | 4 +-
lib/librte_eal/linuxapp/eal/eal_vfio.c | 15 +-
lib/librte_eal/linuxapp/eal/eal_vfio_mp_sync.c | 3 +-
lib/librte_eal/linuxapp/igb_uio/igb_uio.c | 2 -
lib/librte_eal/linuxapp/kni/ethtool/igb/kcompat.h | 24 +-
lib/librte_ether/Makefile | 2 +-
lib/librte_ether/rte_ethdev.c | 25 +-
lib/librte_gro/rte_gro_version.map | 4 +-
lib/librte_hash/rte_cuckoo_hash.c | 13 +-
lib/librte_lpm/rte_lpm6.c | 2 +-
lib/librte_net/rte_net.c | 1 +
lib/librte_timer/rte_timer.c | 2 +-
lib/librte_vhost/fd_man.c | 5 +-
lib/librte_vhost/vhost_user.c | 6 +
pkg/dpdk.spec | 2 +-
test/test/test_cryptodev.c | 2 +-
test/test/test_cryptodev_blockcipher.c | 4 +-
test/test/test_cryptodev_perf.c | 4 +-
test/test/test_link_bonding_mode4.c | 2 +-
test/test/test_malloc.c | 12 +-
148 files changed, 2501 insertions(+), 1176 deletions(-)
---
Aaron Conole (1):
net/enic: fix assignment
Ajit Khaparde (28):
net/bnxt: fix HWRM macros and locking
net/bnxt: use 64-bits of address for VLAN table
net/bnxt: fix an issue with group id calculation
net/bnxt: fix calculation of number of pools
net/bnxt: handle multi queue mode properly
net/bnxt: fix Rx handling and buffer allocation logic
net/bnxt: fix an issue with broadcast traffic
net/bnxt: fix usage of VMDq flags
net/bnxt: set checksum offload flags correctly
net/bnxt: update status of Rx IP/L4 CKSUM
net/bnxt: fix config RSS update
net/bnxt: set the hash key size
net/bnxt: fix per queue stats display in xstats
net/bnxt: fix interrupt handler
net/bnxt: fix number of MAC addresses for VMDq
net/bnxt: fix the association of a MACVLAN per VNIC
net/bnxt: fix Tx offload capability
net/bnxt: fix Rx offload capability
net/bnxt: handle Rx multi queue creation properly
net/bnxt: remove redundant code parsing pool map
net/bnxt: fix a bit shift operation
net/bnxt: fix a potential null pointer dereference
net/bnxt: fix a potential null pointer dereference
net/bnxt: fix a pointer deref before null check
net/bnxt: fix an unused value
net/bnxt: check VLANs from pool map only for VMDq
net/bnxt: do not set hash type unnecessarily
net/bnxt: fix VLAN spoof configuration
Akhil Goyal (2):
test/crypto: fix dpaa2 sec macros and definitions
net/dpaa2: set queues after reconfiguration
Alejandro Lucero (2):
net/nfp: fix RSS
net/nfp: fix Rx interrupt when multiqueue
Alok Makhariya (2):
crypto/dpaa2_sec: remove ICV memset on decryption side
crypto/dpaa2_sec: add check for segmented buffer
Anatoly Burakov (1):
vfio: fix secondary process initialization
Andrey Chilikin (1):
net/i40e: fix flexible payload configuration
Aviad Yehezkel (4):
examples/ipsec-secgw: fix crypto device mapping
examples/ipsec-secgw: fix session creation
examples/ipsec-secgw: fix AAD length setting
app/testpmd: fix build without ixgbe and bnxt PMDs
Beilei Xing (1):
net/i40e: fix VF device stop issue
Chas Williams (1):
net/vmxnet3: fix memory leak when releasing queues
Congwen Zhang (1):
net/cxgbe: fix memory leak
Daniel Mrzyglod (3):
net/virtio: fix untrusted scalar value
app/testpmd: fix DDP package filesize detection
net/bonding: fix default aggregator mode to stable
David Harton (2):
net/vmxnet3: fix MAC address set
net/i40e: fix i40evf MAC filter table
Ferruh Yigit (4):
ethdev: fix ABI version
ethdev: revert use port name from device structure
igb_uio: remove device reset in open
net/qede: fix icc build
Gaetan Rivet (1):
net/failsafe: fix errno set on command execution
Gowrishankar Muthukrishnan (1):
net/bonding: support bifurcated driver in eal
Guduri Prathyusha (2):
examples/l3fwd: fix NEON instructions
examples/l3fwd: fix aliasing in port grouping
Harish Patil (4):
net/qede: fix supported packet types
net/qede: fix to re-enable LRO during device start
net/qede: disable per-VF Tx switching feature
net/qede: fix default config option
Hemant Agrawal (3):
net/dpaa2: fix the Tx handling of non HW pool bufs
examples/l2fwd-crypto: fix uninitialized errno value
app/crypto-perf: fix uninitialized errno value
Ian Stokes (1):
cryptodev: fix build with -Ofast
Ivan Malov (2):
net/sfc: specify correct scale table size on Rx start
net/sfc: fix unused variable in RSS-agnostic build
Jacek Piasecki (1):
examples/vhost_scsi: fix product id string termination
Jasvinder Singh (1):
examples/qos_sched: fix uninitialized config
Jerin Jacob (1):
timer: use 64-bit specific code on more platforms
Jianbo Liu (1):
net/i40e: fix Rx packets number for NEON
Jiayu Hu (1):
gro: fix typo in map file
Jingjing Wu (4):
net/i40e: fix interrupt throttling setting in PF
net/i40e: fix memory leak if VF init fails
net/i40e: fix variable assignment
net/i40e: fix VF initialization error
John Daley (3):
net/enic: fix multi-process operation
net/enic: fix packet loss after MTU change
net/enic: fix TSO for packets greater than 9208 bytes
John Miller (1):
net/ark: fix loop counter
Kuba Kozak (2):
vfio: fix close unchecked file descriptor
vhost: check poll error code
Li Han (1):
app/testpmd: fix invalid port id parameters
Lukasz Majczak (1):
eal: fix auxv open check for ARM and PPC
Mark Spender (1):
net/sfc/base: fix default RSS context check on Siena
Matan Azrad (7):
net/failsafe: fix Tx sub device deactivating
net/mlx5: fix locking in xstats functions
net/failsafe: fix parameters parsing
net/mlx5: fix probe failure report
net/failsafe: fix adding MAC error report miss
app/testpmd: fix forward port ids setting
net/failsafe: fix Rx clean race
Maxime Coquelin (1):
vhost: fix dereferencing invalid pointer after realloc
Michal Jastrzebski (1):
net/vmxnet3: fix dereference before null check
Nikhil Rao (1):
eal/x86: fix atomic cmpset
Nirmoy Das (1):
kni: fix SLE version detection
Nélio Laranjeiro (4):
net/mlx5: fix clang build
net/mlx5: fix SSE Rx support verification
net/mlx5: fix clang compilation error
app/testpmd: fix RSS structure initialisation
Olivier Matz (12):
net: fix inner L2 length in packet type parser
net/bnxt: fix compilation with -Og
net/qede: fix compilation with -Og
app/test-crypto-perf: fix memory leak
app/test-crypto-perf: fix compilation with -Og
net/virtio: revert not claiming LRO support
net/virtio: revert not claiming IP checksum offload
net/virtio: fix log levels in configure
net/virtio: fix mbuf port for simple Rx function
net/virtio: fix queue setup consistency
net/virtio: fix compilation with -Og
lpm6: fix compilation with -Og
Ophir Munk (3):
net/tap: fix flow and port commands
net/failsafe: fix VLAN stripping configuration
app/testpmd: fix forwarding between non consecutive ports
Pablo de Lara (8):
hash: fix eviction counter
crypto/aesni_gcm: fix zero data operation
app/crypto-perf: fix packet length check
app/crypto-perf: parse AEAD data from vectors
crypto/openssl: fix AEAD parameters
examples/l2fwd-crypto: fix physical address setting
crypto/qat: fix HMAC supported digest sizes
app/testpmd: fix topology error message
Patrick MacArthur (1):
eal: copy raw strings taken from command line
Phil Yang (1):
app/testpmd: fix quitting in container
Qi Zhang (4):
net/i40e: fix flow control watermark mismatch
net/i40e: fix packet count for PF
net/i40e: fix mbuf free in vector Tx
net/i40e: fix mirror with firmware 6.0
Rami Rosen (1):
net/kni: remove driver struct forward declaration
Rasesh Mody (4):
net/qede/base: fix to use a passed ptt handle
net/qede/base: fix return code to align with FW
net/qede: remove duplicate includes
net/qede/base: fix division by zero
Raslan Darawsheh (2):
net/failsafe: fix failsafe bus uninit return value
net/failsafe: fix PCI devices init
RongQiang Xie (2):
net/enic: fix possible null pointer dereference
net/qede: fix possible null pointer dereference
Sebastian Basierski (3):
net/vmxnet3: fix unintentional integer overflow
net/virtio-user: fix TAP name string termination
net/virtio: check error on setting non block flag
Sergio Gonzalez Monroy (1):
crypto/aesni_mb: fix invalid session error
Shahaf Shuler (5):
net/mlx5: fix num seg assumption in SSE Tx
net/mlx5: fix Tx stats error counter definition
net/mlx5: fix Tx stats error counter logic
net/mlx5: fix TSO segment size verification
net/mlx5: fix packet type flags for Ethernet only frame
Stefan Baranoff (1):
net/pcap: fix memory leak in dumper open
Stephen Hemminger (1):
eal: initialize logging before bus
Tiwei Bie (1):
net/virtio: flush Rx queues on start
Tomasz Duszynski (3):
drivers/crypto: use snprintf return value correctly
examples/ipsec-secgw: fix IP version check
examples/ipsec-secgw: fix IPv6 payload length
Tomasz Kulasek (3):
net/bonding: fix slaves capacity check
net/i40e: fix assignment of enum values
net/bonding: fix check slaves link properties
Vipin Varghese (1):
net/tap: fix unregistering callback with invalid fd
Wei Dai (8):
net/ixgbe: fix mapping of user priority to TC
net/ixgbe: fix adding a mirror rule
net/i40e: fix mirror rule reset when port is closed
net/ixgbe: fix Rx queue interrupt mapping in VF
net/ixgbe: fix VFIO interrupt mapping in VF
net/ixgbe: fix PF DCB info
app/testpmd: fix mapping of user priority to DCB TC
net/i40e: fix VFIO interrupt mapping in VF
Wei Zhao (4):
net/ixgbe: fix MAC VLAN filter fail problem
net/i40e: fix clear xstats bug in VF
app/testpmd: fix packet throughput after stats reset
net/ixgbe: fix filter parser for L2 tunnel
Wenzhuo Lu (7):
net/i40e: fix TM node parameter checking
net/i40e: fix TM level capability getting
net/ixgbe: fix TM node parameter checking
net/ixgbe: fix TM level capability getting
net/i40e: fix not supporting NULL TM profile
net/ixgbe: fix not supporting NULL TM profile
net/i40e: fix parent when adding TM node
Xiaoyun Li (2):
net/i40e: fix PF notify issue when VF is not up
net/igb: fix Rx interrupt with VFIO and MSI-X
Xueming Li (5):
net/mlx5: fix tunnel offload detection
mem: fix malloc debug config
mem: fix malloc element free in debug mode
examples/l2fwd_fork: fix message pool init
examples/multi_process: fix received message length
Yi Yang (1):
service: fix build with gcc 4.9
Yong Wang (4):
net/liquidio: fix uninitialized variable
net/igb: fix memcpy length
net/i40e: fix uninitialized variable
net/ixgbe: fix uninitialized variable
Yongseok Koh (3):
net/mlx5: fix calculating TSO inline size
net/mlx5: fix overflow of Rx SW ring
net/mlx5: fix tunneled TCP/UDP packet type
Yuanhan Liu (2):
Revert "net/virtio: flush Rx queues on start"
version: 17.08.1
Zhiyong Yang (2):
test: fix assignment operation
net/virtio: fix Tx packet length stats
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH] doc: announce ABI change for ring structure
@ 2017-12-08 14:14 4% ` Olivier MATZ
2017-12-08 17:01 7% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Olivier MATZ @ 2017-12-08 14:14 UTC (permalink / raw)
To: dev
Cc: bruce.richardson, john.mcnamara, daniel.verkamp,
konstantin.ananyev, Thomas Monjalon
Hi,
On Mon, Sep 11, 2017 at 03:39:13PM +0200, Olivier Matz wrote:
> As discussed on the mailing list, the alignment constraint of
> the ring structure can be relaxed.
>
> Link: http://dpdk.org/dev/patchwork/patch/25039
> Link: http://dpdk.org/dev/patchwork/patch/26103
>
> Signed-off-by: Olivier Matz <olivier.matz@6wind.com>
> ---
> doc/guides/rel_notes/deprecation.rst | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 3362f3350..5a63c0277 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -120,3 +120,9 @@ Deprecation Notices
> The non-"do-sig" versions of the hash tables will be removed
> (including the ``signature_offset`` parameter)
> and the "do-sig" versions renamed accordingly.
> +
> +* ring: The alignment constraints on the ring structure will be relaxed
> + to one cache line instead of two, and an empty cache line padding will
> + be added between the producer and consumer structures. The size of the
> + structure and the offset of the fields will remain the same on
> + platforms with 64B cache line, but will change on other platforms.
> --
> 2.11.0
>
It looks this patch was forgotten.
It has 3 acks but was not integrated in 17.11.
Or did I miss something?
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] doc: announce ABI change for ring structure
2017-12-08 14:14 4% ` Olivier MATZ
@ 2017-12-08 17:01 7% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2017-12-08 17:01 UTC (permalink / raw)
To: Olivier MATZ
Cc: dev, bruce.richardson, john.mcnamara, daniel.verkamp, konstantin.ananyev
08/12/2017 15:14, Olivier MATZ:
> > +* ring: The alignment constraints on the ring structure will be relaxed
> > + to one cache line instead of two, and an empty cache line padding will
> > + be added between the producer and consumer structures. The size of the
> > + structure and the offset of the fields will remain the same on
> > + platforms with 64B cache line, but will change on other platforms.
>
> It looks this patch was forgotten.
> It has 3 acks but was not integrated in 17.11.
> Or did I miss something?
It seems I missed something. Sorry about that.
The release 18.02 should be ABI stable.
While happy to experiment such stability on one release,
it seems I forgot to notify you on this thread.
Sorry again
^ permalink raw reply [relevance 7%]
* [dpdk-dev] [PATCHv2 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-01 18:56 4% [dpdk-dev] [PATCH 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
2017-12-01 18:56 5% ` [dpdk-dev] [PATCH 2/4] compat: Add __experimental macro Neil Horman
@ 2017-12-08 17:14 4% ` Neil Horman
2017-12-08 17:14 5% ` [dpdk-dev] [PATCHv2 2/4] compat: Add __experimental macro Neil Horman
2017-12-11 19:36 4% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
2017-12-13 15:17 4% ` [dpdk-dev] [PATCHv4 " Neil Horman
3 siblings, 1 reply; 200+ results
From: Neil Horman @ 2017-12-08 17:14 UTC (permalink / raw)
To: dev
Hey all-
A few days ago, I was lamenting the fact that, when reviewing patches I
would frequently complain about ABI changes that were actually considered safe
because they were part of the EXPERIMENTAL api set. John M. asked me then what
I might do to improve the situation, and the following patch set is a proposal
that I've come up with.
In thinking about the problem I identified two issues that I think we
can improve on in this area:
1) Make experimental api calls more visible in the source code. That is to say,
when reviewing patches, it would be nice to have some sort of visual reference
that indicates that the changes being made are part of an experimental API and
therefore ABI concerns need not be addressed
2) Make experimenal api usage more visible to consumers of the DPDK, so that
they can make a more informed decision about the API's they consume in their
application. We make an effort to document all the experimental API's, but
there is no guarantee that a user will check the documentation before making use
of a new library.
This patch set attempts to achieve both of the above goals. To do this I've
added an __experimental macro tag, suitable for inserting into api forward
declarations and definitions.
The presence of the tag in the header and c files where the api code resides
increases the likelyhood that any patch submitted against them will include the
tag in the context, making it clear to reviewers that ABI stability isn't a
concern here.
Also, This tag marks each function it is used on with an attibute causing any
use of the fuction to emit a warning during the build
with a message indicating that the API call in question is not yet part of the
stable interface. Developers can then make an informed decision to suppress
that warning or not.
Because there is internal use of several experimental API's, this set also
includes a new override macro ALLOW_EXPERIMENTAL_FUNCTIONS to automatically
suprress these warnings. I think its fair to assume that, for internal use, we
almost always want to suppress these warnings, as by definition any change to
the apis (even their removal) must be done in parallel with an appropriate
change in the calling locations, lest the dpdk build itself break.
Neil
---
Change Notes:
v2)
* Cleaned up checkpatch errors
* Added Allowance for building experimental on BSD
* Swapped Patch 3 and 4 so that we didn't have a commit level that issued
warnings/errors without need
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCHv2 2/4] compat: Add __experimental macro
2017-12-08 17:14 4% ` [dpdk-dev] [PATCHv2 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
@ 2017-12-08 17:14 5% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2017-12-08 17:14 UTC (permalink / raw)
To: dev; +Cc: Neil Horman, Thomas Monjalon, Mcnamara, John
The __experimental macro tags a given exported function as being part of
the EXPERIMENTAL api. Use of this tag will cause any caller of the
function (that isn't removed by dead code elimination) to emit a warning
that the user is making use of an API whos stabilty isn't guaranteed.
It also places the function in the .text.experimental section, which is
used to validate the tag against the corresponding library version map
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Thomas Monjalon <thomas@monjalon.net>
CC: "Mcnamara, John" <john.mcnamara@intel.com>
---
lib/librte_compat/rte_compat.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/lib/librte_compat/rte_compat.h b/lib/librte_compat/rte_compat.h
index 41e8032ba..3365a0345 100644
--- a/lib/librte_compat/rte_compat.h
+++ b/lib/librte_compat/rte_compat.h
@@ -101,5 +101,8 @@
*/
#endif
+#define __experimental \
+__attribute__((deprecated("Symbol is not yet part of stable abi"), \
+section(".text.experimental")))
#endif /* _RTE_COMPAT_H_ */
--
2.14.3
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] Guidelines for moving PMDs to new ethdev offloads API
@ 2017-12-10 5:52 3% ` Stephen Hemminger
2017-12-10 6:04 0% ` Shahaf Shuler
0 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2017-12-10 5:52 UTC (permalink / raw)
To: Shahaf Shuler; +Cc: dev
On Sun, 10 Dec 2017 05:35:45 +0000
Shahaf Shuler <shahafs@mellanox.com> wrote:
> In 17.11 the ethdev offloads API has changed:
>
> commit cba7f53b717d ("ethdev: introduce Tx queue offloads API")
>
> commit ce17eddefc20 ("ethdev: introduce Rx queue offloads API") The new API is documented in the programmer's guide:
>
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdpdk.org%2Fdoc%2Fguides%2Fprog_guide%2Fpoll_mode_drv.html%23hardware-offload&data=02%7C01%7Cshahafs%40mellanox.com%7Cc365451c3f934b73db5e08d53f6fe6fd%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C0%7C636484672216209911&sdata=l0OkZ8m78BMsw%2F0d7bA8m80gVqlSL%2Bpcs9UplVSmlOA%3D&reserved=0
>
>
>
> As announced in the deprecation notice, the old API is planned to be removed in 18.05:
>
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdpdk.org%2Fdoc%2Fguides%2Frel_notes%2Fdeprecation.html&data=02%7C01%7Cshahafs%40mellanox.com%7Cc365451c3f934b73db5e08d53f6fe6fd%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C0%7C636484672216209911&sdata=85wB%2BoU3um%2BXegYiLAJIDYWIkvpb9WQtPSgA73zsLHI%3D&reserved=0
>
> As agreed, all the PMDs must be converted to the new API by their maintainers.
>
> This email will better explain the transition process.
>
>
>
> The main concepts in the new API are:
>
> - All offloads are disabled by default
>
> - Distinction between per port and per queue offloads.
>
> Per port offloads needs to be set also for each queue of the port.
>
>
>
> The transition period is using an API translation in rte_ethdev.c:
>
> - The old API is translated to allow using converted PMDs
>
> - The new API is translated to allow using not converted PMDs
>
> - The use of the new API is flagged to trigger the right translation
>
>
>
> * Device capabilities - rte_eth_dev_info_get()
>
> - Not changing: use DEV_RX/TX_OFFLOAD_* flags
>
> - Old API: per-port fields rte_eth_dev_info.rx/tx_offload_capa
>
> - New API: added per-queue rte_eth_dev_info.rx/tx_queue_offload_capa
>
>
>
> * Rx offloads
>
> - Not changing: offload disabled by default
>
> - Old API: per-port rte_eth_conf.rxmode.[bit-fields]
>
> - New API: per-port rte_eth_conf.rxmode.offloads and per queue rte_eth_rxconf.offloads using DEV_RX_OFFLOAD_*
>
> - Transition: rte_eth_conf.rxmode.ignore_offload_bitfield must be set
>
> when using the new API (Done by application)
>
> - To be removed: rte_eth_conf.rxmode.[
>
> header_split, hw_ip_checksum, hw_vlan_filter, hw_vlan_strip,
>
> hw_vlan_extend, jumbo_frame, hw_strip_crc, enable_scatter,
>
> enable_lro, hw_timestamp, security]
>
>
>
> * Tx offloads
>
> - Old API: enabled by default
>
> per-queue rte_eth_txconf.txq_flags using ETH_TXQ_FLAGS_NO*
>
> - New API: disabled by default
>
> per-port rte_eth_conf.txmode.offloads and per queue rte_eth_txconf.offloads using DEV_TX_OFFLOAD_*
>
> - Transition: ETH_TXQ_FLAGS_IGNORE must be set when using the new API (Done by application)
>
> PMD should ignore port offloads not set on the device configuration when using old API
>
> - To be removed: rte_eth_txconf.txq_flags and ETH_TXQ_FLAGS_NO*
>
>
> --Shahaf
>
I agree with this change. but how can it be done with out breaking ABI?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] Guidelines for moving PMDs to new ethdev offloads API
2017-12-10 5:52 3% ` Stephen Hemminger
@ 2017-12-10 6:04 0% ` Shahaf Shuler
0 siblings, 0 replies; 200+ results
From: Shahaf Shuler @ 2017-12-10 6:04 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: dev
Sunday, December 10, 2017 7:52 AM, Stephen Hemminger:
>
> On Sun, 10 Dec 2017 05:35:45 +0000
> Shahaf Shuler <shahafs@mellanox.com> wrote:
>
> > In 17.11 the ethdev offloads API has changed:
> >
> > commit cba7f53b717d ("ethdev: introduce Tx queue offloads API")
> >
> > commit ce17eddefc20 ("ethdev: introduce Rx queue offloads API")
> The new API is documented in the programmer's guide:
> >
> >
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdpd
> k.org%2Fdoc%2Fguides%2Fprog_guide%2Fpoll_mode_drv.html%23hardwar
> e-
> offload&data=02%7C01%7Cshahafs%40mellanox.com%7Cc365451c3f934b73d
> b5e08d53f6fe6fd%7Ca652971c7d2e4d9ba6a4d149256f461b%7C0%7C0%7C636
> 484672216209911&sdata=l0OkZ8m78BMsw%2F0d7bA8m80gVqlSL%2Bpcs9Up
> lVSmlOA%3D&reserved=0
> >
> >
> >
> > As announced in the deprecation notice, the old API is planned to be
> removed in 18.05:
> >
> >
> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fdpd
> k.org%2Fdoc%2Fguides%2Frel_notes%2Fdeprecation.html&data=02%7C01%
> 7Cshahafs%40mellanox.com%7Cc365451c3f934b73db5e08d53f6fe6fd%7Ca65
> 2971c7d2e4d9ba6a4d149256f461b%7C0%7C0%7C636484672216209911&sdata
> =85wB%2BoU3um%2BXegYiLAJIDYWIkvpb9WQtPSgA73zsLHI%3D&reserved=
> 0
> >
[.. ]
>
> I agree with this change. but how can it be done with out breaking ABI?
Not sure I understand.
The new API has already been accepted on 17.11.
you mean the deprecation in 18.05? This also been accepted during 17.11 release.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] examples/ipsec-secgw: fix usage of incorrect port
2017-12-06 11:08 3% ` Anoob
@ 2017-12-11 10:26 0% ` Radu Nicolau
2017-12-11 10:38 0% ` Anoob Joseph
0 siblings, 1 reply; 200+ results
From: Radu Nicolau @ 2017-12-11 10:26 UTC (permalink / raw)
To: Anoob, Akhil Goyal, Declan Doherty, Sergio Gonzalez Monroy,
Bruce Richardson
Cc: Narayana Prasad, Jerin Jacob, dev
Hi,
On 12/6/2017 11:08 AM, Anoob wrote:
> Hi Akhil,
>
> On 12/04/2017 01:19 PM, Akhil Goyal wrote:
>> Hi Anoob,
>> On 11/29/2017 9:51 AM, Anoob Joseph wrote:
>>> Hi Akhil,
>>>
>>>
>>> On 24-11-2017 16:19, Akhil Goyal wrote:
>>>> Hi Anoob,
>>>>
>>>> On 11/24/2017 3:28 PM, Anoob wrote:
>>>>>>> static inline void
>>>>>>> route4_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[],
>>>>>>> uint8_t nb_pkts)
>>>>>>> {
>>>>>>> uint32_t hop[MAX_PKT_BURST * 2];
>>>>>>> uint32_t dst_ip[MAX_PKT_BURST * 2];
>>>>>>> + int32_t pkt_hop = 0;
>>>>>>> uint16_t i, offset;
>>>>>>> + uint16_t lpm_pkts = 0;
>>>>>>> if (nb_pkts == 0)
>>>>>>> return;
>>>>>>> + /* Need to do an LPM lookup for non-offload packets.
>>>>>>> Offload packets
>>>>>>> + * will have port ID in the SA
>>>>>>> + */
>>>>>>> +
>>>>>>> for (i = 0; i < nb_pkts; i++) {
>>>>>>> - offset = offsetof(struct ip, ip_dst);
>>>>>>> - dst_ip[i] = *rte_pktmbuf_mtod_offset(pkts[i],
>>>>>>> - uint32_t *, offset);
>>>>>>> - dst_ip[i] = rte_be_to_cpu_32(dst_ip[i]);
>>>>>>> + if (!(pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD)) {
>>>>>>> + /* Security offload not enabled. So an LPM lookup is
>>>>>>> + * required to get the hop
>>>>>>> + */
>>>>>>> + offset = offsetof(struct ip, ip_dst);
>>>>>>> + dst_ip[lpm_pkts] = *rte_pktmbuf_mtod_offset(pkts[i],
>>>>>>> + uint32_t *, offset);
>>>>>>> + dst_ip[lpm_pkts] = rte_be_to_cpu_32(dst_ip[lpm_pkts]);
>>>>>>> + lpm_pkts++;
>>>>>>> + }
>>>>>>> }
>>>>>>> - rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip,
>>>>>>> hop, nb_pkts);
>>>>>>> + rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip, hop,
>>>>>>> lpm_pkts);
>>>>>>> +
>>>>>>> + lpm_pkts = 0;
>>>>>>> for (i = 0; i < nb_pkts; i++) {
>>>>>>> - if ((hop[i] & RTE_LPM_LOOKUP_SUCCESS) == 0) {
>>>>>>> + if (pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD) {
>>>>>>> + /* Read hop from the SA */
>>>>>>> + pkt_hop = get_hop_for_offload_pkt(pkts[i]);
>>>>>>> + } else {
>>>>>>> + /* Need to use hop returned by lookup */
>>>>>>> + pkt_hop = hop[lpm_pkts++];
>>>>>>> + if ((pkt_hop & RTE_LPM_LOOKUP_SUCCESS) == 0)
>>>>>>> + pkt_hop = -1;
>>>>>>> + }
>>>>>>> +
>>>>>> I believe the following check is redundant for non inline case. I
>>>>>> believe get_hop_for_offload_pkt can also set the
>>>>>> RTE_LPM_LOOKUP_SUCCESS if route is success and take the (pkt_hop
>>>>>> & RTE_LPM_LOOKUP_SUCCESS) == 0 check outside the if else block
>>>>>> and free the packet if it is unsuccessful.
>>>>>>
>>>>>> Same comment for route6_pkts. Checking with -1 may not be a good
>>>>>> idea if we have a flag available for the same.
>>>>>> Others can comment.
>>>>> The problem is ipv4 & ipv6 LPM lookups return different error
>>>>> values, but we are using a single routine to get the hop for
>>>>> offload packets. The flag(RTE_LPM_LOOKUP_SUCCESS) is only for ipv4
>>>>> lookups. For ipv6, error is -1. If we need a cleaner solution, we
>>>>> can have ipv4 & ipv6 variants of "get_hop_for_offload_pkt". But
>>>>> that would be repetition of some code.
>>>>
>>>> my concern over this patch is that there is an addition of an extra
>>>> check in the non inline case and we can get rid of that with some
>>>> changes in the code(lib/app). Regarding route6_pkts, the code looks
>>>> cleaner than route4_pkts
>>> If we have ipv4 and ipv6 variants of the
>>> "get_hop_for_offload_packet" function, the code would look much
>>> cleaner. Shall I update the patch with such a change and send v4?
>>
>> I believe we shall get rid of "RTE_LPM_LOOKUP_SUCCESS" from the
>> rte_lpm_lookup_bulk(), we shall have similar error flags for v4 and
>> v6 APIs. Either we can have RTE_LPM_LOOKUP_SUCCESS or -1 as check for
>> errors.
> This will call for an ABI change. And LPM library has multiple
> variants for v4 & v6 lookups. We will need to modify all such
> instances. I've CCed Bruce for his opinion on this matter. If
> maintainers can decide on how to address this properly, I can plan my
> next steps accordingly.
Maybe this alternative approach will help: change the
get_hop_for_offload_packet to return -1 for v6 and clear
RTE_LPM_LOOKUP_SUCCESS flag for v4 errors. This will be on the error
path so the extra code to check the pkt type will have no performance
impact, and the route function can be cleaner and we can lose the extra
if in the v4 one.
>> Sergio can comment on this.
>>
>> Duplicating code for get_hop_for_offload_packet may not be a good idea.
>>
>> -Akhil
>>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] examples/ipsec-secgw: fix usage of incorrect port
2017-12-11 10:26 0% ` Radu Nicolau
@ 2017-12-11 10:38 0% ` Anoob Joseph
0 siblings, 0 replies; 200+ results
From: Anoob Joseph @ 2017-12-11 10:38 UTC (permalink / raw)
To: Radu Nicolau, Akhil Goyal, Declan Doherty,
Sergio Gonzalez Monroy, Bruce Richardson
Cc: anoob.joseph, Narayana Prasad, Jerin Jacob, dev
Hi,
On 12/11/2017 03:56 PM, Radu Nicolau wrote:
> Hi,
>
>
> On 12/6/2017 11:08 AM, Anoob wrote:
>> Hi Akhil,
>>
>> On 12/04/2017 01:19 PM, Akhil Goyal wrote:
>>> Hi Anoob,
>>> On 11/29/2017 9:51 AM, Anoob Joseph wrote:
>>>> Hi Akhil,
>>>>
>>>>
>>>> On 24-11-2017 16:19, Akhil Goyal wrote:
>>>>> Hi Anoob,
>>>>>
>>>>> On 11/24/2017 3:28 PM, Anoob wrote:
>>>>>>>> static inline void
>>>>>>>> route4_pkts(struct rt_ctx *rt_ctx, struct rte_mbuf *pkts[],
>>>>>>>> uint8_t nb_pkts)
>>>>>>>> {
>>>>>>>> uint32_t hop[MAX_PKT_BURST * 2];
>>>>>>>> uint32_t dst_ip[MAX_PKT_BURST * 2];
>>>>>>>> + int32_t pkt_hop = 0;
>>>>>>>> uint16_t i, offset;
>>>>>>>> + uint16_t lpm_pkts = 0;
>>>>>>>> if (nb_pkts == 0)
>>>>>>>> return;
>>>>>>>> + /* Need to do an LPM lookup for non-offload packets.
>>>>>>>> Offload packets
>>>>>>>> + * will have port ID in the SA
>>>>>>>> + */
>>>>>>>> +
>>>>>>>> for (i = 0; i < nb_pkts; i++) {
>>>>>>>> - offset = offsetof(struct ip, ip_dst);
>>>>>>>> - dst_ip[i] = *rte_pktmbuf_mtod_offset(pkts[i],
>>>>>>>> - uint32_t *, offset);
>>>>>>>> - dst_ip[i] = rte_be_to_cpu_32(dst_ip[i]);
>>>>>>>> + if (!(pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD)) {
>>>>>>>> + /* Security offload not enabled. So an LPM lookup is
>>>>>>>> + * required to get the hop
>>>>>>>> + */
>>>>>>>> + offset = offsetof(struct ip, ip_dst);
>>>>>>>> + dst_ip[lpm_pkts] = *rte_pktmbuf_mtod_offset(pkts[i],
>>>>>>>> + uint32_t *, offset);
>>>>>>>> + dst_ip[lpm_pkts] =
>>>>>>>> rte_be_to_cpu_32(dst_ip[lpm_pkts]);
>>>>>>>> + lpm_pkts++;
>>>>>>>> + }
>>>>>>>> }
>>>>>>>> - rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip,
>>>>>>>> hop, nb_pkts);
>>>>>>>> + rte_lpm_lookup_bulk((struct rte_lpm *)rt_ctx, dst_ip, hop,
>>>>>>>> lpm_pkts);
>>>>>>>> +
>>>>>>>> + lpm_pkts = 0;
>>>>>>>> for (i = 0; i < nb_pkts; i++) {
>>>>>>>> - if ((hop[i] & RTE_LPM_LOOKUP_SUCCESS) == 0) {
>>>>>>>> + if (pkts[i]->ol_flags & PKT_TX_SEC_OFFLOAD) {
>>>>>>>> + /* Read hop from the SA */
>>>>>>>> + pkt_hop = get_hop_for_offload_pkt(pkts[i]);
>>>>>>>> + } else {
>>>>>>>> + /* Need to use hop returned by lookup */
>>>>>>>> + pkt_hop = hop[lpm_pkts++];
>>>>>>>> + if ((pkt_hop & RTE_LPM_LOOKUP_SUCCESS) == 0)
>>>>>>>> + pkt_hop = -1;
>>>>>>>> + }
>>>>>>>> +
>>>>>>> I believe the following check is redundant for non inline case.
>>>>>>> I believe get_hop_for_offload_pkt can also set the
>>>>>>> RTE_LPM_LOOKUP_SUCCESS if route is success and take the (pkt_hop
>>>>>>> & RTE_LPM_LOOKUP_SUCCESS) == 0 check outside the if else block
>>>>>>> and free the packet if it is unsuccessful.
>>>>>>>
>>>>>>> Same comment for route6_pkts. Checking with -1 may not be a good
>>>>>>> idea if we have a flag available for the same.
>>>>>>> Others can comment.
>>>>>> The problem is ipv4 & ipv6 LPM lookups return different error
>>>>>> values, but we are using a single routine to get the hop for
>>>>>> offload packets. The flag(RTE_LPM_LOOKUP_SUCCESS) is only for
>>>>>> ipv4 lookups. For ipv6, error is -1. If we need a cleaner
>>>>>> solution, we can have ipv4 & ipv6 variants of
>>>>>> "get_hop_for_offload_pkt". But that would be repetition of some
>>>>>> code.
>>>>>
>>>>> my concern over this patch is that there is an addition of an
>>>>> extra check in the non inline case and we can get rid of that with
>>>>> some changes in the code(lib/app). Regarding route6_pkts, the code
>>>>> looks cleaner than route4_pkts
>>>> If we have ipv4 and ipv6 variants of the
>>>> "get_hop_for_offload_packet" function, the code would look much
>>>> cleaner. Shall I update the patch with such a change and send v4?
>>>
>>> I believe we shall get rid of "RTE_LPM_LOOKUP_SUCCESS" from the
>>> rte_lpm_lookup_bulk(), we shall have similar error flags for v4 and
>>> v6 APIs. Either we can have RTE_LPM_LOOKUP_SUCCESS or -1 as check
>>> for errors.
>> This will call for an ABI change. And LPM library has multiple
>> variants for v4 & v6 lookups. We will need to modify all such
>> instances. I've CCed Bruce for his opinion on this matter. If
>> maintainers can decide on how to address this properly, I can plan my
>> next steps accordingly.
> Maybe this alternative approach will help: change the
> get_hop_for_offload_packet to return -1 for v6 and clear
> RTE_LPM_LOOKUP_SUCCESS flag for v4 errors. This will be on the error
> path so the extra code to check the pkt type will have no performance
> impact, and the route function can be cleaner and we can lose the
> extra if in the v4 one.
That should be fine I guess. So the get_hop_for_offload_packet will have
one more argument to specify whether it is ipv4 or ipv6, right?
I'll revise the patch with this suggestion.
>>> Sergio can comment on this.
>>>
>>> Duplicating code for get_hop_for_offload_packet may not be a good idea.
>>>
>>> -Akhil
>>>
>>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v1 0/8] Bus control framework
@ 2017-12-11 11:53 3% ` Shreyansh Jain
1 sibling, 0 replies; 200+ results
From: Shreyansh Jain @ 2017-12-11 11:53 UTC (permalink / raw)
To: Gaetan Rivet; +Cc: dev
Hello Gaetan,
(I am assuming that this series is still valid for 18.02 and you will
spin a new version of this.)
On Thursday 12 October 2017 01:48 PM, Gaetan Rivet wrote:
> Probing policy was introduced in the previous release as a configuration item.
> It was thus added to the generic bus structure, breaking its ABI.
>
> In this release, the IOVA mode can be read from a bus to configure the
> EAL. This new configuration element also broke the bus ABI when it was
> added.
>
> As new operators had to be implemented for the probe policy item, these
> patches were developed to help mitigate this issue.
>
> This control framework allows to expand the rte_bus API without breaking
> its ABI. It is meant to be used with configuration elements that may
> only be valid for a few buses, while the others would remain untouched
> and unaware of the evolution.
>
> A central control operator is used, similarly to the working of rte_flow
> API in the ether layer. Each driver thus chooses to expose a set of
> operators relevant to its implementation. The caller is then free to use
> those if they are available.
I like the overall idea - similar to an ioctl.
It would help extend the control knobs of buses (drivers?) without
adding additional dependency on ABI/API.
+1
>
> Both Probe mode and IOVA mode operators are implemented for the PCI bus. >
[...]
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v1 2/8] bus: introduce opaque control framework
@ 2017-12-11 12:00 0% ` Shreyansh Jain
2017-12-11 12:43 4% ` Gaëtan Rivet
0 siblings, 1 reply; 200+ results
From: Shreyansh Jain @ 2017-12-11 12:00 UTC (permalink / raw)
To: Gaetan Rivet; +Cc: dev
On Thursday 12 October 2017 01:48 PM, Gaetan Rivet wrote:
> New configuration elements are added to the buses. They make the ABI
> unstable and will continue to do so.
>
> This new control scheme allows to add new bus operators without
> breaking the ABI and by only expanding the API.
>
> This helps having more stability in core EAL subsystems, while allowing
> flexibility for future evolutions.
>
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---
> lib/librte_eal/common/eal_common_bus.c | 9 +++++++
> lib/librte_eal/common/include/rte_bus.h | 46 +++++++++++++++++++++++++++++++++
> 2 files changed, 55 insertions(+)
>
> diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
> index 3c66a02..65d7229 100644
> --- a/lib/librte_eal/common/eal_common_bus.c
> +++ b/lib/librte_eal/common/eal_common_bus.c
> @@ -42,6 +42,13 @@
> struct rte_bus_list rte_bus_list =
> TAILQ_HEAD_INITIALIZER(rte_bus_list);
>
> +static rte_bus_ctrl_t
> +rte_bus_default_ctrl(enum rte_bus_ctrl_op op __rte_unused,
> + enum rte_bus_ctrl_item item __rte_unused)
> +{
> + return NULL;
> +}
> +
> void
> rte_bus_register(struct rte_bus *bus)
> {
> @@ -53,6 +60,8 @@ rte_bus_register(struct rte_bus *bus)
> RTE_VERIFY(bus->find_device);
> /* Buses supporting driver plug also require unplug. */
> RTE_VERIFY(!bus->plug || bus->unplug);
> + if (bus->ctrl == NULL)
> + bus->ctrl = &rte_bus_default_ctrl;
>
> TAILQ_INSERT_TAIL(&rte_bus_list, bus, next);
> RTE_LOG(DEBUG, EAL, "Registered [%s] bus.\n", bus->name);
> diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
> index 331d954..bd3c28e 100644
> --- a/lib/librte_eal/common/include/rte_bus.h
> +++ b/lib/librte_eal/common/include/rte_bus.h
> @@ -183,6 +183,51 @@ struct rte_bus_conf {
> enum rte_bus_probe_mode probe_mode; /**< Probe policy. */
> };
>
> +/**
> + * Bus configuration items.
> + */
> +enum rte_bus_ctrl_item {
> + RTE_BUS_CTRL_PROBE_MODE = 0,
> + RTE_BUS_CTRL_ITEM_MAX,
> +};
I am assuming that a driver implementation can take more than ITEM_MAX
control knobs. It is opaque to the library. Are we on same page?
For example, a bus driver can implement:
rte_bus_XXX_ctrl_item {
<Leaving space for allowing rte_bus.h implementations>
RTE_BUS_XYZ_KNOB_1 = 100,
RTE_BUS_XYZ_KNOB_2,
RTE_BUS_XYZ_KNOB_3,
};
without the library knowing or restricting the API to RTE_BUS_CTRL_ITEM_MAX.
I see that in your code for PCI (Patch 5/8: pci_ctrl) you have
restricted the control knob to RTE_BUS_CTRL_ITEM_MAX.
I hope that such restrictions would not float to library layer.
If we are on same page, should this be documented as a code comment
somewhere?
if not, do you think what I am stating makes sense?
> +
> +/**
> + * Bus configuration operations.
> + */
> +enum rte_bus_ctrl_op {
> + RTE_BUS_CTRL_GET = 0,
> + RTE_BUS_CTRL_SET,
> + RTE_BUS_CTRL_RESET,
> + RTE_BUS_CTRL_OP_MAX,
> +};
Similarly, the driver implementation can choose to implement a operation
which is not defined in the above structures. Obviously, the application
is expected to know - it being a custom knob.
[...]
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v1 2/8] bus: introduce opaque control framework
2017-12-11 12:00 0% ` Shreyansh Jain
@ 2017-12-11 12:43 4% ` Gaëtan Rivet
2017-12-11 13:36 4% ` Shreyansh Jain
0 siblings, 1 reply; 200+ results
From: Gaëtan Rivet @ 2017-12-11 12:43 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: dev
On Mon, Dec 11, 2017 at 05:30:16PM +0530, Shreyansh Jain wrote:
> On Thursday 12 October 2017 01:48 PM, Gaetan Rivet wrote:
> > New configuration elements are added to the buses. They make the ABI
> > unstable and will continue to do so.
> >
> > This new control scheme allows to add new bus operators without
> > breaking the ABI and by only expanding the API.
> >
> > This helps having more stability in core EAL subsystems, while allowing
> > flexibility for future evolutions.
> >
> > Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> > ---
> > lib/librte_eal/common/eal_common_bus.c | 9 +++++++
> > lib/librte_eal/common/include/rte_bus.h | 46 +++++++++++++++++++++++++++++++++
> > 2 files changed, 55 insertions(+)
> >
> > diff --git a/lib/librte_eal/common/eal_common_bus.c b/lib/librte_eal/common/eal_common_bus.c
> > index 3c66a02..65d7229 100644
> > --- a/lib/librte_eal/common/eal_common_bus.c
> > +++ b/lib/librte_eal/common/eal_common_bus.c
> > @@ -42,6 +42,13 @@
> > struct rte_bus_list rte_bus_list =
> > TAILQ_HEAD_INITIALIZER(rte_bus_list);
> > +static rte_bus_ctrl_t
> > +rte_bus_default_ctrl(enum rte_bus_ctrl_op op __rte_unused,
> > + enum rte_bus_ctrl_item item __rte_unused)
> > +{
> > + return NULL;
> > +}
> > +
> > void
> > rte_bus_register(struct rte_bus *bus)
> > {
> > @@ -53,6 +60,8 @@ rte_bus_register(struct rte_bus *bus)
> > RTE_VERIFY(bus->find_device);
> > /* Buses supporting driver plug also require unplug. */
> > RTE_VERIFY(!bus->plug || bus->unplug);
> > + if (bus->ctrl == NULL)
> > + bus->ctrl = &rte_bus_default_ctrl;
> > TAILQ_INSERT_TAIL(&rte_bus_list, bus, next);
> > RTE_LOG(DEBUG, EAL, "Registered [%s] bus.\n", bus->name);
> > diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
> > index 331d954..bd3c28e 100644
> > --- a/lib/librte_eal/common/include/rte_bus.h
> > +++ b/lib/librte_eal/common/include/rte_bus.h
> > @@ -183,6 +183,51 @@ struct rte_bus_conf {
> > enum rte_bus_probe_mode probe_mode; /**< Probe policy. */
> > };
> > +/**
> > + * Bus configuration items.
> > + */
> > +enum rte_bus_ctrl_item {
> > + RTE_BUS_CTRL_PROBE_MODE = 0,
> > + RTE_BUS_CTRL_ITEM_MAX,
> > +};
>
> I am assuming that a driver implementation can take more than ITEM_MAX
> control knobs. It is opaque to the library. Are we on same page?
>
> For example, a bus driver can implement:
>
> rte_bus_XXX_ctrl_item {
> <Leaving space for allowing rte_bus.h implementations>
> RTE_BUS_XYZ_KNOB_1 = 100,
> RTE_BUS_XYZ_KNOB_2,
> RTE_BUS_XYZ_KNOB_3,
> };
>
> without the library knowing or restricting the API to RTE_BUS_CTRL_ITEM_MAX.
>
> I see that in your code for PCI (Patch 5/8: pci_ctrl) you have restricted
> the control knob to RTE_BUS_CTRL_ITEM_MAX.
> I hope that such restrictions would not float to library layer.
>
> If we are on same page, should this be documented as a code comment
> somewhere?
> if not, do you think what I am stating makes sense?
>
I see what you mean, but I'm not sure it would be a good thing.
Actually, I think proposing this ITEM_MAX was a mistake.
Regarding the specific bus knobs:
- If a single bus needs this knob, then it would be better for the dev
to add it as part of the bus' public API, following the correct
library versioning processes. This would not break this bus control
structure ABI.
- If more than one bus implement this knob, then it should be proposed
as part of the library API. Buses adding this new knob would break
their ABI, other buses would be left untouched.
This makes me realize that proposing this ITEM_MAX value is not good to
the intended purpose of this patchset:
- If a bus implementation use a reference to ITEM_MAX, then the control
structure ABI would be broken by any new control knob added, even if the
bus does not implement it. Granted, it would not break the driver
structure itself, but still. My PCI implementation is thus incorrect.
Therefore I think that it would be best to remove this ITEM_MAX altogether,
forcing bus developpers to use other ways that would not break their
ABIs every other release.
--
Gaëtan Rivet
6WIND
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v1 2/8] bus: introduce opaque control framework
2017-12-11 12:43 4% ` Gaëtan Rivet
@ 2017-12-11 13:36 4% ` Shreyansh Jain
2017-12-11 14:38 4% ` Gaëtan Rivet
0 siblings, 1 reply; 200+ results
From: Shreyansh Jain @ 2017-12-11 13:36 UTC (permalink / raw)
To: Gaëtan Rivet; +Cc: dev
On Monday 11 December 2017 06:13 PM, Gaëtan Rivet wrote:
> On Mon, Dec 11, 2017 at 05:30:16PM +0530, Shreyansh Jain wrote:
>> On Thursday 12 October 2017 01:48 PM, Gaetan Rivet wrote:
[...]
>>> diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
>>> index 331d954..bd3c28e 100644
>>> --- a/lib/librte_eal/common/include/rte_bus.h
>>> +++ b/lib/librte_eal/common/include/rte_bus.h
>>> @@ -183,6 +183,51 @@ struct rte_bus_conf {
>>> enum rte_bus_probe_mode probe_mode; /**< Probe policy. */
>>> };
>>> +/**
>>> + * Bus configuration items.
>>> + */
>>> +enum rte_bus_ctrl_item {
>>> + RTE_BUS_CTRL_PROBE_MODE = 0,
>>> + RTE_BUS_CTRL_ITEM_MAX,
>>> +};
>>
>> I am assuming that a driver implementation can take more than ITEM_MAX
>> control knobs. It is opaque to the library. Are we on same page?
>>
>> For example, a bus driver can implement:
>>
>> rte_bus_XXX_ctrl_item {
>> <Leaving space for allowing rte_bus.h implementations>
>> RTE_BUS_XYZ_KNOB_1 = 100,
>> RTE_BUS_XYZ_KNOB_2,
>> RTE_BUS_XYZ_KNOB_3,
>> };
>>
>> without the library knowing or restricting the API to RTE_BUS_CTRL_ITEM_MAX.
>>
>> I see that in your code for PCI (Patch 5/8: pci_ctrl) you have restricted
>> the control knob to RTE_BUS_CTRL_ITEM_MAX.
>> I hope that such restrictions would not float to library layer.
>>
>> If we are on same page, should this be documented as a code comment
>> somewhere?
>> if not, do you think what I am stating makes sense?
>>
>
> I see what you mean, but I'm not sure it would be a good thing.
> Actually, I think proposing this ITEM_MAX was a mistake.
>
> Regarding the specific bus knobs:
>
> - If a single bus needs this knob, then it would be better for the dev
> to add it as part of the bus' public API, following the correct
> library versioning processes. This would not break this bus control
> structure ABI.
Sorry, but can you elaborate on "...add it as part of bus' public API"?
This is what I had in mind:
ctrl_fn = rte_bus_control_get(busname, RTE_BUS_XYZ_KNOB_1);
(unlike specific functions like probe_mode_get/set and iova_mode_get/set)
Where ctrl_fn would then point to a method specific to bus for KNOB_1
configuration parameter.
Thereafter, ctrl_fn(KNOB_1, void *arg).
What other public API method are you hinting at?
>
> - If more than one bus implement this knob, then it should be proposed
> as part of the library API. Buses adding this new knob would break
> their ABI, other buses would be left untouched.
Agree, if more than one bus implements same operation.
>
> This makes me realize that proposing this ITEM_MAX value is not good to
> the intended purpose of this patchset:
>
> - If a bus implementation use a reference to ITEM_MAX, then the control
> structure ABI would be broken by any new control knob added, even if the
> bus does not implement it. Granted, it would not break the driver
> structure itself, but still. My PCI implementation is thus incorrect.
Changes to enum wouldn't break ABI as far as I understand. Adding a new
entry only expands it to a new declaration without impacting its size or
signature.
>
> Therefore I think that it would be best to remove this ITEM_MAX altogether,
> forcing bus developpers to use other ways that would not break their
> ABIs every other release.
>
Removing ITEM_MAX is OK from my side. It doesn't serve much purpose.
But, not for the "ABI break" reason.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v1 2/8] bus: introduce opaque control framework
2017-12-11 13:36 4% ` Shreyansh Jain
@ 2017-12-11 14:38 4% ` Gaëtan Rivet
2017-12-12 7:21 0% ` Shreyansh Jain
0 siblings, 1 reply; 200+ results
From: Gaëtan Rivet @ 2017-12-11 14:38 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: dev
On Mon, Dec 11, 2017 at 07:06:55PM +0530, Shreyansh Jain wrote:
> On Monday 11 December 2017 06:13 PM, Gaëtan Rivet wrote:
> > On Mon, Dec 11, 2017 at 05:30:16PM +0530, Shreyansh Jain wrote:
> > > On Thursday 12 October 2017 01:48 PM, Gaetan Rivet wrote:
>
> [...]
>
> > > > diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
> > > > index 331d954..bd3c28e 100644
> > > > --- a/lib/librte_eal/common/include/rte_bus.h
> > > > +++ b/lib/librte_eal/common/include/rte_bus.h
> > > > @@ -183,6 +183,51 @@ struct rte_bus_conf {
> > > > enum rte_bus_probe_mode probe_mode; /**< Probe policy. */
> > > > };
> > > > +/**
> > > > + * Bus configuration items.
> > > > + */
> > > > +enum rte_bus_ctrl_item {
> > > > + RTE_BUS_CTRL_PROBE_MODE = 0,
> > > > + RTE_BUS_CTRL_ITEM_MAX,
> > > > +};
> > >
> > > I am assuming that a driver implementation can take more than ITEM_MAX
> > > control knobs. It is opaque to the library. Are we on same page?
> > >
> > > For example, a bus driver can implement:
> > >
> > > rte_bus_XXX_ctrl_item {
> > > <Leaving space for allowing rte_bus.h implementations>
> > > RTE_BUS_XYZ_KNOB_1 = 100,
> > > RTE_BUS_XYZ_KNOB_2,
> > > RTE_BUS_XYZ_KNOB_3,
> > > };
> > >
> > > without the library knowing or restricting the API to RTE_BUS_CTRL_ITEM_MAX.
> > >
> > > I see that in your code for PCI (Patch 5/8: pci_ctrl) you have restricted
> > > the control knob to RTE_BUS_CTRL_ITEM_MAX.
> > > I hope that such restrictions would not float to library layer.
> > >
> > > If we are on same page, should this be documented as a code comment
> > > somewhere?
> > > if not, do you think what I am stating makes sense?
> > >
> >
> > I see what you mean, but I'm not sure it would be a good thing.
> > Actually, I think proposing this ITEM_MAX was a mistake.
> >
> > Regarding the specific bus knobs:
> >
> > - If a single bus needs this knob, then it would be better for the dev
> > to add it as part of the bus' public API, following the correct
> > library versioning processes. This would not break this bus control
> > structure ABI.
>
> Sorry, but can you elaborate on "...add it as part of bus' public API"?
>
> This is what I had in mind:
>
> ctrl_fn = rte_bus_control_get(busname, RTE_BUS_XYZ_KNOB_1);
>
> (unlike specific functions like probe_mode_get/set and iova_mode_get/set)
>
> Where ctrl_fn would then point to a method specific to bus for KNOB_1
> configuration parameter.
> Thereafter, ctrl_fn(KNOB_1, void *arg).
>
> What other public API method are you hinting at?
>
>
I was thinking that buses would simply expose a function
rte_busname_xyz_knob1(void *arg);
as part of their public API. This would not require an ABI break for
this bus, as it would only be an API extension and would not use
callbacks within the bus structure.
Thus, I think that for buses tempted to propose a specific API, this would be
the cleanest way.
The bus proposing it as part of a custom control section would only be
interesting when the operation is expected to become a standard API for
other buses but was not yet accepted. Applications would be able to use
the interface and the ITEM could be added later. But I doubt this is
encouraging best practices as far as API evolution go.
> >
> > - If more than one bus implement this knob, then it should be proposed
> > as part of the library API. Buses adding this new knob would break
> > their ABI, other buses would be left untouched.
>
> Agree, if more than one bus implements same operation.
>
> >
> > This makes me realize that proposing this ITEM_MAX value is not good to
> > the intended purpose of this patchset:
> >
> > - If a bus implementation use a reference to ITEM_MAX, then the control
> > structure ABI would be broken by any new control knob added, even if the
> > bus does not implement it. Granted, it would not break the driver
> > structure itself, but still. My PCI implementation is thus incorrect.
>
> Changes to enum wouldn't break ABI as far as I understand. Adding a new
> entry only expands it to a new declaration without impacting its size or
> signature.
>
> >
> > Therefore I think that it would be best to remove this ITEM_MAX altogether,
> > forcing bus developpers to use other ways that would not break their
> > ABIs every other release.
> >
>
> Removing ITEM_MAX is OK from my side. It doesn't serve much purpose. But,
> not for the "ABI break" reason.
Adding the enum would not break ABI indeed, but I was thinking about the
way the bus control structure would be declared.
However, upon second inspection on the my PCI implementation, I did not
actually use ITEM_MAX:
> static rte_bus_ctrl_t pci_ctrl_ops[][RTE_BUS_CTRL_OP_MAX] = {
> » [RTE_BUS_CTRL_PROBE_MODE] = {
> » » [RTE_BUS_CTRL_GET] = pci_probe_mode_get,
> » » [RTE_BUS_CTRL_SET] = pci_probe_mode_set,
> » },
> };
I just thought I had used RTE_BUS_CTRL_ITEM_MAX instead of RTE_BUS_CTRL_OP_MAX.
So my line of thought was simply that if any new item was declared, the control
structure would then change size.
But I was mistaken, so that's actually not a problem :)
Having ITEM_MAX available would still make those kind of mistakes
possible however. It might be better to prevent it completely by
removing it. This would however also prevent a custom control section.
Do you think this would be useful enough to justify the slightly more
complex maintenance and review of bus implementations?
--
Gaëtan Rivet
6WIND
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-01 18:56 4% [dpdk-dev] [PATCH 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
2017-12-01 18:56 5% ` [dpdk-dev] [PATCH 2/4] compat: Add __experimental macro Neil Horman
2017-12-08 17:14 4% ` [dpdk-dev] [PATCHv2 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
@ 2017-12-11 19:36 4% ` Neil Horman
2017-12-11 19:36 5% ` [dpdk-dev] [PATCHv3 2/4] compat: Add __experimental macro Neil Horman
` (3 more replies)
2017-12-13 15:17 4% ` [dpdk-dev] [PATCHv4 " Neil Horman
3 siblings, 4 replies; 200+ results
From: Neil Horman @ 2017-12-11 19:36 UTC (permalink / raw)
To: dev; +Cc: thomas, john.mcnamara, bruce.richardson
Hey all-
A few days ago, I was lamenting the fact that, when reviewing patches I
would frequently complain about ABI changes that were actually considered safe
because they were part of the EXPERIMENTAL api set. John M. asked me then what
I might do to improve the situation, and the following patch set is a proposal
that I've come up with.
In thinking about the problem I identified two issues that I think we
can improve on in this area:
1) Make experimental api calls more visible in the source code. That is to say,
when reviewing patches, it would be nice to have some sort of visual reference
that indicates that the changes being made are part of an experimental API and
therefore ABI concerns need not be addressed
2) Make experimenal api usage more visible to consumers of the DPDK, so that
they can make a more informed decision about the API's they consume in their
application. We make an effort to document all the experimental API's, but
there is no guarantee that a user will check the documentation before making use
of a new library.
This patch set attempts to achieve both of the above goals. To do this I've
added an __experimental macro tag, suitable for inserting into api forward
declarations and definitions.
The presence of the tag in the header and c files where the api code resides
increases the likelyhood that any patch submitted against them will include the
tag in the context, making it clear to reviewers that ABI stability isn't a
concern here.
Also, This tag marks each function it is used on with an attibute causing any
use of the fuction to emit a warning during the build
with a message indicating that the API call in question is not yet part of the
stable interface. Developers can then make an informed decision to suppress
that warning or not.
Because there is internal use of several experimental API's, this set also
includes a new override macro ALLOW_EXPERIMENTAL_APIS to automatically
suprress these warnings. I think its fair to assume that, for internal use, we
almost always want to suppress these warnings, as by definition any change to
the apis (even their removal) must be done in parallel with an appropriate
change in the calling locations, lest the dpdk build itself break.
Neil
---
Change Notes:
v2)
* Cleaned up checkpatch errors
* Added Allowance for building experimental on BSD
* Swapped Patch 3 and 4 so that we didn't have a commit level that issued
warnings/errors without need
v3)
* On suggestion from Bruce, modify ALLOW_EXPERIMENTAL_APIS to be defined in
CFLAGS rather than a makefile variable. This is more flexible in that it
allows us to suppress this specific feature rather than all uses of the
deprecated attribute, as we might use it for other features in the furute
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCHv3 2/4] compat: Add __experimental macro
2017-12-11 19:36 4% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
@ 2017-12-11 19:36 5% ` Neil Horman
2017-12-12 14:07 0% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Bruce Richardson
` (2 subsequent siblings)
3 siblings, 0 replies; 200+ results
From: Neil Horman @ 2017-12-11 19:36 UTC (permalink / raw)
To: dev; +Cc: thomas, john.mcnamara, bruce.richardson, Neil Horman
The __experimental macro tags a given exported function as being part of
the EXPERIMENTAL api. Use of this tag will cause any caller of the
function (that isn't removed by dead code elimination) to emit a warning
that the user is making use of an API whos stabilty isn't guaranteed.
It also places the function in the .text.experimental section, which is
used to validate the tag against the corresponding library version map
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Thomas Monjalon <thomas@monjalon.net>
CC: "Mcnamara, John" <john.mcnamara@intel.com>
CC: Bruce Richardson <bruce.richardson@intel.com>
---
lib/librte_compat/rte_compat.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/lib/librte_compat/rte_compat.h b/lib/librte_compat/rte_compat.h
index 41e8032ba..450dd542c 100644
--- a/lib/librte_compat/rte_compat.h
+++ b/lib/librte_compat/rte_compat.h
@@ -101,5 +101,16 @@
*/
#endif
+#ifndef ALLOW_EXPERIMENTAL_APIS
+#define __experimental \
+__attribute__((deprecated("Symbol is not yet part of stable abi"), \
+section(".text.experimental")))
+
+#else
+
+#define __experimental \
+__attribute__((section(".text.experimental")))
+
+#endif
#endif /* _RTE_COMPAT_H_ */
--
2.14.3
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCH v1 2/8] bus: introduce opaque control framework
2017-12-11 14:38 4% ` Gaëtan Rivet
@ 2017-12-12 7:21 0% ` Shreyansh Jain
0 siblings, 0 replies; 200+ results
From: Shreyansh Jain @ 2017-12-12 7:21 UTC (permalink / raw)
To: Gaëtan Rivet; +Cc: dev
On Monday 11 December 2017 08:08 PM, Gaëtan Rivet wrote:
> On Mon, Dec 11, 2017 at 07:06:55PM +0530, Shreyansh Jain wrote:
>> On Monday 11 December 2017 06:13 PM, Gaëtan Rivet wrote:
>>> On Mon, Dec 11, 2017 at 05:30:16PM +0530, Shreyansh Jain wrote:
>>>> On Thursday 12 October 2017 01:48 PM, Gaetan Rivet wrote:
>>
>> [...]
>>
>>>>> diff --git a/lib/librte_eal/common/include/rte_bus.h b/lib/librte_eal/common/include/rte_bus.h
>>>>> index 331d954..bd3c28e 100644
>>>>> --- a/lib/librte_eal/common/include/rte_bus.h
>>>>> +++ b/lib/librte_eal/common/include/rte_bus.h
>>>>> @@ -183,6 +183,51 @@ struct rte_bus_conf {
>>>>> enum rte_bus_probe_mode probe_mode; /**< Probe policy. */
>>>>> };
>>>>> +/**
>>>>> + * Bus configuration items.
>>>>> + */
>>>>> +enum rte_bus_ctrl_item {
>>>>> + RTE_BUS_CTRL_PROBE_MODE = 0,
>>>>> + RTE_BUS_CTRL_ITEM_MAX,
>>>>> +};
>>>>
>>>> I am assuming that a driver implementation can take more than ITEM_MAX
>>>> control knobs. It is opaque to the library. Are we on same page?
>>>>
>>>> For example, a bus driver can implement:
>>>>
>>>> rte_bus_XXX_ctrl_item {
>>>> <Leaving space for allowing rte_bus.h implementations>
>>>> RTE_BUS_XYZ_KNOB_1 = 100,
>>>> RTE_BUS_XYZ_KNOB_2,
>>>> RTE_BUS_XYZ_KNOB_3,
>>>> };
>>>>
>>>> without the library knowing or restricting the API to RTE_BUS_CTRL_ITEM_MAX.
>>>>
>>>> I see that in your code for PCI (Patch 5/8: pci_ctrl) you have restricted
>>>> the control knob to RTE_BUS_CTRL_ITEM_MAX.
>>>> I hope that such restrictions would not float to library layer.
>>>>
>>>> If we are on same page, should this be documented as a code comment
>>>> somewhere?
>>>> if not, do you think what I am stating makes sense?
>>>>
>>>
>>> I see what you mean, but I'm not sure it would be a good thing.
>>> Actually, I think proposing this ITEM_MAX was a mistake.
>>>
>>> Regarding the specific bus knobs:
>>>
>>> - If a single bus needs this knob, then it would be better for the dev
>>> to add it as part of the bus' public API, following the correct
>>> library versioning processes. This would not break this bus control
>>> structure ABI.
>>
>> Sorry, but can you elaborate on "...add it as part of bus' public API"?
>>
>> This is what I had in mind:
>>
>> ctrl_fn = rte_bus_control_get(busname, RTE_BUS_XYZ_KNOB_1);
>>
>> (unlike specific functions like probe_mode_get/set and iova_mode_get/set)
>>
>> Where ctrl_fn would then point to a method specific to bus for KNOB_1
>> configuration parameter.
>> Thereafter, ctrl_fn(KNOB_1, void *arg).
>>
>> What other public API method are you hinting at?
>>
>>
>
> I was thinking that buses would simply expose a function
>
> rte_busname_xyz_knob1(void *arg);
Yes, that is possible but only for cases where some very specific
functionality needs to be exposed which is not expected to be
generalized ever.
>
> as part of their public API. This would not require an ABI break for
> this bus, as it would only be an API extension and would not use
> callbacks within the bus structure.
Yes, agree with your point.
As such APIs are outside control of DPDK framework, they are something
which will never impact the library layer.
>
> Thus, I think that for buses tempted to propose a specific API, this would be
> the cleanest way. >
> The bus proposing it as part of a custom control section would only be
> interesting when the operation is expected to become a standard API for
> other buses but was not yet accepted. Applications would be able to use
> the interface and the ITEM could be added later. But I doubt this is
> encouraging best practices as far as API evolution go.
So, technically both are feasible: 1) having a bus specific API like
rte_busname_xyz_knob1 and 2) expanding OPS with bus specific values and
allowing application to use them.
But, in either case, if the APIs can be generalized and/or can be used
by multiple buses, they can definitely be moved into the library API
(e.g. rte_bus_probe_mode_set) and/or can be added to rte_bus_ctrl_item.
To summarize, I am OK with your approach.
>
>>>
>>> - If more than one bus implement this knob, then it should be proposed
>>> as part of the library API. Buses adding this new knob would break
>>> their ABI, other buses would be left untouched.
>>
>> Agree, if more than one bus implements same operation.
>>
>>>
>>> This makes me realize that proposing this ITEM_MAX value is not good to
>>> the intended purpose of this patchset:
>>>
>>> - If a bus implementation use a reference to ITEM_MAX, then the control
>>> structure ABI would be broken by any new control knob added, even if the
>>> bus does not implement it. Granted, it would not break the driver
>>> structure itself, but still. My PCI implementation is thus incorrect.
>>
>> Changes to enum wouldn't break ABI as far as I understand. Adding a new
>> entry only expands it to a new declaration without impacting its size or
>> signature.
>>
>>>
>>> Therefore I think that it would be best to remove this ITEM_MAX altogether,
>>> forcing bus developpers to use other ways that would not break their
>>> ABIs every other release.
>>>
>>
>> Removing ITEM_MAX is OK from my side. It doesn't serve much purpose. But,
>> not for the "ABI break" reason.
>
> Adding the enum would not break ABI indeed, but I was thinking about the
> way the bus control structure would be declared.
>
> However, upon second inspection on the my PCI implementation, I did not
> actually use ITEM_MAX:
>
>> static rte_bus_ctrl_t pci_ctrl_ops[][RTE_BUS_CTRL_OP_MAX] = {
>> » [RTE_BUS_CTRL_PROBE_MODE] = {
>> » » [RTE_BUS_CTRL_GET] = pci_probe_mode_get,
>> » » [RTE_BUS_CTRL_SET] = pci_probe_mode_set,
>> » },
>> };
>
> I just thought I had used RTE_BUS_CTRL_ITEM_MAX instead of RTE_BUS_CTRL_OP_MAX.
> So my line of thought was simply that if any new item was declared, the control
> structure would then change size.
>
> But I was mistaken, so that's actually not a problem :)
>
> Having ITEM_MAX available would still make those kind of mistakes
> possible however. It might be better to prevent it completely by
> removing it. This would however also prevent a custom control section.
It might be a naive question, but, why do you think it would prevent a
custom control section?
Assuming that only RTE_BUS_CTRL_ITEM_MAX is not available
(RTE_BUS_CTRL_OPS_MAX is available), Bus driver can still define:
static rte_bus_ctrl_t pci_ctrl_ops[][RTE_BUS_CTRL_OP_MAX] = {
[ITEM_1] = {
{...},
{...},
},
[ITEM_2] = {
{...},
{...},
},
[ITEM_NOT_IN_RTE_BUS.H] = {
{...},
{...},
},
}
(I know you disagree with third element of above definition - but
somehow I feel it is a good addition for defining a knob which doesn't
require an additional API call. Just assume as an example for now, please!)
>
> Do you think this would be useful enough to justify the slightly more
> complex maintenance and review of bus implementations?
>
Having RTE_BUS_CTRL_ITEM_MAX is helpful if one has to iterate over all
ctrl_items - but, that might never be required in my perception. Other
than that, I don't have a strong reason to say that ITEM_MAX is required.
Though, same is not true for OP_MAX - which is required for definitions
like above.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2 1/4] lib/librte_meter: add meter configuration profile
@ 2017-12-12 9:53 2% ` Jasvinder Singh
0 siblings, 1 reply; 200+ results
From: Jasvinder Singh @ 2017-12-12 9:53 UTC (permalink / raw)
To: dev; +Cc: cristian.dumitrescu
From: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
This patch set adds api for meter configuration profiles. For a given
meter object, the parameters such as the rates and sizes for
the token buckets are defined as configuration profile parameters.
This helps in reducing the memory footprint of a meter object which
results in better cache utilization for the typical case when large
arrays of meter objects are used.
Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
---
v2:
- increment LIBABIVAR
- update release note and deprecation notice
- fix checkpatch errors
doc/guides/rel_notes/deprecation.rst | 3 -
doc/guides/rel_notes/release_18_02.rst | 2 +-
lib/librte_meter/Makefile | 2 +-
lib/librte_meter/rte_meter.c | 95 +++++++++-------
lib/librte_meter/rte_meter.h | 197 +++++++++++++++++++++++----------
lib/librte_meter/rte_meter_version.map | 8 ++
6 files changed, 205 insertions(+), 102 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..6ba5ffd 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -50,6 +50,3 @@ Deprecation Notices
required the previous behavior can be configured using existing flow
director APIs. There is no ABI/API break. This change will just remove a
global configuration setting and require explicit configuration.
-
-* librte_meter: The API will change to accommodate configuration profiles.
- Most of the API functions will have an additional opaque parameter.
diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst
index 24b67bb..7343b74 100644
--- a/doc/guides/rel_notes/release_18_02.rst
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -141,7 +141,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_lpm.so.2
librte_mbuf.so.3
librte_mempool.so.3
- librte_meter.so.1
+ + librte_meter.so.2
librte_metrics.so.1
librte_net.so.1
librte_pci.so.1
diff --git a/lib/librte_meter/Makefile b/lib/librte_meter/Makefile
index bfeb5d6..d05fe39 100644
--- a/lib/librte_meter/Makefile
+++ b/lib/librte_meter/Makefile
@@ -44,7 +44,7 @@ LDLIBS += -lrte_eal
EXPORT_MAP := rte_meter_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_meter/rte_meter.c b/lib/librte_meter/rte_meter.c
index 5e2dadb..9db7a4a 100644
--- a/lib/librte_meter/rte_meter.c
+++ b/lib/librte_meter/rte_meter.c
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -60,61 +60,82 @@ rte_meter_get_tb_params(uint64_t hz, uint64_t rate, uint64_t *tb_period, uint64_
}
int
-rte_meter_srtcm_config(struct rte_meter_srtcm *m, struct rte_meter_srtcm_params *params)
+rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
+ struct rte_meter_srtcm_params *params)
{
- uint64_t hz;
+ uint64_t hz = rte_get_tsc_hz();
/* Check input parameters */
- if ((m == NULL) || (params == NULL)) {
- return -1;
- }
+ if ((p == NULL) ||
+ (params == NULL) ||
+ (params->cir == 0) ||
+ ((params->cbs == 0) && (params->ebs == 0)))
+ return -EINVAL;
- if ((params->cir == 0) || ((params->cbs == 0) && (params->ebs == 0))) {
- return -2;
- }
+ /* Initialize srTCM run-time structure */
+ p->cbs = params->cbs;
+ p->ebs = params->ebs;
+ rte_meter_get_tb_params(hz, params->cir, &p->cir_period,
+ &p->cir_bytes_per_period);
+
+ return 0;
+}
+
+int
+rte_meter_srtcm_config(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p)
+{
+ /* Check input parameters */
+ if ((m == NULL) || (p == NULL))
+ return -EINVAL;
/* Initialize srTCM run-time structure */
- hz = rte_get_tsc_hz();
m->time = rte_get_tsc_cycles();
- m->tc = m->cbs = params->cbs;
- m->te = m->ebs = params->ebs;
- rte_meter_get_tb_params(hz, params->cir, &m->cir_period, &m->cir_bytes_per_period);
-
- RTE_LOG(INFO, METER, "Low level srTCM config: \n"
- "\tCIR period = %" PRIu64 ", CIR bytes per period = %" PRIu64 "\n",
- m->cir_period, m->cir_bytes_per_period);
+ m->tc = p->cbs;
+ m->te = p->ebs;
return 0;
}
int
-rte_meter_trtcm_config(struct rte_meter_trtcm *m, struct rte_meter_trtcm_params *params)
+rte_meter_trtcm_profile_config(struct rte_meter_trtcm_profile *p,
+ struct rte_meter_trtcm_params *params)
{
- uint64_t hz;
+ uint64_t hz = rte_get_tsc_hz();
/* Check input parameters */
- if ((m == NULL) || (params == NULL)) {
- return -1;
- }
+ if ((p == NULL) ||
+ (params == NULL) ||
+ (params->cir == 0) ||
+ (params->pir == 0) ||
+ (params->pir < params->cir) ||
+ (params->cbs == 0) ||
+ (params->pbs == 0))
+ return -EINVAL;
- if ((params->cir == 0) || (params->pir == 0) || (params->pir < params->cir) ||
- (params->cbs == 0) || (params->pbs == 0)) {
- return -2;
- }
+ /* Initialize trTCM run-time structure */
+ p->cbs = params->cbs;
+ p->pbs = params->pbs;
+ rte_meter_get_tb_params(hz, params->cir, &p->cir_period,
+ &p->cir_bytes_per_period);
+ rte_meter_get_tb_params(hz, params->pir, &p->pir_period,
+ &p->pir_bytes_per_period);
+
+ return 0;
+}
+
+int
+rte_meter_trtcm_config(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p)
+{
+ /* Check input parameters */
+ if ((m == NULL) || (p == NULL))
+ return -EINVAL;
/* Initialize trTCM run-time structure */
- hz = rte_get_tsc_hz();
m->time_tc = m->time_tp = rte_get_tsc_cycles();
- m->tc = m->cbs = params->cbs;
- m->tp = m->pbs = params->pbs;
- rte_meter_get_tb_params(hz, params->cir, &m->cir_period, &m->cir_bytes_per_period);
- rte_meter_get_tb_params(hz, params->pir, &m->pir_period, &m->pir_bytes_per_period);
-
- RTE_LOG(INFO, METER, "Low level trTCM config: \n"
- "\tCIR period = %" PRIu64 ", CIR bytes per period = %" PRIu64 "\n"
- "\tPIR period = %" PRIu64 ", PIR bytes per period = %" PRIu64 "\n",
- m->cir_period, m->cir_bytes_per_period,
- m->pir_period, m->pir_bytes_per_period);
+ m->tc = p->cbs;
+ m->tp = p->pbs;
return 0;
}
diff --git a/lib/librte_meter/rte_meter.h b/lib/librte_meter/rte_meter.h
index 2ab7184..38994c3 100644
--- a/lib/librte_meter/rte_meter.h
+++ b/lib/librte_meter/rte_meter.h
@@ -1,7 +1,7 @@
/*-
* BSD LICENSE
*
- * Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+ * Copyright(c) 2010-2017 Intel Corporation. All rights reserved.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -82,6 +82,18 @@ struct rte_meter_trtcm_params {
uint64_t pbs; /**< Peak Burst Size (PBS). Measured in bytes. */
};
+/**
+ * Internal data structure storing the srTCM configuration profile. Typically
+ * shared by multiple srTCM objects.
+ */
+struct rte_meter_srtcm_profile;
+
+/**
+ * Internal data structure storing the trTCM configuration profile. Typically
+ * shared by multiple trTCM objects.
+ */
+struct rte_meter_trtcm_profile;
+
/** Internal data structure storing the srTCM run-time context per metered traffic flow. */
struct rte_meter_srtcm;
@@ -89,38 +101,66 @@ struct rte_meter_srtcm;
struct rte_meter_trtcm;
/**
+ * srTCM profile configuration
+ *
+ * @param p
+ * Pointer to pre-allocated srTCM profile data structure
+ * @param params
+ * srTCM profile parameters
+ * @return
+ * 0 upon success, error code otherwise
+ */
+int rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
+ struct rte_meter_srtcm_params *params);
+
+/**
+ * trTCM profile configuration
+ *
+ * @param p
+ * Pointer to pre-allocated trTCM profile data structure
+ * @param params
+ * trTCM profile parameters
+ * @return
+ * 0 upon success, error code otherwise
+ */
+int rte_meter_trtcm_profile_config(struct rte_meter_trtcm_profile *p,
+ struct rte_meter_trtcm_params *params);
+
+/**
* srTCM configuration per metered traffic flow
*
* @param m
* Pointer to pre-allocated srTCM data structure
- * @param params
- * User parameters per srTCM metered traffic flow
+ * @param p
+ * srTCM profile. Needs to be valid.
* @return
* 0 upon success, error code otherwise
*/
int
rte_meter_srtcm_config(struct rte_meter_srtcm *m,
- struct rte_meter_srtcm_params *params);
+ struct rte_meter_srtcm_profile *p);
/**
* trTCM configuration per metered traffic flow
*
* @param m
* Pointer to pre-allocated trTCM data structure
- * @param params
- * User parameters per trTCM metered traffic flow
+ * @param p
+ * trTCM profile. Needs to be valid.
* @return
* 0 upon success, error code otherwise
*/
int
rte_meter_trtcm_config(struct rte_meter_trtcm *m,
- struct rte_meter_trtcm_params *params);
+ struct rte_meter_trtcm_profile *p);
/**
* srTCM color blind traffic metering
*
* @param m
* Handle to srTCM instance
+ * @param p
+ * srTCM profile specified at srTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -130,6 +170,7 @@ rte_meter_trtcm_config(struct rte_meter_trtcm *m,
*/
static inline enum rte_meter_color
rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len);
@@ -138,6 +179,8 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
*
* @param m
* Handle to srTCM instance
+ * @param p
+ * srTCM profile specified at srTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -149,6 +192,7 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
*/
static inline enum rte_meter_color
rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color);
@@ -158,6 +202,8 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
*
* @param m
* Handle to trTCM instance
+ * @param p
+ * trTCM profile specified at trTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -167,6 +213,7 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
*/
static inline enum rte_meter_color
rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len);
@@ -175,6 +222,8 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
*
* @param m
* Handle to trTCM instance
+ * @param p
+ * trTCM profile specified at trTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -186,6 +235,7 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
*/
static inline enum rte_meter_color
rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color);
@@ -195,33 +245,57 @@ rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
*
***/
+struct rte_meter_srtcm_profile {
+ uint64_t cbs;
+ /**< Upper limit for C token bucket */
+ uint64_t ebs;
+ /**< Upper limit for E token bucket */
+ uint64_t cir_period;
+ /**< Number of CPU cycles for each update of C and E token buckets */
+ uint64_t cir_bytes_per_period;
+ /**< Number of bytes to add to C and E token buckets on each update */
+};
+
/* Internal data structure storing the srTCM run-time context per metered traffic flow. */
struct rte_meter_srtcm {
uint64_t time; /* Time of latest update of C and E token buckets */
uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
uint64_t te; /* Number of bytes currently available in the excess (E) token bucket */
- uint64_t cbs; /* Upper limit for C token bucket */
- uint64_t ebs; /* Upper limit for E token bucket */
- uint64_t cir_period; /* Number of CPU cycles for one update of C and E token buckets */
- uint64_t cir_bytes_per_period; /* Number of bytes to add to C and E token buckets on each update */
};
-/* Internal data structure storing the trTCM run-time context per metered traffic flow. */
+struct rte_meter_trtcm_profile {
+ uint64_t cbs;
+ /**< Upper limit for C token bucket */
+ uint64_t pbs;
+ /** Upper limit for P token bucket */
+ uint64_t cir_period;
+ /** Number of CPU cycles for one update of C token bucket */
+ uint64_t cir_bytes_per_period;
+ /** Number of bytes to add to C token bucket on each update */
+ uint64_t pir_period;
+ /** Number of CPU cycles for one update of P token bucket */
+ uint64_t pir_bytes_per_period;
+ /** Number of bytes to add to P token bucket on each update */
+};
+
+/**
+ * Internal data structure storing the trTCM run-time context per metered
+ * traffic flow.
+ */
struct rte_meter_trtcm {
- uint64_t time_tc; /* Time of latest update of C token bucket */
- uint64_t time_tp; /* Time of latest update of E token bucket */
- uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
- uint64_t tp; /* Number of bytes currently available in the peak (P) token bucket */
- uint64_t cbs; /* Upper limit for C token bucket */
- uint64_t pbs; /* Upper limit for P token bucket */
- uint64_t cir_period; /* Number of CPU cycles for one update of C token bucket */
- uint64_t cir_bytes_per_period; /* Number of bytes to add to C token bucket on each update */
- uint64_t pir_period; /* Number of CPU cycles for one update of P token bucket */
- uint64_t pir_bytes_per_period; /* Number of bytes to add to P token bucket on each update */
+ uint64_t time_tc;
+ /**< Time of latest update of C token bucket */
+ uint64_t time_tp;
+ /**< Time of latest update of E token bucket */
+ uint64_t tc;
+ /**< Number of bytes currently available in committed(C) token bucket */
+ uint64_t tp;
+ /**< Number of bytes currently available in the peak(P) token bucket */
};
static inline enum rte_meter_color
rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len)
{
@@ -229,17 +303,17 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
/* Bucket update */
time_diff = time - m->time;
- n_periods = time_diff / m->cir_period;
- m->time += n_periods * m->cir_period;
+ n_periods = time_diff / p->cir_period;
+ m->time += n_periods * p->cir_period;
/* Put the tokens overflowing from tc into te bucket */
- tc = m->tc + n_periods * m->cir_bytes_per_period;
+ tc = m->tc + n_periods * p->cir_bytes_per_period;
te = m->te;
- if (tc > m->cbs) {
- te += (tc - m->cbs);
- if (te > m->ebs)
- te = m->ebs;
- tc = m->cbs;
+ if (tc > p->cbs) {
+ te += (tc - p->cbs);
+ if (te > p->ebs)
+ te = p->ebs;
+ tc = p->cbs;
}
/* Color logic */
@@ -262,6 +336,7 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
static inline enum rte_meter_color
rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color)
@@ -270,17 +345,17 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
/* Bucket update */
time_diff = time - m->time;
- n_periods = time_diff / m->cir_period;
- m->time += n_periods * m->cir_period;
+ n_periods = time_diff / p->cir_period;
+ m->time += n_periods * p->cir_period;
/* Put the tokens overflowing from tc into te bucket */
- tc = m->tc + n_periods * m->cir_bytes_per_period;
+ tc = m->tc + n_periods * p->cir_bytes_per_period;
te = m->te;
- if (tc > m->cbs) {
- te += (tc - m->cbs);
- if (te > m->ebs)
- te = m->ebs;
- tc = m->cbs;
+ if (tc > p->cbs) {
+ te += (tc - p->cbs);
+ if (te > p->ebs)
+ te = p->ebs;
+ tc = p->cbs;
}
/* Color logic */
@@ -303,6 +378,7 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
static inline enum rte_meter_color
rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len)
{
@@ -311,18 +387,18 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
/* Bucket update */
time_diff_tc = time - m->time_tc;
time_diff_tp = time - m->time_tp;
- n_periods_tc = time_diff_tc / m->cir_period;
- n_periods_tp = time_diff_tp / m->pir_period;
- m->time_tc += n_periods_tc * m->cir_period;
- m->time_tp += n_periods_tp * m->pir_period;
+ n_periods_tc = time_diff_tc / p->cir_period;
+ n_periods_tp = time_diff_tp / p->pir_period;
+ m->time_tc += n_periods_tc * p->cir_period;
+ m->time_tp += n_periods_tp * p->pir_period;
- tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
- if (tc > m->cbs)
- tc = m->cbs;
+ tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
+ if (tc > p->cbs)
+ tc = p->cbs;
- tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
- if (tp > m->pbs)
- tp = m->pbs;
+ tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
+ if (tp > p->pbs)
+ tp = p->pbs;
/* Color logic */
if (tp < pkt_len) {
@@ -344,6 +420,7 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
static inline enum rte_meter_color
rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color)
@@ -353,18 +430,18 @@ rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
/* Bucket update */
time_diff_tc = time - m->time_tc;
time_diff_tp = time - m->time_tp;
- n_periods_tc = time_diff_tc / m->cir_period;
- n_periods_tp = time_diff_tp / m->pir_period;
- m->time_tc += n_periods_tc * m->cir_period;
- m->time_tp += n_periods_tp * m->pir_period;
-
- tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
- if (tc > m->cbs)
- tc = m->cbs;
-
- tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
- if (tp > m->pbs)
- tp = m->pbs;
+ n_periods_tc = time_diff_tc / p->cir_period;
+ n_periods_tp = time_diff_tp / p->pir_period;
+ m->time_tc += n_periods_tc * p->cir_period;
+ m->time_tp += n_periods_tp * p->pir_period;
+
+ tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
+ if (tc > p->cbs)
+ tc = p->cbs;
+
+ tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
+ if (tp > p->pbs)
+ tp = p->pbs;
/* Color logic */
if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index 2fd647c..c4422ef 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -10,3 +10,11 @@ DPDK_2.0 {
local: *;
};
+
+DPDK_18.02 {
+ global:
+
+ rte_meter_srtcm_profile_config;
+ rte_meter_trtcm_profile_config;
+
+} DPDK_2.0;
--
2.9.3
^ permalink raw reply [relevance 2%]
* Re: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
@ 2017-12-12 11:03 3% ` Ananyev, Konstantin
2017-12-12 13:43 0% ` Shreyansh Jain
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2017-12-12 11:03 UTC (permalink / raw)
To: Matan Azrad, Nikhil Agarwal, dev
Cc: Hunt, David, nikhil.agarwal, hemant.agrawal, Yigit, Ferruh
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Matan Azrad
> Sent: Tuesday, December 12, 2017 10:46 AM
> To: Nikhil Agarwal <nikhil.agarwal@linaro.org>; dev@dpdk.org
> Cc: Hunt, David <david.hunt@intel.com>; nikhil.agarwal@nxp.com; hemant.agrawal@nxp.com; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
>
> Hi Nikhil
>
> > -----Original Message-----
> > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Nikhil Agarwal
> > Sent: Tuesday, December 12, 2017 12:05 PM
> > To: dev@dpdk.org
> > Cc: david.hunt@intel.com; nikhil.agarwal@nxp.com;
> > hemant.agrawal@nxp.com; ferruh.yigit@intel.com
> > Subject: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
> >
> > Currently, if the rte_eth_rx_burst() function returns a value less than
> > *nb_pkts*, the application will assume that no more packets are present.
> >
> > Some of the hw queue based hardware can only support smaller burst for RX
> > and TX and thus break the expectation of the rx_burst API.
> >
>
> Doesn't such like devices PMDs should try to retrieve multiple HW burst to adjust the asked received packet number?
Same thought here...
Can't that limitation be hidden inside PMD by calling HW burst multiple times?
Also if I am not mistaken - it would increase size of struct rte_eth_dev_info, right?
If so, then it means ABI breakage.
Konstantin
>
> > This patch adds support to provide the maximum burst size that can be
> > supported by a given PMD. The dev_info is being memset to '0' in
> > rte_ethdev library. The value of '0' indicates that any value for burst size can
> > be supported i.e. no change for existing PMDs.
> >
> > The application can now use the lowest available max_burst_size value for
> > rte_eth_rx_burst.
> >
>
> If you are talking about performance, maybe the right field to expose is something like "perf_burst_size" or "preferred_burst_size".
> I also suggest to expose different fields for RX and for TX.
> Maybe the rte_eth_rx\tx_burst() descriptions should be updated.
>
> Thanks
> Matan.
>
> > Signed-off-by: Nikhil Agarwal <nikhil.agarwal@linaro.org>
> > ---
> > lib/librte_ether/rte_ethdev.h | 1 +
> > 1 file changed, 1 insertion(+)
> >
> > diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> > index 341c2d6..3ab6f02 100644
> > --- a/lib/librte_ether/rte_ethdev.h
> > +++ b/lib/librte_ether/rte_ethdev.h
> > @@ -1047,6 +1047,7 @@ struct rte_eth_dev_info {
> > /** Configured number of rx/tx queues */
> > uint16_t nb_rx_queues; /**< Number of RX queues. */
> > uint16_t nb_tx_queues; /**< Number of TX queues. */
> > + uint16_t max_burst_size; /**< MAX burst size, 0 for no limit. */
> > };
> >
> > /**
> > --
> > 2.7.4
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
2017-12-12 11:03 3% ` Ananyev, Konstantin
@ 2017-12-12 13:43 0% ` Shreyansh Jain
2017-12-13 12:52 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Shreyansh Jain @ 2017-12-12 13:43 UTC (permalink / raw)
To: Ananyev, Konstantin, Matan Azrad, Nikhil Agarwal
Cc: dev, Hunt, David, nikhil.agarwal, hemant.agrawal, Yigit, Ferruh
On Tuesday 12 December 2017 04:33 PM, Ananyev, Konstantin wrote:
>
>
>> -----Original Message-----
>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Matan Azrad
>> Sent: Tuesday, December 12, 2017 10:46 AM
>> To: Nikhil Agarwal <nikhil.agarwal@linaro.org>; dev@dpdk.org
>> Cc: Hunt, David <david.hunt@intel.com>; nikhil.agarwal@nxp.com; hemant.agrawal@nxp.com; Yigit, Ferruh <ferruh.yigit@intel.com>
>> Subject: Re: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
>>
>> Hi Nikhil
>>
>>> -----Original Message-----
>>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Nikhil Agarwal
>>> Sent: Tuesday, December 12, 2017 12:05 PM
>>> To: dev@dpdk.org
>>> Cc: david.hunt@intel.com; nikhil.agarwal@nxp.com;
>>> hemant.agrawal@nxp.com; ferruh.yigit@intel.com
>>> Subject: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
>>>
>>> Currently, if the rte_eth_rx_burst() function returns a value less than
>>> *nb_pkts*, the application will assume that no more packets are present..
>>>
>>> Some of the hw queue based hardware can only support smaller burst for RX
>>> and TX and thus break the expectation of the rx_burst API.
>>>
>>
>> Doesn't such like devices PMDs should try to retrieve multiple HW burst to adjust the asked received packet number?
>
> Same thought here...
> Can't that limitation be hidden inside PMD by calling HW burst multiple times?
This might be required in some cases for performance.
It is possible that for each request containing N buffers, if the PMD
fetches all N (more than its preferred burst_size), cache misses reduce
the performance - especially for SoC with limited cache size.
Also, a complete cycle of
application->driver->hardware->driver->application can help driver
prefetch buffers - which, in case of hw burst looping, might be too
little to complete the prefetch cycle.
To summarize, indeed this is for performance specific cases and the idea
that @Matan gave for renaming 'perf_buf_size' to highlight this, sounds
logical.
> Also if I am not mistaken - it would increase size of struct rte_eth_dev_info, right?
> If so, then it means ABI breakage.
Yes, deprecation notice should have been sent - if we continue with the
dev_info change. To me that looks as one of the option. Maybe, someone
on the list has a better idea.
> Konstantin
>
>>
>>> This patch adds support to provide the maximum burst size that can be
>>> supported by a given PMD. The dev_info is being memset to '0' in
>>> rte_ethdev library. The value of '0' indicates that any value for burst size can
>>> be supported i.e. no change for existing PMDs.
>>>
>>> The application can now use the lowest available max_burst_size value for
>>> rte_eth_rx_burst.
>>>
>>
>> If you are talking about performance, maybe the right field to expose is something like "perf_burst_size" or "preferred_burst_size".
>> I also suggest to expose different fields for RX and for TX.
>> Maybe the rte_eth_rx\tx_burst() descriptions should be updated.
>>
>> Thanks
>> Matan.
>>
>>> Signed-off-by: Nikhil Agarwal <nikhil.agarwal@linaro.org>
>>> ---
>>> lib/librte_ether/rte_ethdev.h | 1 +
>>> 1 file changed, 1 insertion(+)
>>>
>>> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
>>> index 341c2d6..3ab6f02 100644
>>> --- a/lib/librte_ether/rte_ethdev.h
>>> +++ b/lib/librte_ether/rte_ethdev.h
>>> @@ -1047,6 +1047,7 @@ struct rte_eth_dev_info {
>>> /** Configured number of rx/tx queues */
>>> uint16_t nb_rx_queues; /**< Number of RX queues. */
>>> uint16_t nb_tx_queues; /**< Number of TX queues. */
>>> + uint16_t max_burst_size; /**< MAX burst size, 0 for no limit. */
>>> };
>>>
>>> /**
>>> --
>>> 2.7.4
>
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-11 19:36 4% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
2017-12-11 19:36 5% ` [dpdk-dev] [PATCHv3 2/4] compat: Add __experimental macro Neil Horman
@ 2017-12-12 14:07 0% ` Bruce Richardson
2017-12-30 17:15 0% ` Neil Horman
2017-12-12 14:33 0% ` Mcnamara, John
2017-12-12 15:11 3% ` Wiles, Keith
3 siblings, 1 reply; 200+ results
From: Bruce Richardson @ 2017-12-12 14:07 UTC (permalink / raw)
To: Neil Horman; +Cc: dev, thomas, john.mcnamara
On Mon, Dec 11, 2017 at 02:36:15PM -0500, Neil Horman wrote:
> Hey all-
> A few days ago, I was lamenting the fact that, when reviewing patches I
> would frequently complain about ABI changes that were actually considered safe
> because they were part of the EXPERIMENTAL api set. John M. asked me then what
> I might do to improve the situation, and the following patch set is a proposal
> that I've come up with.
>
> In thinking about the problem I identified two issues that I think we
> can improve on in this area:
>
> 1) Make experimental api calls more visible in the source code. That is to say,
> when reviewing patches, it would be nice to have some sort of visual reference
> that indicates that the changes being made are part of an experimental API and
> therefore ABI concerns need not be addressed
>
> 2) Make experimenal api usage more visible to consumers of the DPDK, so that
> they can make a more informed decision about the API's they consume in their
> application. We make an effort to document all the experimental API's, but
> there is no guarantee that a user will check the documentation before making use
> of a new library.
>
> This patch set attempts to achieve both of the above goals. To do this I've
> added an __experimental macro tag, suitable for inserting into api forward
> declarations and definitions.
>
> The presence of the tag in the header and c files where the api code resides
> increases the likelyhood that any patch submitted against them will include the
> tag in the context, making it clear to reviewers that ABI stability isn't a
> concern here.
>
>
> Also, This tag marks each function it is used on with an attibute causing any
> use of the fuction to emit a warning during the build
> with a message indicating that the API call in question is not yet part of the
> stable interface. Developers can then make an informed decision to suppress
> that warning or not.
>
> Because there is internal use of several experimental API's, this set also
> includes a new override macro ALLOW_EXPERIMENTAL_APIS to automatically
> suprress these warnings. I think its fair to assume that, for internal use, we
> almost always want to suppress these warnings, as by definition any change to
> the apis (even their removal) must be done in parallel with an appropriate
> change in the calling locations, lest the dpdk build itself break.
>
> Neil
>
> ---
> Change Notes:
> v2)
> * Cleaned up checkpatch errors
> * Added Allowance for building experimental on BSD
> * Swapped Patch 3 and 4 so that we didn't have a commit level that issued
> warnings/errors without need
>
> v3)
> * On suggestion from Bruce, modify ALLOW_EXPERIMENTAL_APIS to be defined in
> CFLAGS rather than a makefile variable. This is more flexible in that it
> allows us to suppress this specific feature rather than all uses of the
> deprecated attribute, as we might use it for other features in the furute
>
Despite the fact that this is making yet more work for porting to a new
build system, I think this is a good idea to have. As such,
Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-11 19:36 4% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
2017-12-11 19:36 5% ` [dpdk-dev] [PATCHv3 2/4] compat: Add __experimental macro Neil Horman
2017-12-12 14:07 0% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Bruce Richardson
@ 2017-12-12 14:33 0% ` Mcnamara, John
2017-12-12 20:18 0% ` Neil Horman
2017-12-12 15:11 3% ` Wiles, Keith
3 siblings, 1 reply; 200+ results
From: Mcnamara, John @ 2017-12-12 14:33 UTC (permalink / raw)
To: Neil Horman, dev; +Cc: thomas, Richardson, Bruce
> -----Original Message-----
> From: Neil Horman [mailto:nhorman@tuxdriver.com]
> Sent: Monday, December 11, 2017 7:36 PM
> To: dev@dpdk.org
> Cc: thomas@monjalon.net; Mcnamara, John <john.mcnamara@intel.com>;
> Richardson, Bruce <bruce.richardson@intel.com>
> Subject: [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
>
> Hey all-
> A few days ago, I was lamenting the fact that, when reviewing
> patches I would frequently complain about ABI changes that were actually
> considered safe because they were part of the EXPERIMENTAL api set. John
> M. asked me then what I might do to improve the situation, and the
> following patch set is a proposal that I've come up with.
Hi Neil,
Thanks for this and apologies in advance for making more work for you but
it would be good to have a short section in the Contributors Guide on how
to add/check experimental APIs. I think the information in this cover
letter could be repurposed along with a few code and shell examples.
Probably as a new high level section in the Contributors Guides:
http://dpdk.org/doc/guides/contributing/index.html
Thanks,
John
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 3/3] doc: ethdev ABI change deprecation notice
2017-12-01 14:48 19% ` [dpdk-dev] [RFC PATCH 3/3] doc: ethdev ABI change deprecation notice Konstantin Ananyev
@ 2017-12-12 14:55 4% ` Kovacevic, Marko
0 siblings, 0 replies; 200+ results
From: Kovacevic, Marko @ 2017-12-12 14:55 UTC (permalink / raw)
To: Ananyev, Konstantin, dev; +Cc: Ananyev, Konstantin
> -----Original Message-----
> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Konstantin Ananyev
> Sent: Friday, December 1, 2017 2:48 PM
> To: dev@dpdk.org; dev@dpdk.org
> Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>
> Subject: [dpdk-dev] [RFC PATCH 3/3] doc: ethdev ABI change deprecation notice
>
> Signed-off-by: Konstantin Ananyev <konstantin.ananyev@intel.com>
> ---
> doc/guides/rel_notes/deprecation.rst | 5 +++++
> 1 file changed, 5 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst
> b/doc/guides/rel_notes/deprecation.rst
> index 13e85432f..038b55fd5 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -8,6 +8,11 @@ API and ABI deprecation notices are to be posted here.
> Deprecation Notices
> -------------------
>
> +* ethdev: an ABI changes for ``rte_ethdev`` are planned in v18.05.
> + The size and layout of struct rte_eth_dev will change.
> + Mainly to accommodate queue specific RX/TX function pointers, plus
> + reorganize RX/TX callback related information.
> +
> * eal: several API and ABI changes are planned for ``rte_devargs`` in v18.02.
> The format of device command line parameters will change. The bus will need
> to be explicitly stated in the device declaration. The enum ``rte_devtype``
> --
> 2.13.5
Acked-by: Marko Kovacevic <marko.kovacevic@intel.com>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-11 19:36 4% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
` (2 preceding siblings ...)
2017-12-12 14:33 0% ` Mcnamara, John
@ 2017-12-12 15:11 3% ` Wiles, Keith
2017-12-12 20:14 0% ` Neil Horman
3 siblings, 1 reply; 200+ results
From: Wiles, Keith @ 2017-12-12 15:11 UTC (permalink / raw)
To: Neil Horman; +Cc: DPDK, Thomas Monjalon, Mcnamara, John, Richardson, Bruce
> On Dec 11, 2017, at 1:36 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
>
> Hey all-
> A few days ago, I was lamenting the fact that, when reviewing patches I
> would frequently complain about ABI changes that were actually considered safe
> because they were part of the EXPERIMENTAL api set. John M. asked me then what
> I might do to improve the situation, and the following patch set is a proposal
> that I've come up with.
>
> In thinking about the problem I identified two issues that I think we
> can improve on in this area:
One question is how does this effect the ABI map files or does it? If an API is exposed in the map file does it need any type of special indicator on that API line? It may not make much difference, but I was thinking it could be an indicator the API is experimental and may not exist. If the new experimental API is included in the map file then it could become a problem for systems expecting all of the APIs in the map file to be solid.
Regards,
Keith
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-12 15:11 3% ` Wiles, Keith
@ 2017-12-12 20:14 0% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2017-12-12 20:14 UTC (permalink / raw)
To: Wiles, Keith; +Cc: DPDK, Thomas Monjalon, Mcnamara, John, Richardson, Bruce
On Tue, Dec 12, 2017 at 03:11:33PM +0000, Wiles, Keith wrote:
>
>
> > On Dec 11, 2017, at 1:36 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> >
> > Hey all-
> > A few days ago, I was lamenting the fact that, when reviewing patches I
> > would frequently complain about ABI changes that were actually considered safe
> > because they were part of the EXPERIMENTAL api set. John M. asked me then what
> > I might do to improve the situation, and the following patch set is a proposal
> > that I've come up with.
> >
> > In thinking about the problem I identified two issues that I think we
> > can improve on in this area:
>
> One question is how does this effect the ABI map files or does it? If an API is exposed in the map file does it need any type of special indicator on that API line? It may not make much difference, but I was thinking it could be an indicator the API is experimental and may not exist. If the new experimental API is included in the map file then it could become a problem for systems expecting all of the APIs in the map file to be solid.
>
> Regards,
> Keith
>
>
So, thats a few questions that are all interconnected, I'll try to answer them
as completely as I can:
1) Despite being experimental API's, they still need to be part of the version
map files. This is an always condition, and there are no ecpetions to that.
Failure to put an api call in the map file means it won't get exported when we
build as a shared library and so is unusable. This has been the case since we
introduced the map files. You'll note that each map file which exports
experimental APIS has an EXPERIMENTAL clause in the map for expressly this
purpose
2) One of the problems that I identified in my cover letter was that, when
reviewing patches (and when using API's), there was no clear indicator that the
patch we were reviewing was part of an experimental API (without
simeoultaneously consulting the map file). That was part of what this patch set
was meant to address (visual clues in the patch that told reviewers this was
part of an experimental API).
3) The __experimental tag is expressly meant to go on function definitions and
forward declarations to address the concern in (2) expressly
4) The __experimental tag is also meant to trigger a warning to users that build
code using experimental apis. At compile time a warning is generated for any
call made to said tagged api (unless -DALLOW_EXPERIMENTAL_APIS is set)
5) The one issue I had with this patch set was that there was a need to manually
keep in sync items tagged with __experimental and the symbols listed in the
EXPERIMENTAL section of a map file. The first patch in this series addresses
that by adding a build check to make sure that symbols in the map file are
tagged with __experimental in the source.
Hope that answers all your questions
Neil
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-12 14:33 0% ` Mcnamara, John
@ 2017-12-12 20:18 0% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2017-12-12 20:18 UTC (permalink / raw)
To: Mcnamara, John; +Cc: dev, thomas, Richardson, Bruce
On Tue, Dec 12, 2017 at 02:33:13PM +0000, Mcnamara, John wrote:
>
>
> > -----Original Message-----
> > From: Neil Horman [mailto:nhorman@tuxdriver.com]
> > Sent: Monday, December 11, 2017 7:36 PM
> > To: dev@dpdk.org
> > Cc: thomas@monjalon.net; Mcnamara, John <john.mcnamara@intel.com>;
> > Richardson, Bruce <bruce.richardson@intel.com>
> > Subject: [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
> >
> > Hey all-
> > A few days ago, I was lamenting the fact that, when reviewing
> > patches I would frequently complain about ABI changes that were actually
> > considered safe because they were part of the EXPERIMENTAL api set. John
> > M. asked me then what I might do to improve the situation, and the
> > following patch set is a proposal that I've come up with.
>
> Hi Neil,
>
> Thanks for this and apologies in advance for making more work for you but
> it would be good to have a short section in the Contributors Guide on how
> to add/check experimental APIs. I think the information in this cover
> letter could be repurposed along with a few code and shell examples.
>
> Probably as a new high level section in the Contributors Guides:
>
> http://dpdk.org/doc/guides/contributing/index.html
>
> Thanks,
>
> John
>
Thats ok, I was actually trying to think of where to add documentation for this
thing, but couldnt find a really appropriate place. I'll add that in and
repost.
Neil
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 18/18] doc: remove devargs deprecation notices
@ 2017-12-13 10:17 0% ` Shreyansh Jain
2017-12-13 10:25 0% ` Gaëtan Rivet
0 siblings, 1 reply; 200+ results
From: Shreyansh Jain @ 2017-12-13 10:17 UTC (permalink / raw)
To: Gaetan Rivet; +Cc: dev
Hello Gaetan,
On Thursday 12 October 2017 01:51 PM, Gaetan Rivet wrote:
> These actions have been enacted.
>
> Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> ---
> doc/guides/rel_notes/deprecation.rst | 13 -------------
> 1 file changed, 13 deletions(-)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index ef2264f..23faa19 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -16,19 +16,6 @@ Deprecation Notices
> - ``rte_set_log_type``, replaced by ``rte_log_set_level``
> - ``rte_get_log_type``, replaced by ``rte_log_get_level``
>
> -* eal: several API and ABI changes are planned for ``rte_devargs`` in v17.11.
> - The format of device command line parameters will change. The bus will need
> - to be explicitly stated in the device declaration. The enum ``rte_devtype``
> - was used to identify a bus and will disappear.
> - The structure ``rte_devargs`` will change.
> - The ``rte_devargs_list`` will be made private.
> - The following functions are deprecated starting from 17.08 and will either be
> - modified or removed in 17.11:
> -
> - - ``rte_eal_devargs_add``
> - - ``rte_eal_devargs_type_count``
> - - ``rte_eal_parse_devargs_str``, replaced by ``rte_eal_devargs_parse``
> -
> * eal: An ABI change is planned for 17.11 to make DPDK aware of IOVA address
> translation scheme.
> Reference to phys address in EAL data-structure or functions may change to
>
Once this patch is formalized, the documentation reference for
rte_devargs.h also needs to be changed as it still refers to RTE devargs as:
"...These devices can be PCI devices or virtual devices....".
Similarly, the rte_devargs_parse too has PCI traces.
Next step would be to remove the "pci"/"vdev" reference from
rte_eal_dev_attach.
Former can be part of this series, but the later needs to be a separate
patch, I think. Let me know if you want me to work on these (or later).
Other than that, I think I am OK with overall patch. If you can push the
final series (I am not sure it would be with or without bus control), I
can give it a spin (to vaildate if non-PCI like FSLMC bus can work fine).
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 18/18] doc: remove devargs deprecation notices
2017-12-13 10:17 0% ` Shreyansh Jain
@ 2017-12-13 10:25 0% ` Gaëtan Rivet
2017-12-13 10:54 0% ` Shreyansh Jain
0 siblings, 1 reply; 200+ results
From: Gaëtan Rivet @ 2017-12-13 10:25 UTC (permalink / raw)
To: Shreyansh Jain; +Cc: dev
Hello Shreyansh,
On Wed, Dec 13, 2017 at 03:47:04PM +0530, Shreyansh Jain wrote:
> Hello Gaetan,
>
> On Thursday 12 October 2017 01:51 PM, Gaetan Rivet wrote:
> > These actions have been enacted.
> >
> > Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> > ---
> > doc/guides/rel_notes/deprecation.rst | 13 -------------
> > 1 file changed, 13 deletions(-)
> >
> > diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> > index ef2264f..23faa19 100644
> > --- a/doc/guides/rel_notes/deprecation.rst
> > +++ b/doc/guides/rel_notes/deprecation.rst
> > @@ -16,19 +16,6 @@ Deprecation Notices
> > - ``rte_set_log_type``, replaced by ``rte_log_set_level``
> > - ``rte_get_log_type``, replaced by ``rte_log_get_level``
> > -* eal: several API and ABI changes are planned for ``rte_devargs`` in v17.11.
> > - The format of device command line parameters will change. The bus will need
> > - to be explicitly stated in the device declaration. The enum ``rte_devtype``
> > - was used to identify a bus and will disappear.
> > - The structure ``rte_devargs`` will change.
> > - The ``rte_devargs_list`` will be made private.
> > - The following functions are deprecated starting from 17.08 and will either be
> > - modified or removed in 17.11:
> > -
> > - - ``rte_eal_devargs_add``
> > - - ``rte_eal_devargs_type_count``
> > - - ``rte_eal_parse_devargs_str``, replaced by ``rte_eal_devargs_parse``
> > -
> > * eal: An ABI change is planned for 17.11 to make DPDK aware of IOVA address
> > translation scheme.
> > Reference to phys address in EAL data-structure or functions may change to
> >
>
> Once this patch is formalized, the documentation reference for rte_devargs.h
> also needs to be changed as it still refers to RTE devargs as:
>
> "...These devices can be PCI devices or virtual devices....".
>
> Similarly, the rte_devargs_parse too has PCI traces.
>
> Next step would be to remove the "pci"/"vdev" reference from
> rte_eal_dev_attach.
>
Noted, thanks.
> Former can be part of this series, but the later needs to be a separate
> patch, I think. Let me know if you want me to work on these (or later).
>
> Other than that, I think I am OK with overall patch. If you can push the
> final series (I am not sure it would be with or without bus control), I can
> give it a spin (to vaildate if non-PCI like FSLMC bus can work fine).
Indeed, I also think everything should be settled first.
I have mostly finished working on this series yesterday,
I will integrate your above remarks which will be short.
(Well, by finished I mean I finished the first 90%. The other 90% is
still in progress...)
I removed the rte_devargs unit test and am not too happy about it. There
are parsing functions there, which are extremely error-prone and would
like to have at least the basis for some tests, that we could populate
as we go. If I have the courage I will try to write it and send it with
this series.
I would certainly appreciate if you are able to fix the pci / vdev
limitation in rte_eal_dev_attach, as I am starting to be overwhelmed
with work (trying to finish a lot of things before the holidays).
Thanks for the review!
--
Gaëtan Rivet
6WIND
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 18/18] doc: remove devargs deprecation notices
2017-12-13 10:25 0% ` Gaëtan Rivet
@ 2017-12-13 10:54 0% ` Shreyansh Jain
0 siblings, 0 replies; 200+ results
From: Shreyansh Jain @ 2017-12-13 10:54 UTC (permalink / raw)
To: Gaëtan Rivet; +Cc: dev
Hello Gaetan,
> -----Original Message-----
> From: Gaëtan Rivet [mailto:gaetan.rivet@6wind.com]
> Sent: Wednesday, December 13, 2017 3:56 PM
> To: Shreyansh Jain <shreyansh.jain@nxp.com>
> Cc: dev@dpdk.org
> Subject: Re: [PATCH v2 18/18] doc: remove devargs deprecation notices
>
> Hello Shreyansh,
>
> On Wed, Dec 13, 2017 at 03:47:04PM +0530, Shreyansh Jain wrote:
> > Hello Gaetan,
> >
> > On Thursday 12 October 2017 01:51 PM, Gaetan Rivet wrote:
> > > These actions have been enacted.
> > >
> > > Signed-off-by: Gaetan Rivet <gaetan.rivet@6wind.com>
> > > ---
> > > doc/guides/rel_notes/deprecation.rst | 13 -------------
> > > 1 file changed, 13 deletions(-)
> > >
> > > diff --git a/doc/guides/rel_notes/deprecation.rst
> b/doc/guides/rel_notes/deprecation.rst
> > > index ef2264f..23faa19 100644
> > > --- a/doc/guides/rel_notes/deprecation.rst
> > > +++ b/doc/guides/rel_notes/deprecation.rst
> > > @@ -16,19 +16,6 @@ Deprecation Notices
> > > - ``rte_set_log_type``, replaced by ``rte_log_set_level``
> > > - ``rte_get_log_type``, replaced by ``rte_log_get_level``
> > > -* eal: several API and ABI changes are planned for ``rte_devargs`` in
> v17.11.
> > > - The format of device command line parameters will change. The bus will
> need
> > > - to be explicitly stated in the device declaration. The enum
> ``rte_devtype``
> > > - was used to identify a bus and will disappear.
> > > - The structure ``rte_devargs`` will change.
> > > - The ``rte_devargs_list`` will be made private.
> > > - The following functions are deprecated starting from 17.08 and will
> either be
> > > - modified or removed in 17.11:
> > > -
> > > - - ``rte_eal_devargs_add``
> > > - - ``rte_eal_devargs_type_count``
> > > - - ``rte_eal_parse_devargs_str``, replaced by ``rte_eal_devargs_parse``
> > > -
> > > * eal: An ABI change is planned for 17.11 to make DPDK aware of IOVA
> address
> > > translation scheme.
> > > Reference to phys address in EAL data-structure or functions may
> change to
> > >
> >
> > Once this patch is formalized, the documentation reference for
> rte_devargs.h
> > also needs to be changed as it still refers to RTE devargs as:
> >
> > "...These devices can be PCI devices or virtual devices....".
> >
> > Similarly, the rte_devargs_parse too has PCI traces.
> >
> > Next step would be to remove the "pci"/"vdev" reference from
> > rte_eal_dev_attach.
> >
>
> Noted, thanks.
>
> > Former can be part of this series, but the later needs to be a separate
> > patch, I think. Let me know if you want me to work on these (or later).
> >
> > Other than that, I think I am OK with overall patch. If you can push the
> > final series (I am not sure it would be with or without bus control), I can
> > give it a spin (to vaildate if non-PCI like FSLMC bus can work fine).
>
> Indeed, I also think everything should be settled first.
> I have mostly finished working on this series yesterday,
> I will integrate your above remarks which will be short.
>
> (Well, by finished I mean I finished the first 90%. The other 90% is
> still in progress...)
>
> I removed the rte_devargs unit test and am not too happy about it. There
> are parsing functions there, which are extremely error-prone and would
> like to have at least the basis for some tests, that we could populate
> as we go. If I have the courage I will try to write it and send it with
> this series.
While reading through the code, I also had the same feeling - there can be corner cases in the parsing functions which I can't imagine. Anyways, those need to be runtime-verified - static reviews may not suffice.
>
> I would certainly appreciate if you are able to fix the pci / vdev
> limitation in rte_eal_dev_attach, as I am starting to be overwhelmed
> with work (trying to finish a lot of things before the holidays).
OK.
Once you give the devargs a push, I will start work on the PCI removal from rte_eal_dev_attach. Before that, I just want to be sure of devargs with non-PCI bus (non hotplug case).
And, thanks for tons of work you are handling. I saw the patches and really appreciate how you have split things up in sequential manner per-patch. It is difficult.
>
> Thanks for the review!
>
> --
> Gaëtan Rivet
> 6WIND
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
2017-12-12 13:43 0% ` Shreyansh Jain
@ 2017-12-13 12:52 0% ` Ananyev, Konstantin
2017-12-13 15:22 3% ` Shreyansh Jain
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2017-12-13 12:52 UTC (permalink / raw)
To: Shreyansh Jain, Matan Azrad, Nikhil Agarwal
Cc: dev, Hunt, David, nikhil.agarwal, hemant.agrawal, Yigit, Ferruh
> -----Original Message-----
> From: Shreyansh Jain [mailto:shreyansh.jain@nxp.com]
> Sent: Tuesday, December 12, 2017 1:44 PM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Matan Azrad <matan@mellanox.com>; Nikhil Agarwal
> <nikhil.agarwal@linaro.org>
> Cc: dev@dpdk.org; Hunt, David <david.hunt@intel.com>; nikhil.agarwal@nxp.com; hemant.agrawal@nxp.com; Yigit, Ferruh
> <ferruh.yigit@intel.com>
> Subject: Re: [PATCH 1/3] ethdev: add max burst size to device info
>
> On Tuesday 12 December 2017 04:33 PM, Ananyev, Konstantin wrote:
> >
> >
> >> -----Original Message-----
> >> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Matan Azrad
> >> Sent: Tuesday, December 12, 2017 10:46 AM
> >> To: Nikhil Agarwal <nikhil.agarwal@linaro.org>; dev@dpdk.org
> >> Cc: Hunt, David <david.hunt@intel.com>; nikhil.agarwal@nxp.com; hemant.agrawal@nxp.com; Yigit, Ferruh <ferruh.yigit@intel.com>
> >> Subject: Re: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
> >>
> >> Hi Nikhil
> >>
> >>> -----Original Message-----
> >>> From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Nikhil Agarwal
> >>> Sent: Tuesday, December 12, 2017 12:05 PM
> >>> To: dev@dpdk.org
> >>> Cc: david.hunt@intel.com; nikhil.agarwal@nxp.com;
> >>> hemant.agrawal@nxp.com; ferruh.yigit@intel.com
> >>> Subject: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
> >>>
> >>> Currently, if the rte_eth_rx_burst() function returns a value less than
> >>> *nb_pkts*, the application will assume that no more packets are present..
> >>>
> >>> Some of the hw queue based hardware can only support smaller burst for RX
> >>> and TX and thus break the expectation of the rx_burst API.
> >>>
> >>
> >> Doesn't such like devices PMDs should try to retrieve multiple HW burst to adjust the asked received packet number?
> >
> > Same thought here...
> > Can't that limitation be hidden inside PMD by calling HW burst multiple times?
>
> This might be required in some cases for performance.
> It is possible that for each request containing N buffers, if the PMD
> fetches all N (more than its preferred burst_size), cache misses reduce
> the performance - especially for SoC with limited cache size.
>
> Also, a complete cycle of
> application->driver->hardware->driver->application can help driver
> prefetch buffers - which, in case of hw burst looping, might be too
> little to complete the prefetch cycle.
>
> To summarize, indeed this is for performance specific cases and the idea
> that @Matan gave for renaming 'perf_buf_size' to highlight this, sounds
> logical.
>
> > Also if I am not mistaken - it would increase size of struct rte_eth_dev_info, right?
> > If so, then it means ABI breakage.
>
> Yes, deprecation notice should have been sent - if we continue with the
> dev_info change. To me that looks as one of the option. Maybe, someone
> on the list has a better idea.
In theory there is at least 2 free bytes at the end of struct rte_eth_desc_lim.
Might be it would help a bit.
Konstantin
>
> > Konstantin
> >
> >>
> >>> This patch adds support to provide the maximum burst size that can be
> >>> supported by a given PMD. The dev_info is being memset to '0' in
> >>> rte_ethdev library. The value of '0' indicates that any value for burst size can
> >>> be supported i.e. no change for existing PMDs.
> >>>
> >>> The application can now use the lowest available max_burst_size value for
> >>> rte_eth_rx_burst.
> >>>
> >>
> >> If you are talking about performance, maybe the right field to expose is something like "perf_burst_size" or "preferred_burst_size".
> >> I also suggest to expose different fields for RX and for TX.
> >> Maybe the rte_eth_rx\tx_burst() descriptions should be updated.
> >>
> >> Thanks
> >> Matan.
> >>
> >>> Signed-off-by: Nikhil Agarwal <nikhil.agarwal@linaro.org>
> >>> ---
> >>> lib/librte_ether/rte_ethdev.h | 1 +
> >>> 1 file changed, 1 insertion(+)
> >>>
> >>> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> >>> index 341c2d6..3ab6f02 100644
> >>> --- a/lib/librte_ether/rte_ethdev.h
> >>> +++ b/lib/librte_ether/rte_ethdev.h
> >>> @@ -1047,6 +1047,7 @@ struct rte_eth_dev_info {
> >>> /** Configured number of rx/tx queues */
> >>> uint16_t nb_rx_queues; /**< Number of RX queues. */
> >>> uint16_t nb_tx_queues; /**< Number of TX queues. */
> >>> + uint16_t max_burst_size; /**< MAX burst size, 0 for no limit. */
> >>> };
> >>>
> >>> /**
> >>> --
> >>> 2.7.4
> >
> >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info
2017-12-13 12:52 0% ` Ananyev, Konstantin
@ 2017-12-13 15:22 3% ` Shreyansh Jain
0 siblings, 0 replies; 200+ results
From: Shreyansh Jain @ 2017-12-13 15:22 UTC (permalink / raw)
To: Ananyev, Konstantin, Matan Azrad, Nikhil Agarwal
Cc: dev, Hunt, David, nikhil.agarwal, hemant.agrawal, Yigit, Ferruh
On Wednesday 13 December 2017 06:22 PM, Ananyev, Konstantin wrote:
>
>
>> -----Original Message-----
>> From: Shreyansh Jain [mailto:shreyansh.jain@nxp.com]
>> Sent: Tuesday, December 12, 2017 1:44 PM
>> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Matan Azrad <matan@mellanox.com>; Nikhil Agarwal
>> <nikhil.agarwal@linaro.org>
>> Cc: dev@dpdk.org; Hunt, David <david.hunt@intel.com>; nikhil.agarwal@nxp.com; hemant.agrawal@nxp.com; Yigit, Ferruh
>> <ferruh.yigit@intel.com>
>> Subject: Re: [PATCH 1/3] ethdev: add max burst size to device info
>>
[...]
>>>> Doesn't such like devices PMDs should try to retrieve multiple HW burst to adjust the asked received packet number?
>>>
>>> Same thought here...
>>> Can't that limitation be hidden inside PMD by calling HW burst multiple times?
>>
>> This might be required in some cases for performance.
>> It is possible that for each request containing N buffers, if the PMD
>> fetches all N (more than its preferred burst_size), cache misses reduce
>> the performance - especially for SoC with limited cache size.
>>
>> Also, a complete cycle of
>> application->driver->hardware->driver->application can help driver
>> prefetch buffers - which, in case of hw burst looping, might be too
>> little to complete the prefetch cycle.
>>
>> To summarize, indeed this is for performance specific cases and the idea
>> that @Matan gave for renaming 'perf_buf_size' to highlight this, sounds
>> logical.
>>
>>> Also if I am not mistaken - it would increase size of struct rte_eth_dev_info, right?
>>> If so, then it means ABI breakage.
>>
>> Yes, deprecation notice should have been sent - if we continue with the
>> dev_info change. To me that looks as one of the option. Maybe, someone
>> on the list has a better idea.
>
> In theory there is at least 2 free bytes at the end of struct rte_eth_desc_lim.
> Might be it would help a bit.
:) Thanks for highlighting.
So, you feel it is OK to reuse this assumption of hole in alignment? It
certainly would bypass the ABI limitation but not sure which cases it
would break (for example, same assumptions by others)
It would an issue in case of 32bit systems, though.
[...]
-
Shreyansh
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCHv4 2/5] compat: Add __experimental macro
2017-12-13 15:17 4% ` [dpdk-dev] [PATCHv4 " Neil Horman
@ 2017-12-13 15:17 5% ` Neil Horman
` (4 subsequent siblings)
5 siblings, 0 replies; 200+ results
From: Neil Horman @ 2017-12-13 15:17 UTC (permalink / raw)
To: dev; +Cc: thomas, john.mcnamara, bruce.richardson, Neil Horman
The __experimental macro tags a given exported function as being part of
the EXPERIMENTAL api. Use of this tag will cause any caller of the
function (that isn't removed by dead code elimination) to emit a warning
that the user is making use of an API whos stabilty isn't guaranteed.
It also places the function in the .text.experimental section, which is
used to validate the tag against the corresponding library version map
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Thomas Monjalon <thomas@monjalon.net>
CC: "Mcnamara, John" <john.mcnamara@intel.com>
CC: Bruce Richardson <bruce.richardson@intel.com>
---
lib/librte_compat/rte_compat.h | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/lib/librte_compat/rte_compat.h b/lib/librte_compat/rte_compat.h
index 41e8032ba..450dd542c 100644
--- a/lib/librte_compat/rte_compat.h
+++ b/lib/librte_compat/rte_compat.h
@@ -101,5 +101,16 @@
*/
#endif
+#ifndef ALLOW_EXPERIMENTAL_APIS
+#define __experimental \
+__attribute__((deprecated("Symbol is not yet part of stable abi"), \
+section(".text.experimental")))
+
+#else
+
+#define __experimental \
+__attribute__((section(".text.experimental")))
+
+#endif
#endif /* _RTE_COMPAT_H_ */
--
2.14.3
^ permalink raw reply [relevance 5%]
* [dpdk-dev] [PATCHv4 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-01 18:56 4% [dpdk-dev] [PATCH 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
` (2 preceding siblings ...)
2017-12-11 19:36 4% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
@ 2017-12-13 15:17 4% ` Neil Horman
2017-12-13 15:17 5% ` [dpdk-dev] [PATCHv4 2/5] compat: Add __experimental macro Neil Horman
` (5 more replies)
3 siblings, 6 replies; 200+ results
From: Neil Horman @ 2017-12-13 15:17 UTC (permalink / raw)
To: dev; +Cc: thomas, john.mcnamara, bruce.richardson
Hey all-
A few days ago, I was lamenting the fact that, when reviewing patches I
would frequently complain about ABI changes that were actually considered safe
because they were part of the EXPERIMENTAL api set. John M. asked me then what
I might do to improve the situation, and the following patch set is a proposal
that I've come up with.
In thinking about the problem I identified two issues that I think we
can improve on in this area:
1) Make experimental api calls more visible in the source code. That is to say,
when reviewing patches, it would be nice to have some sort of visual reference
that indicates that the changes being made are part of an experimental API and
therefore ABI concerns need not be addressed
2) Make experimenal api usage more visible to consumers of the DPDK, so that
they can make a more informed decision about the API's they consume in their
application. We make an effort to document all the experimental API's, but
there is no guarantee that a user will check the documentation before making use
of a new library.
This patch set attempts to achieve both of the above goals. To do this I've
added an __experimental macro tag, suitable for inserting into api forward
declarations and definitions.
The presence of the tag in the header and c files where the api code resides
increases the likelyhood that any patch submitted against them will include the
tag in the context, making it clear to reviewers that ABI stability isn't a
concern here.
Also, This tag marks each function it is used on with an attibute causing any
use of the fuction to emit a warning during the build
with a message indicating that the API call in question is not yet part of the
stable interface. Developers can then make an informed decision to suppress
that warning or not.
Because there is internal use of several experimental API's, this set also
includes a new override macro ALLOW_EXPERIMENTAL_APIS to automatically
suprress these warnings. I think its fair to assume that, for internal use, we
almost always want to suppress these warnings, as by definition any change to
the apis (even their removal) must be done in parallel with an appropriate
change in the calling locations, lest the dpdk build itself break.
Neil
---
Change Notes:
v2)
* Cleaned up checkpatch errors
* Added Allowance for building experimental on BSD
* Swapped Patch 3 and 4 so that we didn't have a commit level that issued
warnings/errors without need
v3)
* On suggestion from Bruce, modify ALLOW_EXPERIMENTAL_APIS to be defined in
CFLAGS rather than a makefile variable. This is more flexible in that it
allows us to suppress this specific feature rather than all uses of the
deprecated attribute, as we might use it for other features in the furute
v4)
* Added documentation patch to contributors guide
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2017-12-13 15:17 4% ` [dpdk-dev] [PATCHv4 " Neil Horman
2017-12-13 15:17 5% ` [dpdk-dev] [PATCHv4 2/5] compat: Add __experimental macro Neil Horman
@ 2017-12-13 15:17 10% ` Neil Horman
2017-12-13 15:32 4% ` Bruce Richardson
2018-01-11 20:06 4% ` Ferruh Yigit
2017-12-13 15:32 0% ` [dpdk-dev] [PATCHv4 0/4] dpdk: enhance EXPERIMENTAL api tagging Bruce Richardson
` (2 subsequent siblings)
5 siblings, 2 replies; 200+ results
From: Neil Horman @ 2017-12-13 15:17 UTC (permalink / raw)
To: dev; +Cc: thomas, john.mcnamara, bruce.richardson, Neil Horman
Document the need to add the __experimental tag to appropriate functions
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: Thomas Monjalon <thomas@monjalon.net>
CC: "Mcnamara, John" <john.mcnamara@intel.com>
CC: Bruce Richardson <bruce.richardson@intel.com>
---
doc/guides/contributing/versioning.rst | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
index 400090628..53f56397e 100644
--- a/doc/guides/contributing/versioning.rst
+++ b/doc/guides/contributing/versioning.rst
@@ -50,6 +50,15 @@ those new APIs and start finding issues with them, new DPDK APIs will be
automatically marked as ``experimental`` to allow for a period of stabilization
before they become part of a tracked ABI.
+Note that marking an API as experimental is a two step process. To mark an API
+as experimental, the symbols which are desired to be exported must be placed in
+an EXPERIMENTAL version block in the corresponding libraries' version map
+script. Secondly, the corresponding definitions of those exported functions, and
+their forward declarations (in the development header files), must be marked
+with the __experimental tag (see rte_compat.h). The DPDK build makefiles
+preform a check to ensure that the map file and the C code reflect the same
+list of symbols.
+
ABI versions, once released, are available until such time as their
deprecation has been noted in the Release Notes for at least one major release
cycle. For example consider the case where the ABI for DPDK 2.0 has been
--
2.14.3
^ permalink raw reply [relevance 10%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2017-12-13 15:17 10% ` [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation Neil Horman
@ 2017-12-13 15:32 4% ` Bruce Richardson
2018-01-11 20:06 4% ` Ferruh Yigit
1 sibling, 0 replies; 200+ results
From: Bruce Richardson @ 2017-12-13 15:32 UTC (permalink / raw)
To: Neil Horman; +Cc: dev, thomas, john.mcnamara
On Wed, Dec 13, 2017 at 10:17:28AM -0500, Neil Horman wrote:
> Document the need to add the __experimental tag to appropriate functions
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Thomas Monjalon <thomas@monjalon.net>
> CC: "Mcnamara, John" <john.mcnamara@intel.com>
> CC: Bruce Richardson <bruce.richardson@intel.com>
> ---
> doc/guides/contributing/versioning.rst | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
> index 400090628..53f56397e 100644
> --- a/doc/guides/contributing/versioning.rst
> +++ b/doc/guides/contributing/versioning.rst
> @@ -50,6 +50,15 @@ those new APIs and start finding issues with them, new DPDK APIs will be
> automatically marked as ``experimental`` to allow for a period of stabilization
> before they become part of a tracked ABI.
>
> +Note that marking an API as experimental is a two step process. To mark an API
> +as experimental, the symbols which are desired to be exported must be placed in
> +an EXPERIMENTAL version block in the corresponding libraries' version map
> +script. Secondly, the corresponding definitions of those exported functions, and
> +their forward declarations (in the development header files), must be marked
> +with the __experimental tag (see rte_compat.h). The DPDK build makefiles
> +preform a check to ensure that the map file and the C code reflect the same
> +list of symbols.
> +
Minor typo s/preform/perform/
> ABI versions, once released, are available until such time as their
> deprecation has been noted in the Release Notes for at least one major release
> cycle. For example consider the case where the ABI for DPDK 2.0 has been
> --
> 2.14.3
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv4 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-13 15:17 4% ` [dpdk-dev] [PATCHv4 " Neil Horman
` (2 preceding siblings ...)
2017-12-13 15:17 10% ` [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation Neil Horman
@ 2017-12-13 15:32 0% ` Bruce Richardson
2017-12-21 14:21 0% ` Neil Horman
2017-12-30 19:20 0% ` Luca Boccassi
5 siblings, 0 replies; 200+ results
From: Bruce Richardson @ 2017-12-13 15:32 UTC (permalink / raw)
To: Neil Horman; +Cc: dev, thomas, john.mcnamara
On Wed, Dec 13, 2017 at 10:17:23AM -0500, Neil Horman wrote:
> Hey all-
> A few days ago, I was lamenting the fact that, when reviewing patches I
> would frequently complain about ABI changes that were actually considered safe
> because they were part of the EXPERIMENTAL api set. John M. asked me then what
> I might do to improve the situation, and the following patch set is a proposal
> that I've come up with.
>
> In thinking about the problem I identified two issues that I think we
> can improve on in this area:
>
> 1) Make experimental api calls more visible in the source code. That is to say,
> when reviewing patches, it would be nice to have some sort of visual reference
> that indicates that the changes being made are part of an experimental API and
> therefore ABI concerns need not be addressed
>
> 2) Make experimenal api usage more visible to consumers of the DPDK, so that
> they can make a more informed decision about the API's they consume in their
> application. We make an effort to document all the experimental API's, but
> there is no guarantee that a user will check the documentation before making use
> of a new library.
>
> This patch set attempts to achieve both of the above goals. To do this I've
> added an __experimental macro tag, suitable for inserting into api forward
> declarations and definitions.
>
> The presence of the tag in the header and c files where the api code resides
> increases the likelyhood that any patch submitted against them will include the
> tag in the context, making it clear to reviewers that ABI stability isn't a
> concern here.
>
> Also, This tag marks each function it is used on with an attibute causing any
> use of the fuction to emit a warning during the build
> with a message indicating that the API call in question is not yet part of the
> stable interface. Developers can then make an informed decision to suppress
> that warning or not.
>
> Because there is internal use of several experimental API's, this set also
> includes a new override macro ALLOW_EXPERIMENTAL_APIS to automatically
> suprress these warnings. I think its fair to assume that, for internal use, we
> almost always want to suppress these warnings, as by definition any change to
> the apis (even their removal) must be done in parallel with an appropriate
> change in the calling locations, lest the dpdk build itself break.
>
> Neil
>
> ---
> Change Notes:
> v2)
> * Cleaned up checkpatch errors
> * Added Allowance for building experimental on BSD
> * Swapped Patch 3 and 4 so that we didn't have a commit level that issued
> warnings/errors without need
>
> v3)
> * On suggestion from Bruce, modify ALLOW_EXPERIMENTAL_APIS to be defined in
> CFLAGS rather than a makefile variable. This is more flexible in that it
> allows us to suppress this specific feature rather than all uses of the
> deprecated attribute, as we might use it for other features in the furute
>
> v4)
> * Added documentation patch to contributors guide
>
Series Acked-by: Bruce Richardson <bruce.richardson@intel.com>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer
2017-12-01 14:55 4% [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer Konstantin Ananyev
@ 2017-12-14 4:54 0% ` Jerin Jacob
2017-12-14 13:57 3% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2017-12-14 4:54 UTC (permalink / raw)
To: Konstantin Ananyev; +Cc: dev, shahafs
-----Original Message-----
> Date: Fri, 1 Dec 2017 14:55:12 +0000
> From: Konstantin Ananyev <konstantin.ananyev@intel.com>
> To: dev@dpdk.org, dev@dpdk.org
> CC: Konstantin Ananyev <konstantin.ananyev@intel.com>
> Subject: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer
> X-Mailer: git-send-email 1.7.0.7
>
Hi Konstantin,
> The series introduces 2 main changes:
>
> 1.Introduce a separate data structure (rte_eth_queue_local)
> to store local to given process (i.e. no-shareable) information
> for each configured rx/tx queue.
> Memory for that structure is allocated/freed dynamically during
> rte_eth_dev_configure().
> Reserve a space for queue specific (rx|tx)_pkt_burst(),
> tx_pkt_prepare() function pointers inside that structure.
> Move rx/tx callback related information inside that structure.
> That introduces a change in current behavior: all callbacks for
> un-configured queues will be automatically removed.
> Also as size of struct rte_eth_dev changes that patch is an ABI breakage,
> so deprecation notice for 18.05 is filled.
> Further suggestions how to introduce the same functionality
> without ABI breakage are welcome.
Are we doing this to enable, Tx/Rx queue specific burst functions to
invoke based on new TX/RX queue specific offloads framework.
Meaning, if a offload configured for the given queue,
driver can select a different function pointer for Rx/Tx burst functions.
>
> 2. Make it safe to remove rx/tx callback at runtime.
> Right now it is not possible for the application to figure out
> when it is safe to free removed callback handle and
> associated with it resources(unless the queue is stopped).
> That's probably not a big problem if all callbacks are static
> hange through whole application lifetime)
> and/or application doesn't allocate any resources for the callback handler.
> Though if callbacks have to be added/removed dynamically and
> callback handler would require more resources to operate properly -
> then it might become an issue.
> So patch #2 fixes that problem - now as soon as
> rte_eth_remove_(rx|tx)_callback() completes successfully, application
> can safely free all associated with the removed callback resources.
>
> Performance impact:
> If application doesn't use RX/TX callbacks, then the tests I run didn't
> reveal any performance degradation.
> Though if application do use RX/TX callbacks - patch #2 does introduce
> some slowdown.
>
> To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
> with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
> 1) testpmd ... --latencystats=1 - slowdown < 1%
> 2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
> 3) examples/rxtx_callbacks - slowdown ~8%
> All that in terms of packet throughput (Mpps).
We tried on an arm64 machine; We got following result on host and guest
using l3fwd.
Note:
+ve number means "Performance regression with patches"
-ve number means "Performance improvement with patches"
Relative performance difference in percentage:
% difference on host (2 x 40G)
pkt_sz 1c 2c 4c 8c
64 1.41 0.18 0.51 0.29
72 0.50 0.53 0.09 0.19
128 0.31 0.31 0.42 0.00
256 -0.44 -0.44 0.00 0.00
512 1.94 1.94 0.01 0.01
1024 0.00 0.01 0.00 0.01
1518 0.02 0.01 0.02 0.02
% difference on guest (2 x 40G)
pkt_sz 1c 2c 4c 8c
64 5.78 2.30 -2.45 -0.01
72 1.13 1.13 1.31 -4.29
128 1.36 1.36 1.54 -0.82
256 2.02 2.03 -0.01 -0.35
512 4.05 4.04 0.00 -0.46
1024 0.39 0.38 0.00 -0.74
1518 0.00 0.00 -0.05 -4.20
I think, it is because we added more code under
the RTE_ETHDEV_RXTX_CALLBACKS and it is enabled by
default.
I think, the impact will vary based on
architecture and underneath i-cache, d-cache and IPC.
I am just thinking, How we can avoid such impact?
How about,
# Remove RTE_ETHDEV_RXTX_CALLBACKS option
# Hook Rx/TX callbacks under TX/RX offload flags
# ethdev layer gives helper function to invoke
callbacks to driver. But, don't invoke from common code
# When application needs the callback support, it
configured the given RX/TX queue offloads
# If the Rx/TX callback configure by the application
then driver calls the helper functions exposed by
the common code to invoke RX callbacks.
Jerin
>
> Ability to safely remove callbacks at runtime implies
> some sort of synchronization.
> Even I tried to make it as light as possible,
> probably some slowdown is unavoidable.
> Of course instead of introducing these changes at rte_ethdev layer
> similar technique could be applied on individual callback basis.
> In that case it would be up to callback writer/installer to decide
> does he/she need a removable at runtime callback or not.
> Though in that case, each installed callback might introduce extra
> synchronization overhead and slowdown.
>
> Konstantin Ananyev (3):
> ethdev: introduce eth_queue_local
> ethdev: make it safe to remove rx/tx callback at runtime
> doc: ethdev ABI change deprecation notice
>
> doc/guides/rel_notes/deprecation.rst | 5 +
> lib/librte_ether/rte_ethdev.c | 390 ++++++++++++++++++++++-------------
> lib/librte_ether/rte_ethdev.h | 174 ++++++++++++----
> 3 files changed, 387 insertions(+), 182 deletions(-)
>
> --
> 2.13.5
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 0/6] mempool: add bucket mempool driver
2017-11-24 16:06 4% [dpdk-dev] [RFC PATCH 0/6] mempool: add bucket mempool driver Andrew Rybchenko
@ 2017-12-14 13:36 3% ` Olivier MATZ
0 siblings, 0 replies; 200+ results
From: Olivier MATZ @ 2017-12-14 13:36 UTC (permalink / raw)
To: Andrew Rybchenko; +Cc: dev
Hi Andrew,
Please find some comments about this patchset below.
I'll also send some comments as replies to the specific patch.
On Fri, Nov 24, 2017 at 04:06:25PM +0000, Andrew Rybchenko wrote:
> The patch series adds bucket mempool driver which allows to allocate
> (both physically and virtually) contiguous blocks of objects and adds
> mempool API to do it. It is still capable to provide separate objects,
> but it is definitely more heavy-weight than ring/stack drivers.
>
> The target usecase is dequeue in blocks and enqueue separate objects
> back (which are collected in buckets to be dequeued). So, the memory
> pool with bucket driver is created by an application and provided to
> networking PMD receive queue. The choice of bucket driver is done using
> rte_eth_dev_pool_ops_supported(). A PMD that relies upon contiguous
> block allocation should report the bucket driver as the only supported
> and preferred one.
So, you are planning to use this driver for a future/existing PMD?
Do you have numbers about the performance gain, in which conditions,
etc... ? And are there conditions where there is a performance loss ?
> The number of objects in the contiguous block is a function of bucket
> memory size (.config option) and total element size.
The size of the bucket memory is hardcoded to 32KB.
Why this value ?
Won't that be an issue if the user wants to use larger objects?
> As I understand it breaks ABI so it requires 3 acks in accordance with
> policy, deprecation notice and mempool shared library version bump.
> If there is a way to avoid ABI breakage, please, let us know.
If my understanding is correct, the ABI breakage is caused by the
addition of the new block dequeue operation, right?
Thanks
Olivier
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer
2017-12-14 4:54 0% ` Jerin Jacob
@ 2017-12-14 13:57 3% ` Ananyev, Konstantin
2017-12-18 16:38 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2017-12-14 13:57 UTC (permalink / raw)
To: Jerin Jacob; +Cc: dev, shahafs
Hi Jerin,
>
> Hi Konstantin,
>
> > The series introduces 2 main changes:
> >
> > 1.Introduce a separate data structure (rte_eth_queue_local)
> > to store local to given process (i.e. no-shareable) information
> > for each configured rx/tx queue.
> > Memory for that structure is allocated/freed dynamically during
> > rte_eth_dev_configure().
> > Reserve a space for queue specific (rx|tx)_pkt_burst(),
> > tx_pkt_prepare() function pointers inside that structure.
> > Move rx/tx callback related information inside that structure.
> > That introduces a change in current behavior: all callbacks for
> > un-configured queues will be automatically removed.
> > Also as size of struct rte_eth_dev changes that patch is an ABI breakage,
> > so deprecation notice for 18.05 is filled.
> > Further suggestions how to introduce the same functionality
> > without ABI breakage are welcome.
>
> Are we doing this to enable, Tx/Rx queue specific burst functions to
> invoke based on new TX/RX queue specific offloads framework.
> Meaning, if a offload configured for the given queue,
> driver can select a different function pointer for Rx/Tx burst functions.
Yes that's the stretch goal.
We do need some extra space for rx/tx callbacks (use field) that needs to
be cache aligned and we plan to make rx/tx function per queue.
So I thought it would be a good opportunity to do these 2 things in one go -
to minimize number of ABI breakages.
>
> >
> > 2. Make it safe to remove rx/tx callback at runtime.
> > Right now it is not possible for the application to figure out
> > when it is safe to free removed callback handle and
> > associated with it resources(unless the queue is stopped).
> > That's probably not a big problem if all callbacks are static
> > hange through whole application lifetime)
> > and/or application doesn't allocate any resources for the callback handler.
> > Though if callbacks have to be added/removed dynamically and
> > callback handler would require more resources to operate properly -
> > then it might become an issue.
> > So patch #2 fixes that problem - now as soon as
> > rte_eth_remove_(rx|tx)_callback() completes successfully, application
> > can safely free all associated with the removed callback resources.
> >
> > Performance impact:
> > If application doesn't use RX/TX callbacks, then the tests I run didn't
> > reveal any performance degradation.
> > Though if application do use RX/TX callbacks - patch #2 does introduce
> > some slowdown.
> >
> > To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
> > with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
> > 1) testpmd ... --latencystats=1 - slowdown < 1%
> > 2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
> > 3) examples/rxtx_callbacks - slowdown ~8%
> > All that in terms of packet throughput (Mpps).
>
> We tried on an arm64 machine; We got following result on host and guest
> using l3fwd.
Thanks for testing it.
So these numbers below - are for l3fwd running with or without rx callback installed?
i.e. with or without '--parse-ptype' option (and on a NIC with/without ptype HW support)?
>
>
> Note:
> +ve number means "Performance regression with patches"
> -ve number means "Performance improvement with patches"
>
> Relative performance difference in percentage:
>
> % difference on host (2 x 40G)
> pkt_sz 1c 2c 4c 8c
> 64 1.41 0.18 0.51 0.29
> 72 0.50 0.53 0.09 0.19
> 128 0.31 0.31 0.42 0.00
> 256 -0.44 -0.44 0.00 0.00
> 512 1.94 1.94 0.01 0.01
> 1024 0.00 0.01 0.00 0.01
> 1518 0.02 0.01 0.02 0.02
>
> % difference on guest (2 x 40G)
> pkt_sz 1c 2c 4c 8c
> 64 5.78 2.30 -2.45 -0.01
> 72 1.13 1.13 1.31 -4.29
> 128 1.36 1.36 1.54 -0.82
> 256 2.02 2.03 -0.01 -0.35
> 512 4.05 4.04 0.00 -0.46
> 1024 0.39 0.38 0.00 -0.74
> 1518 0.00 0.00 -0.05 -4.20
>
> I think, it is because we added more code under
> the RTE_ETHDEV_RXTX_CALLBACKS and it is enabled by
> default.
>
> I think, the impact will vary based on
> architecture and underneath i-cache, d-cache and IPC.
>
> I am just thinking, How we can avoid such impact?
> How about,
> # Remove RTE_ETHDEV_RXTX_CALLBACKS option
> # Hook Rx/TX callbacks under TX/RX offload flags
> # ethdev layer gives helper function to invoke
> callbacks to driver.
I suppose you suggest that user would have to decide at queue_setup()
stage does he wants a callback(s) for RX/TX or no?
As I can see, the main drawback with that approach - it would introduce new limitation.
Right now it is possible to add/remove RX/TX callback at runtime
(without stopping and reconfiguring the queue), and I suppose we do want to keep that ability.
Again in some cases user can't decide does he wants a callback installed or not,
before he actually calls dev_start().
l3fwd ptype-parse callback is an example of such situation:
right now user has to start device first to figure out which ptypes are supported by this PMD
with desired configuration, then based on this information he will (or will not) setup the callback.
What I thought in same direction - introduce a notion of 'static' and 'dynamic' callbacks.
Static ones can't be removed while queue is not stopped while dynamic can.
But that also requires user to select at queue_setup() stage does he wants dynamic
callbacks for that queue or not (new offload flag or extra field in rxconf/txconf structure).
So again - same limitation for the user.
Another possibility here - have a flag 'dynamic' or 'static' not per queue, but per individual callback.
Yes, that would mean API change for add/remove callback functions.
Konstantin
> But, don't invoke from common code
> # When application needs the callback support, it
> configured the given RX/TX queue offloads
> # If the Rx/TX callback configure by the application
> then driver calls the helper functions exposed by
> the common code to invoke RX callbacks.
>
> Jerin
>
> >
> > Ability to safely remove callbacks at runtime implies
> > some sort of synchronization.
> > Even I tried to make it as light as possible,
> > probably some slowdown is unavoidable.
> > Of course instead of introducing these changes at rte_ethdev layer
> > similar technique could be applied on individual callback basis.
> > In that case it would be up to callback writer/installer to decide
> > does he/she need a removable at runtime callback or not.
> > Though in that case, each installed callback might introduce extra
> > synchronization overhead and slowdown.
> >
> > Konstantin Ananyev (3):
> > ethdev: introduce eth_queue_local
> > ethdev: make it safe to remove rx/tx callback at runtime
> > doc: ethdev ABI change deprecation notice
> >
> > doc/guides/rel_notes/deprecation.rst | 5 +
> > lib/librte_ether/rte_ethdev.c | 390 ++++++++++++++++++++++-------------
> > lib/librte_ether/rte_ethdev.h | 174 ++++++++++++----
> > 3 files changed, 387 insertions(+), 182 deletions(-)
> >
> > --
> > 2.13.5
> >
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH] doc: announce ABI change for pktmbuf pool create API
@ 2017-12-15 10:20 4% Hemant Agrawal
2017-12-15 10:41 4% ` [dpdk-dev] [PATCH v2] " Hemant Agrawal
0 siblings, 1 reply; 200+ results
From: Hemant Agrawal @ 2017-12-15 10:20 UTC (permalink / raw)
To: olivier.matz; +Cc: dev
Introduce a new argument ops_name in rte_mempool_set_ops_byname
for allowing the application to optionally specify the mempool ops.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/rel_notes/deprecation.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..a853574 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -53,3 +53,6 @@ Deprecation Notices
* librte_meter: The API will change to accommodate configuration profiles.
Most of the API functions will have an additional opaque parameter.
+
+* librte_mbuf: a new optional parameter for representing name of mempool_ops
+ will be added to the API ``rte_pktmbuf_pool_create``.
--
2.7.4
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2] doc: announce ABI change for pktmbuf pool create API
2017-12-15 10:20 4% [dpdk-dev] [PATCH] doc: announce ABI change for pktmbuf pool create API Hemant Agrawal
@ 2017-12-15 10:41 4% ` Hemant Agrawal
2017-12-18 8:58 4% ` Jerin Jacob
2017-12-18 13:51 8% ` Wiles, Keith
0 siblings, 2 replies; 200+ results
From: Hemant Agrawal @ 2017-12-15 10:41 UTC (permalink / raw)
To: olivier.matz; +Cc: dev
Introduce a new argument ops_name in rte_mempool_set_ops_byname
for allowing the application to optionally specify the mempool ops.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
v2: fix checkpatch error
doc/guides/rel_notes/deprecation.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..968ca14 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -53,3 +53,6 @@ Deprecation Notices
* librte_meter: The API will change to accommodate configuration profiles.
Most of the API functions will have an additional opaque parameter.
+
+* librte_mbuf: a new optional parameter for representing name of mempool_ops
+ will be added to the API ``rte_pktmbuf_pool_create``.
--
2.7.4
^ permalink raw reply [relevance 4%]
* [dpdk-dev] Inline/look-aside transformation API (Crypto, IPsec, VLAN insertion, Compression, ...)
@ 2017-12-15 12:29 3% Nelio Laranjeiro
0 siblings, 0 replies; 200+ results
From: Nelio Laranjeiro @ 2017-12-15 12:29 UTC (permalink / raw)
To: Shally.Verma, Mahipal.Challa, NarayanaPrasad.Athreya,
pablo.de.lara.guarch, fiona.trahe, Declan Doherty, Akhil Goyal,
anoob.joseph, Thomas Monjalon, Olivier Matz, Adrien Mazarguil
Cc: dev
Hi all,
I would like to raise an issue to open a more generic discussion,
This concern comes from the issues I am currently facing with rte_security
where there will be 3 different configuration code paths and 2 different
datapath depending on the NIC capability [1][2]. This bring a real
complexity for an application as it will have to use different code
paths for each device/port.
This brings a more general issue concerning such devices which are able to
offload any kind of transformation. For that, new API are starting to appear
(rte_security, Compression) from a generic point of view, it is a
transformation API which is necessary with transformation actions.
Looking into this last point, seems we already have a generic way to
handle it through the generic flow API which matches a pattern and make
actions on it, those actions can finally be something like:
xfrm-crypto algo <algo> hashkey <key> salt <salt> offset <offset>
or
xfrm-compress algo <algo> ...
It could also be used to make multiple transformation on a single flow
like:
xfrm-vlan tci 10 / xfrm-compress ... / xfrm-ipsec-encap ... / xfrm-crypto ...
.................................... / xfrm-macsec-encap ... / xfrm-crypto ...
The missing point seems to be the metadata such offloads may need to
handle the job which is per packet. For such situation we could
eventually use a pointer to a list of offloads request passing among the
packet directly inside the mbuf or in a new argument of {rx,tx}_burst().
This part is more complex to design to avoid huge performance
degradation in both applications and PMD.
The point is, adding new offload bits in the mbuf are not unlimited whereas
the possibilities of those "smart" NIC are, at some moment we will be stuck.
We can avoid it with such kind of approach.
Pros:
- Adding new actions/offloads don't break API/ABI.
- No need for offload capabilities bits/API, an offload request through
rte_flow is enough to know both: offload capabilities and if it is
applicable on the pattern.
- An easier and flexible way to combine transformations.
This is still an idea which needs more meditation.
Thoughts?
Thanks,
[1] https://dpdk.org/browse/dpdk/tree/examples/ipsec-secgw/ipsec.c#n50
[2] https://dpdk.org/ml/archives/dev/2017-December/083983.html
--
Nélio Laranjeiro
6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC] eventdev: add crypto adapter API header
@ 2017-12-18 6:30 4% ` Jerin Jacob
2017-12-18 16:33 3% ` Eads, Gage
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2017-12-18 6:30 UTC (permalink / raw)
To: Eads, Gage
Cc: Gujjar, Abhinandan S, dev, Vangati, Narender, Rao, Nikhil,
hemant.agrawal, Doherty, Declan, nidadavolu.murthy,
nithin.dabilpuram, narayanaprasad.athreya
-----Original Message-----
> Date: Thu, 14 Dec 2017 18:52:02 +0000
> From: "Eads, Gage" <gage.eads@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: "Gujjar, Abhinandan S" <abhinandan.gujjar@intel.com>, "dev@dpdk.org"
> <dev@dpdk.org>, "Vangati, Narender" <narender.vangati@intel.com>, "Rao,
> Nikhil" <nikhil.rao@intel.com>, "hemant.agrawal@nxp.com"
> <hemant.agrawal@nxp.com>, "Doherty, Declan" <declan.doherty@intel.com>,
> "nidadavolu.murthy@cavium.com" <nidadavolu.murthy@cavium.com>,
> "nithin.dabilpuram@cavium.com" <nithin.dabilpuram@cavium.com>,
> "narayanaprasad.athreya@cavium.com" <narayanaprasad.athreya@cavium.com>
> Subject: RE: [RFC] eventdev: add crypto adapter API header
>
>
>
> > -----Original Message-----
> > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > Sent: Wednesday, December 13, 2017 8:49 PM
> > To: Eads, Gage <gage.eads@intel.com>
> > Cc: Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>; dev@dpdk.org;
> > Vangati, Narender <narender.vangati@intel.com>; Rao, Nikhil
> > <nikhil.rao@intel.com>; hemant.agrawal@nxp.com; Doherty, Declan
> > <declan.doherty@intel.com>; nidadavolu.murthy@cavium.com;
> > nithin.dabilpuram@cavium.com; narayanaprasad.athreya@cavium.com
> > Subject: Re: [RFC] eventdev: add crypto adapter API header
> >
> > -----Original Message-----
> > > Date: Wed, 13 Dec 2017 23:35:48 +0000
> > > From: "Eads, Gage" <gage.eads@intel.com>
> > > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, "Gujjar, Abhinandan S"
> > > <abhinandan.gujjar@intel.com>
> > > CC: "dev@dpdk.org" <dev@dpdk.org>, "Vangati, Narender"
> > > <narender.vangati@intel.com>, "Rao, Nikhil" <nikhil.rao@intel.com>,
> > > "hemant.agrawal@nxp.com" <hemant.agrawal@nxp.com>, "Doherty, Declan"
> > > <declan.doherty@intel.com>, "nidadavolu.murthy@cavium.com"
> > > <nidadavolu.murthy@cavium.com>, "nithin.dabilpuram@cavium.com"
> > > <nithin.dabilpuram@cavium.com>, "narayanaprasad.athreya@cavium.com"
> > > <narayanaprasad.athreya@cavium.com>
> > > Subject: RE: [RFC] eventdev: add crypto adapter API header
> > >
> > > Hey Jerin,
> >
> > Hey Gage,
> >
> > >
> > > </snip>
> > >
> > > > > +
> > > > > + /**
> > > > > + * @warning
> > > > > + * @b EXPERIMENTAL: this enum may change without prior notice
> > > > > + *
> > > > > + * Crypto event adapter type
> > > > > + */
> > > > > +enum rte_event_crypto_adapter_type {
> > > > > + RTE_EVENT_CRYPTO_ADAPTER_RX_ONLY = 1,
> > > > > + /**< Start only Rx part of crypto adapter.
> > > > > + * Packets dequeued from cryptodev are new to eventdev and
> > > > > + * events will be treated as RTE_EVENT_OP_NEW */
> > > > > + RTE_EVENT_CRYPTO_ADAPTER_RX_TX,
> > > > > + /**< Start both Rx & Tx part of crypto adapter.
> > > > > + * Packet's event context will be retained and
> > > > > + * event will be treated as RTE_EVENT_OP_FORWARD */ };
> > > >
> > > > How about leveraging ev.op based schematics as mentioned above?
> > >
> > > That could work, but perhaps the ev.op should be configured once up front, as
> > I see it being a function of the application architecture. A couple possible
> > designs, for example:
> > > - Worker enqueues into cryptodev, adapter polls for response: the adapter
> > port would always use OP_NEW here.
> > > - Worker sends a crypto request event to the adapter, which gives the
> > > request to the cryptodev and polls for response: the adapter port
> > > would always use OP_FWD here. (This ties in with my implicit release
> > > patch (http://dpdk.org/ml/archives/dev/2017-December/083535.html))
> > > - Etc.
> >
> > Yes. Semantically both approaches will work. I was trying to avoid extra
> > clutter(enum rte_event_crypto_adapter_type) in adapter API.
> > I don't see any problem in moving ev.op to adapter configuration time if it helps
> > the SW driver.
> >
> > IMO, We can change RTE_EVENT_CRYPTO_ADAPTER_RX_ONLY and
> > RTE_EVENT_CRYPTO_ADAPTER_RX_TX to more appropriate name, something
> > like,
> > RTE_EVENT_CRYPTO_ADAPTER_TYPE_OP_NEW/RTE_EVENT_CRYPTO_ADAPTE
> > R_TYPE_OP_FWD
> > or something like that.
> >
>
> I agree that the two naming schemes are equivalent, but since this option would control the adapter's behavior (Rx only vs. Rx + Tx), (IMO) I think Abhinandan's original names do a better job of conveying what effect these two options have on the adapter, compared to the op type names.
The only concern with Rx/Tx terminology was, It is mostly used in the ethdev domain.
In crypto domain, typically, we use enqueue/dequeue.
The only difference between two modes is if adapter enqueue the events with
RTE_EVENT_OP_NEW vs RTE_EVENT_OP_FORWARD then (IMO) we can change
something related to that name to avoid adding a new terminology.
BTW, Based on the earlier discussion, if we need to add opaque eventdev metadata
to cryptodev then it may change ABI.If so, I think, we need to announce
ABI change notice for cryptodev and plan cryptodev adapter for v18.05.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2] doc: announce ABI change for pktmbuf pool create API
2017-12-15 10:41 4% ` [dpdk-dev] [PATCH v2] " Hemant Agrawal
@ 2017-12-18 8:58 4% ` Jerin Jacob
2017-12-18 13:51 8% ` Wiles, Keith
1 sibling, 0 replies; 200+ results
From: Jerin Jacob @ 2017-12-18 8:58 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: olivier.matz, dev
-----Original Message-----
> Date: Fri, 15 Dec 2017 16:11:22 +0530
> From: Hemant Agrawal <hemant.agrawal@nxp.com>
> To: olivier.matz@6wind.com
> CC: dev@dpdk.org
> Subject: [dpdk-dev] [PATCH v2] doc: announce ABI change for pktmbuf pool
> create API
> X-Mailer: git-send-email 2.7.4
>
> Introduce a new argument ops_name in rte_mempool_set_ops_byname
> for allowing the application to optionally specify the mempool ops.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Acked-by: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> ---
> v2: fix checkpatch error
>
> doc/guides/rel_notes/deprecation.rst | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 13e8543..968ca14 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -53,3 +53,6 @@ Deprecation Notices
>
> * librte_meter: The API will change to accommodate configuration profiles.
> Most of the API functions will have an additional opaque parameter.
> +
> +* librte_mbuf: a new optional parameter for representing name of mempool_ops
> + will be added to the API ``rte_pktmbuf_pool_create``.
> --
> 2.7.4
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2] doc: announce ABI change for pktmbuf pool create API
2017-12-15 10:41 4% ` [dpdk-dev] [PATCH v2] " Hemant Agrawal
2017-12-18 8:58 4% ` Jerin Jacob
@ 2017-12-18 13:51 8% ` Wiles, Keith
2017-12-18 14:43 4% ` Neil Horman
2017-12-19 5:40 4% ` Hemant Agrawal
1 sibling, 2 replies; 200+ results
From: Wiles, Keith @ 2017-12-18 13:51 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: olivier.matz, dev
> On Dec 15, 2017, at 4:41 AM, Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
>
> Introduce a new argument ops_name in rte_mempool_set_ops_byname
> for allowing the application to optionally specify the mempool ops.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> v2: fix checkpatch error
>
> doc/guides/rel_notes/deprecation.rst | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 13e8543..968ca14 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -53,3 +53,6 @@ Deprecation Notices
>
> * librte_meter: The API will change to accommodate configuration profiles.
> Most of the API functions will have an additional opaque parameter.
> +
> +* librte_mbuf: a new optional parameter for representing name of mempool_ops
> + will be added to the API ``rte_pktmbuf_pool_create``.
Sorry, for the late response I was on vacation.
My question is why do we need to change rte_pktmbuf_pool_create ABI yet again, why could we not add a new API to just set the name of the pool after it is created. This would allow all current applications to work without any ABI breakage and only require adding a new API call for anyone that wants the name. The rte_pktmbuf_pool_create() routine could assign a default name or some incrementing style name as the default. e.g. ‘pktmbuf_%d’ with a static incrementing variable or whatever you like.
Sorry if this was asked and answered before.
> --
> 2.7.4
>
Regards,
Keith
^ permalink raw reply [relevance 8%]
* Re: [dpdk-dev] [PATCH v2] doc: announce ABI change for pktmbuf pool create API
2017-12-18 13:51 8% ` Wiles, Keith
@ 2017-12-18 14:43 4% ` Neil Horman
2017-12-19 5:40 4% ` Hemant Agrawal
1 sibling, 0 replies; 200+ results
From: Neil Horman @ 2017-12-18 14:43 UTC (permalink / raw)
To: Wiles, Keith; +Cc: Hemant Agrawal, olivier.matz, dev
On Mon, Dec 18, 2017 at 01:51:52PM +0000, Wiles, Keith wrote:
>
>
> > On Dec 15, 2017, at 4:41 AM, Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
> >
> > Introduce a new argument ops_name in rte_mempool_set_ops_byname
> > for allowing the application to optionally specify the mempool ops.
> >
> > Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> > ---
> > v2: fix checkpatch error
> >
> > doc/guides/rel_notes/deprecation.rst | 3 +++
> > 1 file changed, 3 insertions(+)
> >
> > diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> > index 13e8543..968ca14 100644
> > --- a/doc/guides/rel_notes/deprecation.rst
> > +++ b/doc/guides/rel_notes/deprecation.rst
> > @@ -53,3 +53,6 @@ Deprecation Notices
> >
> > * librte_meter: The API will change to accommodate configuration profiles.
> > Most of the API functions will have an additional opaque parameter.
> > +
> > +* librte_mbuf: a new optional parameter for representing name of mempool_ops
> > + will be added to the API ``rte_pktmbuf_pool_create``.
>
>
> Sorry, for the late response I was on vacation.
>
> My question is why do we need to change rte_pktmbuf_pool_create ABI yet again, why could we not add a new API to just set the name of the pool after it is created. This would allow all current applications to work without any ABI breakage and only require adding a new API call for anyone that wants the name. The rte_pktmbuf_pool_create() routine could assign a default name or some incrementing style name as the default. e.g. ‘pktmbuf_%d’ with a static incrementing variable or whatever you like.
>
> Sorry if this was asked and answered before.
+1, that seems like the more flexible solution.
Neil
>
> > --
> > 2.7.4
> >
>
> Regards,
> Keith
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [RFC] eventdev: add crypto adapter API header
2017-12-18 6:30 4% ` Jerin Jacob
@ 2017-12-18 16:33 3% ` Eads, Gage
2017-12-19 8:47 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Eads, Gage @ 2017-12-18 16:33 UTC (permalink / raw)
To: Jerin Jacob
Cc: Gujjar, Abhinandan S, dev, Vangati, Narender, Rao, Nikhil,
hemant.agrawal, Doherty, Declan, nidadavolu.murthy,
nithin.dabilpuram, narayanaprasad.athreya
> -----Original Message-----
> From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> Sent: Monday, December 18, 2017 12:30 AM
> To: Eads, Gage <gage.eads@intel.com>
> Cc: Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>; dev@dpdk.org;
> Vangati, Narender <narender.vangati@intel.com>; Rao, Nikhil
> <nikhil.rao@intel.com>; hemant.agrawal@nxp.com; Doherty, Declan
> <declan.doherty@intel.com>; nidadavolu.murthy@cavium.com;
> nithin.dabilpuram@cavium.com; narayanaprasad.athreya@cavium.com
> Subject: Re: [RFC] eventdev: add crypto adapter API header
>
> -----Original Message-----
> > Date: Thu, 14 Dec 2017 18:52:02 +0000
> > From: "Eads, Gage" <gage.eads@intel.com>
> > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > CC: "Gujjar, Abhinandan S" <abhinandan.gujjar@intel.com>, "dev@dpdk.org"
> > <dev@dpdk.org>, "Vangati, Narender" <narender.vangati@intel.com>,
> > "Rao, Nikhil" <nikhil.rao@intel.com>, "hemant.agrawal@nxp.com"
> > <hemant.agrawal@nxp.com>, "Doherty, Declan"
> > <declan.doherty@intel.com>, "nidadavolu.murthy@cavium.com"
> > <nidadavolu.murthy@cavium.com>, "nithin.dabilpuram@cavium.com"
> > <nithin.dabilpuram@cavium.com>, "narayanaprasad.athreya@cavium.com"
> > <narayanaprasad.athreya@cavium.com>
> > Subject: RE: [RFC] eventdev: add crypto adapter API header
> >
> >
> >
> > > -----Original Message-----
> > > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > > Sent: Wednesday, December 13, 2017 8:49 PM
> > > To: Eads, Gage <gage.eads@intel.com>
> > > Cc: Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>;
> > > dev@dpdk.org; Vangati, Narender <narender.vangati@intel.com>; Rao,
> > > Nikhil <nikhil.rao@intel.com>; hemant.agrawal@nxp.com; Doherty,
> > > Declan <declan.doherty@intel.com>; nidadavolu.murthy@cavium.com;
> > > nithin.dabilpuram@cavium.com; narayanaprasad.athreya@cavium.com
> > > Subject: Re: [RFC] eventdev: add crypto adapter API header
> > >
> > > -----Original Message-----
> > > > Date: Wed, 13 Dec 2017 23:35:48 +0000
> > > > From: "Eads, Gage" <gage.eads@intel.com>
> > > > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, "Gujjar, Abhinandan
> S"
> > > > <abhinandan.gujjar@intel.com>
> > > > CC: "dev@dpdk.org" <dev@dpdk.org>, "Vangati, Narender"
> > > > <narender.vangati@intel.com>, "Rao, Nikhil"
> > > > <nikhil.rao@intel.com>, "hemant.agrawal@nxp.com"
> <hemant.agrawal@nxp.com>, "Doherty, Declan"
> > > > <declan.doherty@intel.com>, "nidadavolu.murthy@cavium.com"
> > > > <nidadavolu.murthy@cavium.com>, "nithin.dabilpuram@cavium.com"
> > > > <nithin.dabilpuram@cavium.com>,
> "narayanaprasad.athreya@cavium.com"
> > > > <narayanaprasad.athreya@cavium.com>
> > > > Subject: RE: [RFC] eventdev: add crypto adapter API header
> > > >
> > > > Hey Jerin,
> > >
> > > Hey Gage,
> > >
> > > >
> > > > </snip>
> > > >
> > > > > > +
> > > > > > + /**
> > > > > > + * @warning
> > > > > > + * @b EXPERIMENTAL: this enum may change without prior notice
> > > > > > + *
> > > > > > + * Crypto event adapter type
> > > > > > + */
> > > > > > +enum rte_event_crypto_adapter_type {
> > > > > > + RTE_EVENT_CRYPTO_ADAPTER_RX_ONLY = 1,
> > > > > > + /**< Start only Rx part of crypto adapter.
> > > > > > + * Packets dequeued from cryptodev are new to eventdev and
> > > > > > + * events will be treated as RTE_EVENT_OP_NEW */
> > > > > > + RTE_EVENT_CRYPTO_ADAPTER_RX_TX,
> > > > > > + /**< Start both Rx & Tx part of crypto adapter.
> > > > > > + * Packet's event context will be retained and
> > > > > > + * event will be treated as RTE_EVENT_OP_FORWARD */ };
> > > > >
> > > > > How about leveraging ev.op based schematics as mentioned above?
> > > >
> > > > That could work, but perhaps the ev.op should be configured once
> > > > up front, as
> > > I see it being a function of the application architecture. A couple
> > > possible designs, for example:
> > > > - Worker enqueues into cryptodev, adapter polls for response: the
> > > > adapter
> > > port would always use OP_NEW here.
> > > > - Worker sends a crypto request event to the adapter, which gives
> > > > the request to the cryptodev and polls for response: the adapter
> > > > port would always use OP_FWD here. (This ties in with my implicit
> > > > release patch
> > > > (http://dpdk.org/ml/archives/dev/2017-December/083535.html))
> > > > - Etc.
> > >
> > > Yes. Semantically both approaches will work. I was trying to avoid
> > > extra clutter(enum rte_event_crypto_adapter_type) in adapter API.
> > > I don't see any problem in moving ev.op to adapter configuration
> > > time if it helps the SW driver.
> > >
> > > IMO, We can change RTE_EVENT_CRYPTO_ADAPTER_RX_ONLY and
> > > RTE_EVENT_CRYPTO_ADAPTER_RX_TX to more appropriate name,
> something
> > > like,
> RTE_EVENT_CRYPTO_ADAPTER_TYPE_OP_NEW/RTE_EVENT_CRYPTO_ADAPTE
> > > R_TYPE_OP_FWD
> > > or something like that.
> > >
> >
> > I agree that the two naming schemes are equivalent, but since this option
> would control the adapter's behavior (Rx only vs. Rx + Tx), (IMO) I think
> Abhinandan's original names do a better job of conveying what effect these two
> options have on the adapter, compared to the op type names.
>
> The only concern with Rx/Tx terminology was, It is mostly used in the ethdev
> domain.
> In crypto domain, typically, we use enqueue/dequeue.
> The only difference between two modes is if adapter enqueue the events with
> RTE_EVENT_OP_NEW vs RTE_EVENT_OP_FORWARD then (IMO) we can change
> something related to that name to avoid adding a new terminology.
>
Oh, sure -- enqueue/dequeue makes sense here. I'd still prefer DEQ_ONLY or DEQ_ENQ, but the event_op names work just as well.
Speaking of the crypto domain, the cryptodev enqueue and dequeue operations both take crypto op pointers. The original RFC had the request event pointing to an mbuf (which had a crypto_op pointer in its private metadata), but with the suggested opaque eventdev metadata changes it makes more sense for the request event to point to a crypto op. And the RFC didn't specify what the response event would point to (mbuf or crypto op), but to match the cryptodev dequeue operation then a crypto op makes sense. Will this work with your hardware?
> BTW, Based on the earlier discussion, if we need to add opaque eventdev
> metadata to cryptodev then it may change ABI.If so, I think, we need to
> announce ABI change notice for cryptodev and plan cryptodev adapter for
> v18.05.
Personally I'd prefer to get this right/agreed-upon the first time around -- even if that means breaking ABI and pushing this adapter out to 18.05.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer
2017-12-14 13:57 3% ` Ananyev, Konstantin
@ 2017-12-18 16:38 0% ` Jerin Jacob
2017-12-19 15:27 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2017-12-18 16:38 UTC (permalink / raw)
To: Ananyev, Konstantin; +Cc: dev, shahafs
-----Original Message-----
> Date: Thu, 14 Dec 2017 13:57:02 +0000
> From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: "dev@dpdk.org" <dev@dpdk.org>, "shahafs@mellanox.com"
> <shahafs@mellanox.com>
> Subject: RE: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev
> layer
>
> Hi Jerin,
Hi Konstantin,
>
> >
> > Hi Konstantin,
> >
> > > The series introduces 2 main changes:
> > >
> > > 1.Introduce a separate data structure (rte_eth_queue_local)
> > > to store local to given process (i.e. no-shareable) information
> > > for each configured rx/tx queue.
> > > Memory for that structure is allocated/freed dynamically during
> > > rte_eth_dev_configure().
> > > Reserve a space for queue specific (rx|tx)_pkt_burst(),
> > > tx_pkt_prepare() function pointers inside that structure.
> > > Move rx/tx callback related information inside that structure.
> > > That introduces a change in current behavior: all callbacks for
> > > un-configured queues will be automatically removed.
> > > Also as size of struct rte_eth_dev changes that patch is an ABI breakage,
> > > so deprecation notice for 18.05 is filled.
> > > Further suggestions how to introduce the same functionality
> > > without ABI breakage are welcome.
> >
> > Are we doing this to enable, Tx/Rx queue specific burst functions to
> > invoke based on new TX/RX queue specific offloads framework.
> > Meaning, if a offload configured for the given queue,
> > driver can select a different function pointer for Rx/Tx burst functions.
>
> Yes that's the stretch goal.
> We do need some extra space for rx/tx callbacks (use field) that needs to
> be cache aligned and we plan to make rx/tx function per queue.
> So I thought it would be a good opportunity to do these 2 things in one go -
> to minimize number of ABI breakages.
Makes sense.
>
> >
> > >
> > > 2. Make it safe to remove rx/tx callback at runtime.
> > > Right now it is not possible for the application to figure out
> > > when it is safe to free removed callback handle and
> > > associated with it resources(unless the queue is stopped).
> > > That's probably not a big problem if all callbacks are static
> > > hange through whole application lifetime)
> > > and/or application doesn't allocate any resources for the callback handler.
> > > Though if callbacks have to be added/removed dynamically and
> > > callback handler would require more resources to operate properly -
> > > then it might become an issue.
> > > So patch #2 fixes that problem - now as soon as
> > > rte_eth_remove_(rx|tx)_callback() completes successfully, application
> > > can safely free all associated with the removed callback resources.
> > >
> > > Performance impact:
> > > If application doesn't use RX/TX callbacks, then the tests I run didn't
> > > reveal any performance degradation.
> > > Though if application do use RX/TX callbacks - patch #2 does introduce
> > > some slowdown.
> > >
> > > To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
> > > with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
> > > 1) testpmd ... --latencystats=1 - slowdown < 1%
> > > 2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
> > > 3) examples/rxtx_callbacks - slowdown ~8%
> > > All that in terms of packet throughput (Mpps).
> >
> > We tried on an arm64 machine; We got following result on host and guest
> > using l3fwd.
>
> Thanks for testing it.
> So these numbers below - are for l3fwd running with or without rx callback installed?
> i.e. with or without '--parse-ptype' option (and on a NIC with/without ptype HW support)?
without '--parse-ptype' option(i.e without rx callback installed).
That makes it sad, Even though application is not using the rx callback,
We need to pay on a average 3% drop in performance(based on the
use case/arch/SoC/topology etc)
>
> >
> >
> > Note:
> > +ve number means "Performance regression with patches"
> > -ve number means "Performance improvement with patches"
> >
> > Relative performance difference in percentage:
> >
> > % difference on host (2 x 40G)
> > pkt_sz 1c 2c 4c 8c
> > 64 1.41 0.18 0.51 0.29
> > 72 0.50 0.53 0.09 0.19
> > 128 0.31 0.31 0.42 0.00
> > 256 -0.44 -0.44 0.00 0.00
> > 512 1.94 1.94 0.01 0.01
> > 1024 0.00 0.01 0.00 0.01
> > 1518 0.02 0.01 0.02 0.02
> >
> > % difference on guest (2 x 40G)
> > pkt_sz 1c 2c 4c 8c
> > 64 5.78 2.30 -2.45 -0.01
> > 72 1.13 1.13 1.31 -4.29
> > 128 1.36 1.36 1.54 -0.82
> > 256 2.02 2.03 -0.01 -0.35
> > 512 4.05 4.04 0.00 -0.46
> > 1024 0.39 0.38 0.00 -0.74
> > 1518 0.00 0.00 -0.05 -4.20
> >
> > I think, it is because we added more code under
> > the RTE_ETHDEV_RXTX_CALLBACKS and it is enabled by
> > default.
> >
> > I think, the impact will vary based on
> > architecture and underneath i-cache, d-cache and IPC.
> >
> > I am just thinking, How we can avoid such impact?
> > How about,
> > # Remove RTE_ETHDEV_RXTX_CALLBACKS option
> > # Hook Rx/TX callbacks under TX/RX offload flags
> > # ethdev layer gives helper function to invoke
> > callbacks to driver.
>
> I suppose you suggest that user would have to decide at queue_setup()
> stage does he wants a callback(s) for RX/TX or no?
Yes. queue_setup or configure() time.
> As I can see, the main drawback with that approach - it would introduce new limitation.
> Right now it is possible to add/remove RX/TX callback at runtime
> (without stopping and reconfiguring the queue), and I suppose we do want to keep that ability.
For those _application_ where it can not decide or it need to add without
stopping and re configuring the queue still can configure/enable the ethdev
device with RX/TX callback option(and pay price for it)
> Again in some cases user can't decide does he wants a callback installed or not,
> before he actually calls dev_start().
> l3fwd ptype-parse callback is an example of such situation:
> right now user has to start device first to figure out which ptypes are supported by this PMD
> with desired configuration, then based on this information he will (or will not) setup the callback.
Good point. Can we remove that limitation from PMD perspective? IMO, ptype-parse is more of HW feature,
All we need to do a lookup(single load) to convert to DPDK packet type.
http://dpdk.org/browse/dpdk/tree/drivers/net/thunderx/nicvf_rxtx.c#n258
I see almost all the drivers has dummy check like this, I think, That makes it
dependency with start().
if (dev->rx_pkt_burst == i40e_recv_pkts ||
dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
dev->rx_pkt_burst == i40e_recv_scattered_pkts ||
dev->rx_pkt_burst == i40e_recv_scattered_pkts_vec ||
dev->rx_pkt_burst == i40e_recv_pkts_vec)
return ptypes;
> What I thought in same direction - introduce a notion of 'static' and 'dynamic' callbacks.
> Static ones can't be removed while queue is not stopped while dynamic can.
> But that also requires user to select at queue_setup() stage does he wants dynamic
> callbacks for that queue or not (new offload flag or extra field in rxconf/txconf structure).
> So again - same limitation for the user.
> Another possibility here - have a flag 'dynamic' or 'static' not per queue, but per individual callback.
> Yes, that would mean API change for add/remove callback functions.
At least on my test, the regression was caused because adding the code in
tx_burst and rx_burst under the RTE_ETHDEV_RXTX_CALLBACKS(which enabled
by default). By disabling the RTE_ETHDEV_RXTX_CALLBACKS option, I don't
see any regression. If so, Will such regression fixed by introducing
'static' or 'dynamic' callbacks? I am happy to test and provide feedback.
For me, I think, The better option is request from application for the
need for Rx/TX callbacks and set the handler appropriate in the driver to
have zero impact for the application which does not need callback at all.
at minimum, on those PMDs that support detecting the supported ptypes without
device start()
>
> Konstantin
>
> > But, don't invoke from common code
> > # When application needs the callback support, it
> > configured the given RX/TX queue offloads
> > # If the Rx/TX callback configure by the application
> > then driver calls the helper functions exposed by
> > the common code to invoke RX callbacks.
>
>
> >
> > Jerin
> >
> > >
> > > Ability to safely remove callbacks at runtime implies
> > > some sort of synchronization.
> > > Even I tried to make it as light as possible,
> > > probably some slowdown is unavoidable.
> > > Of course instead of introducing these changes at rte_ethdev layer
> > > similar technique could be applied on individual callback basis.
> > > In that case it would be up to callback writer/installer to decide
> > > does he/she need a removable at runtime callback or not.
> > > Though in that case, each installed callback might introduce extra
> > > synchronization overhead and slowdown.
> > >
> > > Konstantin Ananyev (3):
> > > ethdev: introduce eth_queue_local
> > > ethdev: make it safe to remove rx/tx callback at runtime
> > > doc: ethdev ABI change deprecation notice
> > >
> > > doc/guides/rel_notes/deprecation.rst | 5 +
> > > lib/librte_ether/rte_ethdev.c | 390 ++++++++++++++++++++++-------------
> > > lib/librte_ether/rte_ethdev.h | 174 ++++++++++++----
> > > 3 files changed, 387 insertions(+), 182 deletions(-)
> > >
> > > --
> > > 2.13.5
> > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] doc: announce ABI change for pktmbuf pool create API
2017-12-18 13:51 8% ` Wiles, Keith
2017-12-18 14:43 4% ` Neil Horman
@ 2017-12-19 5:40 4% ` Hemant Agrawal
2017-12-19 13:41 4% ` Wiles, Keith
1 sibling, 1 reply; 200+ results
From: Hemant Agrawal @ 2017-12-19 5:40 UTC (permalink / raw)
To: Wiles, Keith; +Cc: olivier.matz, dev, Jerin Jacob, Neil Horman
On 12/18/2017 7:21 PM, Wiles, Keith wrote:
>
>
>> On Dec 15, 2017, at 4:41 AM, Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
>>
>> Introduce a new argument ops_name in rte_mempool_set_ops_byname
>> for allowing the application to optionally specify the mempool ops.
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>> v2: fix checkpatch error
>>
>> doc/guides/rel_notes/deprecation.rst | 3 +++
>> 1 file changed, 3 insertions(+)
>>
>> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
>> index 13e8543..968ca14 100644
>> --- a/doc/guides/rel_notes/deprecation.rst
>> +++ b/doc/guides/rel_notes/deprecation.rst
>> @@ -53,3 +53,6 @@ Deprecation Notices
>>
>> * librte_meter: The API will change to accommodate configuration profiles.
>> Most of the API functions will have an additional opaque parameter.
>> +
>> +* librte_mbuf: a new optional parameter for representing name of mempool_ops
>> + will be added to the API ``rte_pktmbuf_pool_create``.
>
>
> Sorry, for the late response I was on vacation.
>
> My question is why do we need to change rte_pktmbuf_pool_create ABI yet again, why could we not add a new API to just set the name of the pool after it is created. This would allow all current applications to work without any ABI breakage and only require adding a new API call for anyone that wants the name. The rte_pktmbuf_pool_create() routine could assign a default name or some incrementing style name as the default. e.g. ‘pktmbuf_%d’ with a static incrementing variable or whatever you like.
>
> Sorry if this was asked and answered before.
>
I understand the concerns.
However, the new API to just set the name will not work post create.
rte_pktmbuf_pool_create is a wrapper API, which complete the mempool
configuration on the basis default mempool_ops.
The idea proposed is to create pktmbuf pool from a specific mempool
(ops_name).
We can leave "rte_pktmbuf_pool_create" as it is.
and create another similar API with e.g.
"rte_pktmbuf_pool_create_specific", which will also take ops_name as
argument. (We can combine the internal implementation with NULL
ops_name for rte_pktmbuf_pool_create.)
This way we will have flexibility for the applications looking for
pktmbufs from a specific mempool.
any thoughts?
Hemant
>> --
>> 2.7.4
>>
>
> Regards,
> Keith
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [RFC] eventdev: add crypto adapter API header
2017-12-18 16:33 3% ` Eads, Gage
@ 2017-12-19 8:47 0% ` Jerin Jacob
0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2017-12-19 8:47 UTC (permalink / raw)
To: Eads, Gage
Cc: Gujjar, Abhinandan S, dev, Vangati, Narender, Rao, Nikhil,
hemant.agrawal, Doherty, Declan, nidadavolu.murthy,
nithin.dabilpuram, narayanaprasad.athreya
-----Original Message-----
> Date: Mon, 18 Dec 2017 16:33:53 +0000
> From: "Eads, Gage" <gage.eads@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: "Gujjar, Abhinandan S" <abhinandan.gujjar@intel.com>, "dev@dpdk.org"
> <dev@dpdk.org>, "Vangati, Narender" <narender.vangati@intel.com>, "Rao,
> Nikhil" <nikhil.rao@intel.com>, "hemant.agrawal@nxp.com"
> <hemant.agrawal@nxp.com>, "Doherty, Declan" <declan.doherty@intel.com>,
> "nidadavolu.murthy@cavium.com" <nidadavolu.murthy@cavium.com>,
> "nithin.dabilpuram@cavium.com" <nithin.dabilpuram@cavium.com>,
> "narayanaprasad.athreya@cavium.com" <narayanaprasad.athreya@cavium.com>
> Subject: RE: [RFC] eventdev: add crypto adapter API header
>
>
>
> > -----Original Message-----
> > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > Sent: Monday, December 18, 2017 12:30 AM
> > To: Eads, Gage <gage.eads@intel.com>
> > Cc: Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>; dev@dpdk.org;
> > Vangati, Narender <narender.vangati@intel.com>; Rao, Nikhil
> > <nikhil.rao@intel.com>; hemant.agrawal@nxp.com; Doherty, Declan
> > <declan.doherty@intel.com>; nidadavolu.murthy@cavium.com;
> > nithin.dabilpuram@cavium.com; narayanaprasad.athreya@cavium.com
> > Subject: Re: [RFC] eventdev: add crypto adapter API header
> >
> > -----Original Message-----
> > > Date: Thu, 14 Dec 2017 18:52:02 +0000
> > > From: "Eads, Gage" <gage.eads@intel.com>
> > > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > > CC: "Gujjar, Abhinandan S" <abhinandan.gujjar@intel.com>, "dev@dpdk.org"
> > > <dev@dpdk.org>, "Vangati, Narender" <narender.vangati@intel.com>,
> > > "Rao, Nikhil" <nikhil.rao@intel.com>, "hemant.agrawal@nxp.com"
> > > <hemant.agrawal@nxp.com>, "Doherty, Declan"
> > > <declan.doherty@intel.com>, "nidadavolu.murthy@cavium.com"
> > > <nidadavolu.murthy@cavium.com>, "nithin.dabilpuram@cavium.com"
> > > <nithin.dabilpuram@cavium.com>, "narayanaprasad.athreya@cavium.com"
> > > <narayanaprasad.athreya@cavium.com>
> > > Subject: RE: [RFC] eventdev: add crypto adapter API header
> > >
> > >
> > >
> > > > -----Original Message-----
> > > > From: Jerin Jacob [mailto:jerin.jacob@caviumnetworks.com]
> > > > Sent: Wednesday, December 13, 2017 8:49 PM
> > > > To: Eads, Gage <gage.eads@intel.com>
> > > > Cc: Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>;
> > > > dev@dpdk.org; Vangati, Narender <narender.vangati@intel.com>; Rao,
> > > > Nikhil <nikhil.rao@intel.com>; hemant.agrawal@nxp.com; Doherty,
> > > > Declan <declan.doherty@intel.com>; nidadavolu.murthy@cavium.com;
> > > > nithin.dabilpuram@cavium.com; narayanaprasad.athreya@cavium.com
> > > > Subject: Re: [RFC] eventdev: add crypto adapter API header
> > > >
> > > > -----Original Message-----
> > > > > Date: Wed, 13 Dec 2017 23:35:48 +0000
> > > > > From: "Eads, Gage" <gage.eads@intel.com>
> > > > > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>, "Gujjar, Abhinandan
> > S"
> > > > > <abhinandan.gujjar@intel.com>
> > > > > CC: "dev@dpdk.org" <dev@dpdk.org>, "Vangati, Narender"
> > > > > <narender.vangati@intel.com>, "Rao, Nikhil"
> > > > > <nikhil.rao@intel.com>, "hemant.agrawal@nxp.com"
> > <hemant.agrawal@nxp.com>, "Doherty, Declan"
> > > > > <declan.doherty@intel.com>, "nidadavolu.murthy@cavium.com"
> > > > > <nidadavolu.murthy@cavium.com>, "nithin.dabilpuram@cavium.com"
> > > > > <nithin.dabilpuram@cavium.com>,
> > "narayanaprasad.athreya@cavium.com"
> > > > > <narayanaprasad.athreya@cavium.com>
> > > > > Subject: RE: [RFC] eventdev: add crypto adapter API header
> > > > >
> > > > > Hey Jerin,
> > > >
> > > > Hey Gage,
> > > >
> > > > >
> > > > > </snip>
> > > > >
> > > > > > > +
> > > > > > > + /**
> > > > > > > + * @warning
> > > > > > > + * @b EXPERIMENTAL: this enum may change without prior notice
> > > > > > > + *
> > > > > > > + * Crypto event adapter type
> > > > > > > + */
> > > > > > > +enum rte_event_crypto_adapter_type {
> > > > > > > + RTE_EVENT_CRYPTO_ADAPTER_RX_ONLY = 1,
> > > > > > > + /**< Start only Rx part of crypto adapter.
> > > > > > > + * Packets dequeued from cryptodev are new to eventdev and
> > > > > > > + * events will be treated as RTE_EVENT_OP_NEW */
> > > > > > > + RTE_EVENT_CRYPTO_ADAPTER_RX_TX,
> > > > > > > + /**< Start both Rx & Tx part of crypto adapter.
> > > > > > > + * Packet's event context will be retained and
> > > > > > > + * event will be treated as RTE_EVENT_OP_FORWARD */ };
> > > > > >
> > > > > > How about leveraging ev.op based schematics as mentioned above?
> > > > >
> > > > > That could work, but perhaps the ev.op should be configured once
> > > > > up front, as
> > > > I see it being a function of the application architecture. A couple
> > > > possible designs, for example:
> > > > > - Worker enqueues into cryptodev, adapter polls for response: the
> > > > > adapter
> > > > port would always use OP_NEW here.
> > > > > - Worker sends a crypto request event to the adapter, which gives
> > > > > the request to the cryptodev and polls for response: the adapter
> > > > > port would always use OP_FWD here. (This ties in with my implicit
> > > > > release patch
> > > > > (http://dpdk.org/ml/archives/dev/2017-December/083535.html))
> > > > > - Etc.
> > > >
> > > > Yes. Semantically both approaches will work. I was trying to avoid
> > > > extra clutter(enum rte_event_crypto_adapter_type) in adapter API.
> > > > I don't see any problem in moving ev.op to adapter configuration
> > > > time if it helps the SW driver.
> > > >
> > > > IMO, We can change RTE_EVENT_CRYPTO_ADAPTER_RX_ONLY and
> > > > RTE_EVENT_CRYPTO_ADAPTER_RX_TX to more appropriate name,
> > something
> > > > like,
> > RTE_EVENT_CRYPTO_ADAPTER_TYPE_OP_NEW/RTE_EVENT_CRYPTO_ADAPTE
> > > > R_TYPE_OP_FWD
> > > > or something like that.
> > > >
> > >
> > > I agree that the two naming schemes are equivalent, but since this option
> > would control the adapter's behavior (Rx only vs. Rx + Tx), (IMO) I think
> > Abhinandan's original names do a better job of conveying what effect these two
> > options have on the adapter, compared to the op type names.
> >
> > The only concern with Rx/Tx terminology was, It is mostly used in the ethdev
> > domain.
> > In crypto domain, typically, we use enqueue/dequeue.
> > The only difference between two modes is if adapter enqueue the events with
> > RTE_EVENT_OP_NEW vs RTE_EVENT_OP_FORWARD then (IMO) we can change
> > something related to that name to avoid adding a new terminology.
> >
>
> Oh, sure -- enqueue/dequeue makes sense here. I'd still prefer DEQ_ONLY or DEQ_ENQ, but the event_op names work just as well.
I prefer event_op name but enqueue/dequeue name work as well.
>
> Speaking of the crypto domain, the cryptodev enqueue and dequeue operations both take crypto op pointers. The original RFC had the request event pointing to an mbuf (which had a crypto_op pointer in its private metadata), but with the suggested opaque eventdev metadata changes it makes more sense for the request event to point to a crypto op. And the RFC didn't specify what the response event would point to (mbuf or crypto op), but to match the cryptodev dequeue operation then a crypto op makes sense. Will this work with your hardware?
Yes. crypto op will work with Cavium HW. NXP guys can comment on their HW.
We are treating rte_event.event_ptr as opaque event pointer so it can carry
crypto_op or mbuf pointer.I think, For crypto operation, rte_crypto_op make sense as it has "status" etc.
May be for inline ipsec, mbuf would make sense. So I think, we can support both options by
reserving size of struct rte_event as eventdev metadata in crypto area.
>
> > BTW, Based on the earlier discussion, if we need to add opaque eventdev
> > metadata to cryptodev then it may change ABI.If so, I think, we need to
> > announce ABI change notice for cryptodev and plan cryptodev adapter for
> > v18.05.
>
> Personally I'd prefer to get this right/agreed-upon the first time around -- even if that means breaking ABI and pushing this adapter out to 18.05.
I agree and that makes sense too.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/3] lib/cmdline: add echo support in batch loading from file
@ 2017-12-19 10:30 3% ` Olivier MATZ
2017-12-19 11:20 0% ` Xueming(Steven) Li
0 siblings, 1 reply; 200+ results
From: Olivier MATZ @ 2017-12-19 10:30 UTC (permalink / raw)
To: Xueming Li; +Cc: Jingjing Wu, dev
Hi Xueming,
On Wed, Nov 15, 2017 at 11:45:43PM +0800, Xueming Li wrote:
> Add echo option to echo commandline to screen when running loaded
> scripts from file.
>
> Signed-off-by: Xueming Li <xuemingl@mellanox.com>
> ---
> lib/librte_cmdline/cmdline_socket.c | 5 +++--
> lib/librte_cmdline/cmdline_socket.h | 3 ++-
> 2 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/lib/librte_cmdline/cmdline_socket.c b/lib/librte_cmdline/cmdline_socket.c
> index 3fc243b70..e57ddeffb 100644
> --- a/lib/librte_cmdline/cmdline_socket.c
> +++ b/lib/librte_cmdline/cmdline_socket.c
> @@ -73,7 +73,8 @@
> #include "cmdline.h"
>
> struct cmdline *
> -cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path)
> +cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path,
> + int echo)
> {
> int fd;
>
> @@ -86,7 +87,7 @@ cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path)
> dprintf("open() failed\n");
> return NULL;
> }
> - return cmdline_new(ctx, prompt, fd, -1);
> + return cmdline_new(ctx, prompt, fd, echo ? 1 : -1);
> }
>
> struct cmdline *
> diff --git a/lib/librte_cmdline/cmdline_socket.h b/lib/librte_cmdline/cmdline_socket.h
> index aa6068e7e..208134b12 100644
> --- a/lib/librte_cmdline/cmdline_socket.h
> +++ b/lib/librte_cmdline/cmdline_socket.h
> @@ -68,7 +68,8 @@
> extern "C" {
> #endif
>
> -struct cmdline *cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const char *path);
> +struct cmdline *cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt,
> + const char *path, int echo);
> struct cmdline *cmdline_stdin_new(cmdline_parse_ctx_t *ctx, const char *prompt);
> void cmdline_stdin_exit(struct cmdline *cl);
This breaks the API and ABI.
And it also breaks the compilation, because the modifications of applications
are done in the next commits.
You can send a deprecation notice, and this patch could be added in for 18.05.
But instead, I suggest you to reimplement your own version of cmdline_file_new()
with the echo feature inside testpmd.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/3] lib/cmdline: add echo support in batch loading from file
2017-12-19 10:30 3% ` Olivier MATZ
@ 2017-12-19 11:20 0% ` Xueming(Steven) Li
0 siblings, 0 replies; 200+ results
From: Xueming(Steven) Li @ 2017-12-19 11:20 UTC (permalink / raw)
To: Olivier MATZ; +Cc: Jingjing Wu, dev
The idea of implementation in testpmd looks good, thanks!
Then I will combine all patches in v1 to avoid breaking build.
> -----Original Message-----
> From: Olivier MATZ [mailto:olivier.matz@6wind.com]
> Sent: Tuesday, December 19, 2017 6:31 PM
> To: Xueming(Steven) Li <xuemingl@mellanox.com>
> Cc: Jingjing Wu <jingjing.wu@intel.com>; dev@dpdk.org
> Subject: Re: [PATCH 1/3] lib/cmdline: add echo support in batch loading
> from file
>
> Hi Xueming,
>
> On Wed, Nov 15, 2017 at 11:45:43PM +0800, Xueming Li wrote:
> > Add echo option to echo commandline to screen when running loaded
> > scripts from file.
> >
> > Signed-off-by: Xueming Li <xuemingl@mellanox.com>
> > ---
> > lib/librte_cmdline/cmdline_socket.c | 5 +++--
> > lib/librte_cmdline/cmdline_socket.h | 3 ++-
> > 2 files changed, 5 insertions(+), 3 deletions(-)
> >
> > diff --git a/lib/librte_cmdline/cmdline_socket.c
> > b/lib/librte_cmdline/cmdline_socket.c
> > index 3fc243b70..e57ddeffb 100644
> > --- a/lib/librte_cmdline/cmdline_socket.c
> > +++ b/lib/librte_cmdline/cmdline_socket.c
> > @@ -73,7 +73,8 @@
> > #include "cmdline.h"
> >
> > struct cmdline *
> > -cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const
> > char *path)
> > +cmdline_file_new(cmdline_parse_ctx_t *ctx, const char *prompt, const
> char *path,
> > + int echo)
> > {
> > int fd;
> >
> > @@ -86,7 +87,7 @@ cmdline_file_new(cmdline_parse_ctx_t *ctx, const char
> *prompt, const char *path)
> > dprintf("open() failed\n");
> > return NULL;
> > }
> > - return cmdline_new(ctx, prompt, fd, -1);
> > + return cmdline_new(ctx, prompt, fd, echo ? 1 : -1);
> > }
> >
> > struct cmdline *
> > diff --git a/lib/librte_cmdline/cmdline_socket.h
> > b/lib/librte_cmdline/cmdline_socket.h
> > index aa6068e7e..208134b12 100644
> > --- a/lib/librte_cmdline/cmdline_socket.h
> > +++ b/lib/librte_cmdline/cmdline_socket.h
> > @@ -68,7 +68,8 @@
> > extern "C" {
> > #endif
> >
> > -struct cmdline *cmdline_file_new(cmdline_parse_ctx_t *ctx, const char
> > *prompt, const char *path);
> > +struct cmdline *cmdline_file_new(cmdline_parse_ctx_t *ctx, const char
> *prompt,
> > + const char *path, int echo);
> > struct cmdline *cmdline_stdin_new(cmdline_parse_ctx_t *ctx, const
> > char *prompt); void cmdline_stdin_exit(struct cmdline *cl);
>
> This breaks the API and ABI.
> And it also breaks the compilation, because the modifications of
> applications are done in the next commits.
>
> You can send a deprecation notice, and this patch could be added in for
> 18.05.
>
> But instead, I suggest you to reimplement your own version of
> cmdline_file_new() with the echo feature inside testpmd.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] doc: announce ABI change for pktmbuf pool create API
2017-12-19 5:40 4% ` Hemant Agrawal
@ 2017-12-19 13:41 4% ` Wiles, Keith
2017-12-22 15:26 4% ` Olivier MATZ
0 siblings, 1 reply; 200+ results
From: Wiles, Keith @ 2017-12-19 13:41 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: olivier.matz, dev, Jerin Jacob, Neil Horman
> On Dec 18, 2017, at 11:40 PM, Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
>
> On 12/18/2017 7:21 PM, Wiles, Keith wrote:
>>
>>
>>> On Dec 15, 2017, at 4:41 AM, Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
>>>
>>> Introduce a new argument ops_name in rte_mempool_set_ops_byname
>>> for allowing the application to optionally specify the mempool ops.
>>>
>>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>>> ---
>>> v2: fix checkpatch error
>>>
>>> doc/guides/rel_notes/deprecation.rst | 3 +++
>>> 1 file changed, 3 insertions(+)
>>>
>>> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
>>> index 13e8543..968ca14 100644
>>> --- a/doc/guides/rel_notes/deprecation.rst
>>> +++ b/doc/guides/rel_notes/deprecation.rst
>>> @@ -53,3 +53,6 @@ Deprecation Notices
>>>
>>> * librte_meter: The API will change to accommodate configuration profiles.
>>> Most of the API functions will have an additional opaque parameter.
>>> +
>>> +* librte_mbuf: a new optional parameter for representing name of mempool_ops
>>> + will be added to the API ``rte_pktmbuf_pool_create``.
>>
>>
>> Sorry, for the late response I was on vacation.
>>
>> My question is why do we need to change rte_pktmbuf_pool_create ABI yet again, why could we not add a new API to just set the name of the pool after it is created. This would allow all current applications to work without any ABI breakage and only require adding a new API call for anyone that wants the name. The rte_pktmbuf_pool_create() routine could assign a default name or some incrementing style name as the default. e.g. ‘pktmbuf_%d’ with a static incrementing variable or whatever you like.
>>
>> Sorry if this was asked and answered before.
>>
>
> I understand the concerns.
>
> However, the new API to just set the name will not work post create.
> rte_pktmbuf_pool_create is a wrapper API, which complete the mempool configuration on the basis default mempool_ops.
Really can not add the name after the fact, I have not looked, but it seem very odd we can not use the mempool pointer and update the ops_name. What is stopping this from working?
>
> The idea proposed is to create pktmbuf pool from a specific mempool (ops_name).
>
> We can leave "rte_pktmbuf_pool_create" as it is.
> and create another similar API with e.g. "rte_pktmbuf_pool_create_specific", which will also take ops_name as argument. (We can combine the internal implementation with NULL ops_name for rte_pktmbuf_pool_create.)
I would accept this approach over the original patch to change the name of a commonly used API.
>
> This way we will have flexibility for the applications looking for pktmbufs from a specific mempool.
>
> any thoughts?
>
> Hemant
>
>>> --
>>> 2.7.4
>>>
>>
>> Regards,
>> Keith
Regards,
Keith
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer
2017-12-18 16:38 0% ` Jerin Jacob
@ 2017-12-19 15:27 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2017-12-19 15:27 UTC (permalink / raw)
To: Jerin Jacob; +Cc: dev, shahafs
Hi Jerin,
> > > >
> > > > 2. Make it safe to remove rx/tx callback at runtime.
> > > > Right now it is not possible for the application to figure out
> > > > when it is safe to free removed callback handle and
> > > > associated with it resources(unless the queue is stopped).
> > > > That's probably not a big problem if all callbacks are static
> > > > hange through whole application lifetime)
> > > > and/or application doesn't allocate any resources for the callback handler.
> > > > Though if callbacks have to be added/removed dynamically and
> > > > callback handler would require more resources to operate properly -
> > > > then it might become an issue.
> > > > So patch #2 fixes that problem - now as soon as
> > > > rte_eth_remove_(rx|tx)_callback() completes successfully, application
> > > > can safely free all associated with the removed callback resources.
> > > >
> > > > Performance impact:
> > > > If application doesn't use RX/TX callbacks, then the tests I run didn't
> > > > reveal any performance degradation.
> > > > Though if application do use RX/TX callbacks - patch #2 does introduce
> > > > some slowdown.
> > > >
> > > > To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
> > > > with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
> > > > 1) testpmd ... --latencystats=1 - slowdown < 1%
> > > > 2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
> > > > 3) examples/rxtx_callbacks - slowdown ~8%
> > > > All that in terms of packet throughput (Mpps).
> > >
> > > We tried on an arm64 machine; We got following result on host and guest
> > > using l3fwd.
> >
> > Thanks for testing it.
> > So these numbers below - are for l3fwd running with or without rx callback installed?
> > i.e. with or without '--parse-ptype' option (and on a NIC with/without ptype HW support)?
>
> without '--parse-ptype' option(i.e without rx callback installed).
> That makes it sad, Even though application is not using the rx callback,
> We need to pay on a average 3% drop in performance(based on the
> use case/arch/SoC/topology etc)
Yes it is sad...
Do you have any idea why that happens?
Is that the same situation you described before: for arm compiler
often replaces small branches with conditional execution instructions
and miss-prediction for such instructions is not free?
Or is it something else?
Another thing - the series contains 2 main patches:
1) http://dpdk.org/dev/patchwork/patch/31866/
Introduces eth_queue_local and moves callback data into it.
That adds one extra memory reference for rx/tx function to read cb func and data.
2) http://dpdk.org/dev/patchwork/patch/31867/
Introduces some synchronization for cb data.
Is it possible to rerun your tests with just patch #1 installed?
Hopefully it would help us to figure out which of the patches (#1 or #2)
is the main source of slowdown on arm machines.
>
> >
> > >
> > >
> > > Note:
> > > +ve number means "Performance regression with patches"
> > > -ve number means "Performance improvement with patches"
> > >
> > > Relative performance difference in percentage:
> > >
> > > % difference on host (2 x 40G)
> > > pkt_sz 1c 2c 4c 8c
> > > 64 1.41 0.18 0.51 0.29
> > > 72 0.50 0.53 0.09 0.19
> > > 128 0.31 0.31 0.42 0.00
> > > 256 -0.44 -0.44 0.00 0.00
> > > 512 1.94 1.94 0.01 0.01
> > > 1024 0.00 0.01 0.00 0.01
> > > 1518 0.02 0.01 0.02 0.02
> > >
> > > % difference on guest (2 x 40G)
> > > pkt_sz 1c 2c 4c 8c
> > > 64 5.78 2.30 -2.45 -0.01
> > > 72 1.13 1.13 1.31 -4.29
> > > 128 1.36 1.36 1.54 -0.82
> > > 256 2.02 2.03 -0.01 -0.35
> > > 512 4.05 4.04 0.00 -0.46
> > > 1024 0.39 0.38 0.00 -0.74
> > > 1518 0.00 0.00 -0.05 -4.20
> > >
> > > I think, it is because we added more code under
> > > the RTE_ETHDEV_RXTX_CALLBACKS and it is enabled by
> > > default.
> > >
> > > I think, the impact will vary based on
> > > architecture and underneath i-cache, d-cache and IPC.
> > >
> > > I am just thinking, How we can avoid such impact?
> > > How about,
> > > # Remove RTE_ETHDEV_RXTX_CALLBACKS option
> > > # Hook Rx/TX callbacks under TX/RX offload flags
> > > # ethdev layer gives helper function to invoke
> > > callbacks to driver.
> >
> > I suppose you suggest that user would have to decide at queue_setup()
> > stage does he wants a callback(s) for RX/TX or no?
>
> Yes. queue_setup or configure() time.
>
> > As I can see, the main drawback with that approach - it would introduce new limitation.
> > Right now it is possible to add/remove RX/TX callback at runtime
> > (without stopping and reconfiguring the queue), and I suppose we do want to keep that ability.
>
> For those _application_ where it can not decide or it need to add without
> stopping and re configuring the queue still can configure/enable the ethdev
> device with RX/TX callback option(and pay price for it)
>
> > Again in some cases user can't decide does he wants a callback installed or not,
> > before he actually calls dev_start().
> > l3fwd ptype-parse callback is an example of such situation:
> > right now user has to start device first to figure out which ptypes are supported by this PMD
> > with desired configuration, then based on this information he will (or will not) setup the callback.
>
> Good point. Can we remove that limitation from PMD perspective? IMO, ptype-parse is more of HW feature,
> All we need to do a lookup(single load) to convert to DPDK packet type.
> http://dpdk.org/browse/dpdk/tree/drivers/net/thunderx/nicvf_rxtx.c#n258
>
> I see almost all the drivers has dummy check like this, I think, That makes it
> dependency with start().
>
> if (dev->rx_pkt_burst == i40e_recv_pkts ||
> dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
> dev->rx_pkt_burst == i40e_recv_scattered_pkts ||
> dev->rx_pkt_burst == i40e_recv_scattered_pkts_vec ||
> dev->rx_pkt_burst == i40e_recv_pkts_vec)
> return ptypes;
>
We probably can, but it would require extra work and changes inside the PMDs.
i40e is a good one - all rx functions support the same ptypes.
But let say for ixgbe ARM version of vRX doesn't support all ptypes that x86 vRX
and generic scalar RX do.
For fm10k - vector RX and scalar RX also support different ptype sets.
>
> > What I thought in same direction - introduce a notion of 'static' and 'dynamic' callbacks.
> > Static ones can't be removed while queue is not stopped while dynamic can.
> > But that also requires user to select at queue_setup() stage does he wants dynamic
> > callbacks for that queue or not (new offload flag or extra field in rxconf/txconf structure).
> > So again - same limitation for the user.
> > Another possibility here - have a flag 'dynamic' or 'static' not per queue, but per individual callback.
> > Yes, that would mean API change for add/remove callback functions.
>
> At least on my test, the regression was caused because adding the code in
> tx_burst and rx_burst under the RTE_ETHDEV_RXTX_CALLBACKS(which enabled
> by default). By disabling the RTE_ETHDEV_RXTX_CALLBACKS option, I don't
> see any regression. If so, Will such regression fixed by introducing
> 'static' or 'dynamic' callbacks? I am happy to test and provide feedback.
Probably no then, but let's try the experiment I mentioned above first.
>
> For me, I think, The better option is request from application for the
> need for Rx/TX callbacks and set the handler appropriate in the driver to
> have zero impact for the application which does not need callback at all.
It is possible, but:
- that would be quite significant change and would affect each RX and TX function in each PMD.
- from other side - even now there are several libs inside DPDK that rely on ability to add/remove
callbacks on the fly - pdump, latencystats.
ethdev rx profiling also relies on ability to install RX callback.
With all these things I presume most apps will configure their devices with rx/tx callback support enabled anyway.
Which makes me think - is it worth to introduce such changes at all.
Anyway, my first suggestion would be let's try to figure out what exactly causes such big slowdown on ARM.
Konstantin
>
> at minimum, on those PMDs that support detecting the supported ptypes without
> device start()
>
>
>
>
> >
> > Konstantin
> >
> > > But, don't invoke from common code
> > > # When application needs the callback support, it
> > > configured the given RX/TX queue offloads
> > > # If the Rx/TX callback configure by the application
> > > then driver calls the helper functions exposed by
> > > the common code to invoke RX callbacks.
> >
> >
> > >
> > > Jerin
> > >
> > > >
> > > > Ability to safely remove callbacks at runtime implies
> > > > some sort of synchronization.
> > > > Even I tried to make it as light as possible,
> > > > probably some slowdown is unavoidable.
> > > > Of course instead of introducing these changes at rte_ethdev layer
> > > > similar technique could be applied on individual callback basis.
> > > > In that case it would be up to callback writer/installer to decide
> > > > does he/she need a removable at runtime callback or not.
> > > > Though in that case, each installed callback might introduce extra
> > > > synchronization overhead and slowdown.
> > > >
> > > > Konstantin Ananyev (3):
> > > > ethdev: introduce eth_queue_local
> > > > ethdev: make it safe to remove rx/tx callback at runtime
> > > > doc: ethdev ABI change deprecation notice
> > > >
> > > > doc/guides/rel_notes/deprecation.rst | 5 +
> > > > lib/librte_ether/rte_ethdev.c | 390 ++++++++++++++++++++++-------------
> > > > lib/librte_ether/rte_ethdev.h | 174 ++++++++++++----
> > > > 3 files changed, 387 insertions(+), 182 deletions(-)
> > > >
> > > > --
> > > > 2.13.5
> > > >
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer
@ 2017-12-20 18:23 3% ` Ananyev, Konstantin
2018-01-04 9:22 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Ananyev, Konstantin @ 2017-12-20 18:23 UTC (permalink / raw)
To: Jerin Jacob; +Cc: dev, shahafs
Hi Jerin,
>
> Hi Konstantin,
>
> > > > > >
> > > > > > 2. Make it safe to remove rx/tx callback at runtime.
> > > > > > Right now it is not possible for the application to figure out
> > > > > > when it is safe to free removed callback handle and
> > > > > > associated with it resources(unless the queue is stopped).
> > > > > > That's probably not a big problem if all callbacks are static
> > > > > > hange through whole application lifetime)
> > > > > > and/or application doesn't allocate any resources for the callback handler.
> > > > > > Though if callbacks have to be added/removed dynamically and
> > > > > > callback handler would require more resources to operate properly -
> > > > > > then it might become an issue.
> > > > > > So patch #2 fixes that problem - now as soon as
> > > > > > rte_eth_remove_(rx|tx)_callback() completes successfully, application
> > > > > > can safely free all associated with the removed callback resources.
> > > > > >
> > > > > > Performance impact:
> > > > > > If application doesn't use RX/TX callbacks, then the tests I run didn't
> > > > > > reveal any performance degradation.
> > > > > > Though if application do use RX/TX callbacks - patch #2 does introduce
> > > > > > some slowdown.
> > > > > >
> > > > > > To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
> > > > > > with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
> > > > > > 1) testpmd ... --latencystats=1 - slowdown < 1%
> > > > > > 2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
> > > > > > 3) examples/rxtx_callbacks - slowdown ~8%
> > > > > > All that in terms of packet throughput (Mpps).
> > > > >
> > > > > We tried on an arm64 machine; We got following result on host and guest
> > > > > using l3fwd.
> > > >
> > > > Thanks for testing it.
> > > > So these numbers below - are for l3fwd running with or without rx callback installed?
> > > > i.e. with or without '--parse-ptype' option (and on a NIC with/without ptype HW support)?
> > >
> > > without '--parse-ptype' option(i.e without rx callback installed).
> > > That makes it sad, Even though application is not using the rx callback,
> > > We need to pay on a average 3% drop in performance(based on the
> > > use case/arch/SoC/topology etc)
> >
> > Yes it is sad...
> > Do you have any idea why that happens?
> > Is that the same situation you described before: for arm compiler
> > often replaces small branches with conditional execution instructions
> > and miss-prediction for such instructions is not free?
>
> Yes.
Probably a dumb question - is it possible to disable such optimization
for these particular functions (rx_burst/tx_burst)?
Or would it make things even worse?
>
> Another thing I noticed on these inline functions(rx/tx burst)even if we add
> a lot of code which may note be executed, based on the parent
> function layout, the compete register access layout gets change(like
> push/pop from stack etc, as more code gets added).
> I.e This change does not have much impact with testpmd(iofwd) where the
> parent function is not doing much thing.It is showing up only on l3fwd.
Ok sort of register spillage...
But if compiler does it unconditionally (for the code path when it never needed)
seems like a problem with the compile, no?
Wonder if we'll move at least RX/TX CBs invocation into a separate function -
would it help somehow?
I.E. if (q->cb != NULL) execut_cbs(...);
?
Another thought - as I remember a while ago Bruce and other lads suggested to move
rx_burst/tx)burst (and whole struct rte_eth_dev) definitions into rte_ethdev.c...
That would help to avoid such problems, again we'll be able to modify rte_eth_dev
without breaking ABI...
Though it would mean extra call overhead, so don't know of-hand how expensive
it could be.
>
> > Or is it something else?
> >
> > Another thing - the series contains 2 main patches:
> > 1) http://dpdk.org/dev/patchwork/patch/31866/
> > Introduces eth_queue_local and moves callback data into it.
> > That adds one extra memory reference for rx/tx function to read cb func and data.
> > 2) http://dpdk.org/dev/patchwork/patch/31867/
> > Introduces some synchronization for cb data.
> >
> > Is it possible to rerun your tests with just patch #1 installed?
> > Hopefully it would help us to figure out which of the patches (#1 or #2)
> > is the main source of slowdown on arm machines.
>
> I re ran the test as requested:
> With first patch - 1.17% regression
> With first patch + Second patch - 2.84% regression
Thanks
>
> I am fine with slowdown, but it should be effected only with those
> application which request the callback feature.
Ok, but you do realize that if we'll go with rx/tx function per queue,
patch #1 slowdown (1.17%) will probably reappear anyway?
>
> >
> > >
> > > >
> > > > >
> > > > >
> > > > > Note:
> > > > > +ve number means "Performance regression with patches"
> > > > > -ve number means "Performance improvement with patches"
> > > > >
> > > > > Relative performance difference in percentage:
> > > > >
> > > > > % difference on host (2 x 40G)
> > > > > pkt_sz 1c 2c 4c 8c
> > > > > 64 1.41 0.18 0.51 0.29
> > > > > 72 0.50 0.53 0.09 0.19
> > > > > 128 0.31 0.31 0.42 0.00
> > > > > 256 -0.44 -0.44 0.00 0.00
> > > > > 512 1.94 1.94 0.01 0.01
> > > > > 1024 0.00 0.01 0.00 0.01
> > > > > 1518 0.02 0.01 0.02 0.02
> > > > >
> > > > > % difference on guest (2 x 40G)
> > > > > pkt_sz 1c 2c 4c 8c
> > > > > 64 5.78 2.30 -2.45 -0.01
> > > > > 72 1.13 1.13 1.31 -4.29
> > > > > 128 1.36 1.36 1.54 -0.82
> > > > > 256 2.02 2.03 -0.01 -0.35
> > > > > 512 4.05 4.04 0.00 -0.46
> > > > > 1024 0.39 0.38 0.00 -0.74
> > > > > 1518 0.00 0.00 -0.05 -4.20
> > > > >
> > > > > I think, it is because we added more code under
> > > > > the RTE_ETHDEV_RXTX_CALLBACKS and it is enabled by
> > > > > default.
> > > > >
> > > > > I think, the impact will vary based on
> > > > > architecture and underneath i-cache, d-cache and IPC.
> > > > >
> > > > > I am just thinking, How we can avoid such impact?
> > > > > How about,
> > > > > # Remove RTE_ETHDEV_RXTX_CALLBACKS option
> > > > > # Hook Rx/TX callbacks under TX/RX offload flags
> > > > > # ethdev layer gives helper function to invoke
> > > > > callbacks to driver.
> > > >
> > > > I suppose you suggest that user would have to decide at queue_setup()
> > > > stage does he wants a callback(s) for RX/TX or no?
> > >
> > > Yes. queue_setup or configure() time.
> > >
> > > > As I can see, the main drawback with that approach - it would introduce new limitation.
> > > > Right now it is possible to add/remove RX/TX callback at runtime
> > > > (without stopping and reconfiguring the queue), and I suppose we do want to keep that ability.
> > >
> > > For those _application_ where it can not decide or it need to add without
> > > stopping and re configuring the queue still can configure/enable the ethdev
> > > device with RX/TX callback option(and pay price for it)
> > >
> > > > Again in some cases user can't decide does he wants a callback installed or not,
> > > > before he actually calls dev_start().
> > > > l3fwd ptype-parse callback is an example of such situation:
> > > > right now user has to start device first to figure out which ptypes are supported by this PMD
> > > > with desired configuration, then based on this information he will (or will not) setup the callback.
> > >
> > > Good point. Can we remove that limitation from PMD perspective? IMO, ptype-parse is more of HW feature,
> > > All we need to do a lookup(single load) to convert to DPDK packet type.
> > > http://dpdk.org/browse/dpdk/tree/drivers/net/thunderx/nicvf_rxtx.c#n258
> > >
> > > I see almost all the drivers has dummy check like this, I think, That makes it
> > > dependency with start().
> > >
> > > if (dev->rx_pkt_burst == i40e_recv_pkts ||
> > > dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
> > > dev->rx_pkt_burst == i40e_recv_scattered_pkts ||
> > > dev->rx_pkt_burst == i40e_recv_scattered_pkts_vec ||
> > > dev->rx_pkt_burst == i40e_recv_pkts_vec)
> > > return ptypes;
> > >
> >
> > We probably can, but it would require extra work and changes inside the PMDs.
>
> Yes, If we want do it in clean way. Another intermediate solution could
> be return some valid error code on those PMD. On such error code, application can
> start the device and get the supported ptype and then stop/reconfigure it again
>
> > i40e is a good one - all rx functions support the same ptypes.
> > But let say for ixgbe ARM version of vRX doesn't support all ptypes that x86 vRX
> > and generic scalar RX do.
> > For fm10k - vector RX and scalar RX also support different ptype sets.
>
> >
> > >
> > > > What I thought in same direction - introduce a notion of 'static' and 'dynamic' callbacks.
> > > > Static ones can't be removed while queue is not stopped while dynamic can.
> > > > But that also requires user to select at queue_setup() stage does he wants dynamic
> > > > callbacks for that queue or not (new offload flag or extra field in rxconf/txconf structure).
> > > > So again - same limitation for the user.
> > > > Another possibility here - have a flag 'dynamic' or 'static' not per queue, but per individual callback.
> > > > Yes, that would mean API change for add/remove callback functions.
> > >
> > > At least on my test, the regression was caused because adding the code in
> > > tx_burst and rx_burst under the RTE_ETHDEV_RXTX_CALLBACKS(which enabled
> > > by default). By disabling the RTE_ETHDEV_RXTX_CALLBACKS option, I don't
> > > see any regression. If so, Will such regression fixed by introducing
> > > 'static' or 'dynamic' callbacks? I am happy to test and provide feedback.
> >
> > Probably no then, but let's try the experiment I mentioned above first.
> >
> > >
> > > For me, I think, The better option is request from application for the
> > > need for Rx/TX callbacks and set the handler appropriate in the driver to
> > > have zero impact for the application which does not need callback at all.
> >
> > It is possible, but:
> > - that would be quite significant change and would affect each RX and TX function in each PMD.
>
> May be not, assume if we have helper function which invoke the callbacks.
> PMD can just call that before returning it.
Even with helpers it means we'll have to double number of RX/TX functions -
one with a CB support, another without.
>
> > - from other side - even now there are several libs inside DPDK that rely on ability to add/remove
> > callbacks on the fly - pdump, latencystats.
> I think, it is application who decides to use this API,then I think,
> application can request callback feature support. I think, we have
> followed the same method in latest RX/TX offload flag scheme as well.
>
> > ethdev rx profiling also relies on ability to install RX callback.
> >
> > With all these things I presume most apps will configure their devices with rx/tx callback support enabled anyway.
> > Which makes me think - is it worth to introduce such changes at all.
> > Anyway, my first suggestion would be let's try to figure out what exactly causes such big slowdown on ARM.
>
> It may not be ARM in general, Under our roof, We have different class of SoCs based
> on the use case like 4 cores, 16 core, 96 cores part etc with different
> micro architecture etc based on the use case(embedded/server etc) like
> Intel. So it may not very generic with all ARM machines, it is really
> based on micro architecture. ie. The same patch may behave
> differently(less than < 1%) on IA-Atom vs IA-XEON. So IMO, Common code
> change should use helper functions, it up to the driver to use it.
Konstantin
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv4 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-13 15:17 4% ` [dpdk-dev] [PATCHv4 " Neil Horman
` (3 preceding siblings ...)
2017-12-13 15:32 0% ` [dpdk-dev] [PATCHv4 0/4] dpdk: enhance EXPERIMENTAL api tagging Bruce Richardson
@ 2017-12-21 14:21 0% ` Neil Horman
2017-12-30 19:20 0% ` Luca Boccassi
5 siblings, 0 replies; 200+ results
From: Neil Horman @ 2017-12-21 14:21 UTC (permalink / raw)
To: dev; +Cc: thomas, john.mcnamara, bruce.richardson
On Wed, Dec 13, 2017 at 10:17:23AM -0500, Neil Horman wrote:
> Hey all-
> A few days ago, I was lamenting the fact that, when reviewing patches I
> would frequently complain about ABI changes that were actually considered safe
> because they were part of the EXPERIMENTAL api set. John M. asked me then what
> I might do to improve the situation, and the following patch set is a proposal
> that I've come up with.
>
> In thinking about the problem I identified two issues that I think we
> can improve on in this area:
>
> 1) Make experimental api calls more visible in the source code. That is to say,
> when reviewing patches, it would be nice to have some sort of visual reference
> that indicates that the changes being made are part of an experimental API and
> therefore ABI concerns need not be addressed
>
> 2) Make experimenal api usage more visible to consumers of the DPDK, so that
> they can make a more informed decision about the API's they consume in their
> application. We make an effort to document all the experimental API's, but
> there is no guarantee that a user will check the documentation before making use
> of a new library.
>
> This patch set attempts to achieve both of the above goals. To do this I've
> added an __experimental macro tag, suitable for inserting into api forward
> declarations and definitions.
>
> The presence of the tag in the header and c files where the api code resides
> increases the likelyhood that any patch submitted against them will include the
> tag in the context, making it clear to reviewers that ABI stability isn't a
> concern here.
>
> Also, This tag marks each function it is used on with an attibute causing any
> use of the fuction to emit a warning during the build
> with a message indicating that the API call in question is not yet part of the
> stable interface. Developers can then make an informed decision to suppress
> that warning or not.
>
> Because there is internal use of several experimental API's, this set also
> includes a new override macro ALLOW_EXPERIMENTAL_APIS to automatically
> suprress these warnings. I think its fair to assume that, for internal use, we
> almost always want to suppress these warnings, as by definition any change to
> the apis (even their removal) must be done in parallel with an appropriate
> change in the calling locations, lest the dpdk build itself break.
>
> Neil
>
> ---
> Change Notes:
> v2)
> * Cleaned up checkpatch errors
> * Added Allowance for building experimental on BSD
> * Swapped Patch 3 and 4 so that we didn't have a commit level that issued
> warnings/errors without need
>
> v3)
> * On suggestion from Bruce, modify ALLOW_EXPERIMENTAL_APIS to be defined in
> CFLAGS rather than a makefile variable. This is more flexible in that it
> allows us to suppress this specific feature rather than all uses of the
> deprecated attribute, as we might use it for other features in the furute
>
> v4)
> * Added documentation patch to contributors guide
>
>
Ping, can I get some more reviews/acks here please?
Neil
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] mbuf: pktmbuf pool create helper for specific mempool ops
@ 2017-12-22 11:30 3% Hemant Agrawal
2017-12-22 13:53 0% ` Wiles, Keith
0 siblings, 1 reply; 200+ results
From: Hemant Agrawal @ 2017-12-22 11:30 UTC (permalink / raw)
To: dev, olivier.matz; +Cc: jerin.jacob, keith.wiles, Hemant Agrawal
Introduce a new helper for pktmbuf pool, which will allow
the application to optionally specify the mempool ops name
as well.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
This change was discussed in the
"doc: announce ABI change for pktmbuf pool create API"
http://dpdk.org/dev/patchwork/patch/32306/
lib/librte_mbuf/rte_mbuf.c | 24 ++++++++++++++++++------
lib/librte_mbuf/rte_mbuf.h | 42 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 7543662..9cc861b 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -148,15 +148,15 @@ rte_pktmbuf_init(struct rte_mempool *mp,
m->next = NULL;
}
-/* helper to create a mbuf pool */
+/* helper to create a mbuf pool with given mempool ops*/
struct rte_mempool *
-rte_pktmbuf_pool_create(const char *name, unsigned n,
- unsigned cache_size, uint16_t priv_size, uint16_t data_room_size,
- int socket_id)
+rte_pktmbuf_pool_create_specific(const char *name, unsigned int n,
+ unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
+ int socket_id, const char *ops_name)
{
struct rte_mempool *mp;
struct rte_pktmbuf_pool_private mbp_priv;
- const char *mp_ops_name;
+ const char *mp_ops_name = ops_name;
unsigned elt_size;
int ret;
@@ -176,7 +176,9 @@ rte_pktmbuf_pool_create(const char *name, unsigned n,
if (mp == NULL)
return NULL;
- mp_ops_name = rte_eal_mbuf_default_mempool_ops();
+ if (!mp_ops_name)
+ mp_ops_name = rte_eal_mbuf_default_mempool_ops();
+
ret = rte_mempool_set_ops_byname(mp, mp_ops_name, NULL);
if (ret != 0) {
RTE_LOG(ERR, MBUF, "error setting mempool handler\n");
@@ -198,6 +200,16 @@ rte_pktmbuf_pool_create(const char *name, unsigned n,
return mp;
}
+/* helper to create a mbuf pool */
+struct rte_mempool *
+rte_pktmbuf_pool_create(const char *name, unsigned int n,
+ unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
+ int socket_id)
+{
+ return rte_pktmbuf_pool_create_specific(name, n, cache_size, priv_size,
+ data_room_size, socket_id, NULL);
+}
+
/* do some sanity checks on a mbuf: panic if it fails */
void
rte_mbuf_sanity_check(const struct rte_mbuf *m, int is_header)
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index ce8a05d..d4681fd 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -1081,6 +1081,48 @@ rte_pktmbuf_pool_create(const char *name, unsigned n,
int socket_id);
/**
+ * Create a mbuf pool with specific mempool ops
+ *
+ * This function creates and initializes a packet mbuf pool. It is
+ * a wrapper to rte_mempool functions.
+ *
+ * @param name
+ * The name of the mbuf pool.
+ * @param n
+ * The number of elements in the mbuf pool. The optimum size (in terms
+ * of memory usage) for a mempool is when n is a power of two minus one:
+ * n = (2^q - 1).
+ * @param cache_size
+ * Size of the per-core object cache. See rte_mempool_create() for
+ * details.
+ * @param priv_size
+ * Size of application private are between the rte_mbuf structure
+ * and the data buffer. This value must be aligned to RTE_MBUF_PRIV_ALIGN.
+ * @param data_room_size
+ * Size of data buffer in each mbuf, including RTE_PKTMBUF_HEADROOM.
+ * @param socket_id
+ * The socket identifier where the memory should be allocated. The
+ * value can be *SOCKET_ID_ANY* if there is no NUMA constraint for the
+ * reserved zone.
+ * @param ops_name
+ * The mempool ops name to be used for this mempool instead of
+ * default mempool. The value can be *NULL* to use default mempool.
+ * @return
+ * The pointer to the new allocated mempool, on success. NULL on error
+ * with rte_errno set appropriately. Possible rte_errno values include:
+ * - E_RTE_NO_CONFIG - function could not get pointer to rte_config structure
+ * - E_RTE_SECONDARY - function was called from a secondary process instance
+ * - EINVAL - cache size provided is too large, or priv_size is not aligned.
+ * - ENOSPC - the maximum number of memzones has already been allocated
+ * - EEXIST - a memzone with the same name already exists
+ * - ENOMEM - no appropriate memory area found in which to create memzone
+ */
+struct rte_mempool *
+rte_pktmbuf_pool_create_specific(const char *name, unsigned int n,
+ unsigned int cache_size, uint16_t priv_size, uint16_t data_room_size,
+ int socket_id, const char *ops_name);
+
+/**
* Get the data room size of mbufs stored in a pktmbuf_pool
*
* The data room size is the amount of data that can be stored in a
--
2.7.4
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] mbuf: pktmbuf pool create helper for specific mempool ops
2017-12-22 11:30 3% [dpdk-dev] [PATCH] mbuf: pktmbuf pool create helper for specific mempool ops Hemant Agrawal
@ 2017-12-22 13:53 0% ` Wiles, Keith
0 siblings, 0 replies; 200+ results
From: Wiles, Keith @ 2017-12-22 13:53 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: dev, olivier.matz, jerin.jacob
> On Dec 22, 2017, at 5:30 AM, Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
>
> Introduce a new helper for pktmbuf pool, which will allow
> the application to optionally specify the mempool ops name
> as well.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> This change was discussed in the
> "doc: announce ABI change for pktmbuf pool create API"
> http://dpdk.org/dev/patchwork/patch/32306/
>
> lib/librte_mbuf/rte_mbuf.c | 24 ++++++++++++++++++------
> lib/librte_mbuf/rte_mbuf.h | 42 ++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 60 insertions(+), 6 deletions(-)
>
This patch looks good to me, but you forgot the MAP file patch to add the new API.
Regards,
Keith
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v1 6/6] net: fix rte_ether conflicts with libc
@ 2017-12-22 14:25 3% ` Adrien Mazarguil
2018-01-16 13:04 0% ` Olivier Matz
0 siblings, 1 reply; 200+ results
From: Adrien Mazarguil @ 2017-12-22 14:25 UTC (permalink / raw)
To: Olivier MATZ; +Cc: dev, Bruce Richardson
Hi Olivier,
On Fri, Dec 22, 2017 at 02:34:21PM +0100, Olivier MATZ wrote:
> Hi Adrien,
>
> On Thu, Dec 21, 2017 at 02:00:06PM +0100, Adrien Mazarguil wrote:
> > Applications can't combine either net/ethernet.h or netinet/ether.h
> > together with rte_ether.h due to the redefinition of struct ether_addr and
> > various macros by the latter.
> >
> > This patch adapts rte_ether.h to rely on system definitions while
> > maintaining DPDK additions.
> >
> > An unforeseen consequence of involving more system header files compilation
> > issues with some base drivers (i40e, ixgbe) defining their own conflicting
> > types (e.g. __le64). This is addressed by explicitly including rte_ether.h
> > where missing to ensure system definitions always come first.
> >
> > Signed-off-by: Adrien Mazarguil <adrien.mazarguil@6wind.com>
> > Cc: Olivier Matz <olivier.matz@6wind.com>
> > Cc: Bruce Richardson <bruce.richardson@intel.com>
>
> [...]
>
> > --- a/drivers/net/qede/base/bcm_osal.h
> > +++ b/drivers/net/qede/base/bcm_osal.h
> > @@ -334,7 +334,6 @@ u32 qede_find_first_zero_bit(unsigned long *, u32);
> > qede_find_first_zero_bit(bitmap, length)
> >
> > #define OSAL_BUILD_BUG_ON(cond) nothing
> > -#define ETH_ALEN ETHER_ADDR_LEN
> >
> > #define OSAL_BITMAP_WEIGHT(bitmap, count) 0
> >
>
> Not sure we can update code in a 'base' driver as easily.
> It should be checked how it can be done with the qede maintainer.
Sure, although I have to send an update for this chunk already: ETH_ALEN
seems only defined in Linux, not under FreeBSD. I intend to enclose the
above within #ifdef ETH_ALEN.
Besides, updating this file shouldn't be a problem, it's already tailored
for DPDK as it includes and uses several DPDK headers.
> > diff --git a/lib/librte_net/rte_ether.h b/lib/librte_net/rte_ether.h
> > index 06d7b486c..19e62ea89 100644
> > --- a/lib/librte_net/rte_ether.h
> > +++ b/lib/librte_net/rte_ether.h
> > @@ -44,6 +44,7 @@
> > extern "C" {
> > #endif
> >
> > +#include <net/ethernet.h>
> > #include <stdint.h>
> > #include <stdio.h>
> >
> > @@ -52,15 +53,7 @@ extern "C" {
> > #include <rte_mbuf.h>
> > #include <rte_byteorder.h>
> >
> > -#define ETHER_ADDR_LEN 6 /**< Length of Ethernet address. */
> > -#define ETHER_TYPE_LEN 2 /**< Length of Ethernet type field. */
> > -#define ETHER_CRC_LEN 4 /**< Length of Ethernet CRC. */
> > -#define ETHER_HDR_LEN \
> > - (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) /**< Length of Ethernet header. */
> > -#define ETHER_MIN_LEN 64 /**< Minimum frame len, including CRC. */
> > -#define ETHER_MAX_LEN 1518 /**< Maximum frame len, including CRC. */
> > -#define ETHER_MTU \
> > - (ETHER_MAX_LEN - ETHER_HDR_LEN - ETHER_CRC_LEN) /**< Ethernet MTU. */
> > +#define ETHER_MTU ETHERMTU /**< Deprecated, defined for compatibility. */
> >
> > #define ETHER_MAX_VLAN_FRAME_LEN \
> > (ETHER_MAX_LEN + 4) /**< Maximum VLAN frame length, including CRC. */
> > @@ -72,8 +65,11 @@ extern "C" {
> >
> > #define ETHER_MIN_MTU 68 /**< Minimum MTU for IPv4 packets, see RFC 791. */
> >
> > +#ifdef __DOXYGEN__
> > +
> > /**
> > - * Ethernet address:
> > + * Ethernet address.
> > + *
> > * A universally administered address is uniquely assigned to a device by its
> > * manufacturer. The first three octets (in transmission order) contain the
> > * Organizationally Unique Identifier (OUI). The following three (MAC-48 and
> > @@ -82,11 +78,25 @@ extern "C" {
> > * A locally administered address is assigned to a device by a network
> > * administrator and does not contain OUIs.
> > * See http://standards.ieee.org/regauth/groupmac/tutorial.html
> > + *
> > + * This structure is defined system-wide by "net/ethernet.h", however since
> > + * the name of its data field is OS-dependent, a macro named "addr_bytes" is
> > + * defined as an alias for the convenience of DPDK applications.
> > + *
> > + * The following definition is only for documentation purposes.
> > */
> > struct ether_addr {
> > uint8_t addr_bytes[ETHER_ADDR_LEN]; /**< Addr bytes in tx order */
> > } __attribute__((__packed__));
> >
> > +#endif /* __DOXYGEN__ */
> > +
> > +#if defined(__FreeBSD__)
> > +#define addr_bytes octet
> > +#else
> > +#define addr_bytes ether_addr_octet
> > +#endif
> > +
> > #define ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
> > #define ETHER_GROUP_ADDR 0x01 /**< Multicast or broadcast Eth. address. */
>
> This kind of #define looks a bit dangerous to me: it can trigger
> strange bugs because it will replace all occurences of addr_bytes
> after this header is included.
Understandable, I checked before settling on this macro though, there's no
other usage of addr_bytes inside DPDK.
As for applications, there's no way to be completely sure. If we consider
they have to explicitly include rte_ether.h to get this definition, there
are chances addr_bytes is exclusively used with MAC addresses.
This change results in an API change (addr_bytes now documented as a
reserved macro) but has no ABI impact. I think it's a rather harmless
workaround pending your next suggestion:
> Wouldn't it be a good opportunity to think about adding the rte_ prefix
> to all variables/functions of rte_ether.h?
That would be ideal, however since almost all definitions in librte_net
(rte_ip.h, rte_udp.h etc.) also lack this prefix and can still technically
trigger conflicts with outside definitions (I'm aware work was done to avoid
that, but it doesn't change the fact they're not in the official DPDK
namespace), a massive API change would be needed for consistency.
Such a change is unlikely to be accepted for 18.02 in any case, therefore if
the proposed workaround is deemed too risky, I offer to remove this patch
from the series. What do you suggest?
--
Adrien Mazarguil
6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2] doc: announce ABI change for pktmbuf pool create API
2017-12-19 13:41 4% ` Wiles, Keith
@ 2017-12-22 15:26 4% ` Olivier MATZ
0 siblings, 0 replies; 200+ results
From: Olivier MATZ @ 2017-12-22 15:26 UTC (permalink / raw)
To: Wiles, Keith; +Cc: Hemant Agrawal, dev, Jerin Jacob, Neil Horman
On Tue, Dec 19, 2017 at 01:41:05PM +0000, Wiles, Keith wrote:
>
>
> > On Dec 18, 2017, at 11:40 PM, Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
> >
> > On 12/18/2017 7:21 PM, Wiles, Keith wrote:
> >>
> >>
> >>> On Dec 15, 2017, at 4:41 AM, Hemant Agrawal <hemant.agrawal@nxp.com> wrote:
> >>>
> >>> Introduce a new argument ops_name in rte_mempool_set_ops_byname
> >>> for allowing the application to optionally specify the mempool ops.
> >>>
> >>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> >>> ---
> >>> v2: fix checkpatch error
> >>>
> >>> doc/guides/rel_notes/deprecation.rst | 3 +++
> >>> 1 file changed, 3 insertions(+)
> >>>
> >>> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> >>> index 13e8543..968ca14 100644
> >>> --- a/doc/guides/rel_notes/deprecation.rst
> >>> +++ b/doc/guides/rel_notes/deprecation.rst
> >>> @@ -53,3 +53,6 @@ Deprecation Notices
> >>>
> >>> * librte_meter: The API will change to accommodate configuration profiles.
> >>> Most of the API functions will have an additional opaque parameter.
> >>> +
> >>> +* librte_mbuf: a new optional parameter for representing name of mempool_ops
> >>> + will be added to the API ``rte_pktmbuf_pool_create``.
> >>
> >>
> >> Sorry, for the late response I was on vacation.
> >>
> >> My question is why do we need to change rte_pktmbuf_pool_create ABI yet again, why could we not add a new API to just set the name of the pool after it is created. This would allow all current applications to work without any ABI breakage and only require adding a new API call for anyone that wants the name. The rte_pktmbuf_pool_create() routine could assign a default name or some incrementing style name as the default. e.g. ‘pktmbuf_%d’ with a static incrementing variable or whatever you like.
> >>
> >> Sorry if this was asked and answered before.
> >>
> >
> > I understand the concerns.
> >
> > However, the new API to just set the name will not work post create.
> > rte_pktmbuf_pool_create is a wrapper API, which complete the mempool configuration on the basis default mempool_ops.
>
> Really can not add the name after the fact, I have not looked, but it seem very odd we can not use the mempool pointer and update the ops_name. What is stopping this from working?
Changing the ops name is not possible after the mempool is created.
The ops name defines how the objects are stored, we cannot update it
once the objects are created.
> > The idea proposed is to create pktmbuf pool from a specific mempool (ops_name).
> >
> > We can leave "rte_pktmbuf_pool_create" as it is.
> > and create another similar API with e.g. "rte_pktmbuf_pool_create_specific", which will also take ops_name as argument. (We can combine the internal implementation with NULL ops_name for rte_pktmbuf_pool_create.)
>
> I would accept this approach over the original patch to change the name of a commonly used API.
> >
> > This way we will have flexibility for the applications looking for pktmbufs from a specific mempool.
> >
> > any thoughts?
What do you think about this proposition?
http://dpdk.org/ml/archives/dev/2017-December/084775.html
The application can do:
/* override value previously set by eal args, if any */
rte_mbuf_set_user_pool_ops("my-ops");
/* as before, no API change */
rte_pktmbuf_pool_create(...);
With this approach, it is less convenients to create several pools
with different ops, but I'm not sure there is a use case for that.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change
@ 2017-12-22 21:55 3% ` Ferruh Yigit
2017-12-26 10:08 0% ` Hemant Agrawal
2017-12-26 10:36 2% ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
3 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2017-12-22 21:55 UTC (permalink / raw)
To: Hemant Agrawal, dev
On 11/30/2017 3:46 AM, Hemant Agrawal wrote:
> This patch adds following:
> 1. Option to configure the mac address during create. Generate random
> address only if the user has not provided any valid address.
> 2. Inform usespace, if mac address is being changed in linux.
> 3. Implement default handling of mac address change in the corresponding
> ethernet device.>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
Overall lgtm, there are a few issues commented below.
Thanks,
ferruh
<...>
> @@ -269,11 +275,15 @@ The code for allocating the kernel NIC interfaces for a specific port is as foll
> conf.addr = dev_info.pci_dev->addr;
> conf.id = dev_info.pci_dev->id;
>
> + /* Get the interface default mac address */
> + rte_eth_macaddr_get(port_id, struct ether_addr *)&conf.mac_addr);
a parentheses is missing, good to fix although this is document :)
<...>
> @@ -587,3 +603,26 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
> RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id);
> return ret;
> }
> +
> + /* Callback for request of configuring device mac address */
> +
> + static int
> + kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
> + {
> + int ret = 0;
> +
> + if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
> + RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
> + return -EINVAL;
> + }
> +
> + RTE_LOG(INFO, KNI, "Configure mac address of %d", port_id);
> + /* Configure network interface mac address */
> + ret = rte_eth_dev_default_mac_addr_set(port_id,
> + (struct ether_addr *)mac_addr);
> + if (ret < 0)
> + RTE_LOG(ERR, KNI, "Failed to config mac_addr for port %d\n",
> + port_id);
> +
> + return ret;
> + }
It is hard to maintain code in doc, I am aware other related code is already in
document but what do you think keeping this minimal, like:
static int
kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
{
....
}
<...>
> @@ -559,6 +583,14 @@ rte_kni_handle_request(struct rte_kni *kni)
> req->result = kni->ops.config_network_if(\
> kni->ops.port_id, req->if_up);
> break;
> + case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
> + if (kni->ops.config_mac_address)
> + req->result = kni->ops.config_mac_address(
> + kni->ops.port_id, req->mac_addr);
> + else
> + req->result = kni_config_mac_address(
> + kni->ops.port_id, req->mac_addr);
ops.port_id can be unset if there is no physically backing device the kni
interface. And I guess for that case port_id will be 0 and it will corrupt other
interface's data. There needs to find a way to handle the port_id not set case.
Since kni sample always creates a KNI interface backed by pyhsical device, this
is not an issue for kni sample app but please think about kni pmd case.
<...>
> @@ -87,6 +91,7 @@ struct rte_kni_conf {
> unsigned mbuf_size; /* mbuf size */
> struct rte_pci_addr addr;
> struct rte_pci_id id;
> + char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
>
> __extension__
> uint8_t force_bind : 1; /* Flag to bind kernel thread */
"struct rte_kni_conf" is a public struct. Adding a variable into the middle of
the struct will break the ABI.
But I think it is OK to add to the end, unless struct is not used as array.
<...>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 2/3] kni: add support for promisc mode set
@ 2017-12-22 21:57 3% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2017-12-22 21:57 UTC (permalink / raw)
To: Hemant Agrawal, dev
On 11/30/2017 3:46 AM, Hemant Agrawal wrote:
> Inform userspace app about promisc mode change
Same two concerns here with prev patch.
- Breaking ABI
- And handling ops.port_id not set by application case.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
<...>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 3/3] kni: set initial value for MTU
@ 2017-12-22 22:01 4% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2017-12-22 22:01 UTC (permalink / raw)
To: Hemant Agrawal, dev
On 11/30/2017 3:46 AM, Hemant Agrawal wrote:
> Configure initial application provided mtu on the KNI interface.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
<...>
> @@ -95,6 +95,7 @@ struct rte_kni_conf {
> struct rte_pci_addr addr;
> struct rte_pci_id id;
> char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
> + uint16_t mtu;
Same issue here, adding a new field into middle of the public struct.
I think it would be OK to add to the end, but to be sure would you please run
ABI check script (validate-abi.sh) after adding to the end?
Thanks,
ferruh
>
> __extension__
> uint8_t force_bind : 1; /* Flag to bind kernel thread */
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change
2017-12-22 21:55 3% ` [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Ferruh Yigit
@ 2017-12-26 10:08 0% ` Hemant Agrawal
0 siblings, 0 replies; 200+ results
From: Hemant Agrawal @ 2017-12-26 10:08 UTC (permalink / raw)
To: Ferruh Yigit, dev
Hi Ferruh,
On 12/23/2017 3:25 AM, Ferruh Yigit wrote:
> On 11/30/2017 3:46 AM, Hemant Agrawal wrote:
>> This patch adds following:
>> 1. Option to configure the mac address during create. Generate random
>> address only if the user has not provided any valid address.
>> 2. Inform usespace, if mac address is being changed in linux.
>> 3. Implement default handling of mac address change in the corresponding
>> ethernet device.>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>
> Overall lgtm, there are a few issues commented below.
>
> Thanks,
> ferruh
>
> <...>
>> @@ -587,3 +603,26 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
>> RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id);
>> return ret;
>> }
>> +
>> + /* Callback for request of configuring device mac address */
>> +
>> + static int
>> + kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
>> + {
>> + int ret = 0;
>> +
>> + if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
>> + RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
>> + return -EINVAL;
>> + }
>> +
>> + RTE_LOG(INFO, KNI, "Configure mac address of %d", port_id);
>> + /* Configure network interface mac address */
>> + ret = rte_eth_dev_default_mac_addr_set(port_id,
>> + (struct ether_addr *)mac_addr);
>> + if (ret < 0)
>> + RTE_LOG(ERR, KNI, "Failed to config mac_addr for port %d\n",
>> + port_id);
>> +
>> + return ret;
>> + }
>
>
> It is hard to maintain code in doc, I am aware other related code is already in
> document but what do you think keeping this minimal, like:
>
> static int
> kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
> {
> ....
> }
agree.
>
>
> <...>
>
>> @@ -559,6 +583,14 @@ rte_kni_handle_request(struct rte_kni *kni)
>> req->result = kni->ops.config_network_if(\
>> kni->ops.port_id, req->if_up);
>> break;
>> + case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
>> + if (kni->ops.config_mac_address)
>> + req->result = kni->ops.config_mac_address(
>> + kni->ops.port_id, req->mac_addr);
>> + else
>> + req->result = kni_config_mac_address(
>> + kni->ops.port_id, req->mac_addr);
>
> ops.port_id can be unset if there is no physically backing device the kni
> interface. And I guess for that case port_id will be 0 and it will corrupt other
> interface's data. There needs to find a way to handle the port_id not set case.
got it. I will set it as UINT16_MAX and check for it.
>
> Since kni sample always creates a KNI interface backed by pyhsical device, this
> is not an issue for kni sample app but please think about kni pmd case.
>
> <...>
>
>> @@ -87,6 +91,7 @@ struct rte_kni_conf {
>> unsigned mbuf_size; /* mbuf size */
>> struct rte_pci_addr addr;
>> struct rte_pci_id id;
>> + char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
>>
>> __extension__
>> uint8_t force_bind : 1; /* Flag to bind kernel thread */
>
> "struct rte_kni_conf" is a public struct. Adding a variable into the middle of
> the struct will break the ABI.
> But I think it is OK to add to the end, unless struct is not used as array.
>
> <...>
>
yes. adding it into middle breaks the ABIs. However adding into end is ok.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2 1/3] kni: support for MAC addr change
` (2 preceding siblings ...)
2017-12-22 21:55 3% ` [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Ferruh Yigit
@ 2017-12-26 10:36 2% ` Hemant Agrawal
2017-12-26 10:36 3% ` [dpdk-dev] [PATCH v2 2/3] kni: add support for promisc mode set Hemant Agrawal
2017-12-26 10:36 3% ` [dpdk-dev] [PATCH v2 3/3] kni: set initial value for MTU Hemant Agrawal
3 siblings, 2 replies; 200+ results
From: Hemant Agrawal @ 2017-12-26 10:36 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
This patch adds following:
1. Option to configure the mac address during create. Generate random
address only if the user has not provided any valid address.
2. Inform usespace, if mac address is being changed in linux.
3. Implement default handling of mac address change in the corresponding
ethernet device.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
v2:
* fix ABI breakage
* reducing the code in documentation.
* initialize ops.portid to UNIT16_MAX for vdev case
doc/guides/sample_app_ug/kernel_nic_interface.rst | 26 +++++++++++++-
examples/kni/main.c | 36 +++++++++++++++++++
.../linuxapp/eal/include/exec-env/rte_kni_common.h | 3 ++
lib/librte_eal/linuxapp/kni/kni_misc.c | 17 +++++----
lib/librte_eal/linuxapp/kni/kni_net.c | 14 +++++++-
lib/librte_kni/rte_kni.c | 42 ++++++++++++++++++++--
lib/librte_kni/rte_kni.h | 5 +++
test/test/test_kni.c | 2 ++
8 files changed, 134 insertions(+), 11 deletions(-)
diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst
index e1ac415..2c143da 100644
--- a/doc/guides/sample_app_ug/kernel_nic_interface.rst
+++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst
@@ -209,6 +209,12 @@ Dumping the network traffic:
#tcpdump -i vEth0_0
+Change the MAC address:
+
+.. code-block:: console
+
+ #ifconfig vEth0_0 hw ether 0C:01:02:03:04:08
+
When the DPDK userspace application is closed, all the KNI devices are deleted from Linux*.
Explanation
@@ -269,11 +275,15 @@ The code for allocating the kernel NIC interfaces for a specific port is as foll
conf.addr = dev_info.pci_dev->addr;
conf.id = dev_info.pci_dev->id;
+ /* Get the interface default mac address */
+ rte_eth_macaddr_get(port_id, (struct ether_addr *)&conf.mac_addr);
+
memset(&ops, 0, sizeof(ops));
ops.port_id = port_id;
ops.change_mtu = kni_change_mtu;
ops.config_network_if = kni_config_network_interface;
+ ops.config_mac_address = kni_config_mac_address;
kni = rte_kni_alloc(pktmbuf_pool, &conf, &ops);
} else
@@ -502,13 +512,19 @@ Callbacks for Kernel Requests
To execute specific PMD operations in user space requested by some Linux* commands,
callbacks must be implemented and filled in the struct rte_kni_ops structure.
-Currently, setting a new MTU and configuring the network interface (up/ down) are supported.
+Currently, setting a new MTU, change in mac address and configuring the network interface(up/ down)
+are supported.
+Default implementation for following is available in rte_kni library. Application
+may choose to not implement follwoing callbacks:
+ ``config_mac_address``
+
.. code-block:: c
static struct rte_kni_ops kni_ops = {
.change_mtu = kni_change_mtu,
.config_network_if = kni_config_network_interface,
+ .config_mac_address = kni_config_mac_address,
};
/* Callback for request of changing MTU */
@@ -587,3 +603,11 @@ Currently, setting a new MTU and configuring the network interface (up/ down) ar
RTE_LOG(ERR, APP, "Failed to start port %d\n", port_id);
return ret;
}
+
+ /* Callback for request of configuring device mac address */
+
+ static int
+ kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+ {
+ .....
+ }
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 3f17385..1c251c2 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -163,6 +163,7 @@ static struct kni_interface_stats kni_stats[RTE_MAX_ETHPORTS];
static int kni_change_mtu(uint16_t port_id, unsigned int new_mtu);
static int kni_config_network_interface(uint16_t port_id, uint8_t if_up);
+static int kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[]);
static rte_atomic32_t kni_stop = RTE_ATOMIC32_INIT(0);
@@ -766,6 +767,37 @@ kni_config_network_interface(uint16_t port_id, uint8_t if_up)
return ret;
}
+static void
+print_ethaddr(const char *name, struct ether_addr *mac_addr)
+{
+ char buf[ETHER_ADDR_FMT_SIZE];
+ ether_format_addr(buf, ETHER_ADDR_FMT_SIZE, mac_addr);
+ RTE_LOG(INFO, APP, "\t%s%s\n", name, buf);
+}
+
+/* Callback for request of configuring mac address */
+static int
+kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+{
+ int ret = 0;
+
+ if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+ RTE_LOG(ERR, APP, "Invalid port id %d\n", port_id);
+ return -EINVAL;
+ }
+
+ RTE_LOG(INFO, APP, "Configure mac address of %d\n", port_id);
+ print_ethaddr("Address:", (struct ether_addr *)mac_addr);
+
+ ret = rte_eth_dev_default_mac_addr_set(port_id,
+ (struct ether_addr *)mac_addr);
+ if (ret < 0)
+ RTE_LOG(ERR, APP, "Failed to config mac_addr for port %d\n",
+ port_id);
+
+ return ret;
+}
+
static int
kni_alloc(uint16_t port_id)
{
@@ -809,11 +841,15 @@ kni_alloc(uint16_t port_id)
conf.addr = dev_info.pci_dev->addr;
conf.id = dev_info.pci_dev->id;
}
+ /* Get the interface default mac address */
+ rte_eth_macaddr_get(port_id,
+ (struct ether_addr *)&conf.mac_addr);
memset(&ops, 0, sizeof(ops));
ops.port_id = port_id;
ops.change_mtu = kni_change_mtu;
ops.config_network_if = kni_config_network_interface;
+ ops.config_mac_address = kni_config_mac_address;
kni = rte_kni_alloc(pktmbuf_pool, &conf, &ops);
} else
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
index 2ac879f..1a760de 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
@@ -80,6 +80,7 @@ enum rte_kni_req_id {
RTE_KNI_REQ_UNKNOWN = 0,
RTE_KNI_REQ_CHANGE_MTU,
RTE_KNI_REQ_CFG_NETWORK_IF,
+ RTE_KNI_REQ_CHANGE_MAC_ADDR,
RTE_KNI_REQ_MAX,
};
@@ -92,6 +93,7 @@ struct rte_kni_request {
union {
uint32_t new_mtu; /**< New MTU */
uint8_t if_up; /**< 1: interface up, 0: interface down */
+ uint8_t mac_addr[6]; /**< MAC address for interface */
};
int32_t result; /**< Result for processing request */
} __attribute__((__packed__));
@@ -168,6 +170,7 @@ struct rte_kni_device_info {
/* mbuf size */
unsigned mbuf_size;
+ char mac_addr[6];
};
#define KNI_DEVICE "kni"
diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c b/lib/librte_eal/linuxapp/kni/kni_misc.c
index 7590f1f..b524d30 100644
--- a/lib/librte_eal/linuxapp/kni/kni_misc.c
+++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
@@ -458,12 +458,17 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
if (kni->lad_dev)
ether_addr_copy(net_dev->dev_addr, kni->lad_dev->dev_addr);
- else
- /*
- * Generate random mac address. eth_random_addr() is the newer
- * version of generating mac address in linux kernel.
- */
- random_ether_addr(net_dev->dev_addr);
+ else {
+ /* if user has provided a valid mac address */
+ if (is_valid_ether_addr((unsigned char *)(dev_info.mac_addr)))
+ memcpy(net_dev->dev_addr, dev_info.mac_addr, ETH_ALEN);
+ else
+ /*
+ * Generate random mac address. eth_random_addr() is the
+ * newer version of generating mac address in kernel.
+ */
+ random_ether_addr(net_dev->dev_addr);
+ }
ret = register_netdev(net_dev);
if (ret) {
diff --git a/lib/librte_eal/linuxapp/kni/kni_net.c b/lib/librte_eal/linuxapp/kni/kni_net.c
index db9f489..3e02ea1 100644
--- a/lib/librte_eal/linuxapp/kni/kni_net.c
+++ b/lib/librte_eal/linuxapp/kni/kni_net.c
@@ -668,12 +668,24 @@ kni_net_rebuild_header(struct sk_buff *skb)
static int
kni_net_set_mac(struct net_device *netdev, void *p)
{
+ int ret;
+ struct rte_kni_request req;
+ struct kni_dev *kni;
struct sockaddr *addr = p;
+ memset(&req, 0, sizeof(req));
+ req.req_id = RTE_KNI_REQ_CHANGE_MAC_ADDR;
+
if (!is_valid_ether_addr((unsigned char *)(addr->sa_data)))
return -EADDRNOTAVAIL;
+
+ memcpy(req.mac_addr, addr->sa_data, netdev->addr_len);
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
- return 0;
+
+ kni = netdev_priv(netdev);
+ ret = kni_net_process_request(kni, &req);
+
+ return (ret == 0 ? req.result : ret);
}
#ifdef HAVE_CHANGE_CARRIER_CB
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index 8eca8c0..a5ee210 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -356,6 +356,8 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
memset(ctx, 0, sizeof(struct rte_kni));
if (ops)
memcpy(&ctx->ops, ops, sizeof(struct rte_kni_ops));
+ else
+ ctx->ops.port_id = UINT16_MAX;
memset(&dev_info, 0, sizeof(dev_info));
dev_info.bus = conf->addr.bus;
@@ -368,6 +370,8 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
dev_info.group_id = conf->group_id;
dev_info.mbuf_size = conf->mbuf_size;
+ memcpy(dev_info.mac_addr, conf->mac_addr, ETHER_ADDR_LEN);
+
snprintf(ctx->name, RTE_KNI_NAMESIZE, "%s", intf_name);
snprintf(dev_info.name, RTE_KNI_NAMESIZE, "%s", intf_name);
@@ -528,6 +532,28 @@ rte_kni_release(struct rte_kni *kni)
return 0;
}
+/* default callback for request of configuring device mac address */
+static int
+kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
+{
+ int ret = 0;
+
+ if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+ RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+ return -EINVAL;
+ }
+
+ RTE_LOG(INFO, KNI, "Configure mac address of %d", port_id);
+
+ ret = rte_eth_dev_default_mac_addr_set(port_id,
+ (struct ether_addr *)mac_addr);
+ if (ret < 0)
+ RTE_LOG(ERR, KNI, "Failed to config mac_addr for port %d\n",
+ port_id);
+
+ return ret;
+}
+
int
rte_kni_handle_request(struct rte_kni *kni)
{
@@ -559,6 +585,14 @@ rte_kni_handle_request(struct rte_kni *kni)
req->result = kni->ops.config_network_if(\
kni->ops.port_id, req->if_up);
break;
+ case RTE_KNI_REQ_CHANGE_MAC_ADDR: /* Change MAC Address */
+ if (kni->ops.config_mac_address)
+ req->result = kni->ops.config_mac_address(
+ kni->ops.port_id, req->mac_addr);
+ else if (kni->ops.port_id != UNIT16_MAX)
+ req->result = kni_config_mac_address(
+ kni->ops.port_id, req->mac_addr);
+ break;
default:
RTE_LOG(ERR, KNI, "Unknown request id %u\n", req->req_id);
req->result = -EINVAL;
@@ -707,7 +741,9 @@ kni_check_request_register(struct rte_kni_ops *ops)
if( NULL == ops )
return KNI_REQ_NO_REGISTER;
- if((NULL == ops->change_mtu) && (NULL == ops->config_network_if))
+ if ((NULL == ops->change_mtu)
+ && (NULL == ops->config_network_if)
+ && (NULL == ops->config_mac_address))
return KNI_REQ_NO_REGISTER;
return KNI_REQ_REGISTERED;
@@ -746,8 +782,8 @@ rte_kni_unregister_handlers(struct rte_kni *kni)
return -1;
}
- kni->ops.change_mtu = NULL;
- kni->ops.config_network_if = NULL;
+ memset(&kni->ops, 0, sizeof(struct rte_kni_ops));
+
return 0;
}
void
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index d43b5b2..9bdc9f3 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -49,6 +49,7 @@
#include <rte_pci.h>
#include <rte_memory.h>
#include <rte_mempool.h>
+#include <rte_ether.h>
#include <exec-env/rte_kni_common.h>
@@ -70,6 +71,9 @@ struct rte_kni_ops {
/* Pointer to function of configuring network interface */
int (*config_network_if)(uint16_t port_id, uint8_t if_up);
+
+ /* Pointer to function of configuring mac address */
+ int (*config_mac_address)(uint16_t port_id, uint8_t mac_addr[]);
};
/**
@@ -90,6 +94,7 @@ struct rte_kni_conf {
__extension__
uint8_t force_bind : 1; /* Flag to bind kernel thread */
+ char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
};
/**
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index b956727..06448c9 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -103,6 +103,7 @@ static const struct rte_eth_conf port_conf = {
static struct rte_kni_ops kni_ops = {
.change_mtu = NULL,
.config_network_if = NULL,
+ .config_mac_address = NULL,
};
static unsigned lcore_master, lcore_ingress, lcore_egress;
@@ -260,6 +261,7 @@ test_kni_register_handler_mp(void)
struct rte_kni_ops ops = {
.change_mtu = kni_change_mtu,
.config_network_if = NULL,
+ .config_mac_address = NULL,
};
if (!kni) {
--
2.7.4
^ permalink raw reply [relevance 2%]
* [dpdk-dev] [PATCH v2 2/3] kni: add support for promisc mode set
2017-12-26 10:36 2% ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
@ 2017-12-26 10:36 3% ` Hemant Agrawal
2017-12-26 10:36 3% ` [dpdk-dev] [PATCH v2 3/3] kni: set initial value for MTU Hemant Agrawal
1 sibling, 0 replies; 200+ results
From: Hemant Agrawal @ 2017-12-26 10:36 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Inform userspace app about promisc mode change
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
v2:
* fix ABI breakage
* check for ops.port_id for vdev case
doc/guides/sample_app_ug/kernel_nic_interface.rst | 15 ++++++++---
.../linuxapp/eal/include/exec-env/rte_kni_common.h | 2 ++
lib/librte_eal/linuxapp/kni/kni_net.c | 17 ++++++++++++
lib/librte_kni/rte_kni.c | 31 +++++++++++++++++++++-
lib/librte_kni/rte_kni.h | 3 +++
test/test/test_kni.c | 2 ++
6 files changed, 66 insertions(+), 4 deletions(-)
diff --git a/doc/guides/sample_app_ug/kernel_nic_interface.rst b/doc/guides/sample_app_ug/kernel_nic_interface.rst
index 2c143da..4dd1f82 100644
--- a/doc/guides/sample_app_ug/kernel_nic_interface.rst
+++ b/doc/guides/sample_app_ug/kernel_nic_interface.rst
@@ -512,11 +512,11 @@ Callbacks for Kernel Requests
To execute specific PMD operations in user space requested by some Linux* commands,
callbacks must be implemented and filled in the struct rte_kni_ops structure.
-Currently, setting a new MTU, change in mac address and configuring the network interface(up/ down)
-are supported.
+Currently, setting a new MTU, change in mac address, configuring promiscusous mode
+and configuring the network interface(up/ down) are supported.
Default implementation for following is available in rte_kni library. Application
may choose to not implement follwoing callbacks:
- ``config_mac_address``
+ ``config_mac_address`` and ``config_promiscusity``
.. code-block:: c
@@ -525,6 +525,7 @@ may choose to not implement follwoing callbacks:
.change_mtu = kni_change_mtu,
.config_network_if = kni_config_network_interface,
.config_mac_address = kni_config_mac_address,
+ .config_promiscusity = kni_config_promiscusity,
};
/* Callback for request of changing MTU */
@@ -611,3 +612,11 @@ may choose to not implement follwoing callbacks:
{
.....
}
+
+ /* Callback for request of configuring promiscuous mode */
+
+ static int
+ kni_config_promiscusity(uint16_t port_id, uint8_t to_on)
+ {
+ .....
+ }
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
index 1a760de..b519db5 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
@@ -81,6 +81,7 @@ enum rte_kni_req_id {
RTE_KNI_REQ_CHANGE_MTU,
RTE_KNI_REQ_CFG_NETWORK_IF,
RTE_KNI_REQ_CHANGE_MAC_ADDR,
+ RTE_KNI_REQ_CHANGE_PROMISC,
RTE_KNI_REQ_MAX,
};
@@ -94,6 +95,7 @@ struct rte_kni_request {
uint32_t new_mtu; /**< New MTU */
uint8_t if_up; /**< 1: interface up, 0: interface down */
uint8_t mac_addr[6]; /**< MAC address for interface */
+ uint8_t promiscusity;/**< 1: promisc mode enable, 0: disable */
};
int32_t result; /**< Result for processing request */
} __attribute__((__packed__));
diff --git a/lib/librte_eal/linuxapp/kni/kni_net.c b/lib/librte_eal/linuxapp/kni/kni_net.c
index 3e02ea1..e261c58 100644
--- a/lib/librte_eal/linuxapp/kni/kni_net.c
+++ b/lib/librte_eal/linuxapp/kni/kni_net.c
@@ -603,6 +603,22 @@ kni_net_change_mtu(struct net_device *dev, int new_mtu)
return (ret == 0) ? req.result : ret;
}
+static void
+kni_net_set_promiscusity(struct net_device *netdev, int flags)
+{
+ struct rte_kni_request req;
+ struct kni_dev *kni = netdev_priv(netdev);
+
+ memset(&req, 0, sizeof(req));
+ req.req_id = RTE_KNI_REQ_CHANGE_PROMISC;
+
+ if (netdev->flags & IFF_PROMISC)
+ req.promiscusity = 1;
+ else
+ req.promiscusity = 0;
+ kni_net_process_request(kni, &req);
+}
+
/*
* Checks if the user space application provided the resp message
*/
@@ -712,6 +728,7 @@ static const struct net_device_ops kni_net_netdev_ops = {
.ndo_open = kni_net_open,
.ndo_stop = kni_net_release,
.ndo_set_config = kni_net_config,
+ .ndo_change_rx_flags = kni_net_set_promiscusity,
.ndo_start_xmit = kni_net_tx,
.ndo_change_mtu = kni_net_change_mtu,
.ndo_do_ioctl = kni_net_ioctl,
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index a5ee210..bed3f20 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -554,6 +554,26 @@ kni_config_mac_address(uint16_t port_id, uint8_t mac_addr[])
return ret;
}
+/* default callback for request of configuring promiscuous mode */
+static int
+kni_config_promiscusity(uint16_t port_id, uint8_t to_on)
+{
+ if (port_id >= rte_eth_dev_count() || port_id >= RTE_MAX_ETHPORTS) {
+ RTE_LOG(ERR, KNI, "Invalid port id %d\n", port_id);
+ return -EINVAL;
+ }
+
+ RTE_LOG(INFO, KNI, "Configure promiscuous mode of %d to %d\n",
+ port_id, to_on);
+
+ if (to_on)
+ rte_eth_promiscuous_enable(port_id);
+ else
+ rte_eth_promiscuous_disable(port_id);
+
+ return 0;
+}
+
int
rte_kni_handle_request(struct rte_kni *kni)
{
@@ -593,6 +613,14 @@ rte_kni_handle_request(struct rte_kni *kni)
req->result = kni_config_mac_address(
kni->ops.port_id, req->mac_addr);
break;
+ case RTE_KNI_REQ_CHANGE_PROMISC: /* Change PROMISCUOUS MODE */
+ if (kni->ops.config_promiscusity)
+ req->result = kni->ops.config_promiscusity(
+ kni->ops.port_id, req->promiscusity);
+ else if (kni->ops.port_id != UNIT16_MAX)
+ req->result = kni_config_promiscusity(
+ kni->ops.port_id, req->promiscusity);
+ break;
default:
RTE_LOG(ERR, KNI, "Unknown request id %u\n", req->req_id);
req->result = -EINVAL;
@@ -743,7 +771,8 @@ kni_check_request_register(struct rte_kni_ops *ops)
if ((NULL == ops->change_mtu)
&& (NULL == ops->config_network_if)
- && (NULL == ops->config_mac_address))
+ && (NULL == ops->config_mac_address)
+ && (NULL == ops->config_promiscusity))
return KNI_REQ_NO_REGISTER;
return KNI_REQ_REGISTERED;
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 9bdc9f3..4530bdd 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -74,6 +74,9 @@ struct rte_kni_ops {
/* Pointer to function of configuring mac address */
int (*config_mac_address)(uint16_t port_id, uint8_t mac_addr[]);
+
+ /* Pointer to function of configuring promiscuous mode */
+ int (*config_promiscusity)(uint16_t port_id, uint8_t to_on);
};
/**
diff --git a/test/test/test_kni.c b/test/test/test_kni.c
index 06448c9..56a7f3b 100644
--- a/test/test/test_kni.c
+++ b/test/test/test_kni.c
@@ -104,6 +104,7 @@ static struct rte_kni_ops kni_ops = {
.change_mtu = NULL,
.config_network_if = NULL,
.config_mac_address = NULL,
+ .config_promiscusity = NULL,
};
static unsigned lcore_master, lcore_ingress, lcore_egress;
@@ -262,6 +263,7 @@ test_kni_register_handler_mp(void)
.change_mtu = kni_change_mtu,
.config_network_if = NULL,
.config_mac_address = NULL,
+ .config_promiscusity = NULL,
};
if (!kni) {
--
2.7.4
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v2 3/3] kni: set initial value for MTU
2017-12-26 10:36 2% ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
2017-12-26 10:36 3% ` [dpdk-dev] [PATCH v2 2/3] kni: add support for promisc mode set Hemant Agrawal
@ 2017-12-26 10:36 3% ` Hemant Agrawal
1 sibling, 0 replies; 200+ results
From: Hemant Agrawal @ 2017-12-26 10:36 UTC (permalink / raw)
To: dev; +Cc: ferruh.yigit
Configure initial application provided mtu on the KNI interface.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
v2: fix ABI breakage
examples/kni/main.c | 2 ++
lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h | 1 +
lib/librte_eal/linuxapp/kni/kni_misc.c | 3 +++
lib/librte_kni/rte_kni.c | 1 +
lib/librte_kni/rte_kni.h | 1 +
5 files changed, 8 insertions(+)
diff --git a/examples/kni/main.c b/examples/kni/main.c
index 1c251c2..d9c9fa5 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -845,6 +845,8 @@ kni_alloc(uint16_t port_id)
rte_eth_macaddr_get(port_id,
(struct ether_addr *)&conf.mac_addr);
+ rte_eth_dev_get_mtu(port_id, &conf.mtu);
+
memset(&ops, 0, sizeof(ops));
ops.port_id = port_id;
ops.change_mtu = kni_change_mtu;
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
index b519db5..2e393c0 100644
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
+++ b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_kni_common.h
@@ -172,6 +172,7 @@ struct rte_kni_device_info {
/* mbuf size */
unsigned mbuf_size;
+ unsigned int mtu;
char mac_addr[6];
};
diff --git a/lib/librte_eal/linuxapp/kni/kni_misc.c b/lib/librte_eal/linuxapp/kni/kni_misc.c
index b524d30..0ccd227 100644
--- a/lib/librte_eal/linuxapp/kni/kni_misc.c
+++ b/lib/librte_eal/linuxapp/kni/kni_misc.c
@@ -470,6 +470,9 @@ kni_ioctl_create(struct net *net, uint32_t ioctl_num,
random_ether_addr(net_dev->dev_addr);
}
+ if (dev_info.mtu)
+ net_dev->mtu = dev_info.mtu;
+
ret = register_netdev(net_dev);
if (ret) {
pr_err("error %i registering device \"%s\"\n",
diff --git a/lib/librte_kni/rte_kni.c b/lib/librte_kni/rte_kni.c
index bed3f20..2461b47 100644
--- a/lib/librte_kni/rte_kni.c
+++ b/lib/librte_kni/rte_kni.c
@@ -369,6 +369,7 @@ rte_kni_alloc(struct rte_mempool *pktmbuf_pool,
dev_info.force_bind = conf->force_bind;
dev_info.group_id = conf->group_id;
dev_info.mbuf_size = conf->mbuf_size;
+ dev_info.mtu = conf->mtu;
memcpy(dev_info.mac_addr, conf->mac_addr, ETHER_ADDR_LEN);
diff --git a/lib/librte_kni/rte_kni.h b/lib/librte_kni/rte_kni.h
index 4530bdd..cbf3188 100644
--- a/lib/librte_kni/rte_kni.h
+++ b/lib/librte_kni/rte_kni.h
@@ -98,6 +98,7 @@ struct rte_kni_conf {
__extension__
uint8_t force_bind : 1; /* Flag to bind kernel thread */
char mac_addr[ETHER_ADDR_LEN]; /* MAC address assigned to KNI */
+ uint16_t mtu;
};
/**
--
2.7.4
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/2] mbuf: update default Mempool ops with HW active pool
@ 2017-12-28 12:07 3% ` Hemant Agrawal
2018-01-10 12:49 0% ` Hemant Agrawal
0 siblings, 1 reply; 200+ results
From: Hemant Agrawal @ 2017-12-28 12:07 UTC (permalink / raw)
To: Olivier MATZ; +Cc: Jerin Jacob, santosh.shukla, dev
Hi Olivier,
On 12/22/2017 8:29 PM, Olivier MATZ wrote:
> On Mon, Dec 18, 2017 at 03:06:21PM +0530, Hemant Agrawal wrote:
>> On 12/18/2017 2:25 PM, Jerin Jacob wrote:
>>> -----Original Message-----
>>>> Date: Fri, 15 Dec 2017 15:54:42 +0530
>>>> From: Hemant Agrawal <hemant.agrawal@nxp.com>
>>>> To: olivier.matz@6wind.com, santosh.shukla@caviumnetworks.com
>>>> CC: dev@dpdk.org
>>>> Subject: [dpdk-dev] [PATCH 1/2] mbuf: update default Mempool ops with HW
>>>> active pool
>>>> X-Mailer: git-send-email 2.7.4
>>>>
>>>> With this patch the specific HW mempool are no longer required to be
>>>> specified in the config file at compile. A default active hw mempool
>>>> can be detected dynamically and published to default mempools ops
>>>> config at run time. Only one type of HW mempool can be active default.
>>>
>>> For me, it looks very reasonable approach as it caters the basic use
>>> case without any change in the application nor the additional(--mbuf-pool-ops-name)
>>> EAL command line scheme to select different mempool ops.
>>> Though, this option will not enough cater all the use case. I think, we can have
>>> three options and the following order of precedence to select the mempool ops
>>>
>>> 1) This patch(update active mempool based on the device probe())
>>> 2) Selection of mempool ops though --mbuf-pool-ops-name= EAL commandline argument.
>>> Which can overridden the scheme(1)
>>> 3) More sophisticated mempool section based on
>>> a) The ethdev PMD capability exposed through existing rte_eth_dev_pool_ops_supported()
>>> b) Add mempool ops option in rte_pktmbuf_pool_create()
>>> http://dpdk.org/ml/archives/dev/2017-December/083985.html
>>> c) Use (a) and (b) to select the update the mempool ops with
>>> some "weight" based algorithm like
>>> http://dpdk.org/dev/patchwork/patch/32245/
>>>
>>
>> Yes! We need more options to fine tune control over the mempool uses,
>> specially when dealing with HW mempools.
>>
>> Once the above mentioned mechanisms will be in place, it will be much easier
>> and flexible.
>
> I'm inline with this description. It would be great if the same binary can work
> on different platforms without configuration.
>
> I just feel it's a bit messy to have:
>
> - rte_eal_mbuf_default_mempool_ops() in eal API
> return user-selected ops if any, or compile-time default
>
> - rte_pktmbuf_active_mempool_ops() in mbuf API
> return platform ops except if a selected user ops != compile default
>
> Thomas suggested somewhere (but I don't remember in which thread) to have
> rte_eal_mbuf_default_mempool_ops() in mbuf code, and I think he was right.
>
The idea is good. It will break ABI, but we can move around in
systematic way.
> I think the whole mbuf pool ops selection mechanism should be at the
> same place. I could be in a specific file of librte_mbuf.
>
> The API could be:
> - get compile time default ops
We can get them from "RTE_MBUF_DEFAULT_MEMPOOL_OPS"
or "
const char *rte_get_mbuf_config_mempool_ops(void)
> - get/set platform ops (NULL if none)
const char *rte_get_mbuf_platform_mempool_ops(void);
int rte_set_mbuf_platform_mempool_ops(const char *ops_name);
> - get/set user ops (NULL if none)
internal_config will only store the command line argument or NULL.
rename : rte_eal_mbuf_default_mempool_ops(void)
to const char *rte_get_mbuf_user_mempool_ops(void)
> - get preferred ops from currently configured PMD
>
The following proposal is updating the mempool_ops name in
internal_config, I thing that is not the best solution. We shall not
update the internal config.
eal: add API to set default mbuf mempool ops
http://dpdk.org/ml/archives/dev/2017-December/083849.html
rte_eth_dev_get_preferred_pool_name()
> - get best ops: return user, or pmd-prefered, or platform, or default.
>
pktmbuf_pool_create is currently calling, *rte_eal_mbuf_default_mempool_ops*
This should be changed to call *rte_get_mbuf_best_mempool_ops* in the
following order
1. rte_get_mbuf_user_mempool_ops
2. rte_eth_dev_get_preferred_pool_name (whenever this API comes)
3. rte_get_mbuf_platform_mempool_ops
4. rte_get_mbuf_config_mempool_ops
> rte_pktmbuf_pool_create() will use "get best ops" if no ops (NULL) is
> passed as argument.
>
However, we shall still provide a additional API,
*rte_pktmbuf_pool_create_specific* if user still wants fine control or
don't want to use the default best logic.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-12 14:07 0% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Bruce Richardson
@ 2017-12-30 17:15 0% ` Neil Horman
2018-01-04 12:56 0% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2017-12-30 17:15 UTC (permalink / raw)
To: Bruce Richardson; +Cc: dev, thomas, john.mcnamara
On Tue, Dec 12, 2017 at 02:07:52PM +0000, Bruce Richardson wrote:
> On Mon, Dec 11, 2017 at 02:36:15PM -0500, Neil Horman wrote:
> > Hey all-
> > A few days ago, I was lamenting the fact that, when reviewing patches I
> > would frequently complain about ABI changes that were actually considered safe
> > because they were part of the EXPERIMENTAL api set. John M. asked me then what
> > I might do to improve the situation, and the following patch set is a proposal
> > that I've come up with.
> >
> > In thinking about the problem I identified two issues that I think we
> > can improve on in this area:
> >
> > 1) Make experimental api calls more visible in the source code. That is to say,
> > when reviewing patches, it would be nice to have some sort of visual reference
> > that indicates that the changes being made are part of an experimental API and
> > therefore ABI concerns need not be addressed
> >
> > 2) Make experimenal api usage more visible to consumers of the DPDK, so that
> > they can make a more informed decision about the API's they consume in their
> > application. We make an effort to document all the experimental API's, but
> > there is no guarantee that a user will check the documentation before making use
> > of a new library.
> >
> > This patch set attempts to achieve both of the above goals. To do this I've
> > added an __experimental macro tag, suitable for inserting into api forward
> > declarations and definitions.
> >
> > The presence of the tag in the header and c files where the api code resides
> > increases the likelyhood that any patch submitted against them will include the
> > tag in the context, making it clear to reviewers that ABI stability isn't a
> > concern here.
> >
> >
> > Also, This tag marks each function it is used on with an attibute causing any
> > use of the fuction to emit a warning during the build
> > with a message indicating that the API call in question is not yet part of the
> > stable interface. Developers can then make an informed decision to suppress
> > that warning or not.
> >
> > Because there is internal use of several experimental API's, this set also
> > includes a new override macro ALLOW_EXPERIMENTAL_APIS to automatically
> > suprress these warnings. I think its fair to assume that, for internal use, we
> > almost always want to suppress these warnings, as by definition any change to
> > the apis (even their removal) must be done in parallel with an appropriate
> > change in the calling locations, lest the dpdk build itself break.
> >
> > Neil
> >
> > ---
> > Change Notes:
> > v2)
> > * Cleaned up checkpatch errors
> > * Added Allowance for building experimental on BSD
> > * Swapped Patch 3 and 4 so that we didn't have a commit level that issued
> > warnings/errors without need
> >
> > v3)
> > * On suggestion from Bruce, modify ALLOW_EXPERIMENTAL_APIS to be defined in
> > CFLAGS rather than a makefile variable. This is more flexible in that it
> > allows us to suppress this specific feature rather than all uses of the
> > deprecated attribute, as we might use it for other features in the furute
> >
>
> Despite the fact that this is making yet more work for porting to a new
> build system, I think this is a good idea to have. As such,
>
> Acked-by: Bruce Richardson <bruce.richardson@intel.com>
>
>
Thomas-
I just noticed that the ci tests are failing on the intel compiler, which
makes very little sense to me, as the error is a permission error on a bash
script that added in this series, which works during the gcc compilation. Can
you take a look at that please?
thanks
Neil
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv4 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-13 15:17 4% ` [dpdk-dev] [PATCHv4 " Neil Horman
` (4 preceding siblings ...)
2017-12-21 14:21 0% ` Neil Horman
@ 2017-12-30 19:20 0% ` Luca Boccassi
2017-12-31 1:57 0% ` Neil Horman
5 siblings, 1 reply; 200+ results
From: Luca Boccassi @ 2017-12-30 19:20 UTC (permalink / raw)
To: Neil Horman, dev
On Wed, 2017-12-13 at 10:17 -0500, Neil Horman wrote:
> Hey all-
> A few days ago, I was lamenting the fact that, when reviewing
> patches I
> would frequently complain about ABI changes that were actually
> considered safe
> because they were part of the EXPERIMENTAL api set. John M. asked me
> then what
> I might do to improve the situation, and the following patch set is a
> proposal
> that I've come up with.
>
> In thinking about the problem I identified two issues that I
> think we
> can improve on in this area:
>
> 1) Make experimental api calls more visible in the source code. That
> is to say,
> when reviewing patches, it would be nice to have some sort of visual
> reference
> that indicates that the changes being made are part of an
> experimental API and
> therefore ABI concerns need not be addressed
>
> 2) Make experimenal api usage more visible to consumers of the DPDK,
> so that
> they can make a more informed decision about the API's they consume
> in their
> application. We make an effort to document all the experimental
> API's, but
> there is no guarantee that a user will check the documentation before
> making use
> of a new library.
>
> This patch set attempts to achieve both of the above goals. To do
> this I've
> added an __experimental macro tag, suitable for inserting into api
> forward
> declarations and definitions.
>
> The presence of the tag in the header and c files where the api code
> resides
> increases the likelyhood that any patch submitted against them will
> include the
> tag in the context, making it clear to reviewers that ABI stability
> isn't a
> concern here.
>
> Also, This tag marks each function it is used on with an attibute
> causing any
> use of the fuction to emit a warning during the build
> with a message indicating that the API call in question is not yet
> part of the
> stable interface. Developers can then make an informed decision to
> suppress
> that warning or not.
>
> Because there is internal use of several experimental API's, this set
> also
> includes a new override macro ALLOW_EXPERIMENTAL_APIS to
> automatically
> suprress these warnings. I think its fair to assume that, for
> internal use, we
> almost always want to suppress these warnings, as by definition any
> change to
> the apis (even their removal) must be done in parallel with an
> appropriate
> change in the calling locations, lest the dpdk build itself break.
>
> Neil
>
> ---
> Change Notes:
> v2)
> * Cleaned up checkpatch errors
> * Added Allowance for building experimental on BSD
> * Swapped Patch 3 and 4 so that we didn't have a commit level that
> issued
> warnings/errors without need
>
> v3)
> * On suggestion from Bruce, modify ALLOW_EXPERIMENTAL_APIS to be
> defined in
> CFLAGS rather than a makefile variable. This is more flexible in
> that it
> allows us to suppress this specific feature rather than all uses of
> the
> deprecated attribute, as we might use it for other features in the
> furute
>
> v4)
> * Added documentation patch to contributors guide
Acked-by: Luca Boccassi <bluca@debian.org>
I really like the idea of showing warnings at build time for users of
the libraries, in fact I like it so much I'm going to shamelessly steal
it for another few projects I work on where we have an experimental
(DRAFT) api system :-)
--
Kind regards,
Luca Boccassi
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv4 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-30 19:20 0% ` Luca Boccassi
@ 2017-12-31 1:57 0% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2017-12-31 1:57 UTC (permalink / raw)
To: Luca Boccassi; +Cc: dev
On Sat, Dec 30, 2017 at 08:20:58PM +0100, Luca Boccassi wrote:
> On Wed, 2017-12-13 at 10:17 -0500, Neil Horman wrote:
> > Hey all-
> > A few days ago, I was lamenting the fact that, when reviewing
> > patches I
> > would frequently complain about ABI changes that were actually
> > considered safe
> > because they were part of the EXPERIMENTAL api set. John M. asked me
> > then what
> > I might do to improve the situation, and the following patch set is a
> > proposal
> > that I've come up with.
> >
> > In thinking about the problem I identified two issues that I
> > think we
> > can improve on in this area:
> >
> > 1) Make experimental api calls more visible in the source code. That
> > is to say,
> > when reviewing patches, it would be nice to have some sort of visual
> > reference
> > that indicates that the changes being made are part of an
> > experimental API and
> > therefore ABI concerns need not be addressed
> >
> > 2) Make experimenal api usage more visible to consumers of the DPDK,
> > so that
> > they can make a more informed decision about the API's they consume
> > in their
> > application. We make an effort to document all the experimental
> > API's, but
> > there is no guarantee that a user will check the documentation before
> > making use
> > of a new library.
> >
> > This patch set attempts to achieve both of the above goals. To do
> > this I've
> > added an __experimental macro tag, suitable for inserting into api
> > forward
> > declarations and definitions.
> >
> > The presence of the tag in the header and c files where the api code
> > resides
> > increases the likelyhood that any patch submitted against them will
> > include the
> > tag in the context, making it clear to reviewers that ABI stability
> > isn't a
> > concern here.
> >
> > Also, This tag marks each function it is used on with an attibute
> > causing any
> > use of the fuction to emit a warning during the build
> > with a message indicating that the API call in question is not yet
> > part of the
> > stable interface. Developers can then make an informed decision to
> > suppress
> > that warning or not.
> >
> > Because there is internal use of several experimental API's, this set
> > also
> > includes a new override macro ALLOW_EXPERIMENTAL_APIS to
> > automatically
> > suprress these warnings. I think its fair to assume that, for
> > internal use, we
> > almost always want to suppress these warnings, as by definition any
> > change to
> > the apis (even their removal) must be done in parallel with an
> > appropriate
> > change in the calling locations, lest the dpdk build itself break.
> >
> > Neil
> >
> > ---
> > Change Notes:
> > v2)
> > * Cleaned up checkpatch errors
> > * Added Allowance for building experimental on BSD
> > * Swapped Patch 3 and 4 so that we didn't have a commit level that
> > issued
> > warnings/errors without need
> >
> > v3)
> > * On suggestion from Bruce, modify ALLOW_EXPERIMENTAL_APIS to be
> > defined in
> > CFLAGS rather than a makefile variable. This is more flexible in
> > that it
> > allows us to suppress this specific feature rather than all uses of
> > the
> > deprecated attribute, as we might use it for other features in the
> > furute
> >
> > v4)
> > * Added documentation patch to contributors guide
>
> Acked-by: Luca Boccassi <bluca@debian.org>
>
> I really like the idea of showing warnings at build time for users of
> the libraries, in fact I like it so much I'm going to shamelessly steal
> it for another few projects I work on where we have an experimental
> (DRAFT) api system :-)
>
You're welcome to it :)
Neil
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3 1/5] ethdev: remove useless parameter in callback process
@ 2018-01-03 8:17 3% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-01-03 8:17 UTC (permalink / raw)
To: Neil Horman, Iremonger, Bernard; +Cc: dev, Yigit, Ferruh
02/01/2018 13:21, Neil Horman:
> On Tue, Jan 02, 2018 at 11:35:02AM +0000, Iremonger, Bernard wrote:
> > > int _rte_eth_dev_callback_process(struct rte_eth_dev *dev,
> > > - enum rte_eth_event_type event, void *cb_arg, void *ret_param);
> > > + enum rte_eth_event_type event, void *ret_param);
> >
> > As this is a change to the public API of librte_ether is a deprecation notice needed ?
> > This API is currently used by the test/test/virtual_pmd.c APP and may be used by other APP's in the field.
> >
> Agreed, it definately should go through the deprecation process
This function is used by drivers only, that's why there is an underscore
at the beginning of its name.
So it is not part of the regular ABI and does not need any deprecation
notice, in my opinion.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 0/2] vhost: introduce rte_vhost_vring_call()
[not found] ` <20180102181141.GC22252@stefanha-x1.localdomain>
@ 2018-01-03 8:17 0% ` Maxime Coquelin
2018-01-08 13:46 0% ` Yuanhan Liu
0 siblings, 1 reply; 200+ results
From: Maxime Coquelin @ 2018-01-03 8:17 UTC (permalink / raw)
To: Stefan Hajnoczi; +Cc: dev, Yuanhan Liu, Tetsuya Mukawa
On 01/02/2018 07:11 PM, Stefan Hajnoczi wrote:
> On Tue, Jan 02, 2018 at 11:27:02AM +0100, Maxime Coquelin wrote:
>> Hi Stefan,
>>
>> On 01/02/2018 10:31 AM, Stefan Hajnoczi wrote:
>>> v2:
>>> * Add internal vhost_vring_call() helper function [Maxime]
>>>
>>> These patches eliminate code duplication for vhost_virtqueue->callfd users by
>>> introducing rte_vhost_vring_call() (public API) and vhost_vring_call()
>>> (librte_vhost-internal API).
>>>
>>> Stefan Hajnoczi (2):
>>> vhost: add vhost_vring_call() helper
>>> vhost: introduce rte_vhost_vring_call()
>>>
>>> lib/librte_vhost/rte_vhost.h | 15 +++++++++++++++
>>> lib/librte_vhost/vhost.h | 12 ++++++++++++
>>> examples/vhost/virtio_net.c | 11 ++---------
>>> examples/vhost_scsi/vhost_scsi.c | 6 +++---
>>> lib/librte_vhost/vhost.c | 21 +++++++++++++++++++++
>>> lib/librte_vhost/virtio_net.c | 23 +++--------------------
>>> lib/librte_vhost/rte_vhost_version.map | 7 +++++++
>>> 7 files changed, 63 insertions(+), 32 deletions(-)
>>>
>>
>> I just wonder whether tagging the new API as experimental is needed,
>> but apart from that it looks good to me:
>>
>> Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
>
> From 3.2. Managing ABI updates, General Guidelines:
>
> New APIs will be marked as experimental for at least one release to
> allow any issues found by users of the new API to be fixed quickly.
>
> http://dpdk.org/doc/guides/contributing/versioning.html
>
> I'm new to DPDK so I followed this guideline strictly and expect the
> maintainers to mark the API stable at some point in the future when they
> are happy with it. Maybe this guideline isn't followed strictly for
> librte_vhost?
Thanks for the pointer, it seems it is not strictly followed for
librte_vhost & other libs. Let's keep it experimental for the coming
release.
Maxime
> Stefan
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: fix setting of MAC address
@ 2018-01-03 13:43 3% ` Olivier Matz
2018-01-03 13:54 0% ` Olivier Matz
0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2018-01-03 13:43 UTC (permalink / raw)
To: Andrew Rybchenko
Cc: Ivan Malov, Igor Ryzhov, dev, Thomas Monjalon, Laurent Hardy,
Ferruh Yigit, stable
Hi,
On Wed, Dec 20, 2017 at 01:00:01PM +0300, Andrew Rybchenko wrote:
> On 12/19/2017 12:47 PM, Andrew Rybchenko wrote:
> > On 12/19/2017 12:29 PM, Olivier MATZ wrote:
> > > Hi,
> > >
> > > On Mon, Dec 18, 2017 at 02:38:55PM +0300, Andrew Rybchenko wrote:
> > > > On 12/18/2017 01:53 PM, Igor Ryzhov wrote:
> > > > > On Mon, Dec 18, 2017 at 1:35 PM, Andrew Rybchenko
> > > > > <arybchenko@solarflare.com <mailto:arybchenko@solarflare.com>> wrote:
> > > > >
> > > > > On 12/14/2017 08:15 PM, Olivier Matz wrote:
> > > > >
> > > > > From: Laurent Hardy <laurent.hardy@6wind.com
> > > > > <mailto:laurent.hardy@6wind.com>>
> > > > >
> > > > > When a new mac address is set, it is saved in
> > > > > dev->data->mac_addrs
> > > > > before the ethdev handler is called.
> > > > >
> > > > > First, it is inconsistent with the other ethdev functions
> > > > > rte_eth_dev_mac_addr_remove() and rte_eth_dev_mac_addr_add().
> > > > >
> > > > > Moreover, it prevents the drivers from wrongly comparing the
> > > > > old address
> > > > > and the new one, like it's done in i40evf driver:
> > > > >
> > > > > if (is_same_ether_addr(mac_addr,
> > > > > dev->data->mac_addrs))
> > > > > return;
> > > > >
> > > > > Fixes: 943c2d899a0c ("net/i40e: set VF MAC from VF")
> > > > > Fixes: 854d8ad4ef68 ("ethdev: add default mac
> > > > > address modifier")
> > > > > Cc: stable@dpdk.org <mailto:stable@dpdk.org>
> > > > >
> > > > > Signed-off-by: Laurent Hardy <laurent.hardy@6wind.com
> > > > > <mailto:laurent.hardy@6wind.com>>
> > > > > ---
> > > > > lib/librte_ether/rte_ethdev.c | 4 ++--
> > > > > 1 file changed, 2 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/lib/librte_ether/rte_ethdev.c
> > > > > b/lib/librte_ether/rte_ethdev.c
> > > > > index 4f492e3db..297c02a54 100644
> > > > > --- a/lib/librte_ether/rte_ethdev.c
> > > > > +++ b/lib/librte_ether/rte_ethdev.c
> > > > > @@ -2643,11 +2643,11 @@
> > > > > rte_eth_dev_default_mac_addr_set(uint16_t port_id, struct
> > > > > ether_addr *addr)
> > > > > dev = &rte_eth_devices[port_id];
> > > > > RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->mac_addr_set,
> > > > > -ENOTSUP);
> > > > > + (*dev->dev_ops->mac_addr_set)(dev, addr);
> > > > > +
> > > > > /* Update default address in NIC data structure */
> > > > > ether_addr_copy(addr, &dev->data->mac_addrs[0]);
> > > > > - (*dev->dev_ops->mac_addr_set)(dev, addr);
> > > > > -
> > > > > return 0;
> > > > > }
> > > > >
> > > > >
> > > > > NACK, unfortunately it will break net/sfc in one of branches when
> > > > > a new MAC
> > > > > is set using restart. It relies on the fact that a new MAC is
> > > > > already available in
> > > > > device data.
> > > > >
> > > > >
> > > > > Hello Andrew,
> > > > >
> > > > > Don't you think that it's not correct that net/sfc works that way?
> > > > >
> > > > > If we go further, dev->dev_ops->mac_addr_set not only should be called
> > > > before ether_addr_copy.
> > > > > It should return status code, and in case of error ether_addr_copy
> > > > > shouldn't be
> > > > called at all.
> > > > > Am I wrong?
> > > Yes, I also have the same feeling.
> > >
> > > > Current behaviour is convenient. Alternative will require copy of MAC
> > > > address
> > > > to set in device private data and one more copy in the function
> > > > to rollback
> > > > in
> > > > the case of failure. If there are good reasons to change
> > > > behaviour, I don't
> > > > mind but PMDs should be reviewed carefully and fixed before the change.
> > > Right. The first version of the patch was just a fix of the i40e code,
> > > which was of course less risky. But we finally decided to to that way
> > > for consistency.
> > >
> > > I will review the other PMDs and send a v2 that should not break
> > > them. If you have any guidelines for net/sfc, they will be welcome :)
> >
> > We'll send net/sfc patch today/tomorrow to fix it.
>
> Done [1]
>
> [1] http://dpdk.org/ml/archives/dev/2017-December/084526.html
I've walked through the PMDs as suggested by Andrew, and there was
indeed some conflicts with the initial patch. I've just submitted the
patch for vmxnet3 [1] and bnxt [2].
But there is still an issue with the qede driver, that overwrites the
MAC address in dev->data by the previous one if it cannot be set. It
seems it's the only driver that does this in error case, but anyway,
this behavior will be broken by the initial patch.
So I submitted a v2 that only changes the behavior for i40evf [3].
I propose to include these 3 patches for 18.02, and announce an ABI
change for 18.05 to add a return value to dev_ops->mac_addr_set() and
move the ether_addr_copy() after the callback, only in case of success.
Any opinions?
[1] https://dpdk.org/dev/patchwork/patch/32855/
[2] https://dpdk.org/dev/patchwork/patch/32855/
[3] https://dpdk.org/dev/patchwork/patch/32855/
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] ethdev: fix setting of MAC address
2018-01-03 13:43 3% ` Olivier Matz
@ 2018-01-03 13:54 0% ` Olivier Matz
2018-01-03 14:12 4% ` Andrew Rybchenko
0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2018-01-03 13:54 UTC (permalink / raw)
To: Andrew Rybchenko
Cc: Ivan Malov, Igor Ryzhov, dev, Thomas Monjalon, Laurent Hardy,
Ferruh Yigit, stable
On Wed, Jan 03, 2018 at 02:43:59PM +0100, Olivier Matz wrote:
> I've walked through the PMDs as suggested by Andrew, and there was
> indeed some conflicts with the initial patch. I've just submitted the
> patch for vmxnet3 [1] and bnxt [2].
>
> But there is still an issue with the qede driver, that overwrites the
> MAC address in dev->data by the previous one if it cannot be set. It
> seems it's the only driver that does this in error case, but anyway,
> this behavior will be broken by the initial patch.
>
> So I submitted a v2 that only changes the behavior for i40evf [3].
>
> I propose to include these 3 patches for 18.02, and announce an ABI
> change for 18.05 to add a return value to dev_ops->mac_addr_set() and
> move the ether_addr_copy() after the callback, only in case of success.
>
> Any opinions?
>
>
> [1] https://dpdk.org/dev/patchwork/patch/32855/
> [2] https://dpdk.org/dev/patchwork/patch/32855/
> [3] https://dpdk.org/dev/patchwork/patch/32855/
Sorry:
[1] https://dpdk.org/dev/patchwork/patch/32855/
[2] https://dpdk.org/dev/patchwork/patch/32856/
[3] https://dpdk.org/dev/patchwork/patch/32857/
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: fix setting of MAC address
2018-01-03 13:54 0% ` Olivier Matz
@ 2018-01-03 14:12 4% ` Andrew Rybchenko
2018-01-08 11:59 3% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Andrew Rybchenko @ 2018-01-03 14:12 UTC (permalink / raw)
To: Olivier Matz
Cc: Ivan Malov, Igor Ryzhov, dev, Thomas Monjalon, Laurent Hardy,
Ferruh Yigit, stable
On 01/03/2018 04:54 PM, Olivier Matz wrote:
> On Wed, Jan 03, 2018 at 02:43:59PM +0100, Olivier Matz wrote:
>> I've walked through the PMDs as suggested by Andrew, and there was
>> indeed some conflicts with the initial patch. I've just submitted the
>> patch for vmxnet3 [1] and bnxt [2].
>>
>> But there is still an issue with the qede driver, that overwrites the
>> MAC address in dev->data by the previous one if it cannot be set. It
>> seems it's the only driver that does this in error case, but anyway,
>> this behavior will be broken by the initial patch.
>>
>> So I submitted a v2 that only changes the behavior for i40evf [3].
>>
>> I propose to include these 3 patches for 18.02, and announce an ABI
>> change for 18.05 to add a return value to dev_ops->mac_addr_set() and
>> move the ether_addr_copy() after the callback, only in case of success.
>>
>> Any opinions?
I'm not sure if dev_ops->mac_addr_set() is a part of ABI.
It is an internal interface between rte_ethdev library and drivers. Yes,
out-of-tree
drivers will be broken.
rte_eth_dev_default_mac_addr_set() is definitely a part of API/ABI, but
it already
has return value.
So, I'm not sure that we have to wait for 18.05, but it is still may be
too late for
18.02 since integration deadline is pretty close.
> [1] https://dpdk.org/dev/patchwork/patch/32855/
> [2] https://dpdk.org/dev/patchwork/patch/32856/
> [3] https://dpdk.org/dev/patchwork/patch/32857/
Many thanks for drivers review and fixes.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer
2017-12-20 18:23 3% ` Ananyev, Konstantin
@ 2018-01-04 9:22 0% ` Jerin Jacob
2018-01-15 16:29 0% ` Ananyev, Konstantin
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2018-01-04 9:22 UTC (permalink / raw)
To: Ananyev, Konstantin; +Cc: dev, shahafs
-----Original Message-----
> Date: Wed, 20 Dec 2017 18:23:46 +0000
> From: "Ananyev, Konstantin" <konstantin.ananyev@intel.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: "dev@dpdk.org" <dev@dpdk.org>, "shahafs@mellanox.com"
> <shahafs@mellanox.com>
> Subject: RE: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev
> layer
>
Hi Konstantin,
> > > > > > > 2. Make it safe to remove rx/tx callback at runtime.
> > > > > > > Right now it is not possible for the application to figure out
> > > > > > > when it is safe to free removed callback handle and
> > > > > > > associated with it resources(unless the queue is stopped).
> > > > > > > That's probably not a big problem if all callbacks are static
> > > > > > > hange through whole application lifetime)
> > > > > > > and/or application doesn't allocate any resources for the callback handler.
> > > > > > > Though if callbacks have to be added/removed dynamically and
> > > > > > > callback handler would require more resources to operate properly -
> > > > > > > then it might become an issue.
> > > > > > > So patch #2 fixes that problem - now as soon as
> > > > > > > rte_eth_remove_(rx|tx)_callback() completes successfully, application
> > > > > > > can safely free all associated with the removed callback resources.
> > > > > > >
> > > > > > > Performance impact:
> > > > > > > If application doesn't use RX/TX callbacks, then the tests I run didn't
> > > > > > > reveal any performance degradation.
> > > > > > > Though if application do use RX/TX callbacks - patch #2 does introduce
> > > > > > > some slowdown.
> > > > > > >
> > > > > > > To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
> > > > > > > with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
> > > > > > > 1) testpmd ... --latencystats=1 - slowdown < 1%
> > > > > > > 2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
> > > > > > > 3) examples/rxtx_callbacks - slowdown ~8%
> > > > > > > All that in terms of packet throughput (Mpps).
> > > > > >
> > > > > > We tried on an arm64 machine; We got following result on host and guest
> > > > > > using l3fwd.
> > > > >
> > > > > Thanks for testing it.
> > > > > So these numbers below - are for l3fwd running with or without rx callback installed?
> > > > > i.e. with or without '--parse-ptype' option (and on a NIC with/without ptype HW support)?
> > > >
> > > > without '--parse-ptype' option(i.e without rx callback installed).
> > > > That makes it sad, Even though application is not using the rx callback,
> > > > We need to pay on a average 3% drop in performance(based on the
> > > > use case/arch/SoC/topology etc)
> > >
> > > Yes it is sad...
> > > Do you have any idea why that happens?
> > > Is that the same situation you described before: for arm compiler
> > > often replaces small branches with conditional execution instructions
> > > and miss-prediction for such instructions is not free?
> >
> > Yes.
>
> Probably a dumb question - is it possible to disable such optimization
> for these particular functions (rx_burst/tx_burst)?
> Or would it make things even worse?
>
> >
> > Another thing I noticed on these inline functions(rx/tx burst)even if we add
> > a lot of code which may note be executed, based on the parent
> > function layout, the compete register access layout gets change(like
> > push/pop from stack etc, as more code gets added).
> > I.e This change does not have much impact with testpmd(iofwd) where the
> > parent function is not doing much thing.It is showing up only on l3fwd.
>
> Ok sort of register spillage...
> But if compiler does it unconditionally (for the code path when it never needed)
> seems like a problem with the compile, no?
I think, it will be depended on parent function usage.
> Wonder if we'll move at least RX/TX CBs invocation into a separate function -
> would it help somehow?
> I.E. if (q->cb != NULL) execut_cbs(...);
> ?
Yes.I tried to move both (Rx, Tx) execut_cbs as separate in .c func ton.
That is helping the regression in some extended(Reduced from 2.84% to 1.27%)
example:
+uint16_t
+__rte_eth_execut_tx_cbs(uint16_t port_id, uint16_t queue_id,
+ struct rte_mbuf **pkts, uint16_t nb_pkts,
+ struct rte_eth_queue_local *ql);
+
static inline uint16_t
rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id,
struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
@@ -3256,19 +3259,11 @@ rte_eth_tx_burst(uint16_t port_id, uint16_t
queue_id,
#ifdef RTE_ETHDEV_RXTX_CALLBACKS
{
struct rte_eth_queue_local *ql;
- struct rte_eth_rxtx_callback *cb;
ql = dev->tx_ql + queue_id;
- if (unlikely(ql->cbs.head != NULL)) {
-
- __rte_eth_rxtx_cbs_inuse(&ql->cbs);
-
- for (cb = ql->cbs.head; cb != NULL; cb = cb->next)
- nb_pkts = cb->fn.tx(port_id, queue_id, tx_pkts,
- nb_pkts, cb->param);
-
- __rte_eth_rxtx_cbs_unuse(&ql->cbs);
- }
+ if (unlikely(ql->cbs.head != NULL))
+ nb_pkts = __rte_eth_execut_tx_cbs(port_id,queue_id,
+ tx_pkts, nb_pkts, ql);
}
#endif
> Another thought - as I remember a while ago Bruce and other lads suggested to move
> rx_burst/tx)burst (and whole struct rte_eth_dev) definitions into rte_ethdev.c...
> That would help to avoid such problems, again we'll be able to modify rte_eth_dev
> without breaking ABI...
> Though it would mean extra call overhead, so don't know of-hand how expensive
> it could be.
>From my experiments it shows more expensive than above scheme.
>
> >
> > > Or is it something else?
> > >
> > > Another thing - the series contains 2 main patches:
> > > 1) http://dpdk.org/dev/patchwork/patch/31866/
> > > Introduces eth_queue_local and moves callback data into it.
> > > That adds one extra memory reference for rx/tx function to read cb func and data.
> > > 2) http://dpdk.org/dev/patchwork/patch/31867/
> > > Introduces some synchronization for cb data.
> > >
> > > Is it possible to rerun your tests with just patch #1 installed?
> > > Hopefully it would help us to figure out which of the patches (#1 or #2)
> > > is the main source of slowdown on arm machines.
> >
> > I re ran the test as requested:
> > With first patch - 1.17% regression
> > With first patch + Second patch - 2.84% regression
>
> Thanks
>
> >
> > I am fine with slowdown, but it should be effected only with those
> > application which request the callback feature.
>
> Ok, but you do realize that if we'll go with rx/tx function per queue,
> patch #1 slowdown (1.17%) will probably reappear anyway?
May be not, it will be one more redirection to get the rx/tx function
pointer(may be a additionally load instruction)
>
> >
> > >
> > > >
> > > > >
> > > > > >
> > > > > >
> > > > > > Note:
> > > > > > +ve number means "Performance regression with patches"
> > > > > > -ve number means "Performance improvement with patches"
> > > > > >
> > > > > > Relative performance difference in percentage:
> > > > > >
> > > > > > % difference on host (2 x 40G)
> > > > > > pkt_sz 1c 2c 4c 8c
> > > > > > 64 1.41 0.18 0.51 0.29
> > > > > > 72 0.50 0.53 0.09 0.19
> > > > > > 128 0.31 0.31 0.42 0.00
> > > > > > 256 -0.44 -0.44 0.00 0.00
> > > > > > 512 1.94 1.94 0.01 0.01
> > > > > > 1024 0.00 0.01 0.00 0.01
> > > > > > 1518 0.02 0.01 0.02 0.02
> > > > > >
> > > > > > % difference on guest (2 x 40G)
> > > > > > pkt_sz 1c 2c 4c 8c
> > > > > > 64 5.78 2.30 -2.45 -0.01
> > > > > > 72 1.13 1.13 1.31 -4.29
> > > > > > 128 1.36 1.36 1.54 -0.82
> > > > > > 256 2.02 2.03 -0.01 -0.35
> > > > > > 512 4.05 4.04 0.00 -0.46
> > > > > > 1024 0.39 0.38 0.00 -0.74
> > > > > > 1518 0.00 0.00 -0.05 -4.20
> > > > > >
> > > > > > I think, it is because we added more code under
> > > > > > the RTE_ETHDEV_RXTX_CALLBACKS and it is enabled by
> > > > > > default.
> > > > > >
> > > > > > I think, the impact will vary based on
> > > > > > architecture and underneath i-cache, d-cache and IPC.
> > > > > >
> > > > > > I am just thinking, How we can avoid such impact?
> > > > > > How about,
> > > > > > # Remove RTE_ETHDEV_RXTX_CALLBACKS option
> > > > > > # Hook Rx/TX callbacks under TX/RX offload flags
> > > > > > # ethdev layer gives helper function to invoke
> > > > > > callbacks to driver.
> > > > >
> > > > > I suppose you suggest that user would have to decide at queue_setup()
> > > > > stage does he wants a callback(s) for RX/TX or no?
> > > >
> > > > Yes. queue_setup or configure() time.
> > > >
> > > > > As I can see, the main drawback with that approach - it would introduce new limitation.
> > > > > Right now it is possible to add/remove RX/TX callback at runtime
> > > > > (without stopping and reconfiguring the queue), and I suppose we do want to keep that ability.
> > > >
> > > > For those _application_ where it can not decide or it need to add without
> > > > stopping and re configuring the queue still can configure/enable the ethdev
> > > > device with RX/TX callback option(and pay price for it)
> > > >
> > > > > Again in some cases user can't decide does he wants a callback installed or not,
> > > > > before he actually calls dev_start().
> > > > > l3fwd ptype-parse callback is an example of such situation:
> > > > > right now user has to start device first to figure out which ptypes are supported by this PMD
> > > > > with desired configuration, then based on this information he will (or will not) setup the callback.
> > > >
> > > > Good point. Can we remove that limitation from PMD perspective? IMO, ptype-parse is more of HW feature,
> > > > All we need to do a lookup(single load) to convert to DPDK packet type.
> > > > http://dpdk.org/browse/dpdk/tree/drivers/net/thunderx/nicvf_rxtx.c#n258
> > > >
> > > > I see almost all the drivers has dummy check like this, I think, That makes it
> > > > dependency with start().
> > > >
> > > > if (dev->rx_pkt_burst == i40e_recv_pkts ||
> > > > dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
> > > > dev->rx_pkt_burst == i40e_recv_scattered_pkts ||
> > > > dev->rx_pkt_burst == i40e_recv_scattered_pkts_vec ||
> > > > dev->rx_pkt_burst == i40e_recv_pkts_vec)
> > > > return ptypes;
> > > >
> > >
> > > We probably can, but it would require extra work and changes inside the PMDs.
> >
> > Yes, If we want do it in clean way. Another intermediate solution could
> > be return some valid error code on those PMD. On such error code, application can
> > start the device and get the supported ptype and then stop/reconfigure it again
> >
> > > i40e is a good one - all rx functions support the same ptypes.
> > > But let say for ixgbe ARM version of vRX doesn't support all ptypes that x86 vRX
> > > and generic scalar RX do.
> > > For fm10k - vector RX and scalar RX also support different ptype sets.
> >
> > >
> > > >
> > > > > What I thought in same direction - introduce a notion of 'static' and 'dynamic' callbacks.
> > > > > Static ones can't be removed while queue is not stopped while dynamic can.
> > > > > But that also requires user to select at queue_setup() stage does he wants dynamic
> > > > > callbacks for that queue or not (new offload flag or extra field in rxconf/txconf structure).
> > > > > So again - same limitation for the user.
> > > > > Another possibility here - have a flag 'dynamic' or 'static' not per queue, but per individual callback.
> > > > > Yes, that would mean API change for add/remove callback functions.
> > > >
> > > > At least on my test, the regression was caused because adding the code in
> > > > tx_burst and rx_burst under the RTE_ETHDEV_RXTX_CALLBACKS(which enabled
> > > > by default). By disabling the RTE_ETHDEV_RXTX_CALLBACKS option, I don't
> > > > see any regression. If so, Will such regression fixed by introducing
> > > > 'static' or 'dynamic' callbacks? I am happy to test and provide feedback.
> > >
> > > Probably no then, but let's try the experiment I mentioned above first.
> > >
> > > >
> > > > For me, I think, The better option is request from application for the
> > > > need for Rx/TX callbacks and set the handler appropriate in the driver to
> > > > have zero impact for the application which does not need callback at all.
> > >
> > > It is possible, but:
> > > - that would be quite significant change and would affect each RX and TX function in each PMD.
> >
> > May be not, assume if we have helper function which invoke the callbacks.
> > PMD can just call that before returning it.
>
> Even with helpers it means we'll have to double number of RX/TX functions -
> one with a CB support, another without.
IMO, It is up to the PMD driver. It can still choose to enable callbacks
all the time irrespective of input from application(i.e no need for double
number of RX/TX functions).
But it will enable a PMD to choose do optimization if the PMD wants
it. As a NW PMD maintainer, I will be OK to make minimal change(if the
helper function is available) in my PMD, if I get 1-2%
improvement. On the upside, We can remove RTE_ETHDEV_RXTX_CALLBACKS
conditional complication flag.
>
> >
> > > - from other side - even now there are several libs inside DPDK that rely on ability to add/remove
> > > callbacks on the fly - pdump, latencystats.
> > I think, it is application who decides to use this API,then I think,
> > application can request callback feature support. I think, we have
> > followed the same method in latest RX/TX offload flag scheme as well.
> >
> > > ethdev rx profiling also relies on ability to install RX callback.
> > >
> > > With all these things I presume most apps will configure their devices with rx/tx callback support enabled anyway.
> > > Which makes me think - is it worth to introduce such changes at all.
> > > Anyway, my first suggestion would be let's try to figure out what exactly causes such big slowdown on ARM.
> >
> > It may not be ARM in general, Under our roof, We have different class of SoCs based
> > on the use case like 4 cores, 16 core, 96 cores part etc with different
> > micro architecture etc based on the use case(embedded/server etc) like
> > Intel. So it may not very generic with all ARM machines, it is really
> > based on micro architecture. ie. The same patch may behave
> > differently(less than < 1%) on IA-Atom vs IA-XEON. So IMO, Common code
> > change should use helper functions, it up to the driver to use it.
>
> Konstantin
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging
2017-12-30 17:15 0% ` Neil Horman
@ 2018-01-04 12:56 0% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2018-01-04 12:56 UTC (permalink / raw)
To: Bruce Richardson; +Cc: dev, thomas, john.mcnamara
On Sat, Dec 30, 2017 at 12:15:17PM -0500, Neil Horman wrote:
> On Tue, Dec 12, 2017 at 02:07:52PM +0000, Bruce Richardson wrote:
> > On Mon, Dec 11, 2017 at 02:36:15PM -0500, Neil Horman wrote:
> > > Hey all-
> > > A few days ago, I was lamenting the fact that, when reviewing patches I
> > > would frequently complain about ABI changes that were actually considered safe
> > > because they were part of the EXPERIMENTAL api set. John M. asked me then what
> > > I might do to improve the situation, and the following patch set is a proposal
> > > that I've come up with.
> > >
> > > In thinking about the problem I identified two issues that I think we
> > > can improve on in this area:
> > >
> > > 1) Make experimental api calls more visible in the source code. That is to say,
> > > when reviewing patches, it would be nice to have some sort of visual reference
> > > that indicates that the changes being made are part of an experimental API and
> > > therefore ABI concerns need not be addressed
> > >
> > > 2) Make experimenal api usage more visible to consumers of the DPDK, so that
> > > they can make a more informed decision about the API's they consume in their
> > > application. We make an effort to document all the experimental API's, but
> > > there is no guarantee that a user will check the documentation before making use
> > > of a new library.
> > >
> > > This patch set attempts to achieve both of the above goals. To do this I've
> > > added an __experimental macro tag, suitable for inserting into api forward
> > > declarations and definitions.
> > >
> > > The presence of the tag in the header and c files where the api code resides
> > > increases the likelyhood that any patch submitted against them will include the
> > > tag in the context, making it clear to reviewers that ABI stability isn't a
> > > concern here.
> > >
> > >
> > > Also, This tag marks each function it is used on with an attibute causing any
> > > use of the fuction to emit a warning during the build
> > > with a message indicating that the API call in question is not yet part of the
> > > stable interface. Developers can then make an informed decision to suppress
> > > that warning or not.
> > >
> > > Because there is internal use of several experimental API's, this set also
> > > includes a new override macro ALLOW_EXPERIMENTAL_APIS to automatically
> > > suprress these warnings. I think its fair to assume that, for internal use, we
> > > almost always want to suppress these warnings, as by definition any change to
> > > the apis (even their removal) must be done in parallel with an appropriate
> > > change in the calling locations, lest the dpdk build itself break.
> > >
> > > Neil
> > >
> > > ---
> > > Change Notes:
> > > v2)
> > > * Cleaned up checkpatch errors
> > > * Added Allowance for building experimental on BSD
> > > * Swapped Patch 3 and 4 so that we didn't have a commit level that issued
> > > warnings/errors without need
> > >
> > > v3)
> > > * On suggestion from Bruce, modify ALLOW_EXPERIMENTAL_APIS to be defined in
> > > CFLAGS rather than a makefile variable. This is more flexible in that it
> > > allows us to suppress this specific feature rather than all uses of the
> > > deprecated attribute, as we might use it for other features in the furute
> > >
> >
> > Despite the fact that this is making yet more work for porting to a new
> > build system, I think this is a good idea to have. As such,
> >
> > Acked-by: Bruce Richardson <bruce.richardson@intel.com>
> >
> >
>
> Thomas-
> I just noticed that the ci tests are failing on the intel compiler, which
> makes very little sense to me, as the error is a permission error on a bash
> script that added in this series, which works during the gcc compilation. Can
> you take a look at that please?
>
> thanks
> Neil
>
Ping again Thomas, I've still heard nothing from you or the CI group about
getting more visibility into the odd permission problem in the CI runs this
seems to be encountering. I'd love to fix it, but the information in the report
is insufficient to have any idea whats going on and the problem does not occur
on local builds. Please advise.
Neil
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] MAINTAINERS fix style
@ 2018-01-04 23:48 3% Stephen Hemminger
0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2018-01-04 23:48 UTC (permalink / raw)
To: dev; +Cc: Stephen Hemminger, Stephen Hemminger
Checkpatch is complaining because the DPDK MAINTAINERS
file style does not match the Linux style. Linux style is to
always have a TAB (not space) after the tag.
I don't care just want checkpatch to be quiet.
Signed-off-by: Stephen Hemminger <sthemmin@microsoft.com>
---
MAINTAINERS | 1388 +++++++++++++++++++++++++++++------------------------------
1 file changed, 694 insertions(+), 694 deletions(-)
diff --git a/MAINTAINERS b/MAINTAINERS
index e0199b169d1f..3a2e56912f70 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23,1009 +23,1009 @@ General Project Administration
------------------------------
Main Branch
-M: Thomas Monjalon <thomas@monjalon.net>
-M: Ferruh Yigit <ferruh.yigit@intel.com>
-T: git://dpdk.org/dpdk
+M: Thomas Monjalon <thomas@monjalon.net>
+M: Ferruh Yigit <ferruh.yigit@intel.com>
+T: git://dpdk.org/dpdk
Stable Branches
-M: Yuanhan Liu <yliu@fridaylinux.org>
-T: git://dpdk.org/dpdk-stable
+M: Yuanhan Liu <yliu@fridaylinux.org>
+T: git://dpdk.org/dpdk-stable
Security Issues
-M: maintainers@dpdk.org
+M: maintainers@dpdk.org
Documentation (with overlaps)
-M: John McNamara <john.mcnamara@intel.com>
-M: Marko Kovacevic <marko.kovacevic@intel.com>
-F: README
-F: doc/
+M: John McNamara <john.mcnamara@intel.com>
+M: Marko Kovacevic <marko.kovacevic@intel.com>
+F: README
+F: doc/
Developers and Maintainers Tools
-M: Thomas Monjalon <thomas@monjalon.net>
-F: MAINTAINERS
-F: devtools/check-dup-includes.sh
-F: devtools/check-maintainers.sh
-F: devtools/check-git-log.sh
-F: devtools/check-includes.sh
-F: devtools/checkpatches.sh
-F: devtools/get-maintainer.sh
-F: devtools/git-log-fixes.sh
-F: devtools/load-devel-config
-F: devtools/test-build.sh
-F: license/
+M: Thomas Monjalon <thomas@monjalon.net>
+F: MAINTAINERS
+F: devtools/check-dup-includes.sh
+F: devtools/check-maintainers.sh
+F: devtools/check-git-log.sh
+F: devtools/check-includes.sh
+F: devtools/checkpatches.sh
+F: devtools/get-maintainer.sh
+F: devtools/git-log-fixes.sh
+F: devtools/load-devel-config
+F: devtools/test-build.sh
+F: license/
Build System
------------
-M: Thomas Monjalon <thomas@monjalon.net>
-F: GNUmakefile
-F: Makefile
-F: config/
-F: mk/
-F: pkg/
-F: buildtools/auto-config-h.sh
-F: buildtools/gen-build-mk.sh
-F: buildtools/gen-config-h.sh
-F: buildtools/relpath.sh
-F: doc/build-sdk-quick.txt
-F: doc/guides/prog_guide/build_app.rst
-F: doc/guides/prog_guide/dev_kit_*
-F: doc/guides/prog_guide/ext_app_lib_make_help.rst
+M: Thomas Monjalon <thomas@monjalon.net>
+F: GNUmakefile
+F: Makefile
+F: config/
+F: mk/
+F: pkg/
+F: buildtools/auto-config-h.sh
+F: buildtools/gen-build-mk.sh
+F: buildtools/gen-config-h.sh
+F: buildtools/relpath.sh
+F: doc/build-sdk-quick.txt
+F: doc/guides/prog_guide/build_app.rst
+F: doc/guides/prog_guide/dev_kit_*
+F: doc/guides/prog_guide/ext_app_lib_make_help.rst
ABI versioning
-M: Neil Horman <nhorman@tuxdriver.com>
-F: lib/librte_compat/
-F: doc/guides/rel_notes/deprecation.rst
-F: devtools/validate-abi.sh
+M: Neil Horman <nhorman@tuxdriver.com>
+F: lib/librte_compat/
+F: doc/guides/rel_notes/deprecation.rst
+F: devtools/validate-abi.sh
Driver information
-F: buildtools/pmdinfogen/
-F: usertools/dpdk-pmdinfo.py
-F: doc/guides/tools/pmdinfo.rst
+F: buildtools/pmdinfogen/
+F: usertools/dpdk-pmdinfo.py
+F: doc/guides/tools/pmdinfo.rst
Environment Abstraction Layer
-----------------------------
EAL API and common code
-F: lib/librte_eal/common/*
-F: lib/librte_eal/common/include/*
-F: lib/librte_eal/common/include/generic/
-F: lib/librte_eal/rte_eal_version.map
-F: doc/guides/prog_guide/env_abstraction_layer.rst
-F: test/test/test_alarm.c
-F: test/test/test_atomic.c
-F: test/test/test_byteorder.c
-F: test/test/test_common.c
-F: test/test/test_cpuflags.c
-F: test/test/test_cycles.c
-F: test/test/test_debug.c
-F: test/test/test_devargs.c
-F: test/test/test_eal*
-F: test/test/test_errno.c
-F: test/test/test_interrupts.c
-F: test/test/test_logs.c
-F: test/test/test_memcpy*
-F: test/test/test_per_lcore.c
-F: test/test/test_prefetch.c
-F: test/test/test_rwlock.c
-F: test/test/test_spinlock.c
-F: test/test/test_string_fns.c
-F: test/test/test_tailq.c
-F: test/test/test_version.c
+F: lib/librte_eal/common/*
+F: lib/librte_eal/common/include/*
+F: lib/librte_eal/common/include/generic/
+F: lib/librte_eal/rte_eal_version.map
+F: doc/guides/prog_guide/env_abstraction_layer.rst
+F: test/test/test_alarm.c
+F: test/test/test_atomic.c
+F: test/test/test_byteorder.c
+F: test/test/test_common.c
+F: test/test/test_cpuflags.c
+F: test/test/test_cycles.c
+F: test/test/test_debug.c
+F: test/test/test_devargs.c
+F: test/test/test_eal*
+F: test/test/test_errno.c
+F: test/test/test_interrupts.c
+F: test/test/test_logs.c
+F: test/test/test_memcpy*
+F: test/test/test_per_lcore.c
+F: test/test/test_prefetch.c
+F: test/test/test_rwlock.c
+F: test/test/test_spinlock.c
+F: test/test/test_string_fns.c
+F: test/test/test_tailq.c
+F: test/test/test_version.c
Memory Allocation
-M: Anatoly Burakov <anatoly.burakov@intel.com>
-F: lib/librte_eal/common/include/rte_mem*
-F: lib/librte_eal/common/include/rte_malloc.h
-F: lib/librte_eal/common/*malloc*
-F: lib/librte_eal/common/eal_common_mem*
-F: lib/librte_eal/common/eal_hugepages.h
-F: doc/guides/prog_guide/env_abstraction_layer.rst
-F: test/test/test_func_reentrancy.c
-F: test/test/test_malloc.c
-F: test/test/test_memory.c
-F: test/test/test_memzone.c
+M: Anatoly Burakov <anatoly.burakov@intel.com>
+F: lib/librte_eal/common/include/rte_mem*
+F: lib/librte_eal/common/include/rte_malloc.h
+F: lib/librte_eal/common/*malloc*
+F: lib/librte_eal/common/eal_common_mem*
+F: lib/librte_eal/common/eal_hugepages.h
+F: doc/guides/prog_guide/env_abstraction_layer.rst
+F: test/test/test_func_reentrancy.c
+F: test/test/test_malloc.c
+F: test/test/test_memory.c
+F: test/test/test_memzone.c
Keep alive
-M: Remy Horton <remy.horton@intel.com>
-F: lib/librte_eal/common/include/rte_keepalive.h
-F: lib/librte_eal/common/rte_keepalive.c
-F: examples/l2fwd-keepalive/
-F: doc/guides/sample_app_ug/keep_alive.rst
+M: Remy Horton <remy.horton@intel.com>
+F: lib/librte_eal/common/include/rte_keepalive.h
+F: lib/librte_eal/common/rte_keepalive.c
+F: examples/l2fwd-keepalive/
+F: doc/guides/sample_app_ug/keep_alive.rst
Secondary process
-M: Anatoly Burakov <anatoly.burakov@intel.com>
-K: RTE_PROC_
-F: doc/guides/prog_guide/multi_proc_support.rst
-F: test/test/test_mp_secondary.c
-F: examples/multi_process/
-F: doc/guides/sample_app_ug/multi_process.rst
+M: Anatoly Burakov <anatoly.burakov@intel.com>
+K: RTE_PROC_
+F: doc/guides/prog_guide/multi_proc_support.rst
+F: test/test/test_mp_secondary.c
+F: examples/multi_process/
+F: doc/guides/sample_app_ug/multi_process.rst
Service Cores - EXPERIMENTAL
-M: Harry van Haaren <harry.van.haaren@intel.com>
-F: lib/librte_eal/common/include/rte_service.h
-F: lib/librte_eal/common/include/rte_service_component.h
-F: lib/librte_eal/common/rte_service.c
-F: doc/guides/prog_guide/service_cores.rst
-F: test/test/test_service_cores.c
+M: Harry van Haaren <harry.van.haaren@intel.com>
+F: lib/librte_eal/common/include/rte_service.h
+F: lib/librte_eal/common/include/rte_service_component.h
+F: lib/librte_eal/common/rte_service.c
+F: doc/guides/prog_guide/service_cores.rst
+F: test/test/test_service_cores.c
Bitmap
-M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
-F: lib/librte_eal/common/include/rte_bitmap.h
-F: test/test/test_bitmap.c
+M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
+F: lib/librte_eal/common/include/rte_bitmap.h
+F: test/test/test_bitmap.c
ARM v7
-M: Jan Viktorin <viktorin@rehivetech.com>
-M: Jianbo Liu <jianbo.liu@arm.com>
-F: lib/librte_eal/common/arch/arm/
-F: lib/librte_eal/common/include/arch/arm/
+M: Jan Viktorin <viktorin@rehivetech.com>
+M: Jianbo Liu <jianbo.liu@arm.com>
+F: lib/librte_eal/common/arch/arm/
+F: lib/librte_eal/common/include/arch/arm/
ARM v8
-M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
-M: Jianbo Liu <jianbo.liu@arm.com>
-F: lib/librte_eal/common/include/arch/arm/*_64.h
-F: lib/librte_net/net_crc_neon.h
-F: lib/librte_acl/acl_run_neon.*
-F: lib/librte_lpm/rte_lpm_neon.h
-F: lib/librte_hash/rte*_arm64.h
-F: lib/librte_efd/rte*_arm64.h
-F: lib/librte_table/rte*_arm64.h
-F: drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c
-F: drivers/net/i40e/i40e_rxtx_vec_neon.c
-F: drivers/net/virtio/virtio_rxtx_simple_neon.c
+M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
+M: Jianbo Liu <jianbo.liu@arm.com>
+F: lib/librte_eal/common/include/arch/arm/*_64.h
+F: lib/librte_net/net_crc_neon.h
+F: lib/librte_acl/acl_run_neon.*
+F: lib/librte_lpm/rte_lpm_neon.h
+F: lib/librte_hash/rte*_arm64.h
+F: lib/librte_efd/rte*_arm64.h
+F: lib/librte_table/rte*_arm64.h
+F: drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c
+F: drivers/net/i40e/i40e_rxtx_vec_neon.c
+F: drivers/net/virtio/virtio_rxtx_simple_neon.c
IBM POWER
-M: Chao Zhu <chaozhu@linux.vnet.ibm.com>
-F: lib/librte_eal/common/arch/ppc_64/
-F: lib/librte_eal/common/include/arch/ppc_64/
-F: drivers/net/i40e/i40e_rxtx_vec_altivec.c
-F: examples/l3fwd/*altivec.h
+M: Chao Zhu <chaozhu@linux.vnet.ibm.com>
+F: lib/librte_eal/common/arch/ppc_64/
+F: lib/librte_eal/common/include/arch/ppc_64/
+F: drivers/net/i40e/i40e_rxtx_vec_altivec.c
+F: examples/l3fwd/*altivec.h
Intel x86
-M: Bruce Richardson <bruce.richardson@intel.com>
-M: Konstantin Ananyev <konstantin.ananyev@intel.com>
-F: lib/librte_eal/common/arch/x86/
-F: lib/librte_eal/common/include/arch/x86/
+M: Bruce Richardson <bruce.richardson@intel.com>
+M: Konstantin Ananyev <konstantin.ananyev@intel.com>
+F: lib/librte_eal/common/arch/x86/
+F: lib/librte_eal/common/include/arch/x86/
Linux EAL (with overlaps)
-F: lib/librte_eal/linuxapp/Makefile
-F: lib/librte_eal/linuxapp/eal/
-F: doc/guides/linux_gsg/
+F: lib/librte_eal/linuxapp/Makefile
+F: lib/librte_eal/linuxapp/eal/
+F: doc/guides/linux_gsg/
Linux UIO
-M: Ferruh Yigit <ferruh.yigit@intel.com>
-F: lib/librte_eal/linuxapp/igb_uio/
-F: drivers/bus/pci/linux/*uio*
+M: Ferruh Yigit <ferruh.yigit@intel.com>
+F: lib/librte_eal/linuxapp/igb_uio/
+F: drivers/bus/pci/linux/*uio*
Linux VFIO
-M: Anatoly Burakov <anatoly.burakov@intel.com>
-F: lib/librte_eal/linuxapp/eal/*vfio*
-F: drivers/bus/pci/linux/*vfio*
+M: Anatoly Burakov <anatoly.burakov@intel.com>
+F: lib/librte_eal/linuxapp/eal/*vfio*
+F: drivers/bus/pci/linux/*vfio*
FreeBSD EAL (with overlaps)
-M: Bruce Richardson <bruce.richardson@intel.com>
-F: lib/librte_eal/bsdapp/Makefile
-F: lib/librte_eal/bsdapp/eal/
-F: doc/guides/freebsd_gsg/
+M: Bruce Richardson <bruce.richardson@intel.com>
+F: lib/librte_eal/bsdapp/Makefile
+F: lib/librte_eal/bsdapp/eal/
+F: doc/guides/freebsd_gsg/
FreeBSD contigmem
-M: Bruce Richardson <bruce.richardson@intel.com>
-F: lib/librte_eal/bsdapp/contigmem/
+M: Bruce Richardson <bruce.richardson@intel.com>
+F: lib/librte_eal/bsdapp/contigmem/
FreeBSD UIO
-M: Bruce Richardson <bruce.richardson@intel.com>
-F: lib/librte_eal/bsdapp/nic_uio/
+M: Bruce Richardson <bruce.richardson@intel.com>
+F: lib/librte_eal/bsdapp/nic_uio/
Core Libraries
--------------
Memory pool
-M: Olivier Matz <olivier.matz@6wind.com>
-F: lib/librte_mempool/
-F: drivers/mempool/Makefile
-F: drivers/mempool/ring/
-F: drivers/mempool/stack/
-F: doc/guides/prog_guide/mempool_lib.rst
-F: test/test/test_mempool*
-F: test/test/test_func_reentrancy.c
+M: Olivier Matz <olivier.matz@6wind.com>
+F: lib/librte_mempool/
+F: drivers/mempool/Makefile
+F: drivers/mempool/ring/
+F: drivers/mempool/stack/
+F: doc/guides/prog_guide/mempool_lib.rst
+F: test/test/test_mempool*
+F: test/test/test_func_reentrancy.c
Ring queue
-M: Olivier Matz <olivier.matz@6wind.com>
-F: lib/librte_ring/
-F: doc/guides/prog_guide/ring_lib.rst
-F: test/test/test_ring*
-F: test/test/test_func_reentrancy.c
+M: Olivier Matz <olivier.matz@6wind.com>
+F: lib/librte_ring/
+F: doc/guides/prog_guide/ring_lib.rst
+F: test/test/test_ring*
+F: test/test/test_func_reentrancy.c
Packet buffer
-M: Olivier Matz <olivier.matz@6wind.com>
-F: lib/librte_mbuf/
-F: doc/guides/prog_guide/mbuf_lib.rst
-F: test/test/test_mbuf.c
+M: Olivier Matz <olivier.matz@6wind.com>
+F: lib/librte_mbuf/
+F: doc/guides/prog_guide/mbuf_lib.rst
+F: test/test/test_mbuf.c
Ethernet API
-M: Thomas Monjalon <thomas@monjalon.net>
-T: git://dpdk.org/next/dpdk-next-net
-F: lib/librte_ether/
-F: devtools/test-null.sh
+M: Thomas Monjalon <thomas@monjalon.net>
+T: git://dpdk.org/next/dpdk-next-net
+F: lib/librte_ether/
+F: devtools/test-null.sh
Flow API
-M: Adrien Mazarguil <adrien.mazarguil@6wind.com>
-T: git://dpdk.org/next/dpdk-next-net
-F: lib/librte_ether/rte_flow*
+M: Adrien Mazarguil <adrien.mazarguil@6wind.com>
+T: git://dpdk.org/next/dpdk-next-net
+F: lib/librte_ether/rte_flow*
Traffic Management API - EXPERIMENTAL
-M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
-T: git://dpdk.org/next/dpdk-next-tm
-F: lib/librte_ether/rte_tm*
+M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
+T: git://dpdk.org/next/dpdk-next-tm
+F: lib/librte_ether/rte_tm*
Traffic Metering and Policing API - EXPERIMENTAL
-M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
-F: lib/librte_ether/rte_mtr*
+M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
+F: lib/librte_ether/rte_mtr*
Crypto API
-M: Declan Doherty <declan.doherty@intel.com>
-T: git://dpdk.org/next/dpdk-next-crypto
-F: lib/librte_cryptodev/
-F: test/test/test_cryptodev*
-F: examples/l2fwd-crypto/
+M: Declan Doherty <declan.doherty@intel.com>
+T: git://dpdk.org/next/dpdk-next-crypto
+F: lib/librte_cryptodev/
+F: test/test/test_cryptodev*
+F: examples/l2fwd-crypto/
Security API - EXPERIMENTAL
-M: Akhil Goyal <akhil.goyal@nxp.com>
-M: Declan Doherty <declan.doherty@intel.com>
-F: lib/librte_security/
-F: doc/guides/prog_guide/rte_security.rst
+M: Akhil Goyal <akhil.goyal@nxp.com>
+M: Declan Doherty <declan.doherty@intel.com>
+F: lib/librte_security/
+F: doc/guides/prog_guide/rte_security.rst
Eventdev API
-M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
-T: git://dpdk.org/next/dpdk-next-eventdev
-F: lib/librte_eventdev/
-F: drivers/event/skeleton/
-F: test/test/test_eventdev.c
+M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
+T: git://dpdk.org/next/dpdk-next-eventdev
+F: lib/librte_eventdev/
+F: drivers/event/skeleton/
+F: test/test/test_eventdev.c
Eventdev Ethdev Rx Adapter API - EXPERIMENTAL
-M: Nikhil Rao <nikhil.rao@intel.com>
-T: git://dpdk.org/next/dpdk-next-eventdev
-F: lib/librte_eventdev/*eth_rx_adapter*
-F: test/test/test_event_eth_rx_adapter.c
-F: doc/guides/prog_guide/event_ethernet_rx_adapter.rst
+M: Nikhil Rao <nikhil.rao@intel.com>
+T: git://dpdk.org/next/dpdk-next-eventdev
+F: lib/librte_eventdev/*eth_rx_adapter*
+F: test/test/test_event_eth_rx_adapter.c
+F: doc/guides/prog_guide/event_ethernet_rx_adapter.rst
Bus Drivers
-----------
NXP buses
-M: Hemant Agrawal <hemant.agrawal@nxp.com>
-M: Shreyansh Jain <shreyansh.jain@nxp.com>
-F: drivers/bus/dpaa/
-F: drivers/bus/fslmc/
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
+F: drivers/bus/dpaa/
+F: drivers/bus/fslmc/
PCI bus driver
-F: drivers/bus/pci/
+F: drivers/bus/pci/
VDEV bus driver
-M: Jianfeng Tan <jianfeng.tan@intel.com>
-F: drivers/bus/vdev/
+M: Jianfeng Tan <jianfeng.tan@intel.com>
+F: drivers/bus/vdev/
Networking Drivers
------------------
-M: Ferruh Yigit <ferruh.yigit@intel.com>
-T: git://dpdk.org/next/dpdk-next-net
-F: doc/guides/nics/features/default.ini
+M: Ferruh Yigit <ferruh.yigit@intel.com>
+T: git://dpdk.org/next/dpdk-next-net
+F: doc/guides/nics/features/default.ini
Link bonding
-M: Declan Doherty <declan.doherty@intel.com>
-F: drivers/net/bonding/
-F: doc/guides/prog_guide/link_bonding_poll_mode_drv_lib.rst
-F: test/test/test_link_bonding*
-F: examples/bond/
-F: doc/guides/nics/features/bonding.ini
+M: Declan Doherty <declan.doherty@intel.com>
+F: drivers/net/bonding/
+F: doc/guides/prog_guide/link_bonding_poll_mode_drv_lib.rst
+F: test/test/test_link_bonding*
+F: examples/bond/
+F: doc/guides/nics/features/bonding.ini
Linux KNI
-M: Ferruh Yigit <ferruh.yigit@intel.com>
-F: lib/librte_eal/linuxapp/kni/
-F: lib/librte_kni/
-F: doc/guides/prog_guide/kernel_nic_interface.rst
-F: test/test/test_kni.c
-F: examples/kni/
-F: doc/guides/sample_app_ug/kernel_nic_interface.rst
+M: Ferruh Yigit <ferruh.yigit@intel.com>
+F: lib/librte_eal/linuxapp/kni/
+F: lib/librte_kni/
+F: doc/guides/prog_guide/kernel_nic_interface.rst
+F: test/test/test_kni.c
+F: examples/kni/
+F: doc/guides/sample_app_ug/kernel_nic_interface.rst
Linux AF_PACKET
-M: John W. Linville <linville@tuxdriver.com>
-F: drivers/net/af_packet/
-F: doc/guides/nics/features/afpacket.ini
+M: John W. Linville <linville@tuxdriver.com>
+F: drivers/net/af_packet/
+F: doc/guides/nics/features/afpacket.ini
Amazon ENA
-M: Marcin Wojtas <mw@semihalf.com>
-M: Michal Krawczyk <mk@semihalf.com>
-M: Guy Tzalik <gtzalik@amazon.com>
-M: Evgeny Schemeilin <evgenys@amazon.com>
-F: drivers/net/ena/
-F: doc/guides/nics/ena.rst
-F: doc/guides/nics/features/ena.ini
+M: Marcin Wojtas <mw@semihalf.com>
+M: Michal Krawczyk <mk@semihalf.com>
+M: Guy Tzalik <gtzalik@amazon.com>
+M: Evgeny Schemeilin <evgenys@amazon.com>
+F: drivers/net/ena/
+F: doc/guides/nics/ena.rst
+F: doc/guides/nics/features/ena.ini
Atomic Rules ARK
-M: Shepard Siegel <shepard.siegel@atomicrules.com>
-M: Ed Czeck <ed.czeck@atomicrules.com>
-M: John Miller <john.miller@atomicrules.com>
-F: drivers/net/ark/
-F: doc/guides/nics/ark.rst
-F: doc/guides/nics/features/ark.ini
+M: Shepard Siegel <shepard.siegel@atomicrules.com>
+M: Ed Czeck <ed.czeck@atomicrules.com>
+M: John Miller <john.miller@atomicrules.com>
+F: drivers/net/ark/
+F: doc/guides/nics/ark.rst
+F: doc/guides/nics/features/ark.ini
Broadcom bnxt
-M: Stephen Hurd <stephen.hurd@broadcom.com>
-M: Ajit Khaparde <ajit.khaparde@broadcom.com>
-F: drivers/net/bnxt/
-F: doc/guides/nics/bnxt.rst
-F: doc/guides/nics/features/bnxt.ini
+M: Stephen Hurd <stephen.hurd@broadcom.com>
+M: Ajit Khaparde <ajit.khaparde@broadcom.com>
+F: drivers/net/bnxt/
+F: doc/guides/nics/bnxt.rst
+F: doc/guides/nics/features/bnxt.ini
Cavium ThunderX nicvf
-M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
-M: Maciej Czekaj <maciej.czekaj@caviumnetworks.com>
-F: drivers/net/thunderx/
-F: doc/guides/nics/thunderx.rst
-F: doc/guides/nics/features/thunderx.ini
+M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
+M: Maciej Czekaj <maciej.czekaj@caviumnetworks.com>
+F: drivers/net/thunderx/
+F: doc/guides/nics/thunderx.rst
+F: doc/guides/nics/features/thunderx.ini
Cavium LiquidIO
-M: Shijith Thotton <shijith.thotton@cavium.com>
-M: Srisivasubramanian Srinivasan <ssrinivasan@cavium.com>
-F: drivers/net/liquidio/
-F: doc/guides/nics/liquidio.rst
-F: doc/guides/nics/features/liquidio.ini
+M: Shijith Thotton <shijith.thotton@cavium.com>
+M: Srisivasubramanian Srinivasan <ssrinivasan@cavium.com>
+F: drivers/net/liquidio/
+F: doc/guides/nics/liquidio.rst
+F: doc/guides/nics/features/liquidio.ini
Cavium OcteonTX
-M: Santosh Shukla <santosh.shukla@caviumnetworks.com>
-M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
-F: drivers/mempool/octeontx/
-F: drivers/net/octeontx/
-F: doc/guides/nics/octeontx.rst
-F: doc/guides/nics/features/octeontx.ini
+M: Santosh Shukla <santosh.shukla@caviumnetworks.com>
+M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
+F: drivers/mempool/octeontx/
+F: drivers/net/octeontx/
+F: doc/guides/nics/octeontx.rst
+F: doc/guides/nics/features/octeontx.ini
Chelsio cxgbe
-M: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
-F: drivers/net/cxgbe/
-F: doc/guides/nics/cxgbe.rst
-F: doc/guides/nics/features/cxgbe.ini
+M: Rahul Lakkireddy <rahul.lakkireddy@chelsio.com>
+F: drivers/net/cxgbe/
+F: doc/guides/nics/cxgbe.rst
+F: doc/guides/nics/features/cxgbe.ini
Cisco enic
-M: John Daley <johndale@cisco.com>
-M: Nelson Escobar <neescoba@cisco.com>
-F: drivers/net/enic/
-F: doc/guides/nics/enic.rst
-F: doc/guides/nics/features/enic.ini
+M: John Daley <johndale@cisco.com>
+M: Nelson Escobar <neescoba@cisco.com>
+F: drivers/net/enic/
+F: doc/guides/nics/enic.rst
+F: doc/guides/nics/features/enic.ini
Intel e1000
-M: Wenzhuo Lu <wenzhuo.lu@intel.com>
-F: drivers/net/e1000/
-F: doc/guides/nics/e1000em.rst
-F: doc/guides/nics/intel_vf.rst
-F: doc/guides/nics/features/e1000.ini
-F: doc/guides/nics/features/igb*.ini
+M: Wenzhuo Lu <wenzhuo.lu@intel.com>
+F: drivers/net/e1000/
+F: doc/guides/nics/e1000em.rst
+F: doc/guides/nics/intel_vf.rst
+F: doc/guides/nics/features/e1000.ini
+F: doc/guides/nics/features/igb*.ini
Intel ixgbe
-M: Wenzhuo Lu <wenzhuo.lu@intel.com>
-M: Konstantin Ananyev <konstantin.ananyev@intel.com>
-F: drivers/net/ixgbe/
-F: doc/guides/nics/ixgbe.rst
-F: doc/guides/nics/intel_vf.rst
-F: doc/guides/nics/features/ixgbe*.ini
+M: Wenzhuo Lu <wenzhuo.lu@intel.com>
+M: Konstantin Ananyev <konstantin.ananyev@intel.com>
+F: drivers/net/ixgbe/
+F: doc/guides/nics/ixgbe.rst
+F: doc/guides/nics/intel_vf.rst
+F: doc/guides/nics/features/ixgbe*.ini
Intel i40e
-M: Beilei Xing <beilei.xing@intel.com>
-M: Qi Zhang <qi.z.zhang@intel.com>
-F: drivers/net/i40e/
-F: doc/guides/nics/i40e.rst
-F: doc/guides/nics/intel_vf.rst
-F: doc/guides/nics/features/i40e*.ini
+M: Beilei Xing <beilei.xing@intel.com>
+M: Qi Zhang <qi.z.zhang@intel.com>
+F: drivers/net/i40e/
+F: doc/guides/nics/i40e.rst
+F: doc/guides/nics/intel_vf.rst
+F: doc/guides/nics/features/i40e*.ini
Intel fm10k
-M: Qi Zhang <qi.z.zhang@intel.com>
-M: Xiao Wang <xiao.w.wang@intel.com>
-F: drivers/net/fm10k/
-F: doc/guides/nics/features/fm10k*.ini
+M: Qi Zhang <qi.z.zhang@intel.com>
+M: Xiao Wang <xiao.w.wang@intel.com>
+F: drivers/net/fm10k/
+F: doc/guides/nics/features/fm10k*.ini
Mellanox mlx4
-M: Adrien Mazarguil <adrien.mazarguil@6wind.com>
-F: drivers/net/mlx4/
-F: doc/guides/nics/mlx4.rst
-F: doc/guides/nics/features/mlx4.ini
+M: Adrien Mazarguil <adrien.mazarguil@6wind.com>
+F: drivers/net/mlx4/
+F: doc/guides/nics/mlx4.rst
+F: doc/guides/nics/features/mlx4.ini
Mellanox mlx5
-M: Adrien Mazarguil <adrien.mazarguil@6wind.com>
-M: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
-M: Yongseok Koh <yskoh@mellanox.com>
-F: drivers/net/mlx5/
-F: doc/guides/nics/mlx5.rst
-F: doc/guides/nics/features/mlx5.ini
+M: Adrien Mazarguil <adrien.mazarguil@6wind.com>
+M: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
+M: Yongseok Koh <yskoh@mellanox.com>
+F: drivers/net/mlx5/
+F: doc/guides/nics/mlx5.rst
+F: doc/guides/nics/features/mlx5.ini
Marvell mrvl
-M: Jacek Siuda <jck@semihalf.com>
-M: Tomasz Duszynski <tdu@semihalf.com>
-M: Dmitri Epshtein <dima@marvell.com>
-M: Natalie Samsonov <nsamsono@marvell.com>
-M: Jianbo Liu <jianbo.liu@arm.com>
-F: drivers/net/mrvl/
-F: doc/guides/nics/mrvl.rst
-F: doc/guides/nics/features/mrvl.ini
+M: Jacek Siuda <jck@semihalf.com>
+M: Tomasz Duszynski <tdu@semihalf.com>
+M: Dmitri Epshtein <dima@marvell.com>
+M: Natalie Samsonov <nsamsono@marvell.com>
+M: Jianbo Liu <jianbo.liu@arm.com>
+F: drivers/net/mrvl/
+F: doc/guides/nics/mrvl.rst
+F: doc/guides/nics/features/mrvl.ini
Netcope szedata2
-M: Matej Vido <vido@cesnet.cz>
-F: drivers/net/szedata2/
-F: doc/guides/nics/szedata2.rst
-F: doc/guides/nics/features/szedata2.ini
+M: Matej Vido <vido@cesnet.cz>
+F: drivers/net/szedata2/
+F: doc/guides/nics/szedata2.rst
+F: doc/guides/nics/features/szedata2.ini
Netronome nfp
-M: Alejandro Lucero <alejandro.lucero@netronome.com>
-F: drivers/net/nfp/
-F: doc/guides/nics/nfp.rst
-F: doc/guides/nics/features/nfp*.ini
+M: Alejandro Lucero <alejandro.lucero@netronome.com>
+F: drivers/net/nfp/
+F: doc/guides/nics/nfp.rst
+F: doc/guides/nics/features/nfp*.ini
NXP dpaa
-M: Hemant Agrawal <hemant.agrawal@nxp.com>
-M: Shreyansh Jain <shreyansh.jain@nxp.com>
-F: drivers/mempool/dpaa/
-F: drivers/net/dpaa/
-F: doc/guides/nics/dpaa.rst
-F: doc/guides/nics/features/dpaa.ini
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
+F: drivers/mempool/dpaa/
+F: drivers/net/dpaa/
+F: doc/guides/nics/dpaa.rst
+F: doc/guides/nics/features/dpaa.ini
NXP dpaa2
-M: Hemant Agrawal <hemant.agrawal@nxp.com>
-M: Shreyansh Jain <shreyansh.jain@nxp.com>
-F: drivers/mempool/dpaa2/
-F: drivers/net/dpaa2/
-F: doc/guides/nics/dpaa2.rst
-F: doc/guides/nics/features/dpaa2.ini
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+M: Shreyansh Jain <shreyansh.jain@nxp.com>
+F: drivers/mempool/dpaa2/
+F: drivers/net/dpaa2/
+F: doc/guides/nics/dpaa2.rst
+F: doc/guides/nics/features/dpaa2.ini
QLogic bnx2x
-M: Harish Patil <harish.patil@cavium.com>
-M: Rasesh Mody <rasesh.mody@cavium.com>
-F: drivers/net/bnx2x/
-F: doc/guides/nics/bnx2x.rst
-F: doc/guides/nics/features/bnx2x*.ini
+M: Harish Patil <harish.patil@cavium.com>
+M: Rasesh Mody <rasesh.mody@cavium.com>
+F: drivers/net/bnx2x/
+F: doc/guides/nics/bnx2x.rst
+F: doc/guides/nics/features/bnx2x*.ini
QLogic qede PMD
-M: Rasesh Mody <rasesh.mody@cavium.com>
-M: Harish Patil <harish.patil@cavium.com>
-M: Shahed Shaikh <shahed.shaikh@cavium.com>
-F: drivers/net/qede/
-F: doc/guides/nics/qede.rst
-F: doc/guides/nics/features/qede*.ini
+M: Rasesh Mody <rasesh.mody@cavium.com>
+M: Harish Patil <harish.patil@cavium.com>
+M: Shahed Shaikh <shahed.shaikh@cavium.com>
+F: drivers/net/qede/
+F: doc/guides/nics/qede.rst
+F: doc/guides/nics/features/qede*.ini
Solarflare sfc_efx
-M: Andrew Rybchenko <arybchenko@solarflare.com>
-F: drivers/net/sfc/
-F: doc/guides/nics/sfc_efx.rst
-F: doc/guides/nics/features/sfc_efx.ini
+M: Andrew Rybchenko <arybchenko@solarflare.com>
+F: drivers/net/sfc/
+F: doc/guides/nics/sfc_efx.rst
+F: doc/guides/nics/features/sfc_efx.ini
VMware vmxnet3
-M: Shrikrishna Khare <skhare@vmware.com>
-F: drivers/net/vmxnet3/
-F: doc/guides/nics/vmxnet3.rst
-F: doc/guides/nics/features/vmxnet3.ini
+M: Shrikrishna Khare <skhare@vmware.com>
+F: drivers/net/vmxnet3/
+F: doc/guides/nics/vmxnet3.rst
+F: doc/guides/nics/features/vmxnet3.ini
Vhost-user
-M: Yuanhan Liu <yliu@fridaylinux.org>
-M: Maxime Coquelin <maxime.coquelin@redhat.com>
-T: git://dpdk.org/next/dpdk-next-virtio
-F: lib/librte_vhost/
-F: doc/guides/prog_guide/vhost_lib.rst
-F: examples/vhost/
-F: doc/guides/sample_app_ug/vhost.rst
-F: examples/vhost_scsi/
-F: doc/guides/sample_app_ug/vhost_scsi.rst
+M: Yuanhan Liu <yliu@fridaylinux.org>
+M: Maxime Coquelin <maxime.coquelin@redhat.com>
+T: git://dpdk.org/next/dpdk-next-virtio
+F: lib/librte_vhost/
+F: doc/guides/prog_guide/vhost_lib.rst
+F: examples/vhost/
+F: doc/guides/sample_app_ug/vhost.rst
+F: examples/vhost_scsi/
+F: doc/guides/sample_app_ug/vhost_scsi.rst
Vhost PMD
-M: Tetsuya Mukawa <mtetsuyah@gmail.com>
-M: Yuanhan Liu <yliu@fridaylinux.org>
-M: Maxime Coquelin <maxime.coquelin@redhat.com>
-T: git://dpdk.org/next/dpdk-next-virtio
-F: drivers/net/vhost/
-F: doc/guides/nics/features/vhost.ini
+M: Tetsuya Mukawa <mtetsuyah@gmail.com>
+M: Yuanhan Liu <yliu@fridaylinux.org>
+M: Maxime Coquelin <maxime.coquelin@redhat.com>
+T: git://dpdk.org/next/dpdk-next-virtio
+F: drivers/net/vhost/
+F: doc/guides/nics/features/vhost.ini
Virtio PMD
-M: Yuanhan Liu <yliu@fridaylinux.org>
-M: Maxime Coquelin <maxime.coquelin@redhat.com>
-M: Tiwei Bie <tiwei.bie@intel.com>
-T: git://dpdk.org/next/dpdk-next-virtio
-F: drivers/net/virtio/
-F: doc/guides/nics/virtio.rst
-F: doc/guides/nics/features/virtio*.ini
+M: Yuanhan Liu <yliu@fridaylinux.org>
+M: Maxime Coquelin <maxime.coquelin@redhat.com>
+M: Tiwei Bie <tiwei.bie@intel.com>
+T: git://dpdk.org/next/dpdk-next-virtio
+F: drivers/net/virtio/
+F: doc/guides/nics/virtio.rst
+F: doc/guides/nics/features/virtio*.ini
Wind River AVP
-M: Allain Legacy <allain.legacy@windriver.com>
-M: Matt Peters <matt.peters@windriver.com>
-F: drivers/net/avp/
-F: doc/guides/nics/avp.rst
-F: doc/guides/nics/features/avp.ini
+M: Allain Legacy <allain.legacy@windriver.com>
+M: Matt Peters <matt.peters@windriver.com>
+F: drivers/net/avp/
+F: doc/guides/nics/avp.rst
+F: doc/guides/nics/features/avp.ini
PCAP PMD
-M: Ferruh Yigit <ferruh.yigit@intel.com>
-F: drivers/net/pcap/
-F: doc/guides/nics/pcap_ring.rst
-F: doc/guides/nics/features/pcap.ini
+M: Ferruh Yigit <ferruh.yigit@intel.com>
+F: drivers/net/pcap/
+F: doc/guides/nics/pcap_ring.rst
+F: doc/guides/nics/features/pcap.ini
Tap PMD
-M: Pascal Mazon <pascal.mazon@6wind.com>
-F: drivers/net/tap/
-F: doc/guides/nics/tap.rst
-F: doc/guides/nics/features/tap.ini
+M: Pascal Mazon <pascal.mazon@6wind.com>
+F: drivers/net/tap/
+F: doc/guides/nics/tap.rst
+F: doc/guides/nics/features/tap.ini
KNI PMD
-M: Ferruh Yigit <ferruh.yigit@intel.com>
-F: drivers/net/kni/
-F: doc/guides/nics/kni.rst
-F: doc/guides/nics/features/kni.ini
+M: Ferruh Yigit <ferruh.yigit@intel.com>
+F: drivers/net/kni/
+F: doc/guides/nics/kni.rst
+F: doc/guides/nics/features/kni.ini
Ring PMD
-M: Bruce Richardson <bruce.richardson@intel.com>
-F: drivers/net/ring/
-F: doc/guides/nics/pcap_ring.rst
-F: test/test/test_pmd_ring.c
-F: test/test/test_pmd_ring_perf.c
-F: doc/guides/nics/features/ring.ini
+M: Bruce Richardson <bruce.richardson@intel.com>
+F: drivers/net/ring/
+F: doc/guides/nics/pcap_ring.rst
+F: test/test/test_pmd_ring.c
+F: test/test/test_pmd_ring_perf.c
+F: doc/guides/nics/features/ring.ini
Null Networking PMD
-M: Tetsuya Mukawa <mtetsuyah@gmail.com>
-F: drivers/net/null/
-F: doc/guides/nics/features/null.ini
+M: Tetsuya Mukawa <mtetsuyah@gmail.com>
+F: drivers/net/null/
+F: doc/guides/nics/features/null.ini
Fail-safe PMD
-M: Gaetan Rivet <gaetan.rivet@6wind.com>
-F: drivers/net/failsafe/
-F: doc/guides/nics/fail_safe.rst
+M: Gaetan Rivet <gaetan.rivet@6wind.com>
+F: drivers/net/failsafe/
+F: doc/guides/nics/fail_safe.rst
Softnic PMD
-M: Jasvinder Singh <jasvinder.singh@intel.com>
-M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
-F: drivers/net/softnic/
+M: Jasvinder Singh <jasvinder.singh@intel.com>
+M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
+F: drivers/net/softnic/
Crypto Drivers
--------------
-M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
-T: git://dpdk.org/next/dpdk-next-crypto
-F: doc/guides/cryptodevs/features/default.ini
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+T: git://dpdk.org/next/dpdk-next-crypto
+F: doc/guides/cryptodevs/features/default.ini
ARMv8 Crypto
-M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
-F: drivers/crypto/armv8/
-F: doc/guides/cryptodevs/armv8.rst
-F: doc/guides/cryptodevs/features/armv8.ini
+M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
+F: drivers/crypto/armv8/
+F: doc/guides/cryptodevs/armv8.rst
+F: doc/guides/cryptodevs/features/armv8.ini
Crypto Scheduler
-M: Fan Zhang <roy.fan.zhang@intel.com>
-F: drivers/crypto/scheduler/
-F: doc/guides/cryptodevs/scheduler.rst
+M: Fan Zhang <roy.fan.zhang@intel.com>
+F: drivers/crypto/scheduler/
+F: doc/guides/cryptodevs/scheduler.rst
Intel AES-NI GCM
-M: Declan Doherty <declan.doherty@intel.com>
-F: drivers/crypto/aesni_gcm/
-F: doc/guides/cryptodevs/aesni_gcm.rst
-F: doc/guides/cryptodevs/features/aesni_gcm.ini
+M: Declan Doherty <declan.doherty@intel.com>
+F: drivers/crypto/aesni_gcm/
+F: doc/guides/cryptodevs/aesni_gcm.rst
+F: doc/guides/cryptodevs/features/aesni_gcm.ini
Intel AES-NI Multi-Buffer
-M: Declan Doherty <declan.doherty@intel.com>
-F: drivers/crypto/aesni_mb/
-F: doc/guides/cryptodevs/aesni_mb.rst
-F: doc/guides/cryptodevs/features/aesni_mb.ini
+M: Declan Doherty <declan.doherty@intel.com>
+F: drivers/crypto/aesni_mb/
+F: doc/guides/cryptodevs/aesni_mb.rst
+F: doc/guides/cryptodevs/features/aesni_mb.ini
Intel QuickAssist
-M: John Griffin <john.griffin@intel.com>
-M: Fiona Trahe <fiona.trahe@intel.com>
-M: Deepak Kumar Jain <deepak.k.jain@intel.com>
-F: drivers/crypto/qat/
-F: doc/guides/cryptodevs/qat.rst
-F: doc/guides/cryptodevs/features/qat.ini
+M: John Griffin <john.griffin@intel.com>
+M: Fiona Trahe <fiona.trahe@intel.com>
+M: Deepak Kumar Jain <deepak.k.jain@intel.com>
+F: drivers/crypto/qat/
+F: doc/guides/cryptodevs/qat.rst
+F: doc/guides/cryptodevs/features/qat.ini
KASUMI
-M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
-F: drivers/crypto/kasumi/
-F: doc/guides/cryptodevs/kasumi.rst
-F: doc/guides/cryptodevs/features/kasumi.ini
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+F: drivers/crypto/kasumi/
+F: doc/guides/cryptodevs/kasumi.rst
+F: doc/guides/cryptodevs/features/kasumi.ini
Marvell Mrvl
-M: Jacek Siuda <jck@semihalf.com>
-M: Tomasz Duszynski <tdu@semihalf.com>
-M: Dmitri Epshtein <dima@marvell.com>
-M: Natalie Samsonov <nsamsono@marvell.com>
-M: Jianbo Liu <jianbo.liu@arm.com>
-F: drivers/crypto/mrvl/
-F: doc/guides/cryptodevs/mrvl.rst
-F: doc/guides/cryptodevs/features/mrvl.ini
+M: Jacek Siuda <jck@semihalf.com>
+M: Tomasz Duszynski <tdu@semihalf.com>
+M: Dmitri Epshtein <dima@marvell.com>
+M: Natalie Samsonov <nsamsono@marvell.com>
+M: Jianbo Liu <jianbo.liu@arm.com>
+F: drivers/crypto/mrvl/
+F: doc/guides/cryptodevs/mrvl.rst
+F: doc/guides/cryptodevs/features/mrvl.ini
Null Crypto
-M: Declan Doherty <declan.doherty@intel.com>
-F: drivers/crypto/null/
-F: doc/guides/cryptodevs/null.rst
-F: doc/guides/cryptodevs/features/null.ini
+M: Declan Doherty <declan.doherty@intel.com>
+F: drivers/crypto/null/
+F: doc/guides/cryptodevs/null.rst
+F: doc/guides/cryptodevs/features/null.ini
NXP DPAA_SEC
-M: Akhil Goyal <akhil.goyal@nxp.com>
-M: Hemant Agrawal <hemant.agrawal@nxp.com>
-F: drivers/crypto/dpaa_sec/
-F: doc/guides/cryptodevs/dpaa_sec.rst
-F: doc/guides/cryptodevs/features/dpaa_sec.ini
+M: Akhil Goyal <akhil.goyal@nxp.com>
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: drivers/crypto/dpaa_sec/
+F: doc/guides/cryptodevs/dpaa_sec.rst
+F: doc/guides/cryptodevs/features/dpaa_sec.ini
NXP DPAA2_SEC
-M: Akhil Goyal <akhil.goyal@nxp.com>
-M: Hemant Agrawal <hemant.agrawal@nxp.com>
-F: drivers/crypto/dpaa2_sec/
-F: doc/guides/cryptodevs/dpaa2_sec.rst
-F: doc/guides/cryptodevs/features/dpaa2_sec.ini
+M: Akhil Goyal <akhil.goyal@nxp.com>
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+F: drivers/crypto/dpaa2_sec/
+F: doc/guides/cryptodevs/dpaa2_sec.rst
+F: doc/guides/cryptodevs/features/dpaa2_sec.ini
OpenSSL
-M: Declan Doherty <declan.doherty@intel.com>
-F: drivers/crypto/openssl/
-F: doc/guides/cryptodevs/openssl.rst
-F: doc/guides/cryptodevs/features/openssl.ini
+M: Declan Doherty <declan.doherty@intel.com>
+F: drivers/crypto/openssl/
+F: doc/guides/cryptodevs/openssl.rst
+F: doc/guides/cryptodevs/features/openssl.ini
SNOW 3G
-M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
-F: drivers/crypto/snow3g/
-F: doc/guides/cryptodevs/snow3g.rst
-F: doc/guides/cryptodevs/features/snow3g.ini
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+F: drivers/crypto/snow3g/
+F: doc/guides/cryptodevs/snow3g.rst
+F: doc/guides/cryptodevs/features/snow3g.ini
ZUC
-M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
-F: drivers/crypto/zuc/
-F: doc/guides/cryptodevs/zuc.rst
-F: doc/guides/cryptodevs/features/zuc.ini
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+F: drivers/crypto/zuc/
+F: doc/guides/cryptodevs/zuc.rst
+F: doc/guides/cryptodevs/features/zuc.ini
Eventdev Drivers
----------------
-M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
-T: git://dpdk.org/next/dpdk-next-eventdev
+M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
+T: git://dpdk.org/next/dpdk-next-eventdev
Cavium OCTEONTX ssovf
-M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
-M: Santosh Shukla <santosh.shukla@caviumnetworks.com>
-F: drivers/event/octeontx/
-F: test/test/test_eventdev_octeontx.c
-F: doc/guides/eventdevs/octeontx.rst
+M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
+M: Santosh Shukla <santosh.shukla@caviumnetworks.com>
+F: drivers/event/octeontx/
+F: test/test/test_eventdev_octeontx.c
+F: doc/guides/eventdevs/octeontx.rst
NXP DPAA2 eventdev
-M: Hemant Agrawal <hemant.agrawal@nxp.com>
-M: Nipun Gupta <nipun.gupta@nxp.com>
-F: drivers/event/dpaa2/
-F: doc/guides/eventdevs/dpaa2.rst
+M: Hemant Agrawal <hemant.agrawal@nxp.com>
+M: Nipun Gupta <nipun.gupta@nxp.com>
+F: drivers/event/dpaa2/
+F: doc/guides/eventdevs/dpaa2.rst
Software Eventdev PMD
-M: Harry van Haaren <harry.van.haaren@intel.com>
-F: drivers/event/sw/
-F: test/test/test_eventdev_sw.c
-F: doc/guides/eventdevs/sw.rst
-F: examples/eventdev_pipeline_sw_pmd/
-F: doc/guides/sample_app_ug/eventdev_pipeline_sw_pmd.rst
+M: Harry van Haaren <harry.van.haaren@intel.com>
+F: drivers/event/sw/
+F: test/test/test_eventdev_sw.c
+F: doc/guides/eventdevs/sw.rst
+F: examples/eventdev_pipeline_sw_pmd/
+F: doc/guides/sample_app_ug/eventdev_pipeline_sw_pmd.rst
Packet processing
-----------------
Network headers
-M: Olivier Matz <olivier.matz@6wind.com>
-F: lib/librte_net/
+M: Olivier Matz <olivier.matz@6wind.com>
+F: lib/librte_net/
Packet CRC
-M: Jasvinder Singh <jasvinder.singh@intel.com>
-F: lib/librte_net/rte_net_crc*
-F: lib/librte_net/net_crc_sse.h
-F: test/test/test_crc.c
+M: Jasvinder Singh <jasvinder.singh@intel.com>
+F: lib/librte_net/rte_net_crc*
+F: lib/librte_net/net_crc_sse.h
+F: test/test/test_crc.c
IP fragmentation & reassembly
-M: Konstantin Ananyev <konstantin.ananyev@intel.com>
-F: lib/librte_ip_frag/
-F: doc/guides/prog_guide/ip_fragment_reassembly_lib.rst
-F: examples/ip_fragmentation/
-F: doc/guides/sample_app_ug/ip_frag.rst
-F: examples/ip_reassembly/
-F: doc/guides/sample_app_ug/ip_reassembly.rst
+M: Konstantin Ananyev <konstantin.ananyev@intel.com>
+F: lib/librte_ip_frag/
+F: doc/guides/prog_guide/ip_fragment_reassembly_lib.rst
+F: examples/ip_fragmentation/
+F: doc/guides/sample_app_ug/ip_frag.rst
+F: examples/ip_reassembly/
+F: doc/guides/sample_app_ug/ip_reassembly.rst
Generic Receive Offload - EXPERIMENTAL
-M: Jiayu Hu <jiayu.hu@intel.com>
-F: lib/librte_gro/
-F: doc/guides/prog_guide/generic_receive_offload_lib.rst
+M: Jiayu Hu <jiayu.hu@intel.com>
+F: lib/librte_gro/
+F: doc/guides/prog_guide/generic_receive_offload_lib.rst
Generic Segmentation Offload
-M: Jiayu Hu <jiayu.hu@intel.com>
-M: Mark Kavanagh <mark.b.kavanagh@intel.com>
-F: lib/librte_gso/
-F: doc/guides/prog_guide/generic_segmentation_offload_lib.rst
+M: Jiayu Hu <jiayu.hu@intel.com>
+M: Mark Kavanagh <mark.b.kavanagh@intel.com>
+F: lib/librte_gso/
+F: doc/guides/prog_guide/generic_segmentation_offload_lib.rst
Flow Classify - EXPERIMENTAL
-M: Bernard Iremonger <bernard.iremonger@intel.com>
-F: lib/librte_flow_classify/
-F: test/test/test_flow_classify*
-F: doc/guides/prog_guide/flow_classify_lib.rst
-F: examples/flow_classify/
-F: doc/guides/sample_app_ug/flow_classify.rst
+M: Bernard Iremonger <bernard.iremonger@intel.com>
+F: lib/librte_flow_classify/
+F: test/test/test_flow_classify*
+F: doc/guides/prog_guide/flow_classify_lib.rst
+F: examples/flow_classify/
+F: doc/guides/sample_app_ug/flow_classify.rst
Distributor
-M: Bruce Richardson <bruce.richardson@intel.com>
-M: David Hunt <david.hunt@intel.com>
-F: lib/librte_distributor/
-F: doc/guides/prog_guide/packet_distrib_lib.rst
-F: test/test/test_distributor*
-F: examples/distributor/
-F: doc/guides/sample_app_ug/dist_app.rst
+M: Bruce Richardson <bruce.richardson@intel.com>
+M: David Hunt <david.hunt@intel.com>
+F: lib/librte_distributor/
+F: doc/guides/prog_guide/packet_distrib_lib.rst
+F: test/test/test_distributor*
+F: examples/distributor/
+F: doc/guides/sample_app_ug/dist_app.rst
Reorder
-M: Reshma Pattan <reshma.pattan@intel.com>
-F: lib/librte_reorder/
-F: doc/guides/prog_guide/reorder_lib.rst
-F: test/test/test_reorder*
-F: examples/packet_ordering/
-F: doc/guides/sample_app_ug/packet_ordering.rst
+M: Reshma Pattan <reshma.pattan@intel.com>
+F: lib/librte_reorder/
+F: doc/guides/prog_guide/reorder_lib.rst
+F: test/test/test_reorder*
+F: examples/packet_ordering/
+F: doc/guides/sample_app_ug/packet_ordering.rst
Hierarchical scheduler
-M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
-F: lib/librte_sched/
-F: doc/guides/prog_guide/qos_framework.rst
-F: test/test/test_red.c
-F: test/test/test_sched.c
-F: examples/qos_sched/
-F: doc/guides/sample_app_ug/qos_scheduler.rst
+M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
+F: lib/librte_sched/
+F: doc/guides/prog_guide/qos_framework.rst
+F: test/test/test_red.c
+F: test/test/test_sched.c
+F: examples/qos_sched/
+F: doc/guides/sample_app_ug/qos_scheduler.rst
Packet capture
-M: Reshma Pattan <reshma.pattan@intel.com>
-F: lib/librte_pdump/
-F: doc/guides/prog_guide/pdump_lib.rst
-F: app/pdump/
-F: doc/guides/tools/pdump.rst
+M: Reshma Pattan <reshma.pattan@intel.com>
+F: lib/librte_pdump/
+F: doc/guides/prog_guide/pdump_lib.rst
+F: app/pdump/
+F: doc/guides/tools/pdump.rst
Packet Framework
----------------
-M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
-F: lib/librte_pipeline/
-F: lib/librte_port/
-F: lib/librte_table/
-F: doc/guides/prog_guide/packet_framework.rst
-F: test/test/test_table*
-F: test/test-pipeline/
-F: doc/guides/sample_app_ug/test_pipeline.rst
-F: examples/ip_pipeline/
-F: doc/guides/sample_app_ug/ip_pipeline.rst
+M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
+F: lib/librte_pipeline/
+F: lib/librte_port/
+F: lib/librte_table/
+F: doc/guides/prog_guide/packet_framework.rst
+F: test/test/test_table*
+F: test/test-pipeline/
+F: doc/guides/sample_app_ug/test_pipeline.rst
+F: examples/ip_pipeline/
+F: doc/guides/sample_app_ug/ip_pipeline.rst
Algorithms
----------
ACL
-M: Konstantin Ananyev <konstantin.ananyev@intel.com>
-F: lib/librte_acl/
-F: doc/guides/prog_guide/packet_classif_access_ctrl.rst
-F: test/test-acl/
-F: test/test/test_acl.*
-F: examples/l3fwd-acl/
-F: doc/guides/sample_app_ug/l3_forward_access_ctrl.rst
+M: Konstantin Ananyev <konstantin.ananyev@intel.com>
+F: lib/librte_acl/
+F: doc/guides/prog_guide/packet_classif_access_ctrl.rst
+F: test/test-acl/
+F: test/test/test_acl.*
+F: examples/l3fwd-acl/
+F: doc/guides/sample_app_ug/l3_forward_access_ctrl.rst
EFD
-M: Byron Marohn <byron.marohn@intel.com>
-M: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
-F: lib/librte_efd/
-F: doc/guides/prog_guide/efd_lib.rst
-F: test/test/test_efd*
-F: examples/server_node_efd/
-F: doc/guides/sample_app_ug/server_node_efd.rst
+M: Byron Marohn <byron.marohn@intel.com>
+M: Pablo de Lara Guarch <pablo.de.lara.guarch@intel.com>
+F: lib/librte_efd/
+F: doc/guides/prog_guide/efd_lib.rst
+F: test/test/test_efd*
+F: examples/server_node_efd/
+F: doc/guides/sample_app_ug/server_node_efd.rst
Hashes
-M: Bruce Richardson <bruce.richardson@intel.com>
-M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
-F: lib/librte_hash/
-F: doc/guides/prog_guide/hash_lib.rst
-F: test/test/test_*hash*
-F: test/test/test_func_reentrancy.c
+M: Bruce Richardson <bruce.richardson@intel.com>
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+F: lib/librte_hash/
+F: doc/guides/prog_guide/hash_lib.rst
+F: test/test/test_*hash*
+F: test/test/test_func_reentrancy.c
LPM
-M: Bruce Richardson <bruce.richardson@intel.com>
-F: lib/librte_lpm/
-F: doc/guides/prog_guide/lpm*
-F: test/test/test_lpm*
-F: test/test/test_func_reentrancy.c
-F: test/test/test_xmmt_ops.h
+M: Bruce Richardson <bruce.richardson@intel.com>
+F: lib/librte_lpm/
+F: doc/guides/prog_guide/lpm*
+F: test/test/test_lpm*
+F: test/test/test_func_reentrancy.c
+F: test/test/test_xmmt_ops.h
Membership - EXPERIMENTAL
-M: Yipeng Wang <yipeng1.wang@intel.com>
-M: Sameh Gobriel <sameh.gobriel@intel.com>
-F: lib/librte_member/
-F: doc/guides/prog_guide/member_lib.rst
-F: test/test/test_member*
+M: Yipeng Wang <yipeng1.wang@intel.com>
+M: Sameh Gobriel <sameh.gobriel@intel.com>
+F: lib/librte_member/
+F: doc/guides/prog_guide/member_lib.rst
+F: test/test/test_member*
Traffic metering
-M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
-F: lib/librte_meter/
-F: doc/guides/sample_app_ug/qos_scheduler.rst
-F: test/test/test_meter.c
-F: examples/qos_meter/
-F: doc/guides/sample_app_ug/qos_metering.rst
+M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
+F: lib/librte_meter/
+F: doc/guides/sample_app_ug/qos_scheduler.rst
+F: test/test/test_meter.c
+F: examples/qos_meter/
+F: doc/guides/sample_app_ug/qos_metering.rst
Other libraries
---------------
Configuration file
-M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
-F: lib/librte_cfgfile/
-F: test/test/test_cfgfile.c
-F: test/test/test_cfgfiles/
+M: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
+F: lib/librte_cfgfile/
+F: test/test/test_cfgfile.c
+F: test/test/test_cfgfiles/
Interactive command line
-M: Olivier Matz <olivier.matz@6wind.com>
-F: lib/librte_cmdline/
-F: test/cmdline_test/
-F: test/test/test_cmdline*
-F: examples/cmdline/
-F: doc/guides/sample_app_ug/cmd_line.rst
+M: Olivier Matz <olivier.matz@6wind.com>
+F: lib/librte_cmdline/
+F: test/cmdline_test/
+F: test/test/test_cmdline*
+F: examples/cmdline/
+F: doc/guides/sample_app_ug/cmd_line.rst
Key/Value parsing
-M: Olivier Matz <olivier.matz@6wind.com>
-F: lib/librte_kvargs/
-F: test/test/test_kvargs.c
+M: Olivier Matz <olivier.matz@6wind.com>
+F: lib/librte_kvargs/
+F: test/test/test_kvargs.c
PCI
-M: Gaetan Rivet <gaetan.rivet@6wind.com>
-F: lib/librte_pci/
+M: Gaetan Rivet <gaetan.rivet@6wind.com>
+F: lib/librte_pci/
Power management
-M: David Hunt <david.hunt@intel.com>
-F: lib/librte_power/
-F: doc/guides/prog_guide/power_man.rst
-F: test/test/test_power*
-F: examples/l3fwd-power/
-F: doc/guides/sample_app_ug/l3_forward_power_man.rst
-F: examples/vm_power_manager/
-F: doc/guides/sample_app_ug/vm_power_management.rst
+M: David Hunt <david.hunt@intel.com>
+F: lib/librte_power/
+F: doc/guides/prog_guide/power_man.rst
+F: test/test/test_power*
+F: examples/l3fwd-power/
+F: doc/guides/sample_app_ug/l3_forward_power_man.rst
+F: examples/vm_power_manager/
+F: doc/guides/sample_app_ug/vm_power_management.rst
Timers
-M: Robert Sanford <rsanford@akamai.com>
-F: lib/librte_timer/
-F: doc/guides/prog_guide/timer_lib.rst
-F: test/test/test_timer*
-F: examples/timer/
-F: doc/guides/sample_app_ug/timer.rst
+M: Robert Sanford <rsanford@akamai.com>
+F: lib/librte_timer/
+F: doc/guides/prog_guide/timer_lib.rst
+F: test/test/test_timer*
+F: examples/timer/
+F: doc/guides/sample_app_ug/timer.rst
Job statistics
-M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
-F: lib/librte_jobstats/
-F: examples/l2fwd-jobstats/
-F: doc/guides/sample_app_ug/l2_forward_job_stats.rst
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+F: lib/librte_jobstats/
+F: examples/l2fwd-jobstats/
+F: doc/guides/sample_app_ug/l2_forward_job_stats.rst
Metrics
-M: Remy Horton <remy.horton@intel.com>
-F: lib/librte_metrics/
+M: Remy Horton <remy.horton@intel.com>
+F: lib/librte_metrics/
Bit-rate statistics
-M: Remy Horton <remy.horton@intel.com>
-F: lib/librte_bitratestats/
+M: Remy Horton <remy.horton@intel.com>
+F: lib/librte_bitratestats/
Latency statistics
-M: Reshma Pattan <reshma.pattan@intel.com>
-F: lib/librte_latencystats/
+M: Reshma Pattan <reshma.pattan@intel.com>
+F: lib/librte_latencystats/
Test Applications
-----------------
Unit tests framework
-F: test/Makefile
-F: test/test/Makefile
-F: test/test/autotest*
-F: test/test/commands.c
-F: test/test/packet_burst_generator.c
-F: test/test/packet_burst_generator.h
-F: test/test/process.h
-F: test/test/resource.*
-F: test/test/test.c
-F: test/test/test.h
-F: test/test/test_pmd_perf.c
-F: test/test/test_resource.c
-F: test/test/virtual_pmd.c
-F: test/test/virtual_pmd.h
+F: test/Makefile
+F: test/test/Makefile
+F: test/test/autotest*
+F: test/test/commands.c
+F: test/test/packet_burst_generator.c
+F: test/test/packet_burst_generator.h
+F: test/test/process.h
+F: test/test/resource.*
+F: test/test/test.c
+F: test/test/test.h
+F: test/test/test_pmd_perf.c
+F: test/test/test_resource.c
+F: test/test/virtual_pmd.c
+F: test/test/virtual_pmd.h
Driver testing tool
-M: Wenzhuo Lu <wenzhuo.lu@intel.com>
-M: Jingjing Wu <jingjing.wu@intel.com>
-F: app/test-pmd/
-F: doc/guides/testpmd_app_ug/
+M: Wenzhuo Lu <wenzhuo.lu@intel.com>
+M: Jingjing Wu <jingjing.wu@intel.com>
+F: app/test-pmd/
+F: doc/guides/testpmd_app_ug/
Crypto performance test application
-M: Declan Doherty <declan.doherty@intel.com>
-F: app/test-crypto-perf/
-F: doc/guides/tools/cryptoperf.rst
+M: Declan Doherty <declan.doherty@intel.com>
+F: app/test-crypto-perf/
+F: doc/guides/tools/cryptoperf.rst
Eventdev test application
-M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
-F: app/test-eventdev/
-F: doc/guides/tools/testeventdev.rst
-F: doc/guides/tools/img/eventdev_*
-F: test/test/test_event_ring.c
+M: Jerin Jacob <jerin.jacob@caviumnetworks.com>
+F: app/test-eventdev/
+F: doc/guides/tools/testeventdev.rst
+F: doc/guides/tools/img/eventdev_*
+F: test/test/test_event_ring.c
Procinfo tool
-M: Maryam Tahhan <maryam.tahhan@intel.com>
-M: Reshma Pattan <reshma.pattan@intel.com>
-F: app/proc_info/
-F: doc/guides/tools/proc_info.rst
+M: Maryam Tahhan <maryam.tahhan@intel.com>
+M: Reshma Pattan <reshma.pattan@intel.com>
+F: app/proc_info/
+F: doc/guides/tools/proc_info.rst
Other Example Applications
--------------------------
-M: Remy Horton <remy.horton@intel.com>
-F: examples/ethtool/
-F: doc/guides/sample_app_ug/ethtool.rst
+M: Remy Horton <remy.horton@intel.com>
+F: examples/ethtool/
+F: doc/guides/sample_app_ug/ethtool.rst
-F: examples/exception_path/
-F: doc/guides/sample_app_ug/exception_path.rst
+F: examples/exception_path/
+F: doc/guides/sample_app_ug/exception_path.rst
-M: Ori Kam <orika@mellanox.com>
-F: examples/flow_filtering/
-F: doc/guides/sample_app_ug/flow_filtering.rst
+M: Ori Kam <orika@mellanox.com>
+F: examples/flow_filtering/
+F: doc/guides/sample_app_ug/flow_filtering.rst
-M: Bruce Richardson <bruce.richardson@intel.com>
-M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
-F: examples/helloworld/
-F: doc/guides/sample_app_ug/hello_world.rst
+M: Bruce Richardson <bruce.richardson@intel.com>
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+F: examples/helloworld/
+F: doc/guides/sample_app_ug/hello_world.rst
-M: Radu Nicolau <radu.nicolau@intel.com>
-F: examples/ipsec-secgw/
-F: doc/guides/sample_app_ug/ipsec_secgw.rst
+M: Radu Nicolau <radu.nicolau@intel.com>
+F: examples/ipsec-secgw/
+F: doc/guides/sample_app_ug/ipsec_secgw.rst
-F: examples/ipv4_multicast/
-F: doc/guides/sample_app_ug/ipv4_multicast.rst
+F: examples/ipv4_multicast/
+F: doc/guides/sample_app_ug/ipv4_multicast.rst
-M: Bruce Richardson <bruce.richardson@intel.com>
-M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
-F: examples/l2fwd/
-F: doc/guides/sample_app_ug/l2_forward_real_virtual.rst
+M: Bruce Richardson <bruce.richardson@intel.com>
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+F: examples/l2fwd/
+F: doc/guides/sample_app_ug/l2_forward_real_virtual.rst
-M: Tomasz Kantecki <tomasz.kantecki@intel.com>
-F: doc/guides/sample_app_ug/l2_forward_cat.rst
-F: examples/l2fwd-cat/
+M: Tomasz Kantecki <tomasz.kantecki@intel.com>
+F: doc/guides/sample_app_ug/l2_forward_cat.rst
+F: examples/l2fwd-cat/
-F: examples/l3fwd/
-F: doc/guides/sample_app_ug/l3_forward.rst
+F: examples/l3fwd/
+F: doc/guides/sample_app_ug/l3_forward.rst
-F: examples/l3fwd-vf/
-F: doc/guides/sample_app_ug/l3_forward_virtual.rst
+F: examples/l3fwd-vf/
+F: doc/guides/sample_app_ug/l3_forward_virtual.rst
-F: examples/link_status_interrupt/
-F: doc/guides/sample_app_ug/link_status_intr.rst
+F: examples/link_status_interrupt/
+F: doc/guides/sample_app_ug/link_status_intr.rst
-F: examples/load_balancer/
-F: doc/guides/sample_app_ug/load_balancer.rst
+F: examples/load_balancer/
+F: doc/guides/sample_app_ug/load_balancer.rst
-F: examples/netmap_compat/
-F: doc/guides/sample_app_ug/netmap_compatibility.rst
+F: examples/netmap_compat/
+F: doc/guides/sample_app_ug/netmap_compatibility.rst
L-threads - EXPERIMENTAL
-M: John McNamara <john.mcnamara@intel.com>
-F: examples/performance-thread/
-F: doc/guides/sample_app_ug/performance_thread.rst
+M: John McNamara <john.mcnamara@intel.com>
+F: examples/performance-thread/
+F: doc/guides/sample_app_ug/performance_thread.rst
-M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
-F: examples/ptpclient/
+M: Pablo de Lara <pablo.de.lara.guarch@intel.com>
+F: examples/ptpclient/
-F: examples/quota_watermark/
-F: doc/guides/sample_app_ug/quota_watermark.rst
+F: examples/quota_watermark/
+F: doc/guides/sample_app_ug/quota_watermark.rst
-M: Bruce Richardson <bruce.richardson@intel.com>
-M: John McNamara <john.mcnamara@intel.com>
-F: examples/rxtx_callbacks/
-F: doc/guides/sample_app_ug/rxtx_callbacks.rst
+M: Bruce Richardson <bruce.richardson@intel.com>
+M: John McNamara <john.mcnamara@intel.com>
+F: examples/rxtx_callbacks/
+F: doc/guides/sample_app_ug/rxtx_callbacks.rst
-M: Harry van Haaren <harry.van.haaren@intel.com>
-F: examples/service_cores/
-F: doc/guides/sample_app_ug/service_cores.rst
+M: Harry van Haaren <harry.van.haaren@intel.com>
+F: examples/service_cores/
+F: doc/guides/sample_app_ug/service_cores.rst
-M: Bruce Richardson <bruce.richardson@intel.com>
-M: John McNamara <john.mcnamara@intel.com>
-F: examples/skeleton/
-F: doc/guides/sample_app_ug/skeleton.rst
+M: Bruce Richardson <bruce.richardson@intel.com>
+M: John McNamara <john.mcnamara@intel.com>
+F: examples/skeleton/
+F: doc/guides/sample_app_ug/skeleton.rst
-M: Jijiang Liu <jijiang.liu@intel.com>
-F: examples/tep_termination/
+M: Jijiang Liu <jijiang.liu@intel.com>
+F: examples/tep_termination/
-F: examples/vmdq/
-F: examples/vmdq_dcb/
-F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
+F: examples/vmdq/
+F: examples/vmdq_dcb/
+F: doc/guides/sample_app_ug/vmdq_dcb_forwarding.rst
--
2.15.1
^ permalink raw reply [relevance 3%]
* [dpdk-dev] [PATCH v3] lib/librte_meter: add meter configuration profile
@ 2018-01-08 10:00 1% ` Jasvinder Singh
2018-01-08 15:43 1% ` [dpdk-dev] [PATCH v4] " Jasvinder Singh
0 siblings, 1 reply; 200+ results
From: Jasvinder Singh @ 2018-01-08 10:00 UTC (permalink / raw)
To: dev; +Cc: cristian.dumitrescu
From: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
This patch adds api for meter configuration profiles. For a given
meter object, the parameters such as the rates and sizes for
the token buckets are defined as configuration profile parameters.
This helps in reducing the memory footprint of a meter object which
results in better cache utilization for the typical case when large
arrays of meter objects are used.
Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
v3:
- fix doxygen comments
v2:
- fix checkpatch warnings
- fix build error in ip_pipeline sample app
doc/guides/rel_notes/deprecation.rst | 3 -
doc/guides/rel_notes/release_18_02.rst | 2 +-
.../pipeline/pipeline_flow_actions_be.c | 25 ++-
examples/qos_meter/main.c | 39 ++++-
examples/qos_meter/main.h | 32 ++--
lib/librte_meter/Makefile | 2 +-
lib/librte_meter/rte_meter.c | 93 ++++++----
lib/librte_meter/rte_meter.h | 195 ++++++++++++++-------
lib/librte_meter/rte_meter_version.map | 8 +
test/test/test_meter.c | 194 +++++++++++---------
10 files changed, 392 insertions(+), 201 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..6ba5ffd 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -50,6 +50,3 @@ Deprecation Notices
required the previous behavior can be configured using existing flow
director APIs. There is no ABI/API break. This change will just remove a
global configuration setting and require explicit configuration.
-
-* librte_meter: The API will change to accommodate configuration profiles.
- Most of the API functions will have an additional opaque parameter.
diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst
index 24b67bb..7343b74 100644
--- a/doc/guides/rel_notes/release_18_02.rst
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -141,7 +141,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_lpm.so.2
librte_mbuf.so.3
librte_mempool.so.3
- librte_meter.so.1
+ + librte_meter.so.2
librte_metrics.so.1
librte_net.so.1
librte_pci.so.1
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
index 9599b7d..33f1c41 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
@@ -111,6 +111,7 @@ static pipeline_msg_req_handler custom_handlers[] = {
*/
struct meter_policer {
struct rte_meter_trtcm meter;
+ struct rte_meter_trtcm_profile meter_profile;
struct pipeline_fa_policer_params policer;
struct pipeline_fa_policer_stats stats;
};
@@ -127,8 +128,15 @@ flow_table_entry_set_meter(struct flow_table_entry *entry,
{
struct rte_meter_trtcm *meter = &entry->mp[meter_id].meter;
struct rte_meter_trtcm_params *meter_params = ¶ms->m[meter_id];
+ struct rte_meter_trtcm_profile *meter_profile =
+ &entry->mp[meter_id].meter_profile;
+ int status;
- return rte_meter_trtcm_config(meter, meter_params);
+ status = rte_meter_trtcm_profile_config(meter_profile, meter_params);
+ if (status)
+ return status;
+
+ return rte_meter_trtcm_config(meter, meter_profile);
}
static void
@@ -202,11 +210,14 @@ pkt_work(
enum rte_meter_color color = p->dscp[dscp].color;
struct rte_meter_trtcm *meter = &entry->mp[tc].meter;
+ struct rte_meter_trtcm_profile *meter_profile =
+ &entry->mp[tc].meter_profile;
struct pipeline_fa_policer_params *policer = &entry->mp[tc].policer;
struct pipeline_fa_policer_stats *stats = &entry->mp[tc].stats;
/* Read (entry), compute */
enum rte_meter_color color2 = rte_meter_trtcm_color_aware_check(meter,
+ meter_profile,
time,
total_length,
color);
@@ -284,42 +295,54 @@ pkt4_work(
enum rte_meter_color color3 = p->dscp[dscp3].color;
struct rte_meter_trtcm *meter0 = &entry0->mp[tc0].meter;
+ struct rte_meter_trtcm_profile *meter0_profile =
+ &entry0->mp[tc0].meter_profile;
struct pipeline_fa_policer_params *policer0 = &entry0->mp[tc0].policer;
struct pipeline_fa_policer_stats *stats0 = &entry0->mp[tc0].stats;
struct rte_meter_trtcm *meter1 = &entry1->mp[tc1].meter;
+ struct rte_meter_trtcm_profile *meter1_profile =
+ &entry1->mp[tc1].meter_profile;
struct pipeline_fa_policer_params *policer1 = &entry1->mp[tc1].policer;
struct pipeline_fa_policer_stats *stats1 = &entry1->mp[tc1].stats;
struct rte_meter_trtcm *meter2 = &entry2->mp[tc2].meter;
+ struct rte_meter_trtcm_profile *meter2_profile =
+ &entry2->mp[tc2].meter_profile;
struct pipeline_fa_policer_params *policer2 = &entry2->mp[tc2].policer;
struct pipeline_fa_policer_stats *stats2 = &entry2->mp[tc2].stats;
struct rte_meter_trtcm *meter3 = &entry3->mp[tc3].meter;
+ struct rte_meter_trtcm_profile *meter3_profile =
+ &entry3->mp[tc3].meter_profile;
struct pipeline_fa_policer_params *policer3 = &entry3->mp[tc3].policer;
struct pipeline_fa_policer_stats *stats3 = &entry3->mp[tc3].stats;
/* Read (entry), compute, write (entry) */
enum rte_meter_color color2_0 = rte_meter_trtcm_color_aware_check(
meter0,
+ meter0_profile,
time,
total_length0,
color0);
enum rte_meter_color color2_1 = rte_meter_trtcm_color_aware_check(
meter1,
+ meter1_profile,
time,
total_length1,
color1);
enum rte_meter_color color2_2 = rte_meter_trtcm_color_aware_check(
meter2,
+ meter2_profile,
time,
total_length2,
color2);
enum rte_meter_color color2_3 = rte_meter_trtcm_color_aware_check(
meter3,
+ meter3_profile,
time,
total_length3,
color3);
diff --git a/examples/qos_meter/main.c b/examples/qos_meter/main.c
index 7a0df50..1e1370f 100644
--- a/examples/qos_meter/main.c
+++ b/examples/qos_meter/main.c
@@ -92,14 +92,23 @@ static uint16_t port_tx;
static struct rte_mbuf *pkts_rx[PKT_RX_BURST_MAX];
struct rte_eth_dev_tx_buffer *tx_buffer;
-struct rte_meter_srtcm_params app_srtcm_params[] = {
- {.cir = 1000000 * 46, .cbs = 2048, .ebs = 2048},
+struct rte_meter_srtcm_params app_srtcm_params = {
+ .cir = 1000000 * 46,
+ .cbs = 2048,
+ .ebs = 2048
};
-struct rte_meter_trtcm_params app_trtcm_params[] = {
- {.cir = 1000000 * 46, .pir = 1500000 * 46, .cbs = 2048, .pbs = 2048},
+struct rte_meter_srtcm_profile app_srtcm_profile;
+
+struct rte_meter_trtcm_params app_trtcm_params = {
+ .cir = 1000000 * 46,
+ .pir = 1500000 * 46,
+ .cbs = 2048,
+ .pbs = 2048
};
+struct rte_meter_trtcm_profile app_trtcm_profile;
+
#define APP_FLOWS_MAX 256
FLOW_METER app_flows[APP_FLOWS_MAX];
@@ -107,12 +116,21 @@ FLOW_METER app_flows[APP_FLOWS_MAX];
static int
app_configure_flow_table(void)
{
- uint32_t i, j;
+ uint32_t i;
int ret;
- for (i = 0, j = 0; i < APP_FLOWS_MAX;
- i ++, j = (j + 1) % RTE_DIM(PARAMS)) {
- ret = FUNC_CONFIG(&app_flows[i], &PARAMS[j]);
+ ret = rte_meter_srtcm_profile_config(&app_srtcm_profile,
+ &app_srtcm_params);
+ if (ret)
+ return ret;
+
+ ret = rte_meter_trtcm_profile_config(&app_trtcm_profile,
+ &app_trtcm_params);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < APP_FLOWS_MAX; i++) {
+ ret = FUNC_CONFIG(&app_flows[i], &PROFILE);
if (ret)
return ret;
}
@@ -137,7 +155,10 @@ app_pkt_handle(struct rte_mbuf *pkt, uint64_t time)
enum policer_action action;
/* color input is not used for blind modes */
- output_color = (uint8_t) FUNC_METER(&app_flows[flow_id], time, pkt_len,
+ output_color = (uint8_t) FUNC_METER(&app_flows[flow_id],
+ &PROFILE,
+ time,
+ pkt_len,
(enum rte_meter_color) input_color);
/* Apply policing and set the output color */
diff --git a/examples/qos_meter/main.h b/examples/qos_meter/main.h
index b27e8eb..f51eb66 100644
--- a/examples/qos_meter/main.h
+++ b/examples/qos_meter/main.h
@@ -21,44 +21,52 @@ enum policer_action policer_table[e_RTE_METER_COLORS][e_RTE_METER_COLORS] =
#if APP_MODE == APP_MODE_FWD
-#define FUNC_METER(a,b,c,d) color, flow_id=flow_id, pkt_len=pkt_len, time=time
+#define FUNC_METER(m, p, time, pkt_len, pkt_color) \
+({ \
+ void *mp = m; \
+ void *pp = p; \
+ mp = mp; \
+ pp = pp; \
+ time = time; \
+ pkt_len = pkt_len; \
+ pkt_color; \
+})
#define FUNC_CONFIG(a, b) 0
-#define PARAMS app_srtcm_params
#define FLOW_METER int
+#define PROFILE app_srtcm_profile
#elif APP_MODE == APP_MODE_SRTCM_COLOR_BLIND
-#define FUNC_METER(a,b,c,d) rte_meter_srtcm_color_blind_check(a,b,c)
+#define FUNC_METER(m, p, time, pkt_len, pkt_color) \
+ rte_meter_srtcm_color_blind_check(m, p, time, pkt_len)
#define FUNC_CONFIG rte_meter_srtcm_config
-#define PARAMS app_srtcm_params
#define FLOW_METER struct rte_meter_srtcm
+#define PROFILE app_srtcm_profile
#elif (APP_MODE == APP_MODE_SRTCM_COLOR_AWARE)
#define FUNC_METER rte_meter_srtcm_color_aware_check
#define FUNC_CONFIG rte_meter_srtcm_config
-#define PARAMS app_srtcm_params
#define FLOW_METER struct rte_meter_srtcm
+#define PROFILE app_srtcm_profile
#elif (APP_MODE == APP_MODE_TRTCM_COLOR_BLIND)
-#define FUNC_METER(a,b,c,d) rte_meter_trtcm_color_blind_check(a,b,c)
+#define FUNC_METER(m, p, time, pkt_len, pkt_color) \
+ rte_meter_trtcm_color_blind_check(m, p, time, pkt_len)
#define FUNC_CONFIG rte_meter_trtcm_config
-#define PARAMS app_trtcm_params
#define FLOW_METER struct rte_meter_trtcm
+#define PROFILE app_trtcm_profile
#elif (APP_MODE == APP_MODE_TRTCM_COLOR_AWARE)
-#define FUNC_METER rte_meter_trtcm_color_aware_check
+#define FUNC_METER rte_meter_trtcm_color_aware_check
#define FUNC_CONFIG rte_meter_trtcm_config
-#define PARAMS app_trtcm_params
#define FLOW_METER struct rte_meter_trtcm
+#define PROFILE app_trtcm_profile
#else
#error Invalid value for APP_MODE
#endif
-
-
-
#endif /* _MAIN_H_ */
diff --git a/lib/librte_meter/Makefile b/lib/librte_meter/Makefile
index 3b80c6a..2dc071e 100644
--- a/lib/librte_meter/Makefile
+++ b/lib/librte_meter/Makefile
@@ -16,7 +16,7 @@ LDLIBS += -lrte_eal
EXPORT_MAP := rte_meter_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_meter/rte_meter.c b/lib/librte_meter/rte_meter.c
index 332c519..473f69a 100644
--- a/lib/librte_meter/rte_meter.c
+++ b/lib/librte_meter/rte_meter.c
@@ -31,61 +31,82 @@ rte_meter_get_tb_params(uint64_t hz, uint64_t rate, uint64_t *tb_period, uint64_
}
int
-rte_meter_srtcm_config(struct rte_meter_srtcm *m, struct rte_meter_srtcm_params *params)
+rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
+ struct rte_meter_srtcm_params *params)
{
- uint64_t hz;
+ uint64_t hz = rte_get_tsc_hz();
/* Check input parameters */
- if ((m == NULL) || (params == NULL)) {
- return -1;
- }
+ if ((p == NULL) ||
+ (params == NULL) ||
+ (params->cir == 0) ||
+ ((params->cbs == 0) && (params->ebs == 0)))
+ return -EINVAL;
- if ((params->cir == 0) || ((params->cbs == 0) && (params->ebs == 0))) {
- return -2;
- }
+ /* Initialize srTCM run-time structure */
+ p->cbs = params->cbs;
+ p->ebs = params->ebs;
+ rte_meter_get_tb_params(hz, params->cir, &p->cir_period,
+ &p->cir_bytes_per_period);
+
+ return 0;
+}
+
+int
+rte_meter_srtcm_config(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p)
+{
+ /* Check input parameters */
+ if ((m == NULL) || (p == NULL))
+ return -EINVAL;
/* Initialize srTCM run-time structure */
- hz = rte_get_tsc_hz();
m->time = rte_get_tsc_cycles();
- m->tc = m->cbs = params->cbs;
- m->te = m->ebs = params->ebs;
- rte_meter_get_tb_params(hz, params->cir, &m->cir_period, &m->cir_bytes_per_period);
-
- RTE_LOG(INFO, METER, "Low level srTCM config: \n"
- "\tCIR period = %" PRIu64 ", CIR bytes per period = %" PRIu64 "\n",
- m->cir_period, m->cir_bytes_per_period);
+ m->tc = p->cbs;
+ m->te = p->ebs;
return 0;
}
int
-rte_meter_trtcm_config(struct rte_meter_trtcm *m, struct rte_meter_trtcm_params *params)
+rte_meter_trtcm_profile_config(struct rte_meter_trtcm_profile *p,
+ struct rte_meter_trtcm_params *params)
{
- uint64_t hz;
+ uint64_t hz = rte_get_tsc_hz();
/* Check input parameters */
- if ((m == NULL) || (params == NULL)) {
- return -1;
- }
+ if ((p == NULL) ||
+ (params == NULL) ||
+ (params->cir == 0) ||
+ (params->pir == 0) ||
+ (params->pir < params->cir) ||
+ (params->cbs == 0) ||
+ (params->pbs == 0))
+ return -EINVAL;
- if ((params->cir == 0) || (params->pir == 0) || (params->pir < params->cir) ||
- (params->cbs == 0) || (params->pbs == 0)) {
- return -2;
- }
+ /* Initialize trTCM run-time structure */
+ p->cbs = params->cbs;
+ p->pbs = params->pbs;
+ rte_meter_get_tb_params(hz, params->cir, &p->cir_period,
+ &p->cir_bytes_per_period);
+ rte_meter_get_tb_params(hz, params->pir, &p->pir_period,
+ &p->pir_bytes_per_period);
+
+ return 0;
+}
+
+int
+rte_meter_trtcm_config(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p)
+{
+ /* Check input parameters */
+ if ((m == NULL) || (p == NULL))
+ return -EINVAL;
/* Initialize trTCM run-time structure */
- hz = rte_get_tsc_hz();
m->time_tc = m->time_tp = rte_get_tsc_cycles();
- m->tc = m->cbs = params->cbs;
- m->tp = m->pbs = params->pbs;
- rte_meter_get_tb_params(hz, params->cir, &m->cir_period, &m->cir_bytes_per_period);
- rte_meter_get_tb_params(hz, params->pir, &m->pir_period, &m->pir_bytes_per_period);
-
- RTE_LOG(INFO, METER, "Low level trTCM config: \n"
- "\tCIR period = %" PRIu64 ", CIR bytes per period = %" PRIu64 "\n"
- "\tPIR period = %" PRIu64 ", PIR bytes per period = %" PRIu64 "\n",
- m->cir_period, m->cir_bytes_per_period,
- m->pir_period, m->pir_bytes_per_period);
+ m->tc = p->cbs;
+ m->tp = p->pbs;
return 0;
}
diff --git a/lib/librte_meter/rte_meter.h b/lib/librte_meter/rte_meter.h
index ebdc453..29b46bb 100644
--- a/lib/librte_meter/rte_meter.h
+++ b/lib/librte_meter/rte_meter.h
@@ -53,6 +53,18 @@ struct rte_meter_trtcm_params {
uint64_t pbs; /**< Peak Burst Size (PBS). Measured in bytes. */
};
+/**
+ * Internal data structure storing the srTCM configuration profile. Typically
+ * shared by multiple srTCM objects.
+ */
+struct rte_meter_srtcm_profile;
+
+/**
+ * Internal data structure storing the trTCM configuration profile. Typically
+ * shared by multiple trTCM objects.
+ */
+struct rte_meter_trtcm_profile;
+
/** Internal data structure storing the srTCM run-time context per metered traffic flow. */
struct rte_meter_srtcm;
@@ -60,38 +72,66 @@ struct rte_meter_srtcm;
struct rte_meter_trtcm;
/**
+ * srTCM profile configuration
+ *
+ * @param p
+ * Pointer to pre-allocated srTCM profile data structure
+ * @param params
+ * srTCM profile parameters
+ * @return
+ * 0 upon success, error code otherwise
+ */
+int rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
+ struct rte_meter_srtcm_params *params);
+
+/**
+ * trTCM profile configuration
+ *
+ * @param p
+ * Pointer to pre-allocated trTCM profile data structure
+ * @param params
+ * trTCM profile parameters
+ * @return
+ * 0 upon success, error code otherwise
+ */
+int rte_meter_trtcm_profile_config(struct rte_meter_trtcm_profile *p,
+ struct rte_meter_trtcm_params *params);
+
+/**
* srTCM configuration per metered traffic flow
*
* @param m
* Pointer to pre-allocated srTCM data structure
- * @param params
- * User parameters per srTCM metered traffic flow
+ * @param p
+ * srTCM profile. Needs to be valid.
* @return
* 0 upon success, error code otherwise
*/
int
rte_meter_srtcm_config(struct rte_meter_srtcm *m,
- struct rte_meter_srtcm_params *params);
+ struct rte_meter_srtcm_profile *p);
/**
* trTCM configuration per metered traffic flow
*
* @param m
* Pointer to pre-allocated trTCM data structure
- * @param params
- * User parameters per trTCM metered traffic flow
+ * @param p
+ * trTCM profile. Needs to be valid.
* @return
* 0 upon success, error code otherwise
*/
int
rte_meter_trtcm_config(struct rte_meter_trtcm *m,
- struct rte_meter_trtcm_params *params);
+ struct rte_meter_trtcm_profile *p);
/**
* srTCM color blind traffic metering
*
* @param m
* Handle to srTCM instance
+ * @param p
+ * srTCM profile specified at srTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -101,6 +141,7 @@ rte_meter_trtcm_config(struct rte_meter_trtcm *m,
*/
static inline enum rte_meter_color
rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len);
@@ -109,6 +150,8 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
*
* @param m
* Handle to srTCM instance
+ * @param p
+ * srTCM profile specified at srTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -120,6 +163,7 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
*/
static inline enum rte_meter_color
rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color);
@@ -129,6 +173,8 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
*
* @param m
* Handle to trTCM instance
+ * @param p
+ * trTCM profile specified at trTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -138,6 +184,7 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
*/
static inline enum rte_meter_color
rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len);
@@ -146,6 +193,8 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
*
* @param m
* Handle to trTCM instance
+ * @param p
+ * trTCM profile specified at trTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -157,6 +206,7 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
*/
static inline enum rte_meter_color
rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color);
@@ -166,33 +216,57 @@ rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
*
***/
+struct rte_meter_srtcm_profile {
+ uint64_t cbs;
+ /**< Upper limit for C token bucket */
+ uint64_t ebs;
+ /**< Upper limit for E token bucket */
+ uint64_t cir_period;
+ /**< Number of CPU cycles for each update of C and E token buckets */
+ uint64_t cir_bytes_per_period;
+ /**< Number of bytes to add to C and E token buckets on each update */
+};
+
/* Internal data structure storing the srTCM run-time context per metered traffic flow. */
struct rte_meter_srtcm {
uint64_t time; /* Time of latest update of C and E token buckets */
uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
uint64_t te; /* Number of bytes currently available in the excess (E) token bucket */
- uint64_t cbs; /* Upper limit for C token bucket */
- uint64_t ebs; /* Upper limit for E token bucket */
- uint64_t cir_period; /* Number of CPU cycles for one update of C and E token buckets */
- uint64_t cir_bytes_per_period; /* Number of bytes to add to C and E token buckets on each update */
};
-/* Internal data structure storing the trTCM run-time context per metered traffic flow. */
+struct rte_meter_trtcm_profile {
+ uint64_t cbs;
+ /**< Upper limit for C token bucket */
+ uint64_t pbs;
+ /**< Upper limit for P token bucket */
+ uint64_t cir_period;
+ /**< Number of CPU cycles for one update of C token bucket */
+ uint64_t cir_bytes_per_period;
+ /**< Number of bytes to add to C token bucket on each update */
+ uint64_t pir_period;
+ /**< Number of CPU cycles for one update of P token bucket */
+ uint64_t pir_bytes_per_period;
+ /**< Number of bytes to add to P token bucket on each update */
+};
+
+/**
+ * Internal data structure storing the trTCM run-time context per metered
+ * traffic flow.
+ */
struct rte_meter_trtcm {
- uint64_t time_tc; /* Time of latest update of C token bucket */
- uint64_t time_tp; /* Time of latest update of E token bucket */
- uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
- uint64_t tp; /* Number of bytes currently available in the peak (P) token bucket */
- uint64_t cbs; /* Upper limit for C token bucket */
- uint64_t pbs; /* Upper limit for P token bucket */
- uint64_t cir_period; /* Number of CPU cycles for one update of C token bucket */
- uint64_t cir_bytes_per_period; /* Number of bytes to add to C token bucket on each update */
- uint64_t pir_period; /* Number of CPU cycles for one update of P token bucket */
- uint64_t pir_bytes_per_period; /* Number of bytes to add to P token bucket on each update */
+ uint64_t time_tc;
+ /**< Time of latest update of C token bucket */
+ uint64_t time_tp;
+ /**< Time of latest update of E token bucket */
+ uint64_t tc;
+ /**< Number of bytes currently available in committed(C) token bucket */
+ uint64_t tp;
+ /**< Number of bytes currently available in the peak(P) token bucket */
};
static inline enum rte_meter_color
rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len)
{
@@ -200,17 +274,17 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
/* Bucket update */
time_diff = time - m->time;
- n_periods = time_diff / m->cir_period;
- m->time += n_periods * m->cir_period;
+ n_periods = time_diff / p->cir_period;
+ m->time += n_periods * p->cir_period;
/* Put the tokens overflowing from tc into te bucket */
- tc = m->tc + n_periods * m->cir_bytes_per_period;
+ tc = m->tc + n_periods * p->cir_bytes_per_period;
te = m->te;
- if (tc > m->cbs) {
- te += (tc - m->cbs);
- if (te > m->ebs)
- te = m->ebs;
- tc = m->cbs;
+ if (tc > p->cbs) {
+ te += (tc - p->cbs);
+ if (te > p->ebs)
+ te = p->ebs;
+ tc = p->cbs;
}
/* Color logic */
@@ -233,6 +307,7 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
static inline enum rte_meter_color
rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color)
@@ -241,17 +316,17 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
/* Bucket update */
time_diff = time - m->time;
- n_periods = time_diff / m->cir_period;
- m->time += n_periods * m->cir_period;
+ n_periods = time_diff / p->cir_period;
+ m->time += n_periods * p->cir_period;
/* Put the tokens overflowing from tc into te bucket */
- tc = m->tc + n_periods * m->cir_bytes_per_period;
+ tc = m->tc + n_periods * p->cir_bytes_per_period;
te = m->te;
- if (tc > m->cbs) {
- te += (tc - m->cbs);
- if (te > m->ebs)
- te = m->ebs;
- tc = m->cbs;
+ if (tc > p->cbs) {
+ te += (tc - p->cbs);
+ if (te > p->ebs)
+ te = p->ebs;
+ tc = p->cbs;
}
/* Color logic */
@@ -274,6 +349,7 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
static inline enum rte_meter_color
rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len)
{
@@ -282,18 +358,18 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
/* Bucket update */
time_diff_tc = time - m->time_tc;
time_diff_tp = time - m->time_tp;
- n_periods_tc = time_diff_tc / m->cir_period;
- n_periods_tp = time_diff_tp / m->pir_period;
- m->time_tc += n_periods_tc * m->cir_period;
- m->time_tp += n_periods_tp * m->pir_period;
+ n_periods_tc = time_diff_tc / p->cir_period;
+ n_periods_tp = time_diff_tp / p->pir_period;
+ m->time_tc += n_periods_tc * p->cir_period;
+ m->time_tp += n_periods_tp * p->pir_period;
- tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
- if (tc > m->cbs)
- tc = m->cbs;
+ tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
+ if (tc > p->cbs)
+ tc = p->cbs;
- tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
- if (tp > m->pbs)
- tp = m->pbs;
+ tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
+ if (tp > p->pbs)
+ tp = p->pbs;
/* Color logic */
if (tp < pkt_len) {
@@ -315,6 +391,7 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
static inline enum rte_meter_color
rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color)
@@ -324,18 +401,18 @@ rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
/* Bucket update */
time_diff_tc = time - m->time_tc;
time_diff_tp = time - m->time_tp;
- n_periods_tc = time_diff_tc / m->cir_period;
- n_periods_tp = time_diff_tp / m->pir_period;
- m->time_tc += n_periods_tc * m->cir_period;
- m->time_tp += n_periods_tp * m->pir_period;
-
- tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
- if (tc > m->cbs)
- tc = m->cbs;
-
- tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
- if (tp > m->pbs)
- tp = m->pbs;
+ n_periods_tc = time_diff_tc / p->cir_period;
+ n_periods_tp = time_diff_tp / p->pir_period;
+ m->time_tc += n_periods_tc * p->cir_period;
+ m->time_tp += n_periods_tp * p->pir_period;
+
+ tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
+ if (tc > p->cbs)
+ tc = p->cbs;
+
+ tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
+ if (tp > p->pbs)
+ tp = p->pbs;
/* Color logic */
if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index 2fd647c..c4422ef 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -10,3 +10,11 @@ DPDK_2.0 {
local: *;
};
+
+DPDK_18.02 {
+ global:
+
+ rte_meter_srtcm_profile_config;
+ rte_meter_trtcm_profile_config;
+
+} DPDK_2.0;
diff --git a/test/test/test_meter.c b/test/test/test_meter.c
index 9f6abf9..8bb47e7 100644
--- a/test/test/test_meter.c
+++ b/test/test/test_meter.c
@@ -53,43 +53,43 @@ static inline int
tm_test_srtcm_config(void)
{
#define SRTCM_CFG_MSG "srtcm_config"
- struct rte_meter_srtcm sm;
+ struct rte_meter_srtcm_profile sp;
struct rte_meter_srtcm_params sparams1;
/* invalid parameter test */
- if(rte_meter_srtcm_config(NULL, NULL) == 0)
+ if (rte_meter_srtcm_profile_config(NULL, NULL) == 0)
melog(SRTCM_CFG_MSG);
- if(rte_meter_srtcm_config(&sm, NULL) == 0)
+ if (rte_meter_srtcm_profile_config(&sp, NULL) == 0)
melog(SRTCM_CFG_MSG);
- if(rte_meter_srtcm_config(NULL, &sparams) == 0)
+ if (rte_meter_srtcm_profile_config(NULL, &sparams) == 0)
melog(SRTCM_CFG_MSG);
/* cbs and ebs can't both be zero */
sparams1 = sparams;
sparams1.cbs = 0;
sparams1.ebs = 0;
- if(rte_meter_srtcm_config(&sm, &sparams1) == 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams1) == 0)
melog(SRTCM_CFG_MSG);
/* cir should never be 0 */
sparams1 = sparams;
sparams1.cir = 0;
- if(rte_meter_srtcm_config(&sm, &sparams1) == 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams1) == 0)
melog(SRTCM_CFG_MSG);
/* one of ebs and cbs can be zero, should be successful */
sparams1 = sparams;
sparams1.ebs = 0;
- if(rte_meter_srtcm_config(&sm, &sparams1) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams1) != 0)
melog(SRTCM_CFG_MSG);
sparams1 = sparams;
sparams1.cbs = 0;
- if(rte_meter_srtcm_config(&sm, &sparams1) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams1) != 0)
melog(SRTCM_CFG_MSG);
/* usual parameter, should be successful */
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
melog(SRTCM_CFG_MSG);
return 0;
@@ -102,47 +102,47 @@ tm_test_srtcm_config(void)
static inline int
tm_test_trtcm_config(void)
{
- struct rte_meter_trtcm tm;
+ struct rte_meter_trtcm_profile tp;
struct rte_meter_trtcm_params tparams1;
#define TRTCM_CFG_MSG "trtcm_config"
/* invalid parameter test */
- if(rte_meter_trtcm_config(NULL, NULL) == 0)
+ if (rte_meter_trtcm_profile_config(NULL, NULL) == 0)
melog(TRTCM_CFG_MSG);
- if(rte_meter_trtcm_config(&tm, NULL) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, NULL) == 0)
melog(TRTCM_CFG_MSG);
- if(rte_meter_trtcm_config(NULL, &tparams) == 0)
+ if (rte_meter_trtcm_profile_config(NULL, &tparams) == 0)
melog(TRTCM_CFG_MSG);
/* cir, cbs, pir and pbs never be zero */
tparams1 = tparams;
tparams1.cir = 0;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
tparams1 = tparams;
tparams1.cbs = 0;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
tparams1 = tparams;
tparams1.pbs = 0;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
tparams1 = tparams;
tparams1.pir = 0;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
/* pir should be greater or equal to cir */
tparams1 = tparams;
tparams1.pir = tparams1.cir - 1;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG" pir < cir test");
/* usual parameter, should be successful */
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
melog(TRTCM_CFG_MSG);
return 0;
@@ -155,41 +155,50 @@ static inline int
tm_test_srtcm_color_blind_check(void)
{
#define SRTCM_BLIND_CHECK_MSG "srtcm_blind_check"
+ struct rte_meter_srtcm_profile sp;
struct rte_meter_srtcm sm;
uint64_t time;
uint64_t hz = rte_get_tsc_hz();
/* Test green */
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_blind_check(
- &sm, time, TM_TEST_SRTCM_CBS_DF - 1)
+ if (rte_meter_srtcm_color_blind_check(
+ &sm, &sp, time, TM_TEST_SRTCM_CBS_DF - 1)
!= e_RTE_METER_GREEN)
melog(SRTCM_BLIND_CHECK_MSG" GREEN");
/* Test yellow */
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_blind_check(
- &sm, time, TM_TEST_SRTCM_CBS_DF + 1)
+ if (rte_meter_srtcm_color_blind_check(
+ &sm, &sp, time, TM_TEST_SRTCM_CBS_DF + 1)
!= e_RTE_METER_YELLOW)
melog(SRTCM_BLIND_CHECK_MSG" YELLOW");
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_blind_check(
- &sm, time, (uint32_t)sm.ebs - 1) != e_RTE_METER_YELLOW)
+ if (rte_meter_srtcm_color_blind_check(
+ &sm, &sp, time, (uint32_t)sp.ebs - 1) != e_RTE_METER_YELLOW)
melog(SRTCM_BLIND_CHECK_MSG" YELLOW");
/* Test red */
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_blind_check(
- &sm, time, TM_TEST_SRTCM_EBS_DF + 1)
+ if (rte_meter_srtcm_color_blind_check(
+ &sm, &sp, time, TM_TEST_SRTCM_EBS_DF + 1)
!= e_RTE_METER_RED)
melog(SRTCM_BLIND_CHECK_MSG" RED");
@@ -206,41 +215,50 @@ tm_test_trtcm_color_blind_check(void)
#define TRTCM_BLIND_CHECK_MSG "trtcm_blind_check"
uint64_t time;
+ struct rte_meter_trtcm_profile tp;
struct rte_meter_trtcm tm;
uint64_t hz = rte_get_tsc_hz();
/* Test green */
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_blind_check(
- &tm, time, TM_TEST_TRTCM_CBS_DF - 1)
+ if (rte_meter_trtcm_color_blind_check(
+ &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1)
!= e_RTE_METER_GREEN)
melog(TRTCM_BLIND_CHECK_MSG" GREEN");
/* Test yellow */
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_blind_check(
- &tm, time, TM_TEST_TRTCM_CBS_DF + 1)
+ if (rte_meter_trtcm_color_blind_check(
+ &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1)
!= e_RTE_METER_YELLOW)
melog(TRTCM_BLIND_CHECK_MSG" YELLOW");
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_blind_check(
- &tm, time, TM_TEST_TRTCM_PBS_DF - 1)
+ if (rte_meter_trtcm_color_blind_check(
+ &tm, &tp, time, TM_TEST_TRTCM_PBS_DF - 1)
!= e_RTE_METER_YELLOW)
melog(TRTCM_BLIND_CHECK_MSG" YELLOW");
/* Test red */
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_blind_check(
- &tm, time, TM_TEST_TRTCM_PBS_DF + 1)
+ if (rte_meter_trtcm_color_blind_check(
+ &tm, &tp, time, TM_TEST_TRTCM_PBS_DF + 1)
!= e_RTE_METER_RED)
melog(TRTCM_BLIND_CHECK_MSG" RED");
@@ -262,36 +280,45 @@ tm_test_srtcm_aware_check
(enum rte_meter_color in[4], enum rte_meter_color out[4])
{
#define SRTCM_AWARE_CHECK_MSG "srtcm_aware_check"
+ struct rte_meter_srtcm_profile sp;
struct rte_meter_srtcm sm;
uint64_t time;
uint64_t hz = rte_get_tsc_hz();
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_aware_check(
- &sm, time, TM_TEST_SRTCM_CBS_DF - 1, in[0]) != out[0])
+ if (rte_meter_srtcm_color_aware_check(
+ &sm, &sp, time, TM_TEST_SRTCM_CBS_DF - 1, in[0]) != out[0])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]);
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_aware_check(
- &sm, time, TM_TEST_SRTCM_CBS_DF + 1, in[1]) != out[1])
+ if (rte_meter_srtcm_color_aware_check(
+ &sm, &sp, time, TM_TEST_SRTCM_CBS_DF + 1, in[1]) != out[1])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]);
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_aware_check(
- &sm, time, TM_TEST_SRTCM_EBS_DF - 1, in[2]) != out[2])
+ if (rte_meter_srtcm_color_aware_check(
+ &sm, &sp, time, TM_TEST_SRTCM_EBS_DF - 1, in[2]) != out[2])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]);
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_aware_check(
- &sm, time, TM_TEST_SRTCM_EBS_DF + 1, in[3]) != out[3])
+ if (rte_meter_srtcm_color_aware_check(
+ &sm, &sp, time, TM_TEST_SRTCM_EBS_DF + 1, in[3]) != out[3])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]);
return 0;
@@ -317,7 +344,7 @@ tm_test_srtcm_color_aware_check(void)
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
- if(tm_test_srtcm_aware_check(in, out) != 0)
+ if (tm_test_srtcm_aware_check(in, out) != 0)
return -1;
/**
@@ -329,7 +356,7 @@ tm_test_srtcm_color_aware_check(void)
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
- if(tm_test_srtcm_aware_check(in, out) != 0)
+ if (tm_test_srtcm_aware_check(in, out) != 0)
return -1;
/**
@@ -341,7 +368,7 @@ tm_test_srtcm_color_aware_check(void)
out[1] = e_RTE_METER_RED;
out[2] = e_RTE_METER_RED;
out[3] = e_RTE_METER_RED;
- if(tm_test_srtcm_aware_check(in, out) != 0)
+ if (tm_test_srtcm_aware_check(in, out) != 0)
return -1;
return 0;
@@ -360,36 +387,45 @@ tm_test_trtcm_aware_check
(enum rte_meter_color in[4], enum rte_meter_color out[4])
{
#define TRTCM_AWARE_CHECK_MSG "trtcm_aware_check"
+ struct rte_meter_trtcm_profile tp;
struct rte_meter_trtcm tm;
uint64_t time;
uint64_t hz = rte_get_tsc_hz();
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_aware_check(
- &tm, time, TM_TEST_TRTCM_CBS_DF - 1, in[0]) != out[0])
+ if (rte_meter_trtcm_color_aware_check(
+ &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1, in[0]) != out[0])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]);
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_aware_check(
- &tm, time, TM_TEST_TRTCM_CBS_DF + 1, in[1]) != out[1])
+ if (rte_meter_trtcm_color_aware_check(
+ &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1, in[1]) != out[1])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]);
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_aware_check(
- &tm, time, TM_TEST_TRTCM_PBS_DF - 1, in[2]) != out[2])
+ if (rte_meter_trtcm_color_aware_check(
+ &tm, &tp, time, TM_TEST_TRTCM_PBS_DF - 1, in[2]) != out[2])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]);
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_aware_check(
- &tm, time, TM_TEST_TRTCM_PBS_DF + 1, in[3]) != out[3])
+ if (rte_meter_trtcm_color_aware_check(
+ &tm, &tp, time, TM_TEST_TRTCM_PBS_DF + 1, in[3]) != out[3])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]);
return 0;
@@ -415,7 +451,7 @@ tm_test_trtcm_color_aware_check(void)
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
- if(tm_test_trtcm_aware_check(in, out) != 0)
+ if (tm_test_trtcm_aware_check(in, out) != 0)
return -1;
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_YELLOW;
@@ -423,7 +459,7 @@ tm_test_trtcm_color_aware_check(void)
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
- if(tm_test_trtcm_aware_check(in, out) != 0)
+ if (tm_test_trtcm_aware_check(in, out) != 0)
return -1;
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_RED;
@@ -431,7 +467,7 @@ tm_test_trtcm_color_aware_check(void)
out[1] = e_RTE_METER_RED;
out[2] = e_RTE_METER_RED;
out[3] = e_RTE_METER_RED;
- if(tm_test_trtcm_aware_check(in, out) != 0)
+ if (tm_test_trtcm_aware_check(in, out) != 0)
return -1;
return 0;
@@ -443,22 +479,22 @@ tm_test_trtcm_color_aware_check(void)
static int
test_meter(void)
{
- if(tm_test_srtcm_config() != 0 )
+ if (tm_test_srtcm_config() != 0)
return -1;
- if(tm_test_trtcm_config() != 0 )
+ if (tm_test_trtcm_config() != 0)
return -1;
- if(tm_test_srtcm_color_blind_check() != 0)
+ if (tm_test_srtcm_color_blind_check() != 0)
return -1;
- if(tm_test_trtcm_color_blind_check()!= 0)
+ if (tm_test_trtcm_color_blind_check() != 0)
return -1;
- if(tm_test_srtcm_color_aware_check()!= 0)
+ if (tm_test_srtcm_color_aware_check() != 0)
return -1;
- if(tm_test_trtcm_color_aware_check()!= 0)
+ if (tm_test_trtcm_color_aware_check() != 0)
return -1;
return 0;
--
2.9.3
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] [PATCH] ethdev: fix setting of MAC address
2018-01-03 14:12 4% ` Andrew Rybchenko
@ 2018-01-08 11:59 3% ` Ferruh Yigit
2018-01-08 14:23 0% ` Olivier Matz
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-01-08 11:59 UTC (permalink / raw)
To: Andrew Rybchenko, Olivier Matz
Cc: Ivan Malov, Igor Ryzhov, dev, Thomas Monjalon, Laurent Hardy, stable
On 1/3/2018 2:12 PM, Andrew Rybchenko wrote:
> On 01/03/2018 04:54 PM, Olivier Matz wrote:
>> On Wed, Jan 03, 2018 at 02:43:59PM +0100, Olivier Matz wrote:
>>> I've walked through the PMDs as suggested by Andrew, and there was
>>> indeed some conflicts with the initial patch. I've just submitted the
>>> patch for vmxnet3 [1] and bnxt [2].
>>>
>>> But there is still an issue with the qede driver, that overwrites the
>>> MAC address in dev->data by the previous one if it cannot be set. It
>>> seems it's the only driver that does this in error case, but anyway,
>>> this behavior will be broken by the initial patch.
>>>
>>> So I submitted a v2 that only changes the behavior for i40evf [3].
>>>
>>> I propose to include these 3 patches for 18.02, and announce an ABI
>>> change for 18.05 to add a return value to dev_ops->mac_addr_set() and
>>> move the ether_addr_copy() after the callback, only in case of success.
>>>
>>> Any opinions?
>
> I'm not sure if dev_ops->mac_addr_set() is a part of ABI.
> It is an internal interface between rte_ethdev library and drivers. Yes, out-of-tree
> drivers will be broken.
> rte_eth_dev_default_mac_addr_set() is definitely a part of API/ABI, but it already
> has return value.
> So, I'm not sure that we have to wait for 18.05, but it is still may be too late for
> 18.02 since integration deadline is pretty close.
I think there is no API/ABI breakage, but it can be good to announce the change
and give time for modifications.
+1 for proposal.
>
>> [1] https://dpdk.org/dev/patchwork/patch/32855/
>> [2] https://dpdk.org/dev/patchwork/patch/32856/
>> [3] https://dpdk.org/dev/patchwork/patch/32857/
>
> Many thanks for drivers review and fixes.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 0/2] vhost: introduce rte_vhost_vring_call()
2018-01-03 8:17 0% ` Maxime Coquelin
@ 2018-01-08 13:46 0% ` Yuanhan Liu
0 siblings, 0 replies; 200+ results
From: Yuanhan Liu @ 2018-01-08 13:46 UTC (permalink / raw)
To: Maxime Coquelin; +Cc: Stefan Hajnoczi, dev, Tetsuya Mukawa, Thomas Monjalon
On Wed, Jan 03, 2018 at 09:17:32AM +0100, Maxime Coquelin wrote:
> >>Reviewed-by: Maxime Coquelin <maxime.coquelin@redhat.com>
> >
> > From 3.2. Managing ABI updates, General Guidelines:
> >
> > New APIs will be marked as experimental for at least one release to
> > allow any issues found by users of the new API to be fixed quickly.
> >
> >http://dpdk.org/doc/guides/contributing/versioning.html
> >
> >I'm new to DPDK so I followed this guideline strictly and expect the
> >maintainers to mark the API stable at some point in the future when they
> >are happy with it. Maybe this guideline isn't followed strictly for
> >librte_vhost?
>
> Thanks for the pointer, it seems it is not strictly followed for
> librte_vhost & other libs. Let's keep it experimental for the coming
> release.
IIRC, it's a new guideline added recently (people were talking about
that in last year's DPDK user event after all).
And my understanding is, for a new (big set of) APIs, it's good to
make them experimental, as normally, it's not an easy task to make
a big stuff right in one time.
For this one, which is simple and straightforward, I don't see a
strong need to mark it as experimental.
Thus I have removed it (while apply). If anyone has objections,
let me know.
Thanks.
--yliu
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: fix setting of MAC address
2018-01-08 11:59 3% ` Ferruh Yigit
@ 2018-01-08 14:23 0% ` Olivier Matz
0 siblings, 0 replies; 200+ results
From: Olivier Matz @ 2018-01-08 14:23 UTC (permalink / raw)
To: Ferruh Yigit
Cc: Andrew Rybchenko, Ivan Malov, Igor Ryzhov, dev, Thomas Monjalon,
Laurent Hardy, stable
On Mon, Jan 08, 2018 at 11:59:09AM +0000, Ferruh Yigit wrote:
> On 1/3/2018 2:12 PM, Andrew Rybchenko wrote:
> > On 01/03/2018 04:54 PM, Olivier Matz wrote:
> >> On Wed, Jan 03, 2018 at 02:43:59PM +0100, Olivier Matz wrote:
> >>> I've walked through the PMDs as suggested by Andrew, and there was
> >>> indeed some conflicts with the initial patch. I've just submitted the
> >>> patch for vmxnet3 [1] and bnxt [2].
> >>>
> >>> But there is still an issue with the qede driver, that overwrites the
> >>> MAC address in dev->data by the previous one if it cannot be set. It
> >>> seems it's the only driver that does this in error case, but anyway,
> >>> this behavior will be broken by the initial patch.
> >>>
> >>> So I submitted a v2 that only changes the behavior for i40evf [3].
> >>>
> >>> I propose to include these 3 patches for 18.02, and announce an ABI
> >>> change for 18.05 to add a return value to dev_ops->mac_addr_set() and
> >>> move the ether_addr_copy() after the callback, only in case of success.
> >>>
> >>> Any opinions?
> >
> > I'm not sure if dev_ops->mac_addr_set() is a part of ABI.
> > It is an internal interface between rte_ethdev library and drivers. Yes, out-of-tree
> > drivers will be broken.
> > rte_eth_dev_default_mac_addr_set() is definitely a part of API/ABI, but it already
> > has return value.
> > So, I'm not sure that we have to wait for 18.05, but it is still may be too late for
> > 18.02 since integration deadline is pretty close.
>
> I think there is no API/ABI breakage, but it can be good to announce the change
> and give time for modifications.
>
> +1 for proposal.
Thanks Andrew and Ferruh for the feedback.
I'll send an RFC for this soon.
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v4] lib/librte_meter: add meter configuration profile
2018-01-08 10:00 1% ` [dpdk-dev] [PATCH v3] lib/librte_meter: add meter configuration profile Jasvinder Singh
@ 2018-01-08 15:43 1% ` Jasvinder Singh
0 siblings, 0 replies; 200+ results
From: Jasvinder Singh @ 2018-01-08 15:43 UTC (permalink / raw)
To: dev; +Cc: cristian.dumitrescu
From: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
This patch adds support for meter configuration profiles.
Benefits: simplified configuration procedure, improved performance.
Q1: What is the configuration profile and why does it make sense?
A1: The configuration profile represents the set of configuration
parameters for a given meter object, such as the rates and sizes for
the token buckets. The configuration profile concept makes sense when
many meter objects share the same configuration, which is the typical
usage model: thousands of traffic flows are each individually metered
according to just a few service levels (i.e. profiles).
Q2: How is the configuration profile improving the performance?
A2: The performance improvement is achieved by reducing the memory
footprint of a meter object, which results in better cache utilization
for the typical case when large arrays of meter objects are used. The
internal data structures stored for each meter object contain:
a) Constant fields: Low level translation of the configuration
parameters that does not change post-configuration. This is
really duplicated for all meters that use the same
configuration. This is the configuration profile data that is
moved away from the meter object. Current size (implementation
dependent): srTCM = 32 bytes, trTCM = 32 bytes.
b) Variable fields: Time stamps and running counters that change
during the on-going traffic metering process. Current size
(implementation dependant): srTCM = 24 bytes, trTCM = 32 bytes.
Therefore, by moving the constant fields to a separate profile
data structure shared by all the meters with the same
configuration, the size of the meter object is reduced by ~50%.
Signed-off-by: Cristian Dumitrescu <cristian.dumitrescu@intel.com>
Signed-off-by: Jasvinder Singh <jasvinder.singh@intel.com>
---
V4:
- change commit message
v3:
- fix doxygen comments
v2:
- fix checkpatch warnings
- fix build error in ip_pipeline sample app
doc/guides/rel_notes/deprecation.rst | 3 -
doc/guides/rel_notes/release_18_02.rst | 2 +-
.../pipeline/pipeline_flow_actions_be.c | 25 ++-
examples/qos_meter/main.c | 39 ++++-
examples/qos_meter/main.h | 32 ++--
lib/librte_meter/Makefile | 2 +-
lib/librte_meter/rte_meter.c | 93 ++++++----
lib/librte_meter/rte_meter.h | 195 ++++++++++++++-------
lib/librte_meter/rte_meter_version.map | 8 +
test/test/test_meter.c | 194 +++++++++++---------
10 files changed, 392 insertions(+), 201 deletions(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..6ba5ffd 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -50,6 +50,3 @@ Deprecation Notices
required the previous behavior can be configured using existing flow
director APIs. There is no ABI/API break. This change will just remove a
global configuration setting and require explicit configuration.
-
-* librte_meter: The API will change to accommodate configuration profiles.
- Most of the API functions will have an additional opaque parameter.
diff --git a/doc/guides/rel_notes/release_18_02.rst b/doc/guides/rel_notes/release_18_02.rst
index 24b67bb..7343b74 100644
--- a/doc/guides/rel_notes/release_18_02.rst
+++ b/doc/guides/rel_notes/release_18_02.rst
@@ -141,7 +141,7 @@ The libraries prepended with a plus sign were incremented in this version.
librte_lpm.so.2
librte_mbuf.so.3
librte_mempool.so.3
- librte_meter.so.1
+ + librte_meter.so.2
librte_metrics.so.1
librte_net.so.1
librte_pci.so.1
diff --git a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
index 9599b7d..33f1c41 100644
--- a/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
+++ b/examples/ip_pipeline/pipeline/pipeline_flow_actions_be.c
@@ -111,6 +111,7 @@ static pipeline_msg_req_handler custom_handlers[] = {
*/
struct meter_policer {
struct rte_meter_trtcm meter;
+ struct rte_meter_trtcm_profile meter_profile;
struct pipeline_fa_policer_params policer;
struct pipeline_fa_policer_stats stats;
};
@@ -127,8 +128,15 @@ flow_table_entry_set_meter(struct flow_table_entry *entry,
{
struct rte_meter_trtcm *meter = &entry->mp[meter_id].meter;
struct rte_meter_trtcm_params *meter_params = ¶ms->m[meter_id];
+ struct rte_meter_trtcm_profile *meter_profile =
+ &entry->mp[meter_id].meter_profile;
+ int status;
- return rte_meter_trtcm_config(meter, meter_params);
+ status = rte_meter_trtcm_profile_config(meter_profile, meter_params);
+ if (status)
+ return status;
+
+ return rte_meter_trtcm_config(meter, meter_profile);
}
static void
@@ -202,11 +210,14 @@ pkt_work(
enum rte_meter_color color = p->dscp[dscp].color;
struct rte_meter_trtcm *meter = &entry->mp[tc].meter;
+ struct rte_meter_trtcm_profile *meter_profile =
+ &entry->mp[tc].meter_profile;
struct pipeline_fa_policer_params *policer = &entry->mp[tc].policer;
struct pipeline_fa_policer_stats *stats = &entry->mp[tc].stats;
/* Read (entry), compute */
enum rte_meter_color color2 = rte_meter_trtcm_color_aware_check(meter,
+ meter_profile,
time,
total_length,
color);
@@ -284,42 +295,54 @@ pkt4_work(
enum rte_meter_color color3 = p->dscp[dscp3].color;
struct rte_meter_trtcm *meter0 = &entry0->mp[tc0].meter;
+ struct rte_meter_trtcm_profile *meter0_profile =
+ &entry0->mp[tc0].meter_profile;
struct pipeline_fa_policer_params *policer0 = &entry0->mp[tc0].policer;
struct pipeline_fa_policer_stats *stats0 = &entry0->mp[tc0].stats;
struct rte_meter_trtcm *meter1 = &entry1->mp[tc1].meter;
+ struct rte_meter_trtcm_profile *meter1_profile =
+ &entry1->mp[tc1].meter_profile;
struct pipeline_fa_policer_params *policer1 = &entry1->mp[tc1].policer;
struct pipeline_fa_policer_stats *stats1 = &entry1->mp[tc1].stats;
struct rte_meter_trtcm *meter2 = &entry2->mp[tc2].meter;
+ struct rte_meter_trtcm_profile *meter2_profile =
+ &entry2->mp[tc2].meter_profile;
struct pipeline_fa_policer_params *policer2 = &entry2->mp[tc2].policer;
struct pipeline_fa_policer_stats *stats2 = &entry2->mp[tc2].stats;
struct rte_meter_trtcm *meter3 = &entry3->mp[tc3].meter;
+ struct rte_meter_trtcm_profile *meter3_profile =
+ &entry3->mp[tc3].meter_profile;
struct pipeline_fa_policer_params *policer3 = &entry3->mp[tc3].policer;
struct pipeline_fa_policer_stats *stats3 = &entry3->mp[tc3].stats;
/* Read (entry), compute, write (entry) */
enum rte_meter_color color2_0 = rte_meter_trtcm_color_aware_check(
meter0,
+ meter0_profile,
time,
total_length0,
color0);
enum rte_meter_color color2_1 = rte_meter_trtcm_color_aware_check(
meter1,
+ meter1_profile,
time,
total_length1,
color1);
enum rte_meter_color color2_2 = rte_meter_trtcm_color_aware_check(
meter2,
+ meter2_profile,
time,
total_length2,
color2);
enum rte_meter_color color2_3 = rte_meter_trtcm_color_aware_check(
meter3,
+ meter3_profile,
time,
total_length3,
color3);
diff --git a/examples/qos_meter/main.c b/examples/qos_meter/main.c
index 7a0df50..1e1370f 100644
--- a/examples/qos_meter/main.c
+++ b/examples/qos_meter/main.c
@@ -92,14 +92,23 @@ static uint16_t port_tx;
static struct rte_mbuf *pkts_rx[PKT_RX_BURST_MAX];
struct rte_eth_dev_tx_buffer *tx_buffer;
-struct rte_meter_srtcm_params app_srtcm_params[] = {
- {.cir = 1000000 * 46, .cbs = 2048, .ebs = 2048},
+struct rte_meter_srtcm_params app_srtcm_params = {
+ .cir = 1000000 * 46,
+ .cbs = 2048,
+ .ebs = 2048
};
-struct rte_meter_trtcm_params app_trtcm_params[] = {
- {.cir = 1000000 * 46, .pir = 1500000 * 46, .cbs = 2048, .pbs = 2048},
+struct rte_meter_srtcm_profile app_srtcm_profile;
+
+struct rte_meter_trtcm_params app_trtcm_params = {
+ .cir = 1000000 * 46,
+ .pir = 1500000 * 46,
+ .cbs = 2048,
+ .pbs = 2048
};
+struct rte_meter_trtcm_profile app_trtcm_profile;
+
#define APP_FLOWS_MAX 256
FLOW_METER app_flows[APP_FLOWS_MAX];
@@ -107,12 +116,21 @@ FLOW_METER app_flows[APP_FLOWS_MAX];
static int
app_configure_flow_table(void)
{
- uint32_t i, j;
+ uint32_t i;
int ret;
- for (i = 0, j = 0; i < APP_FLOWS_MAX;
- i ++, j = (j + 1) % RTE_DIM(PARAMS)) {
- ret = FUNC_CONFIG(&app_flows[i], &PARAMS[j]);
+ ret = rte_meter_srtcm_profile_config(&app_srtcm_profile,
+ &app_srtcm_params);
+ if (ret)
+ return ret;
+
+ ret = rte_meter_trtcm_profile_config(&app_trtcm_profile,
+ &app_trtcm_params);
+ if (ret)
+ return ret;
+
+ for (i = 0; i < APP_FLOWS_MAX; i++) {
+ ret = FUNC_CONFIG(&app_flows[i], &PROFILE);
if (ret)
return ret;
}
@@ -137,7 +155,10 @@ app_pkt_handle(struct rte_mbuf *pkt, uint64_t time)
enum policer_action action;
/* color input is not used for blind modes */
- output_color = (uint8_t) FUNC_METER(&app_flows[flow_id], time, pkt_len,
+ output_color = (uint8_t) FUNC_METER(&app_flows[flow_id],
+ &PROFILE,
+ time,
+ pkt_len,
(enum rte_meter_color) input_color);
/* Apply policing and set the output color */
diff --git a/examples/qos_meter/main.h b/examples/qos_meter/main.h
index b27e8eb..f51eb66 100644
--- a/examples/qos_meter/main.h
+++ b/examples/qos_meter/main.h
@@ -21,44 +21,52 @@ enum policer_action policer_table[e_RTE_METER_COLORS][e_RTE_METER_COLORS] =
#if APP_MODE == APP_MODE_FWD
-#define FUNC_METER(a,b,c,d) color, flow_id=flow_id, pkt_len=pkt_len, time=time
+#define FUNC_METER(m, p, time, pkt_len, pkt_color) \
+({ \
+ void *mp = m; \
+ void *pp = p; \
+ mp = mp; \
+ pp = pp; \
+ time = time; \
+ pkt_len = pkt_len; \
+ pkt_color; \
+})
#define FUNC_CONFIG(a, b) 0
-#define PARAMS app_srtcm_params
#define FLOW_METER int
+#define PROFILE app_srtcm_profile
#elif APP_MODE == APP_MODE_SRTCM_COLOR_BLIND
-#define FUNC_METER(a,b,c,d) rte_meter_srtcm_color_blind_check(a,b,c)
+#define FUNC_METER(m, p, time, pkt_len, pkt_color) \
+ rte_meter_srtcm_color_blind_check(m, p, time, pkt_len)
#define FUNC_CONFIG rte_meter_srtcm_config
-#define PARAMS app_srtcm_params
#define FLOW_METER struct rte_meter_srtcm
+#define PROFILE app_srtcm_profile
#elif (APP_MODE == APP_MODE_SRTCM_COLOR_AWARE)
#define FUNC_METER rte_meter_srtcm_color_aware_check
#define FUNC_CONFIG rte_meter_srtcm_config
-#define PARAMS app_srtcm_params
#define FLOW_METER struct rte_meter_srtcm
+#define PROFILE app_srtcm_profile
#elif (APP_MODE == APP_MODE_TRTCM_COLOR_BLIND)
-#define FUNC_METER(a,b,c,d) rte_meter_trtcm_color_blind_check(a,b,c)
+#define FUNC_METER(m, p, time, pkt_len, pkt_color) \
+ rte_meter_trtcm_color_blind_check(m, p, time, pkt_len)
#define FUNC_CONFIG rte_meter_trtcm_config
-#define PARAMS app_trtcm_params
#define FLOW_METER struct rte_meter_trtcm
+#define PROFILE app_trtcm_profile
#elif (APP_MODE == APP_MODE_TRTCM_COLOR_AWARE)
-#define FUNC_METER rte_meter_trtcm_color_aware_check
+#define FUNC_METER rte_meter_trtcm_color_aware_check
#define FUNC_CONFIG rte_meter_trtcm_config
-#define PARAMS app_trtcm_params
#define FLOW_METER struct rte_meter_trtcm
+#define PROFILE app_trtcm_profile
#else
#error Invalid value for APP_MODE
#endif
-
-
-
#endif /* _MAIN_H_ */
diff --git a/lib/librte_meter/Makefile b/lib/librte_meter/Makefile
index 3b80c6a..2dc071e 100644
--- a/lib/librte_meter/Makefile
+++ b/lib/librte_meter/Makefile
@@ -16,7 +16,7 @@ LDLIBS += -lrte_eal
EXPORT_MAP := rte_meter_version.map
-LIBABIVER := 1
+LIBABIVER := 2
#
# all source are stored in SRCS-y
diff --git a/lib/librte_meter/rte_meter.c b/lib/librte_meter/rte_meter.c
index 332c519..473f69a 100644
--- a/lib/librte_meter/rte_meter.c
+++ b/lib/librte_meter/rte_meter.c
@@ -31,61 +31,82 @@ rte_meter_get_tb_params(uint64_t hz, uint64_t rate, uint64_t *tb_period, uint64_
}
int
-rte_meter_srtcm_config(struct rte_meter_srtcm *m, struct rte_meter_srtcm_params *params)
+rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
+ struct rte_meter_srtcm_params *params)
{
- uint64_t hz;
+ uint64_t hz = rte_get_tsc_hz();
/* Check input parameters */
- if ((m == NULL) || (params == NULL)) {
- return -1;
- }
+ if ((p == NULL) ||
+ (params == NULL) ||
+ (params->cir == 0) ||
+ ((params->cbs == 0) && (params->ebs == 0)))
+ return -EINVAL;
- if ((params->cir == 0) || ((params->cbs == 0) && (params->ebs == 0))) {
- return -2;
- }
+ /* Initialize srTCM run-time structure */
+ p->cbs = params->cbs;
+ p->ebs = params->ebs;
+ rte_meter_get_tb_params(hz, params->cir, &p->cir_period,
+ &p->cir_bytes_per_period);
+
+ return 0;
+}
+
+int
+rte_meter_srtcm_config(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p)
+{
+ /* Check input parameters */
+ if ((m == NULL) || (p == NULL))
+ return -EINVAL;
/* Initialize srTCM run-time structure */
- hz = rte_get_tsc_hz();
m->time = rte_get_tsc_cycles();
- m->tc = m->cbs = params->cbs;
- m->te = m->ebs = params->ebs;
- rte_meter_get_tb_params(hz, params->cir, &m->cir_period, &m->cir_bytes_per_period);
-
- RTE_LOG(INFO, METER, "Low level srTCM config: \n"
- "\tCIR period = %" PRIu64 ", CIR bytes per period = %" PRIu64 "\n",
- m->cir_period, m->cir_bytes_per_period);
+ m->tc = p->cbs;
+ m->te = p->ebs;
return 0;
}
int
-rte_meter_trtcm_config(struct rte_meter_trtcm *m, struct rte_meter_trtcm_params *params)
+rte_meter_trtcm_profile_config(struct rte_meter_trtcm_profile *p,
+ struct rte_meter_trtcm_params *params)
{
- uint64_t hz;
+ uint64_t hz = rte_get_tsc_hz();
/* Check input parameters */
- if ((m == NULL) || (params == NULL)) {
- return -1;
- }
+ if ((p == NULL) ||
+ (params == NULL) ||
+ (params->cir == 0) ||
+ (params->pir == 0) ||
+ (params->pir < params->cir) ||
+ (params->cbs == 0) ||
+ (params->pbs == 0))
+ return -EINVAL;
- if ((params->cir == 0) || (params->pir == 0) || (params->pir < params->cir) ||
- (params->cbs == 0) || (params->pbs == 0)) {
- return -2;
- }
+ /* Initialize trTCM run-time structure */
+ p->cbs = params->cbs;
+ p->pbs = params->pbs;
+ rte_meter_get_tb_params(hz, params->cir, &p->cir_period,
+ &p->cir_bytes_per_period);
+ rte_meter_get_tb_params(hz, params->pir, &p->pir_period,
+ &p->pir_bytes_per_period);
+
+ return 0;
+}
+
+int
+rte_meter_trtcm_config(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p)
+{
+ /* Check input parameters */
+ if ((m == NULL) || (p == NULL))
+ return -EINVAL;
/* Initialize trTCM run-time structure */
- hz = rte_get_tsc_hz();
m->time_tc = m->time_tp = rte_get_tsc_cycles();
- m->tc = m->cbs = params->cbs;
- m->tp = m->pbs = params->pbs;
- rte_meter_get_tb_params(hz, params->cir, &m->cir_period, &m->cir_bytes_per_period);
- rte_meter_get_tb_params(hz, params->pir, &m->pir_period, &m->pir_bytes_per_period);
-
- RTE_LOG(INFO, METER, "Low level trTCM config: \n"
- "\tCIR period = %" PRIu64 ", CIR bytes per period = %" PRIu64 "\n"
- "\tPIR period = %" PRIu64 ", PIR bytes per period = %" PRIu64 "\n",
- m->cir_period, m->cir_bytes_per_period,
- m->pir_period, m->pir_bytes_per_period);
+ m->tc = p->cbs;
+ m->tp = p->pbs;
return 0;
}
diff --git a/lib/librte_meter/rte_meter.h b/lib/librte_meter/rte_meter.h
index ebdc453..29b46bb 100644
--- a/lib/librte_meter/rte_meter.h
+++ b/lib/librte_meter/rte_meter.h
@@ -53,6 +53,18 @@ struct rte_meter_trtcm_params {
uint64_t pbs; /**< Peak Burst Size (PBS). Measured in bytes. */
};
+/**
+ * Internal data structure storing the srTCM configuration profile. Typically
+ * shared by multiple srTCM objects.
+ */
+struct rte_meter_srtcm_profile;
+
+/**
+ * Internal data structure storing the trTCM configuration profile. Typically
+ * shared by multiple trTCM objects.
+ */
+struct rte_meter_trtcm_profile;
+
/** Internal data structure storing the srTCM run-time context per metered traffic flow. */
struct rte_meter_srtcm;
@@ -60,38 +72,66 @@ struct rte_meter_srtcm;
struct rte_meter_trtcm;
/**
+ * srTCM profile configuration
+ *
+ * @param p
+ * Pointer to pre-allocated srTCM profile data structure
+ * @param params
+ * srTCM profile parameters
+ * @return
+ * 0 upon success, error code otherwise
+ */
+int rte_meter_srtcm_profile_config(struct rte_meter_srtcm_profile *p,
+ struct rte_meter_srtcm_params *params);
+
+/**
+ * trTCM profile configuration
+ *
+ * @param p
+ * Pointer to pre-allocated trTCM profile data structure
+ * @param params
+ * trTCM profile parameters
+ * @return
+ * 0 upon success, error code otherwise
+ */
+int rte_meter_trtcm_profile_config(struct rte_meter_trtcm_profile *p,
+ struct rte_meter_trtcm_params *params);
+
+/**
* srTCM configuration per metered traffic flow
*
* @param m
* Pointer to pre-allocated srTCM data structure
- * @param params
- * User parameters per srTCM metered traffic flow
+ * @param p
+ * srTCM profile. Needs to be valid.
* @return
* 0 upon success, error code otherwise
*/
int
rte_meter_srtcm_config(struct rte_meter_srtcm *m,
- struct rte_meter_srtcm_params *params);
+ struct rte_meter_srtcm_profile *p);
/**
* trTCM configuration per metered traffic flow
*
* @param m
* Pointer to pre-allocated trTCM data structure
- * @param params
- * User parameters per trTCM metered traffic flow
+ * @param p
+ * trTCM profile. Needs to be valid.
* @return
* 0 upon success, error code otherwise
*/
int
rte_meter_trtcm_config(struct rte_meter_trtcm *m,
- struct rte_meter_trtcm_params *params);
+ struct rte_meter_trtcm_profile *p);
/**
* srTCM color blind traffic metering
*
* @param m
* Handle to srTCM instance
+ * @param p
+ * srTCM profile specified at srTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -101,6 +141,7 @@ rte_meter_trtcm_config(struct rte_meter_trtcm *m,
*/
static inline enum rte_meter_color
rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len);
@@ -109,6 +150,8 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
*
* @param m
* Handle to srTCM instance
+ * @param p
+ * srTCM profile specified at srTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -120,6 +163,7 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
*/
static inline enum rte_meter_color
rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color);
@@ -129,6 +173,8 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
*
* @param m
* Handle to trTCM instance
+ * @param p
+ * trTCM profile specified at trTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -138,6 +184,7 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
*/
static inline enum rte_meter_color
rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len);
@@ -146,6 +193,8 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
*
* @param m
* Handle to trTCM instance
+ * @param p
+ * trTCM profile specified at trTCM object creation time
* @param time
* Current CPU time stamp (measured in CPU cycles)
* @param pkt_len
@@ -157,6 +206,7 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
*/
static inline enum rte_meter_color
rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color);
@@ -166,33 +216,57 @@ rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
*
***/
+struct rte_meter_srtcm_profile {
+ uint64_t cbs;
+ /**< Upper limit for C token bucket */
+ uint64_t ebs;
+ /**< Upper limit for E token bucket */
+ uint64_t cir_period;
+ /**< Number of CPU cycles for each update of C and E token buckets */
+ uint64_t cir_bytes_per_period;
+ /**< Number of bytes to add to C and E token buckets on each update */
+};
+
/* Internal data structure storing the srTCM run-time context per metered traffic flow. */
struct rte_meter_srtcm {
uint64_t time; /* Time of latest update of C and E token buckets */
uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
uint64_t te; /* Number of bytes currently available in the excess (E) token bucket */
- uint64_t cbs; /* Upper limit for C token bucket */
- uint64_t ebs; /* Upper limit for E token bucket */
- uint64_t cir_period; /* Number of CPU cycles for one update of C and E token buckets */
- uint64_t cir_bytes_per_period; /* Number of bytes to add to C and E token buckets on each update */
};
-/* Internal data structure storing the trTCM run-time context per metered traffic flow. */
+struct rte_meter_trtcm_profile {
+ uint64_t cbs;
+ /**< Upper limit for C token bucket */
+ uint64_t pbs;
+ /**< Upper limit for P token bucket */
+ uint64_t cir_period;
+ /**< Number of CPU cycles for one update of C token bucket */
+ uint64_t cir_bytes_per_period;
+ /**< Number of bytes to add to C token bucket on each update */
+ uint64_t pir_period;
+ /**< Number of CPU cycles for one update of P token bucket */
+ uint64_t pir_bytes_per_period;
+ /**< Number of bytes to add to P token bucket on each update */
+};
+
+/**
+ * Internal data structure storing the trTCM run-time context per metered
+ * traffic flow.
+ */
struct rte_meter_trtcm {
- uint64_t time_tc; /* Time of latest update of C token bucket */
- uint64_t time_tp; /* Time of latest update of E token bucket */
- uint64_t tc; /* Number of bytes currently available in the committed (C) token bucket */
- uint64_t tp; /* Number of bytes currently available in the peak (P) token bucket */
- uint64_t cbs; /* Upper limit for C token bucket */
- uint64_t pbs; /* Upper limit for P token bucket */
- uint64_t cir_period; /* Number of CPU cycles for one update of C token bucket */
- uint64_t cir_bytes_per_period; /* Number of bytes to add to C token bucket on each update */
- uint64_t pir_period; /* Number of CPU cycles for one update of P token bucket */
- uint64_t pir_bytes_per_period; /* Number of bytes to add to P token bucket on each update */
+ uint64_t time_tc;
+ /**< Time of latest update of C token bucket */
+ uint64_t time_tp;
+ /**< Time of latest update of E token bucket */
+ uint64_t tc;
+ /**< Number of bytes currently available in committed(C) token bucket */
+ uint64_t tp;
+ /**< Number of bytes currently available in the peak(P) token bucket */
};
static inline enum rte_meter_color
rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len)
{
@@ -200,17 +274,17 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
/* Bucket update */
time_diff = time - m->time;
- n_periods = time_diff / m->cir_period;
- m->time += n_periods * m->cir_period;
+ n_periods = time_diff / p->cir_period;
+ m->time += n_periods * p->cir_period;
/* Put the tokens overflowing from tc into te bucket */
- tc = m->tc + n_periods * m->cir_bytes_per_period;
+ tc = m->tc + n_periods * p->cir_bytes_per_period;
te = m->te;
- if (tc > m->cbs) {
- te += (tc - m->cbs);
- if (te > m->ebs)
- te = m->ebs;
- tc = m->cbs;
+ if (tc > p->cbs) {
+ te += (tc - p->cbs);
+ if (te > p->ebs)
+ te = p->ebs;
+ tc = p->cbs;
}
/* Color logic */
@@ -233,6 +307,7 @@ rte_meter_srtcm_color_blind_check(struct rte_meter_srtcm *m,
static inline enum rte_meter_color
rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
+ struct rte_meter_srtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color)
@@ -241,17 +316,17 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
/* Bucket update */
time_diff = time - m->time;
- n_periods = time_diff / m->cir_period;
- m->time += n_periods * m->cir_period;
+ n_periods = time_diff / p->cir_period;
+ m->time += n_periods * p->cir_period;
/* Put the tokens overflowing from tc into te bucket */
- tc = m->tc + n_periods * m->cir_bytes_per_period;
+ tc = m->tc + n_periods * p->cir_bytes_per_period;
te = m->te;
- if (tc > m->cbs) {
- te += (tc - m->cbs);
- if (te > m->ebs)
- te = m->ebs;
- tc = m->cbs;
+ if (tc > p->cbs) {
+ te += (tc - p->cbs);
+ if (te > p->ebs)
+ te = p->ebs;
+ tc = p->cbs;
}
/* Color logic */
@@ -274,6 +349,7 @@ rte_meter_srtcm_color_aware_check(struct rte_meter_srtcm *m,
static inline enum rte_meter_color
rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len)
{
@@ -282,18 +358,18 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
/* Bucket update */
time_diff_tc = time - m->time_tc;
time_diff_tp = time - m->time_tp;
- n_periods_tc = time_diff_tc / m->cir_period;
- n_periods_tp = time_diff_tp / m->pir_period;
- m->time_tc += n_periods_tc * m->cir_period;
- m->time_tp += n_periods_tp * m->pir_period;
+ n_periods_tc = time_diff_tc / p->cir_period;
+ n_periods_tp = time_diff_tp / p->pir_period;
+ m->time_tc += n_periods_tc * p->cir_period;
+ m->time_tp += n_periods_tp * p->pir_period;
- tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
- if (tc > m->cbs)
- tc = m->cbs;
+ tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
+ if (tc > p->cbs)
+ tc = p->cbs;
- tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
- if (tp > m->pbs)
- tp = m->pbs;
+ tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
+ if (tp > p->pbs)
+ tp = p->pbs;
/* Color logic */
if (tp < pkt_len) {
@@ -315,6 +391,7 @@ rte_meter_trtcm_color_blind_check(struct rte_meter_trtcm *m,
static inline enum rte_meter_color
rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
+ struct rte_meter_trtcm_profile *p,
uint64_t time,
uint32_t pkt_len,
enum rte_meter_color pkt_color)
@@ -324,18 +401,18 @@ rte_meter_trtcm_color_aware_check(struct rte_meter_trtcm *m,
/* Bucket update */
time_diff_tc = time - m->time_tc;
time_diff_tp = time - m->time_tp;
- n_periods_tc = time_diff_tc / m->cir_period;
- n_periods_tp = time_diff_tp / m->pir_period;
- m->time_tc += n_periods_tc * m->cir_period;
- m->time_tp += n_periods_tp * m->pir_period;
-
- tc = m->tc + n_periods_tc * m->cir_bytes_per_period;
- if (tc > m->cbs)
- tc = m->cbs;
-
- tp = m->tp + n_periods_tp * m->pir_bytes_per_period;
- if (tp > m->pbs)
- tp = m->pbs;
+ n_periods_tc = time_diff_tc / p->cir_period;
+ n_periods_tp = time_diff_tp / p->pir_period;
+ m->time_tc += n_periods_tc * p->cir_period;
+ m->time_tp += n_periods_tp * p->pir_period;
+
+ tc = m->tc + n_periods_tc * p->cir_bytes_per_period;
+ if (tc > p->cbs)
+ tc = p->cbs;
+
+ tp = m->tp + n_periods_tp * p->pir_bytes_per_period;
+ if (tp > p->pbs)
+ tp = p->pbs;
/* Color logic */
if ((pkt_color == e_RTE_METER_RED) || (tp < pkt_len)) {
diff --git a/lib/librte_meter/rte_meter_version.map b/lib/librte_meter/rte_meter_version.map
index 2fd647c..c4422ef 100644
--- a/lib/librte_meter/rte_meter_version.map
+++ b/lib/librte_meter/rte_meter_version.map
@@ -10,3 +10,11 @@ DPDK_2.0 {
local: *;
};
+
+DPDK_18.02 {
+ global:
+
+ rte_meter_srtcm_profile_config;
+ rte_meter_trtcm_profile_config;
+
+} DPDK_2.0;
diff --git a/test/test/test_meter.c b/test/test/test_meter.c
index 9f6abf9..8bb47e7 100644
--- a/test/test/test_meter.c
+++ b/test/test/test_meter.c
@@ -53,43 +53,43 @@ static inline int
tm_test_srtcm_config(void)
{
#define SRTCM_CFG_MSG "srtcm_config"
- struct rte_meter_srtcm sm;
+ struct rte_meter_srtcm_profile sp;
struct rte_meter_srtcm_params sparams1;
/* invalid parameter test */
- if(rte_meter_srtcm_config(NULL, NULL) == 0)
+ if (rte_meter_srtcm_profile_config(NULL, NULL) == 0)
melog(SRTCM_CFG_MSG);
- if(rte_meter_srtcm_config(&sm, NULL) == 0)
+ if (rte_meter_srtcm_profile_config(&sp, NULL) == 0)
melog(SRTCM_CFG_MSG);
- if(rte_meter_srtcm_config(NULL, &sparams) == 0)
+ if (rte_meter_srtcm_profile_config(NULL, &sparams) == 0)
melog(SRTCM_CFG_MSG);
/* cbs and ebs can't both be zero */
sparams1 = sparams;
sparams1.cbs = 0;
sparams1.ebs = 0;
- if(rte_meter_srtcm_config(&sm, &sparams1) == 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams1) == 0)
melog(SRTCM_CFG_MSG);
/* cir should never be 0 */
sparams1 = sparams;
sparams1.cir = 0;
- if(rte_meter_srtcm_config(&sm, &sparams1) == 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams1) == 0)
melog(SRTCM_CFG_MSG);
/* one of ebs and cbs can be zero, should be successful */
sparams1 = sparams;
sparams1.ebs = 0;
- if(rte_meter_srtcm_config(&sm, &sparams1) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams1) != 0)
melog(SRTCM_CFG_MSG);
sparams1 = sparams;
sparams1.cbs = 0;
- if(rte_meter_srtcm_config(&sm, &sparams1) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams1) != 0)
melog(SRTCM_CFG_MSG);
/* usual parameter, should be successful */
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
melog(SRTCM_CFG_MSG);
return 0;
@@ -102,47 +102,47 @@ tm_test_srtcm_config(void)
static inline int
tm_test_trtcm_config(void)
{
- struct rte_meter_trtcm tm;
+ struct rte_meter_trtcm_profile tp;
struct rte_meter_trtcm_params tparams1;
#define TRTCM_CFG_MSG "trtcm_config"
/* invalid parameter test */
- if(rte_meter_trtcm_config(NULL, NULL) == 0)
+ if (rte_meter_trtcm_profile_config(NULL, NULL) == 0)
melog(TRTCM_CFG_MSG);
- if(rte_meter_trtcm_config(&tm, NULL) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, NULL) == 0)
melog(TRTCM_CFG_MSG);
- if(rte_meter_trtcm_config(NULL, &tparams) == 0)
+ if (rte_meter_trtcm_profile_config(NULL, &tparams) == 0)
melog(TRTCM_CFG_MSG);
/* cir, cbs, pir and pbs never be zero */
tparams1 = tparams;
tparams1.cir = 0;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
tparams1 = tparams;
tparams1.cbs = 0;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
tparams1 = tparams;
tparams1.pbs = 0;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
tparams1 = tparams;
tparams1.pir = 0;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG);
/* pir should be greater or equal to cir */
tparams1 = tparams;
tparams1.pir = tparams1.cir - 1;
- if(rte_meter_trtcm_config(&tm, &tparams1) == 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams1) == 0)
melog(TRTCM_CFG_MSG" pir < cir test");
/* usual parameter, should be successful */
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
melog(TRTCM_CFG_MSG);
return 0;
@@ -155,41 +155,50 @@ static inline int
tm_test_srtcm_color_blind_check(void)
{
#define SRTCM_BLIND_CHECK_MSG "srtcm_blind_check"
+ struct rte_meter_srtcm_profile sp;
struct rte_meter_srtcm sm;
uint64_t time;
uint64_t hz = rte_get_tsc_hz();
/* Test green */
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_blind_check(
- &sm, time, TM_TEST_SRTCM_CBS_DF - 1)
+ if (rte_meter_srtcm_color_blind_check(
+ &sm, &sp, time, TM_TEST_SRTCM_CBS_DF - 1)
!= e_RTE_METER_GREEN)
melog(SRTCM_BLIND_CHECK_MSG" GREEN");
/* Test yellow */
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_blind_check(
- &sm, time, TM_TEST_SRTCM_CBS_DF + 1)
+ if (rte_meter_srtcm_color_blind_check(
+ &sm, &sp, time, TM_TEST_SRTCM_CBS_DF + 1)
!= e_RTE_METER_YELLOW)
melog(SRTCM_BLIND_CHECK_MSG" YELLOW");
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_blind_check(
- &sm, time, (uint32_t)sm.ebs - 1) != e_RTE_METER_YELLOW)
+ if (rte_meter_srtcm_color_blind_check(
+ &sm, &sp, time, (uint32_t)sp.ebs - 1) != e_RTE_METER_YELLOW)
melog(SRTCM_BLIND_CHECK_MSG" YELLOW");
/* Test red */
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_blind_check(
- &sm, time, TM_TEST_SRTCM_EBS_DF + 1)
+ if (rte_meter_srtcm_color_blind_check(
+ &sm, &sp, time, TM_TEST_SRTCM_EBS_DF + 1)
!= e_RTE_METER_RED)
melog(SRTCM_BLIND_CHECK_MSG" RED");
@@ -206,41 +215,50 @@ tm_test_trtcm_color_blind_check(void)
#define TRTCM_BLIND_CHECK_MSG "trtcm_blind_check"
uint64_t time;
+ struct rte_meter_trtcm_profile tp;
struct rte_meter_trtcm tm;
uint64_t hz = rte_get_tsc_hz();
/* Test green */
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_blind_check(
- &tm, time, TM_TEST_TRTCM_CBS_DF - 1)
+ if (rte_meter_trtcm_color_blind_check(
+ &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1)
!= e_RTE_METER_GREEN)
melog(TRTCM_BLIND_CHECK_MSG" GREEN");
/* Test yellow */
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_blind_check(
- &tm, time, TM_TEST_TRTCM_CBS_DF + 1)
+ if (rte_meter_trtcm_color_blind_check(
+ &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1)
!= e_RTE_METER_YELLOW)
melog(TRTCM_BLIND_CHECK_MSG" YELLOW");
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_blind_check(
- &tm, time, TM_TEST_TRTCM_PBS_DF - 1)
+ if (rte_meter_trtcm_color_blind_check(
+ &tm, &tp, time, TM_TEST_TRTCM_PBS_DF - 1)
!= e_RTE_METER_YELLOW)
melog(TRTCM_BLIND_CHECK_MSG" YELLOW");
/* Test red */
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_BLIND_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_BLIND_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_blind_check(
- &tm, time, TM_TEST_TRTCM_PBS_DF + 1)
+ if (rte_meter_trtcm_color_blind_check(
+ &tm, &tp, time, TM_TEST_TRTCM_PBS_DF + 1)
!= e_RTE_METER_RED)
melog(TRTCM_BLIND_CHECK_MSG" RED");
@@ -262,36 +280,45 @@ tm_test_srtcm_aware_check
(enum rte_meter_color in[4], enum rte_meter_color out[4])
{
#define SRTCM_AWARE_CHECK_MSG "srtcm_aware_check"
+ struct rte_meter_srtcm_profile sp;
struct rte_meter_srtcm sm;
uint64_t time;
uint64_t hz = rte_get_tsc_hz();
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_aware_check(
- &sm, time, TM_TEST_SRTCM_CBS_DF - 1, in[0]) != out[0])
+ if (rte_meter_srtcm_color_aware_check(
+ &sm, &sp, time, TM_TEST_SRTCM_CBS_DF - 1, in[0]) != out[0])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]);
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_aware_check(
- &sm, time, TM_TEST_SRTCM_CBS_DF + 1, in[1]) != out[1])
+ if (rte_meter_srtcm_color_aware_check(
+ &sm, &sp, time, TM_TEST_SRTCM_CBS_DF + 1, in[1]) != out[1])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]);
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_aware_check(
- &sm, time, TM_TEST_SRTCM_EBS_DF - 1, in[2]) != out[2])
+ if (rte_meter_srtcm_color_aware_check(
+ &sm, &sp, time, TM_TEST_SRTCM_EBS_DF - 1, in[2]) != out[2])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]);
- if(rte_meter_srtcm_config(&sm, &sparams) != 0)
+ if (rte_meter_srtcm_profile_config(&sp, &sparams) != 0)
+ melog(SRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_srtcm_config(&sm, &sp) != 0)
melog(SRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_srtcm_color_aware_check(
- &sm, time, TM_TEST_SRTCM_EBS_DF + 1, in[3]) != out[3])
+ if (rte_meter_srtcm_color_aware_check(
+ &sm, &sp, time, TM_TEST_SRTCM_EBS_DF + 1, in[3]) != out[3])
melog(SRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]);
return 0;
@@ -317,7 +344,7 @@ tm_test_srtcm_color_aware_check(void)
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
- if(tm_test_srtcm_aware_check(in, out) != 0)
+ if (tm_test_srtcm_aware_check(in, out) != 0)
return -1;
/**
@@ -329,7 +356,7 @@ tm_test_srtcm_color_aware_check(void)
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
- if(tm_test_srtcm_aware_check(in, out) != 0)
+ if (tm_test_srtcm_aware_check(in, out) != 0)
return -1;
/**
@@ -341,7 +368,7 @@ tm_test_srtcm_color_aware_check(void)
out[1] = e_RTE_METER_RED;
out[2] = e_RTE_METER_RED;
out[3] = e_RTE_METER_RED;
- if(tm_test_srtcm_aware_check(in, out) != 0)
+ if (tm_test_srtcm_aware_check(in, out) != 0)
return -1;
return 0;
@@ -360,36 +387,45 @@ tm_test_trtcm_aware_check
(enum rte_meter_color in[4], enum rte_meter_color out[4])
{
#define TRTCM_AWARE_CHECK_MSG "trtcm_aware_check"
+ struct rte_meter_trtcm_profile tp;
struct rte_meter_trtcm tm;
uint64_t time;
uint64_t hz = rte_get_tsc_hz();
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_aware_check(
- &tm, time, TM_TEST_TRTCM_CBS_DF - 1, in[0]) != out[0])
+ if (rte_meter_trtcm_color_aware_check(
+ &tm, &tp, time, TM_TEST_TRTCM_CBS_DF - 1, in[0]) != out[0])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[0], out[0]);
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_aware_check(
- &tm, time, TM_TEST_TRTCM_CBS_DF + 1, in[1]) != out[1])
+ if (rte_meter_trtcm_color_aware_check(
+ &tm, &tp, time, TM_TEST_TRTCM_CBS_DF + 1, in[1]) != out[1])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[1], out[1]);
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_aware_check(
- &tm, time, TM_TEST_TRTCM_PBS_DF - 1, in[2]) != out[2])
+ if (rte_meter_trtcm_color_aware_check(
+ &tm, &tp, time, TM_TEST_TRTCM_PBS_DF - 1, in[2]) != out[2])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[2], out[2]);
- if(rte_meter_trtcm_config(&tm, &tparams) != 0)
+ if (rte_meter_trtcm_profile_config(&tp, &tparams) != 0)
+ melog(TRTCM_AWARE_CHECK_MSG);
+ if (rte_meter_trtcm_config(&tm, &tp) != 0)
melog(TRTCM_AWARE_CHECK_MSG);
time = rte_get_tsc_cycles() + hz;
- if(rte_meter_trtcm_color_aware_check(
- &tm, time, TM_TEST_TRTCM_PBS_DF + 1, in[3]) != out[3])
+ if (rte_meter_trtcm_color_aware_check(
+ &tm, &tp, time, TM_TEST_TRTCM_PBS_DF + 1, in[3]) != out[3])
melog(TRTCM_AWARE_CHECK_MSG" %u:%u", in[3], out[3]);
return 0;
@@ -415,7 +451,7 @@ tm_test_trtcm_color_aware_check(void)
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
- if(tm_test_trtcm_aware_check(in, out) != 0)
+ if (tm_test_trtcm_aware_check(in, out) != 0)
return -1;
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_YELLOW;
@@ -423,7 +459,7 @@ tm_test_trtcm_color_aware_check(void)
out[1] = e_RTE_METER_YELLOW;
out[2] = e_RTE_METER_YELLOW;
out[3] = e_RTE_METER_RED;
- if(tm_test_trtcm_aware_check(in, out) != 0)
+ if (tm_test_trtcm_aware_check(in, out) != 0)
return -1;
in[0] = in[1] = in[2] = in[3] = e_RTE_METER_RED;
@@ -431,7 +467,7 @@ tm_test_trtcm_color_aware_check(void)
out[1] = e_RTE_METER_RED;
out[2] = e_RTE_METER_RED;
out[3] = e_RTE_METER_RED;
- if(tm_test_trtcm_aware_check(in, out) != 0)
+ if (tm_test_trtcm_aware_check(in, out) != 0)
return -1;
return 0;
@@ -443,22 +479,22 @@ tm_test_trtcm_color_aware_check(void)
static int
test_meter(void)
{
- if(tm_test_srtcm_config() != 0 )
+ if (tm_test_srtcm_config() != 0)
return -1;
- if(tm_test_trtcm_config() != 0 )
+ if (tm_test_trtcm_config() != 0)
return -1;
- if(tm_test_srtcm_color_blind_check() != 0)
+ if (tm_test_srtcm_color_blind_check() != 0)
return -1;
- if(tm_test_trtcm_color_blind_check()!= 0)
+ if (tm_test_trtcm_color_blind_check() != 0)
return -1;
- if(tm_test_srtcm_color_aware_check()!= 0)
+ if (tm_test_srtcm_color_aware_check() != 0)
return -1;
- if(tm_test_trtcm_color_aware_check()!= 0)
+ if (tm_test_trtcm_color_aware_check() != 0)
return -1;
return 0;
--
2.9.3
^ permalink raw reply [relevance 1%]
* Re: [dpdk-dev] Napatech pmd
@ 2018-01-08 15:31 3% ` Stephen Hemminger
0 siblings, 0 replies; 200+ results
From: Stephen Hemminger @ 2018-01-08 15:31 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Finn Christensen, dev
On Mon, 08 Jan 2018 16:15:47 +0100
Thomas Monjalon <thomas@monjalon.net> wrote:
> Hi,
>
> 08/01/2018 14:08, Finn Christensen:
> > Hi Thomas,
> >
> > Thanks for bringing this discussion up again.
> >
> > The Napatech PMD is build on top of our proprietary driver. The reason is basically that we utilize many years of driver development and thus reuses the FPGA controlling code in the DPDK PMD. The Napatech driver suite is still closed source.
> > The current NTNIC PMD dynamically links a Napatech proprietary NTAPI library to control the FPGA on our NICs.
> >
> > We did think of the PMD as being our responsibility to keep updated towards the Napatech NIC communication, and that we would be engaged and asked to modify accordingly if changes in DPDK required that (maintainer). Furthermore, the PMD compiles with no issues, when NTNIC is enabled.
> > We have plans to write a stand-alone PMD, but this is not a small task to do, therefore we haven't got to that yet.
>
> This standalone PMD would be open and BSD licensed?
>
> > If the DPDK community would accept the dynamic linking to a proprietary library, from inside our PMD, then it would be great.
>
> Dynamic linking is OK.
> I think we can accept such PMD at the condition that we can build it,
> meaning we can easily download the build dependencies for free.
>
> > Let me know what you think. Or maybe you have ideas to what else we could do to make it upstream.
>
> My thinking is to allow every hardware to have a good DPDK support.
> Every step in this direction is a progress.
Also the API to the proprietary code must be separate from DPDK headers.
Ideally the ABI for DPDK could evolve and the vendor code would not need to be updated.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 6/7] net/mlx4: convert to new Tx offloads API
@ 2018-01-09 10:35 3% ` Nelio Laranjeiro
0 siblings, 0 replies; 200+ results
From: Nelio Laranjeiro @ 2018-01-09 10:35 UTC (permalink / raw)
To: Shahaf Shuler; +Cc: Adrien Mazarguil, Yongseok Koh, dev
Hi Shahaf,
On Thu, Jan 04, 2018 at 11:55:17AM +0000, Shahaf Shuler wrote:
> Hi Adrien and Nelio,
>
> See below comment regarding your output on the offload check.
> Rest of the comments were accepted.
>
> Wednesday, January 3, 2018 7:29 PM, Adrien Mazarguil :
>
> [...]
>
> >
> > > +{
> > > + uint64_t port_offloads = priv->dev->data-
> > >dev_conf.txmode.offloads;
> > > + uint64_t port_supp_offloads =
> > mlx4_priv_get_tx_port_offloads(priv);
> >
> > Instead of a redundant "port_", how about clarifying it all as follows:
> >
> > offloads -> requested
> > port_offloads -> mandatory
> > port_supp_offloads -> supported
> >
> > > +
> > > + if ((port_offloads ^ offloads) & port_supp_offloads)
> > > + return 0;
> > > + return 1;
> >
> > And simplify this as:
> >
> > return !((mandatory ^ requested) & supported);
> >
> > Maybe I missed something, but there seems to be an inconsistency, e.g.
>
> You are correct that the purpose of this function is to check if the offload configuration is correct.
> However the current code being done on mlx4 does not validate if the queue offloads configured are supported.
> It only validates if the port offloads configuration matches the queue offload configuration.
>
> The reason it lack the supported offloads check was discussed in internal mail (you both CC I believe). Generally it was due to the fact that CRC and VLAN strip offloads are not supported by the PMD, however set for almost every example/application in DPDK.
> For the complete check look on mlx5 patches on this series.
>
> > requesting an unsupported offload does not necessarily fail:
> >
> > mandatory = 0x00
> > requested = 0x40
> > supported = 0x10
> >
> > => valid but shouldn't be
>
> It should if the offload is per-queue offload.
>
>
> >
> > And requesting a supported offload when there are no mandatory ones
> > should not be a problem:
> >
> > mandatory = 0x00
> > requested = 0x10
> > supported = 0x10
> >
> > => invalid but it should be
>
> It is invalid indeed. If the application declare some port offload not to be set on dev_configure, it cannot enable it from the queue setup.
> Port offloads can be set only on device configuration, and when set every queue should have them set as well.
>
> >
> > A naive translation of the above requirements results in the following
> > expression:
> >
> > return (requested | supported) == supported &&
> > (requested & mandatory) == mandatory;
> >
> > What's your opinion?
> >
>From an application point of view, it seems strange to provide an
already configured offload when configuring the queues, i.e.
rte_eth_dev_configure() is called before rte_eth_{tx,rx}_queue_setup().
I think this "mandatory" information should be removed from the API
documentation letting the application the capability to request a null
offload when configuring the queue.
As this modification does not break the API/ABI it only needs eventually
a modification in the driver, it can be done in the future.
For mlx5 part:
Acked-by: Nelio Laranjeiro <nelio.laranjeiro@6wind.com>
--
Nélio Laranjeiro
6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] ethdev: increase flow type limit from 32 to 64
@ 2018-01-09 15:16 3% ` Rybalchenko, Kirill
2018-01-10 13:50 3% ` Thomas Monjalon
2018-01-16 11:13 0% ` Adrien Mazarguil
0 siblings, 2 replies; 200+ results
From: Rybalchenko, Kirill @ 2018-01-09 15:16 UTC (permalink / raw)
To: Adrien Mazarguil
Cc: dev, Wu, Jingjing, Xing, Beilei, johndale, neescoba,
nelio.laranjeiro, yskoh, Lu, Wenzhuo, Ananyev, Konstantin,
Chilikin, Andrey
> -----Original Message-----
> From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> Sent: Monday 4 December 2017 17:43
> To: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>
> Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; johndale@cisco.com; neescoba@cisco.com;
> nelio.laranjeiro@6wind.com; yskoh@mellanox.com; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; Chilikin, Andrey
> <andrey.chilikin@intel.com>
> Subject: Re: [PATCH] ethdev: increase flow type limit from 32 to 64
>
> Hi Kirill,
>
> On Mon, Nov 27, 2017 at 12:29:47PM +0000, Kirill Rybalchenko wrote:
> > Increase the internal limit for flow types from 32 to 64 to support
> > future flow type extensions.
> > Change type of variables from uint32_t[] to uint64_t[]:
> > rte_eth_fdir_info.flow_types_mask
> > rte_eth_hash_global_conf.sym_hash_enable_mask
> > rte_eth_hash_global_conf.valid_bit_mask
> >
> > This modification affects the following components:
> > net/i40e
> > net/enic
> > net/mlx5
> > net/ixgbe
> > app/testpmd
> >
> > Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
>
> Can you elaborate a bit on the need for these changes?
> Have you considered implementing those future extensions through
> rte_flow instead?
Hi Adrien, this is not a new feature but rather fix of existing limitation.
In current implementation the symmetric hash mask and flow mask are
represented by 32-bit variable, while hardware bitmask has 64 bits.
Unfortunately, this modification changes ABI of the library as it changes size
of rte_eth_fdir_info structure. All related PMDs (listed above) had to be modified
accordingly.
>
> --
> Adrien Mazarguil
> 6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/1] eal: return true or false from lcore role check function
@ 2018-01-09 16:44 4% ` Aaron Conole
2018-01-11 23:09 4% ` Carrillo, Erik G
0 siblings, 1 reply; 200+ results
From: Aaron Conole @ 2018-01-09 16:44 UTC (permalink / raw)
To: Erik Gabriel Carrillo; +Cc: pbhagavatula, harry.van.haaren, dev
Hi Erik,
Erik Gabriel Carrillo <erik.g.carrillo@intel.com> writes:
> Update rte_lcore_has_role() so that it returns true/false instead of
> success/failure.
>
> Fixes: 78666372fa2b ("eal: add function to check lcore role")
>
> Signed-off-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> ---
I believe this breaks the published abi - Success is now 'true', and
failure is 'false'; previously success would be 0 == false. You'll
need to invert the test, or note that the abi is breaking (since
semantically any caller will need to invert the test).
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 1/2] mbuf: update default Mempool ops with HW active pool
2017-12-28 12:07 3% ` Hemant Agrawal
@ 2018-01-10 12:49 0% ` Hemant Agrawal
0 siblings, 0 replies; 200+ results
From: Hemant Agrawal @ 2018-01-10 12:49 UTC (permalink / raw)
To: Olivier MATZ; +Cc: Jerin Jacob, santosh.shukla, dev
Hi Olivier,
>> I just feel it's a bit messy to have:
>>
>> - rte_eal_mbuf_default_mempool_ops() in eal API
>> return user-selected ops if any, or compile-time default
>>
>> - rte_pktmbuf_active_mempool_ops() in mbuf API
>> return platform ops except if a selected user ops != compile default
>>
>> Thomas suggested somewhere (but I don't remember in which thread) to have
>> rte_eal_mbuf_default_mempool_ops() in mbuf code, and I think he was
>> right.
>>
>
> The idea is good. It will break ABI, but we can move around in
> systematic way.
>
>> I think the whole mbuf pool ops selection mechanism should be at the
>> same place. I could be in a specific file of librte_mbuf.
>>
I have just tried to implement your suggestions. I need one clarification.
Eal based internal config is being used to store the command line
mempool_ops_name.
If we want it to be a mbuf based API (instead of eal_mbuf), we need to
export internal_config via map file for shared build.
Are you fine with that?
If not, we have to live with eal_mbuf APIs only.
Regards,
Hemant
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: increase flow type limit from 32 to 64
2018-01-09 15:16 3% ` Rybalchenko, Kirill
@ 2018-01-10 13:50 3% ` Thomas Monjalon
2018-01-16 11:13 0% ` Adrien Mazarguil
1 sibling, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-01-10 13:50 UTC (permalink / raw)
To: Rybalchenko, Kirill
Cc: dev, Adrien Mazarguil, Wu, Jingjing, Xing, Beilei, johndale,
neescoba, nelio.laranjeiro, yskoh, Lu, Wenzhuo, Ananyev,
Konstantin, Chilikin, Andrey
Hi,
09/01/2018 16:16, Rybalchenko, Kirill:
> From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > On Mon, Nov 27, 2017 at 12:29:47PM +0000, Kirill Rybalchenko wrote:
> > > Increase the internal limit for flow types from 32 to 64 to support
> > > future flow type extensions.
> > > Change type of variables from uint32_t[] to uint64_t[]:
> > > rte_eth_fdir_info.flow_types_mask
> > > rte_eth_hash_global_conf.sym_hash_enable_mask
> > > rte_eth_hash_global_conf.valid_bit_mask
> > >
> > > This modification affects the following components:
> > > net/i40e
> > > net/enic
> > > net/mlx5
> > > net/ixgbe
> > > app/testpmd
> > >
> > > Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> >
> > Can you elaborate a bit on the need for these changes?
> > Have you considered implementing those future extensions through
> > rte_flow instead?
>
> Hi Adrien, this is not a new feature but rather fix of existing limitation.
> In current implementation the symmetric hash mask and flow mask are
> represented by 32-bit variable, while hardware bitmask has 64 bits.
> Unfortunately, this modification changes ABI of the library as it changes size
> of rte_eth_fdir_info structure. All related PMDs (listed above) had to be modified
> accordingly.
This ABI change is not announced.
Unfortunately it will have to wait the release 18.05.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH V9 1/5] eal: add uevent monitor api and callback func
@ 2018-01-11 1:43 4% ` Thomas Monjalon
2018-01-11 14:24 0% ` Guo, Jia
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-11 1:43 UTC (permalink / raw)
To: Jeff Guo
Cc: dev, stephen, bruce.richardson, ferruh.yigit, gaetan.rivet,
konstantin.ananyev, jblunck, shreyansh.jain, jingjing.wu,
helin.zhang, motih
Hi,
Thanks for splitting the patches.
I will review the first one today. Please see below.
10/01/2018 10:12, Jeff Guo:
> --- /dev/null
> +++ b/lib/librte_eal/bsdapp/eal/eal_dev.c
> +int
> +rte_dev_monitor_start(void)
> +{
> + return -1;
> +}
> +
> +int
> +rte_dev_monitor_stop(void)
> +{
> + return -1;
> +}
You should add a log to show it is not supported.
> --- /dev/null
> +++ b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dev.h
> +#ifndef _RTE_DEV_H_
> +#error "don't include this file directly, please include generic <rte_dev.h>"
> +#endif
Why creating different rte_dev.h for BSD and Linux?
This is an API, it should be the same.
> +/**
> + * Start the device uevent monitoring.
> + *
> + * @param none
> + * @return
> + * - On success, zero.
> + * - On failure, a negative value.
> + */
> +int
> +rte_dev_monitor_start(void);
> +
> +/**
> + * Stop the device uevent monitoring .
> + *
> + * @param none
> + * @return
> + * - On success, zero.
> + * - On failure, a negative value.
> + */
> +
> +int
> +rte_dev_monitor_stop(void);
> --- a/lib/librte_eal/common/eal_common_dev.c
> +++ b/lib/librte_eal/common/eal_common_dev.c
> @@ -42,9 +42,32 @@
> #include <rte_devargs.h>
> #include <rte_debug.h>
> #include <rte_log.h>
> +#include <rte_spinlock.h>
> +#include <rte_malloc.h>
>
> #include "eal_private.h"
>
> +/* spinlock for device callbacks */
> +static rte_spinlock_t rte_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
Please rename to rte_dev_event_lock.
Let's use rte_dev_event_ prefix consistently.
> + * The user application callback description.
> + *
> + * It contains callback address to be registered by user application,
> + * the pointer to the parameters for callback, and the event type.
> + */
> +struct rte_eal_dev_callback {
Rename to rte_dev_event?
> + TAILQ_ENTRY(rte_eal_dev_callback) next; /**< Callbacks list */
> + rte_eal_dev_cb_fn cb_fn; /**< Callback address */
Rename to rte_dev_event_callback?
> + void *cb_arg; /**< Parameter for callback */
Comment should be about opaque context.
> + void *ret_param; /**< Return parameter */
> + enum rte_dev_event_type event; /**< device event type */
> + uint32_t active; /**< Callback is executing */
Why active is needed?
> +};
> +
> +/* A genaral callback for all new devices be added onto the bus */
> +static struct rte_eal_dev_callback *dev_add_cb;
It should not be a different callback for new devices.
You must allow registering the callback for all and new devices.
Please look how it's done for ethdev:
https://dpdk.org/patch/32900/
> +int
> +rte_dev_callback_register(struct rte_device *device,
> + enum rte_dev_event_type event,
> + rte_eal_dev_cb_fn cb_fn, void *cb_arg)
> +{
Why passing an event type at registration?
I think the event processing dispatch must be done in the callback,
not at registration.
> + /* allocate a new interrupt callback entity */
> + user_cb = rte_zmalloc("eal device event",
> + sizeof(*user_cb), 0);
No need to use rte_malloc here.
Please check this callback API patch:
https://dpdk.org/patch/33144/
> --- a/lib/librte_eal/common/include/rte_dev.h
> +++ b/lib/librte_eal/common/include/rte_dev.h
> +enum uev_monitor_netlink_group {
> + UEV_MONITOR_KERNEL,
> + UEV_MONITOR_UDEV,
> +};
Please keep a namespace prefix like RTE_DEV_EVENT_ (same for enum name).
Some comments are missing for these constants.
> +/**
> + * The device event type.
> + */
> +enum rte_dev_event_type {
> + RTE_DEV_EVENT_UNKNOWN, /**< unknown event type */
> + RTE_DEV_EVENT_ADD, /**< device being added */
> + RTE_DEV_EVENT_REMOVE,
> + /**< device being removed */
> + RTE_DEV_EVENT_CHANGE,
> + /**< device status being changed,
> + * etc charger percent
> + */
What means status changed?
What means charger percent?
> + RTE_DEV_EVENT_MOVE, /**< device sysfs path being moved */
sysfs is Linux specific
> + RTE_DEV_EVENT_ONLINE, /**< device being enable */
You mean a device can be added but not enabled?
So enabling is switching it on by a register? or something else?
> + RTE_DEV_EVENT_OFFLINE, /**< device being disable */
> + RTE_DEV_EVENT_MAX /**< max value of this enum */
> +};
> +
> +struct rte_eal_uevent {
> + enum rte_dev_event_type type; /**< device event type */
> + int subsystem; /**< subsystem id */
> + char *devname; /**< device name */
> + enum uev_monitor_netlink_group group; /**< device netlink group */
> +};
I don't understand why this struct is exposed in the public API.
Please rename from rte_eal_ to rte_dev_.
> @@ -166,6 +204,8 @@ struct rte_device {
> const struct rte_driver *driver;/**< Associated driver */
> int numa_node; /**< NUMA node connection */
> struct rte_devargs *devargs; /**< Device user arguments */
> + /** User application callbacks for device event */
> + struct rte_eal_dev_cb_list uev_cbs;
Do not use uev word in API, it refers to uevent which is implementation
specific. You can name it event_callbacks.
I am afraid this change is breaking the ABI.
For the first time, 18.02 will be ABI stable.
> +/**
> + * It registers the callback for the specific event. Multiple
> + * callbacks cal be registered at the same time.
> + * @param event
> + * The device event type.
> + * @param cb_fn
> + * callback address.
> + * @param cb_arg
> + * address of parameter for callback.
> + *
> + * @return
> + * - On success, zero.
> + * - On failure, a negative value.
> + */
> +int rte_dev_callback_register(struct rte_device *device,
> + enum rte_dev_event_type event,
> + rte_eal_dev_cb_fn cb_fn, void *cb_arg);
> +
> +/**
> + * It unregisters the callback according to the specified event.
> + *
> + * @param event
> + * The event type which corresponding to the callback.
> + * @param cb_fn
> + * callback address.
> + * address of parameter for callback, (void *)-1 means to remove all
> + * registered which has the same callback address.
> + *
> + * @return
> + * - On success, return the number of callback entities removed.
> + * - On failure, a negative value.
> + */
> +int rte_dev_callback_unregister(struct rte_device *device,
> + enum rte_dev_event_type event,
> + rte_eal_dev_cb_fn cb_fn, void *cb_arg);
Such new functions should be added as experimental.
There will be probably more to review in this patch.
Let's progress on these comments please.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH V9 1/5] eal: add uevent monitor api and callback func
2018-01-11 1:43 4% ` Thomas Monjalon
@ 2018-01-11 14:24 0% ` Guo, Jia
0 siblings, 0 replies; 200+ results
From: Guo, Jia @ 2018-01-11 14:24 UTC (permalink / raw)
To: Thomas Monjalon
Cc: dev, stephen, bruce.richardson, ferruh.yigit, gaetan.rivet,
konstantin.ananyev, jblunck, shreyansh.jain, jingjing.wu,
helin.zhang, motih
On 1/11/2018 9:43 AM, Thomas Monjalon wrote:
> Hi,
>
> Thanks for splitting the patches.
> I will review the first one today. Please see below.
>
> 10/01/2018 10:12, Jeff Guo:
>> --- /dev/null
>> +++ b/lib/librte_eal/bsdapp/eal/eal_dev.c
>> +int
>> +rte_dev_monitor_start(void)
>> +{
>> + return -1;
>> +}
>> +
>> +int
>> +rte_dev_monitor_stop(void)
>> +{
>> + return -1;
>> +}
> You should add a log to show it is not supported.
ok.
>> --- /dev/null
>> +++ b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dev.h
>> +#ifndef _RTE_DEV_H_
>> +#error "don't include this file directly, please include generic <rte_dev.h>"
>> +#endif
> Why creating different rte_dev.h for BSD and Linux?
> This is an API, it should be the same.
if no need at this time, combine it to a file.
>> +/**
>> + * Start the device uevent monitoring.
>> + *
>> + * @param none
>> + * @return
>> + * - On success, zero.
>> + * - On failure, a negative value.
>> + */
>> +int
>> +rte_dev_monitor_start(void);
>> +
>> +/**
>> + * Stop the device uevent monitoring .
>> + *
>> + * @param none
>> + * @return
>> + * - On success, zero.
>> + * - On failure, a negative value.
>> + */
>> +
>> +int
>> +rte_dev_monitor_stop(void);
>> --- a/lib/librte_eal/common/eal_common_dev.c
>> +++ b/lib/librte_eal/common/eal_common_dev.c
>> @@ -42,9 +42,32 @@
>> #include <rte_devargs.h>
>> #include <rte_debug.h>
>> #include <rte_log.h>
>> +#include <rte_spinlock.h>
>> +#include <rte_malloc.h>
>>
>> #include "eal_private.h"
>>
>> +/* spinlock for device callbacks */
>> +static rte_spinlock_t rte_dev_cb_lock = RTE_SPINLOCK_INITIALIZER;
> Please rename to rte_dev_event_lock.
> Let's use rte_dev_event_ prefix consistently.
make consistently, agree.
>> + * The user application callback description.
>> + *
>> + * It contains callback address to be registered by user application,
>> + * the pointer to the parameters for callback, and the event type.
>> + */
>> +struct rte_eal_dev_callback {
> Rename to rte_dev_event?
>> + TAILQ_ENTRY(rte_eal_dev_callback) next; /**< Callbacks list */
>> + rte_eal_dev_cb_fn cb_fn; /**< Callback address */
> Rename to rte_dev_event_callback?
>> + void *cb_arg; /**< Parameter for callback */
> Comment should be about opaque context.
>> + void *ret_param; /**< Return parameter */
>> + enum rte_dev_event_type event; /**< device event type */
>> + uint32_t active; /**< Callback is executing */
> Why active is needed?
avoid the lock when unregistered callback.
>> +};
>> +
>> +/* A genaral callback for all new devices be added onto the bus */
>> +static struct rte_eal_dev_callback *dev_add_cb;
> It should not be a different callback for new devices.
> You must allow registering the callback for all and new devices.
> Please look how it's done for ethdev:
> https://dpdk.org/patch/32900/
the aim to use this special callback is because when new device add onto
the bus, no device instance to store the callback. i saw ethdev
solution, that is base on port but that would not make sense in rte
device layer. so
i try to abandon add callback in rte device, replace of add device name
into callback , please see my v10 patch.
>> +int
>> +rte_dev_callback_register(struct rte_device *device,
>> + enum rte_dev_event_type event,
>> + rte_eal_dev_cb_fn cb_fn, void *cb_arg)
>> +{
> Why passing an event type at registration?
> I think the event processing dispatch must be done in the callback,
> not at registration.
make sense, just register all type for device ,and let eal to pass the
event.
>> + /* allocate a new interrupt callback entity */
>> + user_cb = rte_zmalloc("eal device event",
>> + sizeof(*user_cb), 0);
> No need to use rte_malloc here.
> Please check this callback API patch:
> https://dpdk.org/patch/33144/
could be better to concentration the code. but if you could tell me why
not use rte_zmalloc.
>> --- a/lib/librte_eal/common/include/rte_dev.h
>> +++ b/lib/librte_eal/common/include/rte_dev.h
>> +enum uev_monitor_netlink_group {
>> + UEV_MONITOR_KERNEL,
>> + UEV_MONITOR_UDEV,
>> +};
> Please keep a namespace prefix like RTE_DEV_EVENT_ (same for enum name).
> Some comments are missing for these constants.
>> +/**
>> + * The device event type.
>> + */
>> +enum rte_dev_event_type {
>> + RTE_DEV_EVENT_UNKNOWN, /**< unknown event type */
>> + RTE_DEV_EVENT_ADD, /**< device being added */
>> + RTE_DEV_EVENT_REMOVE,
>> + /**< device being removed */
>> + RTE_DEV_EVENT_CHANGE,
>> + /**< device status being changed,
>> + * etc charger percent
>> + */
> What means status changed?
> What means charger percent?
status changed means that object path change or other more, charger
percent just a example for some kobject status. so i don't think we
should explicit identify all , i will delete it until we want to use it.
>> + RTE_DEV_EVENT_MOVE, /**< device sysfs path being moved */
> sysfs is Linux specific
>
>> + RTE_DEV_EVENT_ONLINE, /**< device being enable */
> You mean a device can be added but not enabled?
> So enabling is switching it on by a register? or something else?
>
>> + RTE_DEV_EVENT_OFFLINE, /**< device being disable */
>> + RTE_DEV_EVENT_MAX /**< max value of this enum */
>> +};
>> +
>> +struct rte_eal_uevent {
>> + enum rte_dev_event_type type; /**< device event type */
>> + int subsystem; /**< subsystem id */
>> + char *devname; /**< device name */
>> + enum uev_monitor_netlink_group group; /**< device netlink group */
>> +};
> I don't understand why this struct is exposed in the public API.
> Please rename from rte_eal_ to rte_dev_.
will modify the uevent to event.
>> @@ -166,6 +204,8 @@ struct rte_device {
>> const struct rte_driver *driver;/**< Associated driver */
>> int numa_node; /**< NUMA node connection */
>> struct rte_devargs *devargs; /**< Device user arguments */
>> + /** User application callbacks for device event */
>> + struct rte_eal_dev_cb_list uev_cbs;
> Do not use uev word in API, it refers to uevent which is implementation
> specific. You can name it event_callbacks.
>
> I am afraid this change is breaking the ABI.
> For the first time, 18.02 will be ABI stable.
will not modify rte device struct in v10.
>> +/**
>> + * It registers the callback for the specific event. Multiple
>> + * callbacks cal be registered at the same time.
>> + * @param event
>> + * The device event type.
>> + * @param cb_fn
>> + * callback address.
>> + * @param cb_arg
>> + * address of parameter for callback.
>> + *
>> + * @return
>> + * - On success, zero.
>> + * - On failure, a negative value.
>> + */
>> +int rte_dev_callback_register(struct rte_device *device,
>> + enum rte_dev_event_type event,
>> + rte_eal_dev_cb_fn cb_fn, void *cb_arg);
>> +
>> +/**
>> + * It unregisters the callback according to the specified event.
>> + *
>> + * @param event
>> + * The event type which corresponding to the callback.
>> + * @param cb_fn
>> + * callback address.
>> + * address of parameter for callback, (void *)-1 means to remove all
>> + * registered which has the same callback address.
>> + *
>> + * @return
>> + * - On success, return the number of callback entities removed.
>> + * - On failure, a negative value.
>> + */
>> +int rte_dev_callback_unregister(struct rte_device *device,
>> + enum rte_dev_event_type event,
>> + rte_eal_dev_cb_fn cb_fn, void *cb_arg);
> Such new functions should be added as experimental.
>
> There will be probably more to review in this patch.
> Let's progress on these comments please.
thanks for your review!
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] doc: ethdev ABI change deprecation notice
@ 2018-01-11 14:47 11% Kirill Rybalchenko
2018-01-12 10:19 4% ` Kovacevic, Marko
2018-01-12 10:27 11% ` [dpdk-dev] [PATCH v2] " Kirill Rybalchenko
0 siblings, 2 replies; 200+ results
From: Kirill Rybalchenko @ 2018-01-11 14:47 UTC (permalink / raw)
To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, nhorman, thomas
Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..f0589ea 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -45,6 +45,12 @@ Deprecation Notices
Target release for removal of the legacy API will be defined once most
PMDs have switched to rte_flow.
+* ethdev: anounce ABI change
+ The size of variables flow_types_mask in rte_eth_fdir_info structure,
+ sym_hash_enable_mask and valid_bit_mask in rte_eth_hash_global_conf structure
+ will be increased from 32 to 64 bits to fulfill hardware requirements.
+ This change will break existing ABI as size of the structures will increase.
+
* i40e: The default flexible payload configuration which extracts the first 16
bytes of the payload for RSS will be deprecated starting from 18.02. If
required the previous behavior can be configured using existing flow
--
2.5.5
^ permalink raw reply [relevance 11%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2017-12-13 15:17 10% ` [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation Neil Horman
2017-12-13 15:32 4% ` Bruce Richardson
@ 2018-01-11 20:06 4% ` Ferruh Yigit
2018-01-11 21:29 4% ` Neil Horman
1 sibling, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-01-11 20:06 UTC (permalink / raw)
To: Neil Horman, dev; +Cc: thomas, john.mcnamara, bruce.richardson
On 12/13/2017 3:17 PM, Neil Horman wrote:
> Document the need to add the __experimental tag to appropriate functions
>
> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> CC: Thomas Monjalon <thomas@monjalon.net>
> CC: "Mcnamara, John" <john.mcnamara@intel.com>
> CC: Bruce Richardson <bruce.richardson@intel.com>
> ---
> doc/guides/contributing/versioning.rst | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
> index 400090628..53f56397e 100644
> --- a/doc/guides/contributing/versioning.rst
> +++ b/doc/guides/contributing/versioning.rst
> @@ -50,6 +50,15 @@ those new APIs and start finding issues with them, new DPDK APIs will be
> automatically marked as ``experimental`` to allow for a period of stabilization
> before they become part of a tracked ABI.
>
> +Note that marking an API as experimental is a two step process. To mark an API
> +as experimental, the symbols which are desired to be exported must be placed in
> +an EXPERIMENTAL version block in the corresponding libraries' version map
> +script. Secondly, the corresponding definitions of those exported functions, and
> +their forward declarations (in the development header files), must be marked
> +with the __experimental tag (see rte_compat.h). The DPDK build makefiles
> +preform a check to ensure that the map file and the C code reflect the same
> +list of symbols.
There are more steps we historically do to mark an API as experimental:
- Add to function header comment experimental for API documentation, preferably
with a warning tag to highlight it:
/**
* @warning
* @b EXPERIMENTAL:
....
*/
- If whole APIs in header file are experimental, add same experimental warning
doxygen comment in file comment, again preferably with warning.
- If whole library is experimental, put EXPERIMENTAL tag into maintainers file
as well.
> +
> ABI versions, once released, are available until such time as their
> deprecation has been noted in the Release Notes for at least one major release
> cycle. For example consider the case where the ABI for DPDK 2.0 has been
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv4 4/5] dpdk: add __experimental tag to appropriate api calls
@ 2018-01-11 21:24 5% ` Neil Horman
2018-01-12 11:50 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2018-01-11 21:24 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, thomas, john.mcnamara, bruce.richardson
On Thu, Jan 11, 2018 at 08:06:33PM +0000, Ferruh Yigit wrote:
> On 12/13/2017 3:17 PM, Neil Horman wrote:
> > Append the __experimental tag to api calls appearing in the EXPERIMENTAL
> > section of their libraries version map
> >
> > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > CC: Thomas Monjalon <thomas@monjalon.net>
> > CC: "Mcnamara, John" <john.mcnamara@intel.com>
> > CC: Bruce Richardson <bruce.richardson@intel.com>
> > ---
> > lib/librte_eal/common/eal_common_dev.c | 6 ++-
> > lib/librte_eal/common/eal_common_devargs.c | 7 +--
> > lib/librte_eal/common/include/rte_dev.h | 6 ++-
> > lib/librte_eal/common/include/rte_devargs.h | 8 ++--
> > lib/librte_eal/common/include/rte_service.h | 47 ++++++++++---------
> > .../common/include/rte_service_component.h | 14 +++---
> > lib/librte_eal/common/rte_service.c | 52 ++++++++++++----------
> > lib/librte_eal/linuxapp/eal/eal.c | 1 +
> > lib/librte_ether/rte_mtr.c | 25 ++++++-----
> > lib/librte_ether/rte_mtr.h | 26 +++++------
> > lib/librte_flow_classify/rte_flow_classify.c | 13 +++---
> > lib/librte_flow_classify/rte_flow_classify.h | 11 ++---
> > lib/librte_security/rte_security.c | 16 +++----
> > lib/librte_security/rte_security.h | 23 +++++-----
>
> It may not be the responsibility of this patchset, but there are more
> experimental APIs in DPDK.
>
Thats an interesting statement to make. This patchset creates a build time
check that compares symbols located in the EXPERIMENTAL version section of a
libraries' version map file to the symbols that are marked with this new tag,
throwing an error if they don't match. I believe what you say in that there may
be additional APIs that are experimental, but given that, I would have to
conclude one of the following:
1) The missing API's are macros or static inline functions that are not exported
from libraries directly
2) The documentation for experimental API's are out of sync, in that they have
legitimately moved to be supported API's and the documentation needs to be
updated
3) There are API's which are experimental that have been incorrectly placed in a
versioned tag.
I made a pretty good effort to scan comments for the word EXPERIMENTAL so that I
could catch item (1). And while I may not have caught them all, I'd like to
think I got a good chunk of them. That leaves cleanup of (2) and (3), which I
think this patchset can help us idenfity.
> Using EXPERIMENTAL tag in linker script is relatively new approach and this was
> not a requirement, so many experimental APIs are documented in API documentation
> (header file doxygen comment).
> Sample: librte_member
>
That sounds like case (3) above.
Thats a bit odd. I understand that the use of the EXPERIMENTAL version tag is
new, but once it was introduced it should have been made a requirement. There
would have been no penalty for moving the version number (as doing so would not
have violated ABI guarantees, given that those API's were appropriately
documented as experimental). If they have not been, then the use of the
EXPERIMENTAL tag isn't overly useful, as it doesn't provide any segregation of
the stable ABI from the unstable ABI.
> It is required to scan all header files and update their linker scripts for the
> experimental APIs.
>
Yes and no. If a given library is not marked as experimental in its version
map, this change won't flag it as a problem, but if its intended to be
experimental (i.e. if its likely to have its ABI fluctuate), then yes, we should
take the appropriate steps to flag it as such properly.
If a given library is intended to be experimental, I would say yes,
the author should make the appropriate chage to the version map, and then the
corresponding change to the headers and c files with this new tag.
Alternatively, they might choose to simply update the documentation to reflect
the fact that the ABI for that library is now stable.
The thing that should definately not hapen though, is a half measure. We
shouldn't allow libraries to call themselves experimental, and then excuse them
from any rules we have regarding their in-code representation. If we have an
EXPERIMENTAL version in the map, we should require its use, and by extension
require this tag when its merged for the reasons previously outlined
Neil
> > 14 files changed, 139 insertions(+), 116 deletions(-)
>
> <...>
>
>
^ permalink raw reply [relevance 5%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2018-01-11 20:06 4% ` Ferruh Yigit
@ 2018-01-11 21:29 4% ` Neil Horman
2018-01-12 11:50 7% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2018-01-11 21:29 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, thomas, john.mcnamara, bruce.richardson
On Thu, Jan 11, 2018 at 08:06:48PM +0000, Ferruh Yigit wrote:
> On 12/13/2017 3:17 PM, Neil Horman wrote:
> > Document the need to add the __experimental tag to appropriate functions
> >
> > Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> > CC: Thomas Monjalon <thomas@monjalon.net>
> > CC: "Mcnamara, John" <john.mcnamara@intel.com>
> > CC: Bruce Richardson <bruce.richardson@intel.com>
> > ---
> > doc/guides/contributing/versioning.rst | 9 +++++++++
> > 1 file changed, 9 insertions(+)
> >
> > diff --git a/doc/guides/contributing/versioning.rst b/doc/guides/contributing/versioning.rst
> > index 400090628..53f56397e 100644
> > --- a/doc/guides/contributing/versioning.rst
> > +++ b/doc/guides/contributing/versioning.rst
> > @@ -50,6 +50,15 @@ those new APIs and start finding issues with them, new DPDK APIs will be
> > automatically marked as ``experimental`` to allow for a period of stabilization
> > before they become part of a tracked ABI.
> >
> > +Note that marking an API as experimental is a two step process. To mark an API
> > +as experimental, the symbols which are desired to be exported must be placed in
> > +an EXPERIMENTAL version block in the corresponding libraries' version map
> > +script. Secondly, the corresponding definitions of those exported functions, and
> > +their forward declarations (in the development header files), must be marked
> > +with the __experimental tag (see rte_compat.h). The DPDK build makefiles
> > +preform a check to ensure that the map file and the C code reflect the same
> > +list of symbols.
>
> There are more steps we historically do to mark an API as experimental:
> - Add to function header comment experimental for API documentation, preferably
> with a warning tag to highlight it:
>
> /**
> * @warning
> * @b EXPERIMENTAL:
> ....
> */
>
> - If whole APIs in header file are experimental, add same experimental warning
> doxygen comment in file comment, again preferably with warning.
>
> - If whole library is experimental, put EXPERIMENTAL tag into maintainers file
> as well.
>
Is that documented somewhere? I'd like to add this to the same location that it
otherwise is written out. The above location was the only place in the guide
that I could find reference to experimental markings.
> > +
> > ABI versions, once released, are available until such time as their
> > deprecation has been noted in the Release Notes for at least one major release
> > cycle. For example consider the case where the ABI for DPDK 2.0 has been
> >
>
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2] eal: add function to return number of detected sockets
@ 2018-01-11 22:20 3% ` Thomas Monjalon
2018-01-12 11:44 0% ` Burakov, Anatoly
2018-01-16 17:53 17% ` [dpdk-dev] [PATCH] doc: add ABI change notice for numa_node_count in eal Anatoly Burakov
1 sibling, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-11 22:20 UTC (permalink / raw)
To: Anatoly Burakov; +Cc: dev
22/12/2017 13:41, Anatoly Burakov:
> During lcore scan, find maximum socket ID and store it.
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> ---
> --- a/lib/librte_eal/common/include/rte_eal.h
> +++ b/lib/librte_eal/common/include/rte_eal.h
> @@ -83,6 +83,7 @@ enum rte_proc_type_t {
> struct rte_config {
> uint32_t master_lcore; /**< Id of the master lcore */
> uint32_t lcore_count; /**< Number of available logical cores. */
> + uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
> uint32_t service_lcore_count;/**< Number of available service cores. */
> enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
isn't it breaking the ABI?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/1] eal: return true or false from lcore role check function
2018-01-09 16:44 4% ` Aaron Conole
@ 2018-01-11 23:09 4% ` Carrillo, Erik G
2018-01-11 23:17 3% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Carrillo, Erik G @ 2018-01-11 23:09 UTC (permalink / raw)
To: Aaron Conole; +Cc: pbhagavatula, Van Haaren, Harry, dev
Hi Aaron,
> -----Original Message-----
> From: Aaron Conole [mailto:aconole@redhat.com]
> Sent: Tuesday, January 9, 2018 10:45 AM
> To: Carrillo, Erik G <erik.g.carrillo@intel.com>
> Cc: pbhagavatula@caviumnetworks.com; Van Haaren, Harry
> <harry.van.haaren@intel.com>; dev@dpdk.org
> Subject: Re: [dpdk-dev] [PATCH 1/1] eal: return true or false from lcore role
> check function
>
> Hi Erik,
>
> Erik Gabriel Carrillo <erik.g.carrillo@intel.com> writes:
>
> > Update rte_lcore_has_role() so that it returns true/false instead of
> > success/failure.
> >
> > Fixes: 78666372fa2b ("eal: add function to check lcore role")
> >
> > Signed-off-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> > ---
>
> I believe this breaks the published abi - Success is now 'true', and failure is
> 'false'; previously success would be 0 == false. You'll need to invert the test,
> or note that the abi is breaking (since semantically any caller will need to
> invert the test).
Good point. Though it seems like an API change rather than an ABI change to me, would it still be handled the same way in terms of notice? Also, the ABI policy states, "ABI breakage due to changes such as reorganizing public structure fields for aesthetic or readability purposes should be avoided." Perhaps I should go with an alternate patch that fixes the caller.
Thanks,
Erik
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 1/1] eal: return true or false from lcore role check function
2018-01-11 23:09 4% ` Carrillo, Erik G
@ 2018-01-11 23:17 3% ` Thomas Monjalon
2018-01-12 18:01 0% ` Carrillo, Erik G
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-11 23:17 UTC (permalink / raw)
To: Carrillo, Erik G; +Cc: dev, Aaron Conole, pbhagavatula, Van Haaren, Harry
12/01/2018 00:09, Carrillo, Erik G:
> Hi Aaron,
>
> From: Aaron Conole [mailto:aconole@redhat.com]
> >
> > Hi Erik,
> >
> > Erik Gabriel Carrillo <erik.g.carrillo@intel.com> writes:
> >
> > > Update rte_lcore_has_role() so that it returns true/false instead of
> > > success/failure.
> > >
> > > Fixes: 78666372fa2b ("eal: add function to check lcore role")
> > >
> > > Signed-off-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> > > ---
> >
> > I believe this breaks the published abi - Success is now 'true', and failure is
> > 'false'; previously success would be 0 == false. You'll need to invert the test,
> > or note that the abi is breaking (since semantically any caller will need to
> > invert the test).
>
> Good point. Though it seems like an API change rather than an ABI change to me, would it still be handled the same way in terms of notice? Also, the ABI policy states, "ABI breakage due to changes such as reorganizing public structure fields for aesthetic or readability purposes should be avoided." Perhaps I should go with an alternate patch that fixes the caller.
Most of the times, an API change is an ABI change.
Please make a deprecation notice.
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] doc: ethdev ABI change deprecation notice
2018-01-11 14:47 11% [dpdk-dev] [PATCH] doc: ethdev ABI change deprecation notice Kirill Rybalchenko
@ 2018-01-12 10:19 4% ` Kovacevic, Marko
2018-01-12 10:27 11% ` [dpdk-dev] [PATCH v2] " Kirill Rybalchenko
1 sibling, 0 replies; 200+ results
From: Kovacevic, Marko @ 2018-01-12 10:19 UTC (permalink / raw)
To: Rybalchenko, Kirill, dev; +Cc: Chilikin, Andrey, nhorman, thomas
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> +* ethdev: anounce ABI change
^^^^^^^^
One small typo announce
> + The size of variables flow_types_mask in rte_eth_fdir_info structure,
> + sym_hash_enable_mask and valid_bit_mask in rte_eth_hash_global_conf
> structure
> + will be increased from 32 to 64 bits to fulfill hardware requirements.
> + This change will break existing ABI as size of the structures will increase.
> +
> * i40e: The default flexible payload configuration which extracts the first 16
> bytes of the payload for RSS will be deprecated starting from 18.02. If
> required the previous behavior can be configured using existing flow
You can add my ack when changed.
Acked-by: Marko Kovacevic <marko.kovacevic@intel.com>
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2] doc: ethdev ABI change deprecation notice
2018-01-11 14:47 11% [dpdk-dev] [PATCH] doc: ethdev ABI change deprecation notice Kirill Rybalchenko
2018-01-12 10:19 4% ` Kovacevic, Marko
@ 2018-01-12 10:27 11% ` Kirill Rybalchenko
2018-01-12 10:29 11% ` [dpdk-dev] [PATCH v3] " Kirill Rybalchenko
1 sibling, 1 reply; 200+ results
From: Kirill Rybalchenko @ 2018-01-12 10:27 UTC (permalink / raw)
To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, nhorman, thomas
Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
Acked-by: Marko Kovacevic <marko.kovacevic@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..f0589ea 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -45,6 +45,12 @@ Deprecation Notices
Target release for removal of the legacy API will be defined once most
PMDs have switched to rte_flow.
+* ethdev: anounce ABI change
+ The size of variables flow_types_mask in rte_eth_fdir_info structure,
+ sym_hash_enable_mask and valid_bit_mask in rte_eth_hash_global_conf structure
+ will be increased from 32 to 64 bits to fulfill hardware requirements.
+ This change will break existing ABI as size of the structures will increase.
+
* i40e: The default flexible payload configuration which extracts the first 16
bytes of the payload for RSS will be deprecated starting from 18.02. If
required the previous behavior can be configured using existing flow
--
2.5.5
^ permalink raw reply [relevance 11%]
* [dpdk-dev] [PATCH v3] doc: ethdev ABI change deprecation notice
2018-01-12 10:27 11% ` [dpdk-dev] [PATCH v2] " Kirill Rybalchenko
@ 2018-01-12 10:29 11% ` Kirill Rybalchenko
2018-01-12 14:38 4% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Kirill Rybalchenko @ 2018-01-12 10:29 UTC (permalink / raw)
To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, nhorman, thomas
Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
Acked-by: Marko Kovacevic <marko.kovacevic@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..aaf306a 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -45,6 +45,12 @@ Deprecation Notices
Target release for removal of the legacy API will be defined once most
PMDs have switched to rte_flow.
+* ethdev: announce ABI change
+ The size of variables flow_types_mask in rte_eth_fdir_info structure,
+ sym_hash_enable_mask and valid_bit_mask in rte_eth_hash_global_conf structure
+ will be increased from 32 to 64 bits to fulfill hardware requirements.
+ This change will break existing ABI as size of the structures will increase.
+
* i40e: The default flexible payload configuration which extracts the first 16
bytes of the payload for RSS will be deprecated starting from 18.02. If
required the previous behavior can be configured using existing flow
--
2.5.5
^ permalink raw reply [relevance 11%]
* Re: [dpdk-dev] [PATCH v2] eal: add function to return number of detected sockets
2018-01-11 22:20 3% ` Thomas Monjalon
@ 2018-01-12 11:44 0% ` Burakov, Anatoly
2018-01-12 11:50 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Burakov, Anatoly @ 2018-01-12 11:44 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On 11-Jan-18 10:20 PM, Thomas Monjalon wrote:
> 22/12/2017 13:41, Anatoly Burakov:
>> During lcore scan, find maximum socket ID and store it.
>>
>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
>> ---
>> --- a/lib/librte_eal/common/include/rte_eal.h
>> +++ b/lib/librte_eal/common/include/rte_eal.h
>> @@ -83,6 +83,7 @@ enum rte_proc_type_t {
>> struct rte_config {
>> uint32_t master_lcore; /**< Id of the master lcore */
>> uint32_t lcore_count; /**< Number of available logical cores. */
>> + uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
>> uint32_t service_lcore_count;/**< Number of available service cores. */
>> enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
>
> isn't it breaking the ABI?
>
>
Yep, you're right, forgot to add that. I didn't expect this to get
merged in 18.02 anyway, so v2 will follow.
--
Thanks,
Anatoly
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv4 4/5] dpdk: add __experimental tag to appropriate api calls
2018-01-11 21:24 5% ` Neil Horman
@ 2018-01-12 11:50 0% ` Ferruh Yigit
2018-01-12 14:25 3% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-01-12 11:50 UTC (permalink / raw)
To: Neil Horman; +Cc: dev, thomas, john.mcnamara, bruce.richardson
On 1/11/2018 9:24 PM, Neil Horman wrote:
> On Thu, Jan 11, 2018 at 08:06:33PM +0000, Ferruh Yigit wrote:
>> On 12/13/2017 3:17 PM, Neil Horman wrote:
>>> Append the __experimental tag to api calls appearing in the EXPERIMENTAL
>>> section of their libraries version map
>>>
>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>>> CC: Thomas Monjalon <thomas@monjalon.net>
>>> CC: "Mcnamara, John" <john.mcnamara@intel.com>
>>> CC: Bruce Richardson <bruce.richardson@intel.com>
>>> ---
>>> lib/librte_eal/common/eal_common_dev.c | 6 ++-
>>> lib/librte_eal/common/eal_common_devargs.c | 7 +--
>>> lib/librte_eal/common/include/rte_dev.h | 6 ++-
>>> lib/librte_eal/common/include/rte_devargs.h | 8 ++--
>>> lib/librte_eal/common/include/rte_service.h | 47 ++++++++++---------
>>> .../common/include/rte_service_component.h | 14 +++---
>>> lib/librte_eal/common/rte_service.c | 52 ++++++++++++----------
>>> lib/librte_eal/linuxapp/eal/eal.c | 1 +
>>> lib/librte_ether/rte_mtr.c | 25 ++++++-----
>>> lib/librte_ether/rte_mtr.h | 26 +++++------
>>> lib/librte_flow_classify/rte_flow_classify.c | 13 +++---
>>> lib/librte_flow_classify/rte_flow_classify.h | 11 ++---
>>> lib/librte_security/rte_security.c | 16 +++----
>>> lib/librte_security/rte_security.h | 23 +++++-----
>>
>> It may not be the responsibility of this patchset, but there are more
>> experimental APIs in DPDK.
>>
> Thats an interesting statement to make. This patchset creates a build time
> check that compares symbols located in the EXPERIMENTAL version section of a
> libraries' version map file to the symbols that are marked with this new tag,
> throwing an error if they don't match. I believe what you say in that there may
> be additional APIs that are experimental, but given that, I would have to
> conclude one of the following:
>
> 1) The missing API's are macros or static inline functions that are not exported
> from libraries directly
>
> 2) The documentation for experimental API's are out of sync, in that they have
> legitimately moved to be supported API's and the documentation needs to be
> updated
>
> 3) There are API's which are experimental that have been incorrectly placed in a
> versioned tag.
>
> I made a pretty good effort to scan comments for the word EXPERIMENTAL so that I
> could catch item (1). And while I may not have caught them all, I'd like to
> think I got a good chunk of them. That leaves cleanup of (2) and (3), which I
> think this patchset can help us idenfity.
>
>> Using EXPERIMENTAL tag in linker script is relatively new approach and this was
>> not a requirement, so many experimental APIs are documented in API documentation
>> (header file doxygen comment).
>> Sample: librte_member
>>
> That sounds like case (3) above.
>
> Thats a bit odd. I understand that the use of the EXPERIMENTAL version tag is
> new, but once it was introduced it should have been made a requirement. There
> would have been no penalty for moving the version number (as doing so would not
> have violated ABI guarantees, given that those API's were appropriately
> documented as experimental). If they have not been, then the use of the
> EXPERIMENTAL tag isn't overly useful, as it doesn't provide any segregation of
> the stable ABI from the unstable ABI.
>
>> It is required to scan all header files and update their linker scripts for the
>> experimental APIs.
>>
> Yes and no. If a given library is not marked as experimental in its version
> map, this change won't flag it as a problem, but if its intended to be
> experimental (i.e. if its likely to have its ABI fluctuate), then yes, we should
> take the appropriate steps to flag it as such properly.
>
> If a given library is intended to be experimental, I would say yes,
> the author should make the appropriate chage to the version map, and then the
> corresponding change to the headers and c files with this new tag.
> Alternatively, they might choose to simply update the documentation to reflect
> the fact that the ABI for that library is now stable.
>
> The thing that should definately not hapen though, is a half measure. We
> shouldn't allow libraries to call themselves experimental, and then excuse them
> from any rules we have regarding their in-code representation. If we have an
> EXPERIMENTAL version in the map, we should require its use, and by extension
> require this tag when its merged for the reasons previously outlined
My comment is for your item (3), but it is not fair to say "incorrectly placed"
because if I don't miss anything this has never been documented as correct way
to do, and lots of the existing usage is _before_ we start using EXPERIMENTAL
tag in the linker script, so they were doing right thing for that time.
Question is, is this patchset should fix them, since now this patchset defines
using EXPERIMENTAL tag in linker script as way to do it, or should we wait
maintainers to fix it after this has been documented. Waiting for maintainer may
take time because not all maintainers are following the mail list closely to
capture all expectations.
>
> Neil
>
>
>>> 14 files changed, 139 insertions(+), 116 deletions(-)
>>
>> <...>
>>
>>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2018-01-11 21:29 4% ` Neil Horman
@ 2018-01-12 11:50 7% ` Ferruh Yigit
2018-01-12 14:37 4% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-01-12 11:50 UTC (permalink / raw)
To: Neil Horman; +Cc: dev, thomas, john.mcnamara, bruce.richardson
On 1/11/2018 9:29 PM, Neil Horman wrote:
> On Thu, Jan 11, 2018 at 08:06:48PM +0000, Ferruh Yigit wrote:
>> On 12/13/2017 3:17 PM, Neil Horman wrote:
>>> Document the need to add the __experimental tag to appropriate functions
>>>
>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>>> CC: Thomas Monjalon <thomas@monjalon.net>
>>> CC: "Mcnamara, John" <john.mcnamara@intel.com>
>>> CC: Bruce Richardson <bruce.richardson@intel.com>
<...>
>>> automatically marked as ``experimental`` to allow for a period of stabilization>>> before they become part of a tracked ABI.
Full sentences for above statement:
"
Since changes to APIs are most likely immediately after their introduction, as
users begin to take advantage of those new APIs and start finding issues with
them, new DPDK APIs will be automatically marked as experimental to allow for a
period of stabilization before they become part of a tracked ABI.
"
This part is not related to this patchset, but it will be hard to maintain above
behavior, "automatically marked" is not automatic now and moving them to stable
after one release is also not automatic. Do you have any suggestion on how to
manage this, do you think can your script be expanded to cover these checks?
>>>
>>> +Note that marking an API as experimental is a two step process. To mark an API
>>> +as experimental, the symbols which are desired to be exported must be placed in
>>> +an EXPERIMENTAL version block in the corresponding libraries' version map
>>> +script. Secondly, the corresponding definitions of those exported functions, and
>>> +their forward declarations (in the development header files), must be marked
>>> +with the __experimental tag (see rte_compat.h). The DPDK build makefiles
>>> +preform a check to ensure that the map file and the C code reflect the same
>>> +list of symbols.
>>
>> There are more steps we historically do to mark an API as experimental:
>> - Add to function header comment experimental for API documentation, preferably
>> with a warning tag to highlight it:
>>
>> /**
>> * @warning
>> * @b EXPERIMENTAL:
>> ....
>> */
>>
>> - If whole APIs in header file are experimental, add same experimental warning
>> doxygen comment in file comment, again preferably with warning.
>>
>> - If whole library is experimental, put EXPERIMENTAL tag into maintainers file
>> as well.
>>
> Is that documented somewhere? I'd like to add this to the same location that it
> otherwise is written out. The above location was the only place in the guide
> that I could find reference to experimental markings.
As far as I know how to mark an API as experimental is not documented.
What do you think making a new section for this information?
>
>>> +
>>> ABI versions, once released, are available until such time as their
>>> deprecation has been noted in the Release Notes for at least one major release
>>> cycle. For example consider the case where the ABI for DPDK 2.0 has been
>>>
>>
>>
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH v2] eal: add function to return number of detected sockets
2018-01-12 11:44 0% ` Burakov, Anatoly
@ 2018-01-12 11:50 0% ` Thomas Monjalon
2018-01-16 11:56 4% ` Burakov, Anatoly
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-12 11:50 UTC (permalink / raw)
To: Burakov, Anatoly; +Cc: dev
12/01/2018 12:44, Burakov, Anatoly:
> On 11-Jan-18 10:20 PM, Thomas Monjalon wrote:
> > 22/12/2017 13:41, Anatoly Burakov:
> >> During lcore scan, find maximum socket ID and store it.
> >>
> >> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> >> ---
> >> --- a/lib/librte_eal/common/include/rte_eal.h
> >> +++ b/lib/librte_eal/common/include/rte_eal.h
> >> @@ -83,6 +83,7 @@ enum rte_proc_type_t {
> >> struct rte_config {
> >> uint32_t master_lcore; /**< Id of the master lcore */
> >> uint32_t lcore_count; /**< Number of available logical cores. */
> >> + uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
> >> uint32_t service_lcore_count;/**< Number of available service cores. */
> >> enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
> >
> > isn't it breaking the ABI?
> >
> >
>
> Yep, you're right, forgot to add that. I didn't expect this to get
> merged in 18.02 anyway, so v2 will follow.
Please write 18.05 in the subject to show your expectation.
Thanks
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv4 4/5] dpdk: add __experimental tag to appropriate api calls
2018-01-12 11:50 0% ` Ferruh Yigit
@ 2018-01-12 14:25 3% ` Neil Horman
2018-01-12 15:53 0% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2018-01-12 14:25 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, thomas, john.mcnamara, bruce.richardson
On Fri, Jan 12, 2018 at 11:50:01AM +0000, Ferruh Yigit wrote:
> On 1/11/2018 9:24 PM, Neil Horman wrote:
> > On Thu, Jan 11, 2018 at 08:06:33PM +0000, Ferruh Yigit wrote:
> >> On 12/13/2017 3:17 PM, Neil Horman wrote:
> >>> Append the __experimental tag to api calls appearing in the EXPERIMENTAL
> >>> section of their libraries version map
> >>>
> >>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> >>> CC: Thomas Monjalon <thomas@monjalon.net>
> >>> CC: "Mcnamara, John" <john.mcnamara@intel.com>
> >>> CC: Bruce Richardson <bruce.richardson@intel.com>
> >>> ---
> >>> lib/librte_eal/common/eal_common_dev.c | 6 ++-
> >>> lib/librte_eal/common/eal_common_devargs.c | 7 +--
> >>> lib/librte_eal/common/include/rte_dev.h | 6 ++-
> >>> lib/librte_eal/common/include/rte_devargs.h | 8 ++--
> >>> lib/librte_eal/common/include/rte_service.h | 47 ++++++++++---------
> >>> .../common/include/rte_service_component.h | 14 +++---
> >>> lib/librte_eal/common/rte_service.c | 52 ++++++++++++----------
> >>> lib/librte_eal/linuxapp/eal/eal.c | 1 +
> >>> lib/librte_ether/rte_mtr.c | 25 ++++++-----
> >>> lib/librte_ether/rte_mtr.h | 26 +++++------
> >>> lib/librte_flow_classify/rte_flow_classify.c | 13 +++---
> >>> lib/librte_flow_classify/rte_flow_classify.h | 11 ++---
> >>> lib/librte_security/rte_security.c | 16 +++----
> >>> lib/librte_security/rte_security.h | 23 +++++-----
> >>
> >> It may not be the responsibility of this patchset, but there are more
> >> experimental APIs in DPDK.
> >>
> > Thats an interesting statement to make. This patchset creates a build time
> > check that compares symbols located in the EXPERIMENTAL version section of a
> > libraries' version map file to the symbols that are marked with this new tag,
> > throwing an error if they don't match. I believe what you say in that there may
> > be additional APIs that are experimental, but given that, I would have to
> > conclude one of the following:
> >
> > 1) The missing API's are macros or static inline functions that are not exported
> > from libraries directly
> >
> > 2) The documentation for experimental API's are out of sync, in that they have
> > legitimately moved to be supported API's and the documentation needs to be
> > updated
> >
> > 3) There are API's which are experimental that have been incorrectly placed in a
> > versioned tag.
> >
> > I made a pretty good effort to scan comments for the word EXPERIMENTAL so that I
> > could catch item (1). And while I may not have caught them all, I'd like to
> > think I got a good chunk of them. That leaves cleanup of (2) and (3), which I
> > think this patchset can help us idenfity.
> >
> >> Using EXPERIMENTAL tag in linker script is relatively new approach and this was
> >> not a requirement, so many experimental APIs are documented in API documentation
> >> (header file doxygen comment).
> >> Sample: librte_member
> >>
> > That sounds like case (3) above.
> >
> > Thats a bit odd. I understand that the use of the EXPERIMENTAL version tag is
> > new, but once it was introduced it should have been made a requirement. There
> > would have been no penalty for moving the version number (as doing so would not
> > have violated ABI guarantees, given that those API's were appropriately
> > documented as experimental). If they have not been, then the use of the
> > EXPERIMENTAL tag isn't overly useful, as it doesn't provide any segregation of
> > the stable ABI from the unstable ABI.
> >
> >> It is required to scan all header files and update their linker scripts for the
> >> experimental APIs.
> >>
> > Yes and no. If a given library is not marked as experimental in its version
> > map, this change won't flag it as a problem, but if its intended to be
> > experimental (i.e. if its likely to have its ABI fluctuate), then yes, we should
> > take the appropriate steps to flag it as such properly.
> >
> > If a given library is intended to be experimental, I would say yes,
> > the author should make the appropriate chage to the version map, and then the
> > corresponding change to the headers and c files with this new tag.
> > Alternatively, they might choose to simply update the documentation to reflect
> > the fact that the ABI for that library is now stable.
> >
> > The thing that should definately not hapen though, is a half measure. We
> > shouldn't allow libraries to call themselves experimental, and then excuse them
> > from any rules we have regarding their in-code representation. If we have an
> > EXPERIMENTAL version in the map, we should require its use, and by extension
> > require this tag when its merged for the reasons previously outlined
>
> My comment is for your item (3), but it is not fair to say "incorrectly placed"
> because if I don't miss anything this has never been documented as correct way
> to do, and lots of the existing usage is _before_ we start using EXPERIMENTAL
> tag in the linker script, so they were doing right thing for that time.
>
Ok, Apologies, perhaps incorrectly placed isn't a fair term to use. Perhaps it
would be better to say the experimental specification was insufficiently
documented? The point however remains. Defining an API category that conveys a
freedom of modification of ABI needs to follow rules for identification, and
providing a mechanism to tag said ABIs in the code without a requirement to use
it creates an confusing situation to say the least (i.e. some APIS will be
listed as belonging to the EXPERIMENTAL version, others won't, but will be
documented as such, creating an ambiguous status).
> Question is, is this patchset should fix them, since now this patchset defines
> using EXPERIMENTAL tag in linker script as way to do it, or should we wait
> maintainers to fix it after this has been documented. Waiting for maintainer may
> take time because not all maintainers are following the mail list closely to
> capture all expectations.
>
In answer, I think waiting for maintainers to correct their experimental
use isn't going to get anything done. As you said, not all maintainers monitor
all conversations closely enough to pick up on the need, and as we move forward
this effort will likely get de-prioitized, as the status quo will just continue
to exist. I would propose that we accept this patch, and then I subsequently
preform an audit on the documentation to find other APIs which are documented as
EXPERIMENTAL, but not tagged as such in their version files. I can submit
subsequent patches to reconcile those APIs that I find, which should get on the
respective maintainers radars. Does that sound reasonable?
Neil
> >
> > Neil
> >
> >
> >>> 14 files changed, 139 insertions(+), 116 deletions(-)
> >>
> >> <...>
> >>
> >>
>
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2018-01-12 11:50 7% ` Ferruh Yigit
@ 2018-01-12 14:37 4% ` Neil Horman
2018-01-12 15:55 4% ` Ferruh Yigit
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2018-01-12 14:37 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, thomas, john.mcnamara, bruce.richardson
On Fri, Jan 12, 2018 at 11:50:12AM +0000, Ferruh Yigit wrote:
> On 1/11/2018 9:29 PM, Neil Horman wrote:
> > On Thu, Jan 11, 2018 at 08:06:48PM +0000, Ferruh Yigit wrote:
> >> On 12/13/2017 3:17 PM, Neil Horman wrote:
> >>> Document the need to add the __experimental tag to appropriate functions
> >>>
> >>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> >>> CC: Thomas Monjalon <thomas@monjalon.net>
> >>> CC: "Mcnamara, John" <john.mcnamara@intel.com>
> >>> CC: Bruce Richardson <bruce.richardson@intel.com>
>
> <...>
>
> >>> automatically marked as ``experimental`` to allow for a period of stabilization>>> before they become part of a tracked ABI.
>
> Full sentences for above statement:
> "
> Since changes to APIs are most likely immediately after their introduction, as
> users begin to take advantage of those new APIs and start finding issues with
> them, new DPDK APIs will be automatically marked as experimental to allow for a
> period of stabilization before they become part of a tracked ABI.
> "
>
> This part is not related to this patchset, but it will be hard to maintain above
> behavior, "automatically marked" is not automatic now and moving them to stable
> after one release is also not automatic. Do you have any suggestion on how to
> manage this, do you think can your script be expanded to cover these checks?
>
I would make the argument that this was never the case, but rather a statement
of principle. I assert that because I can find no mechanism anywhere in our
build system that 'automatically' documented or marked a new API as experimental
(please correct me if I'm wrong here). I think this was more meant to be a
directive to developers to do whatever coding was needed to preform such
marking/documentation in whatever style/format was current. E.g. introducers of
a new API should document everything as EXPERIMENTAL using the appropriate
doxygen tag and version map tag.
In answer to your question, While we might be able to expand my script to check
for new API's and ensure they are marked as experimental, I don't think thats
the right place to do it, because that script is run at build time, where the
state of the tree is transient. A better place to do it would be with a git hook
at checkin time, or in the checkpatch script to flag new apis as experimental
right before those new API's are comitted. Though I'm not a huge fan of that
either (at least not of the former suggestion). I say that because I think we
need to allow developers the freedom to determine the supported status of any
new API that they add. For example, it seems pretty clear that a new library
might want to have its entire API marked as experimental, but someone adding a
single new function to an existing API might be confident that the new function
is needed and should be immediately supported..
I think the better solution is to define the use of the EXPERIMENTAL tag in the
version map as the canonical location to define unstable API functions. Doing
so immediately commits an author to ensuring that the corresponding function
definitions are marked with the __experimental tags, which in turn will cause
any downstream users to be alerted to the fact that they might be using those
API's in their code, so they can take appropriate action. It still allows for
the Documentation to be out of sync, but alerting authors doing development I
think is the more important element here, as Documentation can be corrected more
easily than code in the field.
Thoughts?
Neil
> >>>
> >>> +Note that marking an API as experimental is a two step process. To mark an API
> >>> +as experimental, the symbols which are desired to be exported must be placed in
> >>> +an EXPERIMENTAL version block in the corresponding libraries' version map
> >>> +script. Secondly, the corresponding definitions of those exported functions, and
> >>> +their forward declarations (in the development header files), must be marked
> >>> +with the __experimental tag (see rte_compat.h). The DPDK build makefiles
> >>> +preform a check to ensure that the map file and the C code reflect the same
> >>> +list of symbols.
> >>
> >> There are more steps we historically do to mark an API as experimental:
> >> - Add to function header comment experimental for API documentation, preferably
> >> with a warning tag to highlight it:
> >>
> >> /**
> >> * @warning
> >> * @b EXPERIMENTAL:
> >> ....
> >> */
> >>
> >> - If whole APIs in header file are experimental, add same experimental warning
> >> doxygen comment in file comment, again preferably with warning.
> >>
> >> - If whole library is experimental, put EXPERIMENTAL tag into maintainers file
> >> as well.
> >>
> > Is that documented somewhere? I'd like to add this to the same location that it
> > otherwise is written out. The above location was the only place in the guide
> > that I could find reference to experimental markings.
>
> As far as I know how to mark an API as experimental is not documented.
> What do you think making a new section for this information?
>
> >
> >>> +
> >>> ABI versions, once released, are available until such time as their
> >>> deprecation has been noted in the Release Notes for at least one major release
> >>> cycle. For example consider the case where the ABI for DPDK 2.0 has been
> >>>
> >>
> >>
>
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3] doc: ethdev ABI change deprecation notice
2018-01-12 10:29 11% ` [dpdk-dev] [PATCH v3] " Kirill Rybalchenko
@ 2018-01-12 14:38 4% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2018-01-12 14:38 UTC (permalink / raw)
To: Kirill Rybalchenko; +Cc: dev, andrey.chilikin, thomas
On Fri, Jan 12, 2018 at 10:29:46AM +0000, Kirill Rybalchenko wrote:
> Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
>
> Acked-by: Marko Kovacevic <marko.kovacevic@intel.com>
> ---
> doc/guides/rel_notes/deprecation.rst | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 13e8543..aaf306a 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -45,6 +45,12 @@ Deprecation Notices
> Target release for removal of the legacy API will be defined once most
> PMDs have switched to rte_flow.
>
> +* ethdev: announce ABI change
> + The size of variables flow_types_mask in rte_eth_fdir_info structure,
> + sym_hash_enable_mask and valid_bit_mask in rte_eth_hash_global_conf structure
> + will be increased from 32 to 64 bits to fulfill hardware requirements.
> + This change will break existing ABI as size of the structures will increase.
> +
> * i40e: The default flexible payload configuration which extracts the first 16
> bytes of the payload for RSS will be deprecated starting from 18.02. If
> required the previous behavior can be configured using existing flow
> --
> 2.5.5
>
>
Acked-by: Neil Horman <nhorman@tuxdriver.com>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv4 4/5] dpdk: add __experimental tag to appropriate api calls
2018-01-12 14:25 3% ` Neil Horman
@ 2018-01-12 15:53 0% ` Ferruh Yigit
0 siblings, 0 replies; 200+ results
From: Ferruh Yigit @ 2018-01-12 15:53 UTC (permalink / raw)
To: Neil Horman; +Cc: dev, thomas, john.mcnamara, bruce.richardson
On 1/12/2018 2:25 PM, Neil Horman wrote:
> On Fri, Jan 12, 2018 at 11:50:01AM +0000, Ferruh Yigit wrote:
>> On 1/11/2018 9:24 PM, Neil Horman wrote:
>>> On Thu, Jan 11, 2018 at 08:06:33PM +0000, Ferruh Yigit wrote:
>>>> On 12/13/2017 3:17 PM, Neil Horman wrote:
>>>>> Append the __experimental tag to api calls appearing in the EXPERIMENTAL
>>>>> section of their libraries version map
>>>>>
>>>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>>>>> CC: Thomas Monjalon <thomas@monjalon.net>
>>>>> CC: "Mcnamara, John" <john.mcnamara@intel.com>
>>>>> CC: Bruce Richardson <bruce.richardson@intel.com>
>>>>> ---
>>>>> lib/librte_eal/common/eal_common_dev.c | 6 ++-
>>>>> lib/librte_eal/common/eal_common_devargs.c | 7 +--
>>>>> lib/librte_eal/common/include/rte_dev.h | 6 ++-
>>>>> lib/librte_eal/common/include/rte_devargs.h | 8 ++--
>>>>> lib/librte_eal/common/include/rte_service.h | 47 ++++++++++---------
>>>>> .../common/include/rte_service_component.h | 14 +++---
>>>>> lib/librte_eal/common/rte_service.c | 52 ++++++++++++----------
>>>>> lib/librte_eal/linuxapp/eal/eal.c | 1 +
>>>>> lib/librte_ether/rte_mtr.c | 25 ++++++-----
>>>>> lib/librte_ether/rte_mtr.h | 26 +++++------
>>>>> lib/librte_flow_classify/rte_flow_classify.c | 13 +++---
>>>>> lib/librte_flow_classify/rte_flow_classify.h | 11 ++---
>>>>> lib/librte_security/rte_security.c | 16 +++----
>>>>> lib/librte_security/rte_security.h | 23 +++++-----
>>>>
>>>> It may not be the responsibility of this patchset, but there are more
>>>> experimental APIs in DPDK.
>>>>
>>> Thats an interesting statement to make. This patchset creates a build time
>>> check that compares symbols located in the EXPERIMENTAL version section of a
>>> libraries' version map file to the symbols that are marked with this new tag,
>>> throwing an error if they don't match. I believe what you say in that there may
>>> be additional APIs that are experimental, but given that, I would have to
>>> conclude one of the following:
>>>
>>> 1) The missing API's are macros or static inline functions that are not exported
>>> from libraries directly
>>>
>>> 2) The documentation for experimental API's are out of sync, in that they have
>>> legitimately moved to be supported API's and the documentation needs to be
>>> updated
>>>
>>> 3) There are API's which are experimental that have been incorrectly placed in a
>>> versioned tag.
>>>
>>> I made a pretty good effort to scan comments for the word EXPERIMENTAL so that I
>>> could catch item (1). And while I may not have caught them all, I'd like to
>>> think I got a good chunk of them. That leaves cleanup of (2) and (3), which I
>>> think this patchset can help us idenfity.
>>>
>>>> Using EXPERIMENTAL tag in linker script is relatively new approach and this was
>>>> not a requirement, so many experimental APIs are documented in API documentation
>>>> (header file doxygen comment).
>>>> Sample: librte_member
>>>>
>>> That sounds like case (3) above.
>>>
>>> Thats a bit odd. I understand that the use of the EXPERIMENTAL version tag is
>>> new, but once it was introduced it should have been made a requirement. There
>>> would have been no penalty for moving the version number (as doing so would not
>>> have violated ABI guarantees, given that those API's were appropriately
>>> documented as experimental). If they have not been, then the use of the
>>> EXPERIMENTAL tag isn't overly useful, as it doesn't provide any segregation of
>>> the stable ABI from the unstable ABI.
>>>
>>>> It is required to scan all header files and update their linker scripts for the
>>>> experimental APIs.
>>>>
>>> Yes and no. If a given library is not marked as experimental in its version
>>> map, this change won't flag it as a problem, but if its intended to be
>>> experimental (i.e. if its likely to have its ABI fluctuate), then yes, we should
>>> take the appropriate steps to flag it as such properly.
>>>
>>> If a given library is intended to be experimental, I would say yes,
>>> the author should make the appropriate chage to the version map, and then the
>>> corresponding change to the headers and c files with this new tag.
>>> Alternatively, they might choose to simply update the documentation to reflect
>>> the fact that the ABI for that library is now stable.
>>>
>>> The thing that should definately not hapen though, is a half measure. We
>>> shouldn't allow libraries to call themselves experimental, and then excuse them
>>> from any rules we have regarding their in-code representation. If we have an
>>> EXPERIMENTAL version in the map, we should require its use, and by extension
>>> require this tag when its merged for the reasons previously outlined
>>
>> My comment is for your item (3), but it is not fair to say "incorrectly placed"
>> because if I don't miss anything this has never been documented as correct way
>> to do, and lots of the existing usage is _before_ we start using EXPERIMENTAL
>> tag in the linker script, so they were doing right thing for that time.
>>
> Ok, Apologies, perhaps incorrectly placed isn't a fair term to use. Perhaps it
> would be better to say the experimental specification was insufficiently
> documented? The point however remains. Defining an API category that conveys a
> freedom of modification of ABI needs to follow rules for identification, and
> providing a mechanism to tag said ABIs in the code without a requirement to use
> it creates an confusing situation to say the least (i.e. some APIS will be
> listed as belonging to the EXPERIMENTAL version, others won't, but will be
> documented as such, creating an ambiguous status).
>
>> Question is, is this patchset should fix them, since now this patchset defines
>> using EXPERIMENTAL tag in linker script as way to do it, or should we wait
>> maintainers to fix it after this has been documented. Waiting for maintainer may
>> take time because not all maintainers are following the mail list closely to
>> capture all expectations.
>>
>
> In answer, I think waiting for maintainers to correct their experimental
> use isn't going to get anything done. As you said, not all maintainers monitor
> all conversations closely enough to pick up on the need, and as we move forward
> this effort will likely get de-prioitized, as the status quo will just continue
> to exist. I would propose that we accept this patch, and then I subsequently
> preform an audit on the documentation to find other APIs which are documented as
> EXPERIMENTAL, but not tagged as such in their version files. I can submit
> subsequent patches to reconcile those APIs that I find, which should get on the
> respective maintainers radars. Does that sound reasonable?
Sounds good to me, hence
Series
Acked-by: Ferruh Yigit <ferruh.yigit@intel.com>
>
> Neil
>
>>>
>>> Neil
>>>
>>>
>>>>> 14 files changed, 139 insertions(+), 116 deletions(-)
>>>>
>>>> <...>
>>>>
>>>>
>>
>>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2018-01-12 14:37 4% ` Neil Horman
@ 2018-01-12 15:55 4% ` Ferruh Yigit
2018-01-13 0:28 4% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Ferruh Yigit @ 2018-01-12 15:55 UTC (permalink / raw)
To: Neil Horman; +Cc: dev, thomas, john.mcnamara, bruce.richardson
On 1/12/2018 2:37 PM, Neil Horman wrote:
> On Fri, Jan 12, 2018 at 11:50:12AM +0000, Ferruh Yigit wrote:
>> On 1/11/2018 9:29 PM, Neil Horman wrote:
>>> On Thu, Jan 11, 2018 at 08:06:48PM +0000, Ferruh Yigit wrote:
>>>> On 12/13/2017 3:17 PM, Neil Horman wrote:
>>>>> Document the need to add the __experimental tag to appropriate functions
>>>>>
>>>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
>>>>> CC: Thomas Monjalon <thomas@monjalon.net>
>>>>> CC: "Mcnamara, John" <john.mcnamara@intel.com>
>>>>> CC: Bruce Richardson <bruce.richardson@intel.com>
>>
>> <...>
>>
>>>>> automatically marked as ``experimental`` to allow for a period of stabilization>>> before they become part of a tracked ABI.
>>
>> Full sentences for above statement:
>> "
>> Since changes to APIs are most likely immediately after their introduction, as
>> users begin to take advantage of those new APIs and start finding issues with
>> them, new DPDK APIs will be automatically marked as experimental to allow for a
>> period of stabilization before they become part of a tracked ABI.
>> "
>>
>> This part is not related to this patchset, but it will be hard to maintain above
>> behavior, "automatically marked" is not automatic now and moving them to stable
>> after one release is also not automatic. Do you have any suggestion on how to
>> manage this, do you think can your script be expanded to cover these checks?
>>
>
> I would make the argument that this was never the case, but rather a statement
> of principle. I assert that because I can find no mechanism anywhere in our
> build system that 'automatically' documented or marked a new API as experimental
> (please correct me if I'm wrong here). I think this was more meant to be a
> directive to developers to do whatever coding was needed to preform such
> marking/documentation in whatever style/format was current. E.g. introducers of
> a new API should document everything as EXPERIMENTAL using the appropriate
> doxygen tag and version map tag.
>
> In answer to your question, While we might be able to expand my script to check
> for new API's and ensure they are marked as experimental, I don't think thats
> the right place to do it, because that script is run at build time, where the
> state of the tree is transient. A better place to do it would be with a git hook
> at checkin time, or in the checkpatch script to flag new apis as experimental
> right before those new API's are comitted. Though I'm not a huge fan of that
> either (at least not of the former suggestion). I say that because I think we
> need to allow developers the freedom to determine the supported status of any
> new API that they add. For example, it seems pretty clear that a new library
> might want to have its entire API marked as experimental, but someone adding a
> single new function to an existing API might be confident that the new function
> is needed and should be immediately supported..
>
> I think the better solution is to define the use of the EXPERIMENTAL tag in the
> version map as the canonical location to define unstable API functions. Doing
> so immediately commits an author to ensuring that the corresponding function
> definitions are marked with the __experimental tags, which in turn will cause
> any downstream users to be alerted to the fact that they might be using those
> API's in their code, so they can take appropriate action. It still allows for
> the Documentation to be out of sync, but alerting authors doing development I
> think is the more important element here, as Documentation can be corrected more
> easily than code in the field.
>
> Thoughts?
After this point agree to using EXPERIMENTAL tag in the version map as standard,
but it will be hard to maintain "API is experimental for first release" without
help of any automated tool.
> Neil
>
>>>>>
>>>>> +Note that marking an API as experimental is a two step process. To mark an API
>>>>> +as experimental, the symbols which are desired to be exported must be placed in
>>>>> +an EXPERIMENTAL version block in the corresponding libraries' version map
>>>>> +script. Secondly, the corresponding definitions of those exported functions, and
>>>>> +their forward declarations (in the development header files), must be marked
>>>>> +with the __experimental tag (see rte_compat.h). The DPDK build makefiles
>>>>> +preform a check to ensure that the map file and the C code reflect the same
>>>>> +list of symbols.
>>>>
>>>> There are more steps we historically do to mark an API as experimental:
>>>> - Add to function header comment experimental for API documentation, preferably
>>>> with a warning tag to highlight it:
>>>>
>>>> /**
>>>> * @warning
>>>> * @b EXPERIMENTAL:
>>>> ....
>>>> */
>>>>
>>>> - If whole APIs in header file are experimental, add same experimental warning
>>>> doxygen comment in file comment, again preferably with warning.
>>>>
>>>> - If whole library is experimental, put EXPERIMENTAL tag into maintainers file
>>>> as well.
>>>>
>>> Is that documented somewhere? I'd like to add this to the same location that it
>>> otherwise is written out. The above location was the only place in the guide
>>> that I could find reference to experimental markings.
>>
>> As far as I know how to mark an API as experimental is not documented.
>> What do you think making a new section for this information?
>>
>>>
>>>>> +
>>>>> ABI versions, once released, are available until such time as their
>>>>> deprecation has been noted in the Release Notes for at least one major release
>>>>> cycle. For example consider the case where the ABI for DPDK 2.0 has been
>>>>>
>>>>
>>>>
>>
>>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 1/1] eal: return true or false from lcore role check function
2018-01-11 23:17 3% ` Thomas Monjalon
@ 2018-01-12 18:01 0% ` Carrillo, Erik G
2018-01-12 18:04 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Carrillo, Erik G @ 2018-01-12 18:01 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, Aaron Conole, pbhagavatula
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Thursday, January 11, 2018 5:17 PM
> To: Carrillo, Erik G <erik.g.carrillo@intel.com>
> Cc: dev@dpdk.org; Aaron Conole <aconole@redhat.com>;
> pbhagavatula@caviumnetworks.com; Van Haaren, Harry
> <harry.van.haaren@intel.com>
> Subject: Re: [dpdk-dev] [PATCH 1/1] eal: return true or false from lcore role
> check function
>
> 12/01/2018 00:09, Carrillo, Erik G:
> > Hi Aaron,
> >
> > From: Aaron Conole [mailto:aconole@redhat.com]
> > >
> > > Hi Erik,
> > >
> > > Erik Gabriel Carrillo <erik.g.carrillo@intel.com> writes:
> > >
> > > > Update rte_lcore_has_role() so that it returns true/false instead
> > > > of success/failure.
> > > >
> > > > Fixes: 78666372fa2b ("eal: add function to check lcore role")
> > > >
> > > > Signed-off-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> > > > ---
> > >
> > > I believe this breaks the published abi - Success is now 'true', and
> > > failure is 'false'; previously success would be 0 == false. You'll
> > > need to invert the test, or note that the abi is breaking (since
> > > semantically any caller will need to invert the test).
> >
> > Good point. Though it seems like an API change rather than an ABI change
> to me, would it still be handled the same way in terms of notice? Also, the
> ABI policy states, "ABI breakage due to changes such as reorganizing public
> structure fields for aesthetic or readability purposes should be avoided."
> Perhaps I should go with an alternate patch that fixes the caller.
>
> Most of the times, an API change is an ABI change.
> Please make a deprecation notice.
Ok, thanks Thomas - will do. Should I mark the above patch as "deferred" for the time being?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/1] eal: return true or false from lcore role check function
2018-01-12 18:01 0% ` Carrillo, Erik G
@ 2018-01-12 18:04 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-01-12 18:04 UTC (permalink / raw)
To: Carrillo, Erik G; +Cc: dev, Aaron Conole, pbhagavatula
12/01/2018 19:01, Carrillo, Erik G:
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > 12/01/2018 00:09, Carrillo, Erik G:
> > > Hi Aaron,
> > >
> > > From: Aaron Conole [mailto:aconole@redhat.com]
> > > >
> > > > Hi Erik,
> > > >
> > > > Erik Gabriel Carrillo <erik.g.carrillo@intel.com> writes:
> > > >
> > > > > Update rte_lcore_has_role() so that it returns true/false instead
> > > > > of success/failure.
> > > > >
> > > > > Fixes: 78666372fa2b ("eal: add function to check lcore role")
> > > > >
> > > > > Signed-off-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
> > > > > ---
> > > >
> > > > I believe this breaks the published abi - Success is now 'true', and
> > > > failure is 'false'; previously success would be 0 == false. You'll
> > > > need to invert the test, or note that the abi is breaking (since
> > > > semantically any caller will need to invert the test).
> > >
> > > Good point. Though it seems like an API change rather than an ABI change
> > to me, would it still be handled the same way in terms of notice? Also, the
> > ABI policy states, "ABI breakage due to changes such as reorganizing public
> > structure fields for aesthetic or readability purposes should be avoided."
> > Perhaps I should go with an alternate patch that fixes the caller.
> >
> > Most of the times, an API change is an ABI change.
> > Please make a deprecation notice.
>
> Ok, thanks Thomas - will do. Should I mark the above patch as "deferred" for the time being?
Yes, thanks
All deferred patches are set to New when starting a new release cycle.
So it should not be lost :)
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH 1/1] doc: announce API change to lcore role function
@ 2018-01-12 20:45 3% Erik Gabriel Carrillo
0 siblings, 0 replies; 200+ results
From: Erik Gabriel Carrillo @ 2018-01-12 20:45 UTC (permalink / raw)
To: nhorman; +Cc: dev, pbhagavatula, aconole, thomas
This an API/ABI change notice for DPDK 18.05 announcing a change in
the meaning of the return values of the rte_lcore_has_role() function.
Signed-off-by: Erik Gabriel Carrillo <erik.g.carrillo@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..15a94cf 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -21,6 +21,11 @@ Deprecation Notices
- ``rte_eal_devargs_type_count``
- ``rte_eal_parse_devargs_str``, replaced by ``rte_eal_devargs_parse``
+* eal: The semantics of the return value for the ``rte_lcore_has_role`` function
+ are planned to change in v18.05. The function currently returns 0 and <0 for
+ success and failure, respectively. This will change to 1 and 0 for true and
+ false, respectively, to make use of the function more intuitive.
+
* pci: Several exposed functions are misnamed.
The following functions are deprecated starting from v17.11 and are replaced:
--
2.6.4
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2018-01-12 15:55 4% ` Ferruh Yigit
@ 2018-01-13 0:28 4% ` Neil Horman
2018-01-13 15:56 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2018-01-13 0:28 UTC (permalink / raw)
To: Ferruh Yigit; +Cc: dev, thomas, john.mcnamara, bruce.richardson
On Fri, Jan 12, 2018 at 03:55:10PM +0000, Ferruh Yigit wrote:
> On 1/12/2018 2:37 PM, Neil Horman wrote:
> > On Fri, Jan 12, 2018 at 11:50:12AM +0000, Ferruh Yigit wrote:
> >> On 1/11/2018 9:29 PM, Neil Horman wrote:
> >>> On Thu, Jan 11, 2018 at 08:06:48PM +0000, Ferruh Yigit wrote:
> >>>> On 12/13/2017 3:17 PM, Neil Horman wrote:
> >>>>> Document the need to add the __experimental tag to appropriate functions
> >>>>>
> >>>>> Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
> >>>>> CC: Thomas Monjalon <thomas@monjalon.net>
> >>>>> CC: "Mcnamara, John" <john.mcnamara@intel.com>
> >>>>> CC: Bruce Richardson <bruce.richardson@intel.com>
> >>
> >> <...>
> >>
> >>>>> automatically marked as ``experimental`` to allow for a period of stabilization>>> before they become part of a tracked ABI.
> >>
> >> Full sentences for above statement:
> >> "
> >> Since changes to APIs are most likely immediately after their introduction, as
> >> users begin to take advantage of those new APIs and start finding issues with
> >> them, new DPDK APIs will be automatically marked as experimental to allow for a
> >> period of stabilization before they become part of a tracked ABI.
> >> "
> >>
> >> This part is not related to this patchset, but it will be hard to maintain above
> >> behavior, "automatically marked" is not automatic now and moving them to stable
> >> after one release is also not automatic. Do you have any suggestion on how to
> >> manage this, do you think can your script be expanded to cover these checks?
> >>
> >
> > I would make the argument that this was never the case, but rather a statement
> > of principle. I assert that because I can find no mechanism anywhere in our
> > build system that 'automatically' documented or marked a new API as experimental
> > (please correct me if I'm wrong here). I think this was more meant to be a
> > directive to developers to do whatever coding was needed to preform such
> > marking/documentation in whatever style/format was current. E.g. introducers of
> > a new API should document everything as EXPERIMENTAL using the appropriate
> > doxygen tag and version map tag.
> >
> > In answer to your question, While we might be able to expand my script to check
> > for new API's and ensure they are marked as experimental, I don't think thats
> > the right place to do it, because that script is run at build time, where the
> > state of the tree is transient. A better place to do it would be with a git hook
> > at checkin time, or in the checkpatch script to flag new apis as experimental
> > right before those new API's are comitted. Though I'm not a huge fan of that
> > either (at least not of the former suggestion). I say that because I think we
> > need to allow developers the freedom to determine the supported status of any
> > new API that they add. For example, it seems pretty clear that a new library
> > might want to have its entire API marked as experimental, but someone adding a
> > single new function to an existing API might be confident that the new function
> > is needed and should be immediately supported..
> >
> > I think the better solution is to define the use of the EXPERIMENTAL tag in the
> > version map as the canonical location to define unstable API functions. Doing
> > so immediately commits an author to ensuring that the corresponding function
> > definitions are marked with the __experimental tags, which in turn will cause
> > any downstream users to be alerted to the fact that they might be using those
> > API's in their code, so they can take appropriate action. It still allows for
> > the Documentation to be out of sync, but alerting authors doing development I
> > think is the more important element here, as Documentation can be corrected more
> > easily than code in the field.
> >
> > Thoughts?
>
> After this point agree to using EXPERIMENTAL tag in the version map as standard,
> but it will be hard to maintain "API is experimental for first release" without
> help of any automated tool.
>
I completely agree, in fact I would say it is impossible to do without tooling,
with or without this change. I think we need to do 1 of 2 things:
1) Add some code to checkpatch.pl to put up a warning if any new apis are added
without marking them as experimental
2) Change the documentation to be a suggestion rather than a requirement.
I'll look into doing (1), but I'm wondering if (2) is the more flexible way to
go. I'm hesitant to enforce the initial marking of new APIs as experimental.
Thoughts?
Neil
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2018-01-13 0:28 4% ` Neil Horman
@ 2018-01-13 15:56 4% ` Thomas Monjalon
2018-01-14 14:36 4% ` Neil Horman
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-13 15:56 UTC (permalink / raw)
To: Neil Horman; +Cc: Ferruh Yigit, dev, john.mcnamara, bruce.richardson
13/01/2018 01:28, Neil Horman:
> On Fri, Jan 12, 2018 at 03:55:10PM +0000, Ferruh Yigit wrote:
> > After this point agree to using EXPERIMENTAL tag in the version map as standard,
> > but it will be hard to maintain "API is experimental for first release" without
> > help of any automated tool.
> >
> I completely agree, in fact I would say it is impossible to do without tooling,
> with or without this change. I think we need to do 1 of 2 things:
>
> 1) Add some code to checkpatch.pl to put up a warning if any new apis are added
> without marking them as experimental
>
> 2) Change the documentation to be a suggestion rather than a requirement.
>
> I'll look into doing (1), but I'm wondering if (2) is the more flexible way to
> go. I'm hesitant to enforce the initial marking of new APIs as experimental.
> Thoughts?
There will be always cases where we are sure that the experimental step
is not needed.
Even if it is required and checked by a tool, we can ignore it, right?
However, there is no big benefit of bypassing the experimental step.
I am for making mandatory the new API as experimental.
We will handle the exceptions case by case if any.
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2018-01-13 15:56 4% ` Thomas Monjalon
@ 2018-01-14 14:36 4% ` Neil Horman
2018-01-14 16:27 4% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Neil Horman @ 2018-01-14 14:36 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: Ferruh Yigit, dev, john.mcnamara, bruce.richardson
On Sat, Jan 13, 2018 at 04:56:11PM +0100, Thomas Monjalon wrote:
> 13/01/2018 01:28, Neil Horman:
> > On Fri, Jan 12, 2018 at 03:55:10PM +0000, Ferruh Yigit wrote:
> > > After this point agree to using EXPERIMENTAL tag in the version map as standard,
> > > but it will be hard to maintain "API is experimental for first release" without
> > > help of any automated tool.
> > >
> > I completely agree, in fact I would say it is impossible to do without tooling,
> > with or without this change. I think we need to do 1 of 2 things:
> >
> > 1) Add some code to checkpatch.pl to put up a warning if any new apis are added
> > without marking them as experimental
> >
> > 2) Change the documentation to be a suggestion rather than a requirement.
> >
> > I'll look into doing (1), but I'm wondering if (2) is the more flexible way to
> > go. I'm hesitant to enforce the initial marking of new APIs as experimental.
> > Thoughts?
>
> There will be always cases where we are sure that the experimental step
> is not needed.
> Even if it is required and checked by a tool, we can ignore it, right?
> However, there is no big benefit of bypassing the experimental step.
>
> I am for making mandatory the new API as experimental.
> We will handle the exceptions case by case if any.
>
If the consensus is to require experimental marking by default, and grant
exceptions as needed, then I would strongly suggest that we do this in
checkpatch as I can modify it to warn people of added API's (which will be
reflected in the CI tool, if the CI group is still maintaining it), but we can
collectively ignore it if its so clearly trivial that it requires no
experimental addition (which I think may freqently be the case).
I'll start work on that on monday
Best
Neil
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation
2018-01-14 14:36 4% ` Neil Horman
@ 2018-01-14 16:27 4% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-01-14 16:27 UTC (permalink / raw)
To: Neil Horman; +Cc: Ferruh Yigit, dev, john.mcnamara, bruce.richardson
14/01/2018 15:36, Neil Horman:
> On Sat, Jan 13, 2018 at 04:56:11PM +0100, Thomas Monjalon wrote:
> > 13/01/2018 01:28, Neil Horman:
> > > On Fri, Jan 12, 2018 at 03:55:10PM +0000, Ferruh Yigit wrote:
> > > > After this point agree to using EXPERIMENTAL tag in the version map as standard,
> > > > but it will be hard to maintain "API is experimental for first release" without
> > > > help of any automated tool.
> > > >
> > > I completely agree, in fact I would say it is impossible to do without tooling,
> > > with or without this change. I think we need to do 1 of 2 things:
> > >
> > > 1) Add some code to checkpatch.pl to put up a warning if any new apis are added
> > > without marking them as experimental
> > >
> > > 2) Change the documentation to be a suggestion rather than a requirement.
> > >
> > > I'll look into doing (1), but I'm wondering if (2) is the more flexible way to
> > > go. I'm hesitant to enforce the initial marking of new APIs as experimental.
> > > Thoughts?
> >
> > There will be always cases where we are sure that the experimental step
> > is not needed.
> > Even if it is required and checked by a tool, we can ignore it, right?
> > However, there is no big benefit of bypassing the experimental step.
> >
> > I am for making mandatory the new API as experimental.
> > We will handle the exceptions case by case if any.
> >
> If the consensus is to require experimental marking by default, and grant
> exceptions as needed, then I would strongly suggest that we do this in
> checkpatch as I can modify it to warn people of added API's (which will be
> reflected in the CI tool, if the CI group is still maintaining it), but we can
> collectively ignore it if its so clearly trivial that it requires no
> experimental addition (which I think may freqently be the case).
I am OK with this approach.
> I'll start work on that on monday
Good
I wonder how difficult it can be to implement.
Note: we do not maintain a fork of checkpatch.pl.
We just have a shell wrapper checkpatch.sh.
Maybe you should start a different tool.
Can it use Coccinelle?
^ permalink raw reply [relevance 4%]
* [dpdk-dev] [PATCH v2 5/5] mbuf: add user command line config mempools ops API
@ 2018-01-15 6:11 10% ` Hemant Agrawal
2018-01-15 12:29 0% ` Jerin Jacob
1 sibling, 1 reply; 200+ results
From: Hemant Agrawal @ 2018-01-15 6:11 UTC (permalink / raw)
To: dev; +Cc: jerin.jacob, olivier.matz, santosh.shukla
This patch add the user command line configured mempool ops name
API to librte_mbuf and sends a deprecation notice to remove the
similar API from eal.
Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
---
doc/guides/rel_notes/deprecation.rst | 7 +++++++
lib/librte_mbuf/rte_mbuf.c | 8 +++++++-
lib/librte_mbuf/rte_mbuf.h | 10 ++++++++++
lib/librte_mbuf/rte_mbuf_version.map | 1 +
4 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..ec8018f 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -8,6 +8,13 @@ API and ABI deprecation notices are to be posted here.
Deprecation Notices
-------------------
+* eal: a mbuf specific API was part of eal APIs. This is now being
+ moved to librte_mbuf to be with other similar APIs.
+ The following API is target to be deprecated on 18.05.
+
+ - ``rte_eal_mbuf_default_mempool_ops`` replaced by
+ ``rte_mbuf_user_mempool_ops''
+
* eal: several API and ABI changes are planned for ``rte_devargs`` in v18.02.
The format of device command line parameters will change. The bus will need
to be explicitly stated in the device declaration. The enum ``rte_devtype``
diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
index 482676c..c587d3a 100644
--- a/lib/librte_mbuf/rte_mbuf.c
+++ b/lib/librte_mbuf/rte_mbuf.c
@@ -168,12 +168,18 @@ rte_mbuf_platform_mempool_ops(void)
return internal_config.plat_mbuf_pool_ops_name;
}
+const char *
+rte_mbuf_user_mempool_ops(void)
+{
+ return internal_config.user_mbuf_pool_ops_name;
+}
+
/* Return mbuf pool ops name */
static const char *
rte_mbuf_best_mempool_ops(void)
{
/* User defined mempool ops takes the priority */
- const char *best_ops = rte_eal_mbuf_default_mempool_ops();
+ const char *best_ops = rte_mbuf_user_mempool_ops();
if (best_ops)
return best_ops;
diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
index f958e3c..7feacc0 100644
--- a/lib/librte_mbuf/rte_mbuf.h
+++ b/lib/librte_mbuf/rte_mbuf.h
@@ -1143,6 +1143,16 @@ const char*
rte_mbuf_platform_mempool_ops(void);
/**
+ * Get user command line configured pool ops name for mbuf
+ *
+ * @return
+ * returns user pool ops name.
+ */
+
+const char*
+rte_mbuf_user_mempool_ops(void);
+
+/**
* Get the data room size of mbufs stored in a pktmbuf_pool
*
* The data room size is the amount of data that can be stored in a
diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
index 9b53502..d4af497 100644
--- a/lib/librte_mbuf/rte_mbuf_version.map
+++ b/lib/librte_mbuf/rte_mbuf_version.map
@@ -41,6 +41,7 @@ DPDK_18.02 {
rte_mbuf_platform_mempool_ops;
rte_mbuf_register_platform_mempool_ops;
+ rte_mbuf_user_mempool_ops;
rte_pktmbuf_pool_create_specific;
} DPDK_16.11;
--
2.7.4
^ permalink raw reply [relevance 10%]
* Re: [dpdk-dev] [PATCH v2 2/5] eal: add platform mempool ops name in internal config
@ 2018-01-15 12:24 3% ` Jerin Jacob
2018-01-15 14:31 3% ` Hemant Agrawal
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2018-01-15 12:24 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: dev, olivier.matz, santosh.shukla
-----Original Message-----
> Date: Mon, 15 Jan 2018 11:41:11 +0530
> From: Hemant Agrawal <hemant.agrawal@nxp.com>
> To: dev@dpdk.org
> CC: jerin.jacob@caviumnetworks.com, olivier.matz@6wind.com,
> santosh.shukla@caviumnetworks.com
> Subject: [PATCH v2 2/5] eal: add platform mempool ops name in internal
> config
> X-Mailer: git-send-email 2.7.4
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> lib/librte_eal/common/eal_common_options.c | 1 +
> lib/librte_eal/common/eal_internal_cfg.h | 2 ++
> lib/librte_eal/rte_eal_version.map | 1 +
> 3 files changed, 4 insertions(+)
>
> diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
> index b6d2762..1ed0ddb 100644
> --- a/lib/librte_eal/common/eal_common_options.c
> +++ b/lib/librte_eal/common/eal_common_options.c
> @@ -219,6 +219,7 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
> internal_cfg->vmware_tsc_map = 0;
> internal_cfg->create_uio_dev = 0;
> internal_cfg->user_mbuf_pool_ops_name = NULL;
> + internal_cfg->plat_mbuf_pool_ops_name = NULL;
> }
>
> static int
> diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
> index 1169fcc..12c5b8a 100644
> --- a/lib/librte_eal/common/eal_internal_cfg.h
> +++ b/lib/librte_eal/common/eal_internal_cfg.h
> @@ -54,6 +54,8 @@ struct internal_config {
> const char *hugepage_dir; /**< specific hugetlbfs directory to use */
> const char *user_mbuf_pool_ops_name;
> /**< user defined mbuf pool ops name */
> + const char *plat_mbuf_pool_ops_name;
> + /**< platform configured mbuf pool ops name */
> unsigned num_hugepage_sizes; /**< how many sizes on this system */
> struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
> };
> diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
> index 3fa1e13..909691f 100644
> --- a/lib/librte_eal/rte_eal_version.map
> +++ b/lib/librte_eal/rte_eal_version.map
> @@ -203,6 +203,7 @@ DPDK_17.11 {
> DPDK_18.02 {
> global:
>
> + internal_config;
I think, exposing the internal_config may not be a good idea. We may
need "plat_mbuf_pool_ops_name" value for multi process case too.
Considering the above points, How about adding it in
struct rte_config and then expose too rte_eal_get_configuration()
On the downside, it would be an ABI change.
> rte_hypervisor_get;
> rte_hypervisor_get_name;
>
> --
> 2.7.4
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 5/5] mbuf: add user command line config mempools ops API
2018-01-15 6:11 10% ` [dpdk-dev] [PATCH v2 5/5] mbuf: add user command line config mempools ops API Hemant Agrawal
@ 2018-01-15 12:29 0% ` Jerin Jacob
2018-01-15 14:35 0% ` Hemant Agrawal
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2018-01-15 12:29 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: dev, olivier.matz, santosh.shukla
-----Original Message-----
> Date: Mon, 15 Jan 2018 11:41:14 +0530
> From: Hemant Agrawal <hemant.agrawal@nxp.com>
> To: dev@dpdk.org
> CC: jerin.jacob@caviumnetworks.com, olivier.matz@6wind.com,
> santosh.shukla@caviumnetworks.com
> Subject: [PATCH v2 5/5] mbuf: add user command line config mempools ops API
> X-Mailer: git-send-email 2.7.4
>
> This patch add the user command line configured mempool ops name
> API to librte_mbuf and sends a deprecation notice to remove the
> similar API from eal.
>
> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> ---
> doc/guides/rel_notes/deprecation.rst | 7 +++++++
> lib/librte_mbuf/rte_mbuf.c | 8 +++++++-
> lib/librte_mbuf/rte_mbuf.h | 10 ++++++++++
> lib/librte_mbuf/rte_mbuf_version.map | 1 +
> 4 files changed, 25 insertions(+), 1 deletion(-)
>
> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> index 13e8543..ec8018f 100644
> --- a/doc/guides/rel_notes/deprecation.rst
> +++ b/doc/guides/rel_notes/deprecation.rst
> @@ -8,6 +8,13 @@ API and ABI deprecation notices are to be posted here.
> Deprecation Notices
> -------------------
>
> +* eal: a mbuf specific API was part of eal APIs. This is now being
> + moved to librte_mbuf to be with other similar APIs.
> + The following API is target to be deprecated on 18.05.
> +
> + - ``rte_eal_mbuf_default_mempool_ops`` replaced by
> + ``rte_mbuf_user_mempool_ops''
> +
I think, deprecation notice need to be in a separate 'doc" patch.
> * eal: several API and ABI changes are planned for ``rte_devargs`` in v18.02.
> The format of device command line parameters will change. The bus will need
> to be explicitly stated in the device declaration. The enum ``rte_devtype``
> diff --git a/lib/librte_mbuf/rte_mbuf.c b/lib/librte_mbuf/rte_mbuf.c
> index 482676c..c587d3a 100644
> --- a/lib/librte_mbuf/rte_mbuf.c
> +++ b/lib/librte_mbuf/rte_mbuf.c
> @@ -168,12 +168,18 @@ rte_mbuf_platform_mempool_ops(void)
> return internal_config.plat_mbuf_pool_ops_name;
> }
>
> +const char *
> +rte_mbuf_user_mempool_ops(void)
> +{
> + return internal_config.user_mbuf_pool_ops_name;
> +}
> +
> /* Return mbuf pool ops name */
> static const char *
> rte_mbuf_best_mempool_ops(void)
> {
> /* User defined mempool ops takes the priority */
> - const char *best_ops = rte_eal_mbuf_default_mempool_ops();
I think, we may need to remove the stale rte_eal_mbuf_default_mempool_ops() once
it is replaced.
> + const char *best_ops = rte_mbuf_user_mempool_ops();
> if (best_ops)
> return best_ops;
>
> diff --git a/lib/librte_mbuf/rte_mbuf.h b/lib/librte_mbuf/rte_mbuf.h
> index f958e3c..7feacc0 100644
> --- a/lib/librte_mbuf/rte_mbuf.h
> +++ b/lib/librte_mbuf/rte_mbuf.h
> @@ -1143,6 +1143,16 @@ const char*
> rte_mbuf_platform_mempool_ops(void);
>
> /**
> + * Get user command line configured pool ops name for mbuf
> + *
> + * @return
> + * returns user pool ops name.
> + */
> +
> +const char*
> +rte_mbuf_user_mempool_ops(void);
> +
> +/**
> * Get the data room size of mbufs stored in a pktmbuf_pool
> *
> * The data room size is the amount of data that can be stored in a
> diff --git a/lib/librte_mbuf/rte_mbuf_version.map b/lib/librte_mbuf/rte_mbuf_version.map
> index 9b53502..d4af497 100644
> --- a/lib/librte_mbuf/rte_mbuf_version.map
> +++ b/lib/librte_mbuf/rte_mbuf_version.map
> @@ -41,6 +41,7 @@ DPDK_18.02 {
>
> rte_mbuf_platform_mempool_ops;
> rte_mbuf_register_platform_mempool_ops;
> + rte_mbuf_user_mempool_ops;
> rte_pktmbuf_pool_create_specific;
>
> } DPDK_16.11;
> --
> 2.7.4
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 2/5] eal: add platform mempool ops name in internal config
2018-01-15 12:24 3% ` Jerin Jacob
@ 2018-01-15 14:31 3% ` Hemant Agrawal
2018-01-15 16:26 3% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Hemant Agrawal @ 2018-01-15 14:31 UTC (permalink / raw)
To: Jerin Jacob; +Cc: dev, olivier.matz, santosh.shukla
On 1/15/2018 5:54 PM, Jerin Jacob wrote:
>> static int
>> diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
>> index 1169fcc..12c5b8a 100644
>> --- a/lib/librte_eal/common/eal_internal_cfg.h
>> +++ b/lib/librte_eal/common/eal_internal_cfg.h
>> @@ -54,6 +54,8 @@ struct internal_config {
>> const char *hugepage_dir; /**< specific hugetlbfs directory to use */
>> const char *user_mbuf_pool_ops_name;
>> /**< user defined mbuf pool ops name */
>> + const char *plat_mbuf_pool_ops_name;
>> + /**< platform configured mbuf pool ops name */
>> unsigned num_hugepage_sizes; /**< how many sizes on this system */
>> struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
>> };
>> diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
>> index 3fa1e13..909691f 100644
>> --- a/lib/librte_eal/rte_eal_version.map
>> +++ b/lib/librte_eal/rte_eal_version.map
>> @@ -203,6 +203,7 @@ DPDK_17.11 {
>> DPDK_18.02 {
>> global:
>>
>> + internal_config;
>
> I think, exposing the internal_config may not be a good idea. We may
> need "plat_mbuf_pool_ops_name" value for multi process case too.
> Considering the above points, How about adding it in
> struct rte_config and then expose too rte_eal_get_configuration()
> On the downside, it would be an ABI change.
Yes! I was also not sure about exposing internal_config.
rte_config is also a good option. If we add these options in the end,
it should not break ABI?
>
>> rte_hypervisor_get;
>> rte_hypervisor_get_name;
>>
>> --
>> 2.7.4
>>
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2 5/5] mbuf: add user command line config mempools ops API
2018-01-15 12:29 0% ` Jerin Jacob
@ 2018-01-15 14:35 0% ` Hemant Agrawal
2018-01-15 16:23 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Hemant Agrawal @ 2018-01-15 14:35 UTC (permalink / raw)
To: Jerin Jacob; +Cc: dev, olivier.matz, santosh.shukla
On 1/15/2018 5:59 PM, Jerin Jacob wrote:
> -----Original Message-----
>> Date: Mon, 15 Jan 2018 11:41:14 +0530
>> From: Hemant Agrawal <hemant.agrawal@nxp.com>
>> This patch add the user command line configured mempool ops name
>> API to librte_mbuf and sends a deprecation notice to remove the
>> similar API from eal.
>>
>> Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
>> ---
>> doc/guides/rel_notes/deprecation.rst | 7 +++++++
>> lib/librte_mbuf/rte_mbuf.c | 8 +++++++-
>> lib/librte_mbuf/rte_mbuf.h | 10 ++++++++++
>> lib/librte_mbuf/rte_mbuf_version.map | 1 +
>> 4 files changed, 25 insertions(+), 1 deletion(-)
>>
>> diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
>> index 13e8543..ec8018f 100644
>> --- a/doc/guides/rel_notes/deprecation.rst
>> +++ b/doc/guides/rel_notes/deprecation.rst
>> @@ -8,6 +8,13 @@ API and ABI deprecation notices are to be posted here.
>> Deprecation Notices
>> -------------------
>>
>> +* eal: a mbuf specific API was part of eal APIs. This is now being
>> + moved to librte_mbuf to be with other similar APIs.
>> + The following API is target to be deprecated on 18.05.
>> +
>> + - ``rte_eal_mbuf_default_mempool_ops`` replaced by
>> + ``rte_mbuf_user_mempool_ops''
>> +
>
> I think, deprecation notice need to be in a separate 'doc" patch.
Yes. you are right.
<snip>..
>> +const char *
>> +rte_mbuf_user_mempool_ops(void)
>> +{
>> + return internal_config.user_mbuf_pool_ops_name;
>> +}
>> +
>> /* Return mbuf pool ops name */
>> static const char *
>> rte_mbuf_best_mempool_ops(void)
>> {
>> /* User defined mempool ops takes the priority */
>> - const char *best_ops = rte_eal_mbuf_default_mempool_ops();
>
> I think, we may need to remove the stale rte_eal_mbuf_default_mempool_ops() once
> it is replaced.
Do you mean that till the API is not deprecated, we shall keep the usage?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 5/5] mbuf: add user command line config mempools ops API
2018-01-15 14:35 0% ` Hemant Agrawal
@ 2018-01-15 16:23 0% ` Jerin Jacob
0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2018-01-15 16:23 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: dev, olivier.matz, santosh.shukla
-----Original Message-----
> Date: Mon, 15 Jan 2018 20:05:16 +0530
> From: Hemant Agrawal <hemant.agrawal@nxp.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: dev@dpdk.org, olivier.matz@6wind.com, santosh.shukla@caviumnetworks.com
> Subject: Re: [PATCH v2 5/5] mbuf: add user command line config mempools ops
> API
> User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101
> Thunderbird/45.8.0
>
> On 1/15/2018 5:59 PM, Jerin Jacob wrote:
> > -----Original Message-----
> > > Date: Mon, 15 Jan 2018 11:41:14 +0530
> > > From: Hemant Agrawal <hemant.agrawal@nxp.com>
>
> > > This patch add the user command line configured mempool ops name
> > > API to librte_mbuf and sends a deprecation notice to remove the
> > > similar API from eal.
> > >
> > > Signed-off-by: Hemant Agrawal <hemant.agrawal@nxp.com>
> > > ---
> > > doc/guides/rel_notes/deprecation.rst | 7 +++++++
> > > lib/librte_mbuf/rte_mbuf.c | 8 +++++++-
> > > lib/librte_mbuf/rte_mbuf.h | 10 ++++++++++
> > > lib/librte_mbuf/rte_mbuf_version.map | 1 +
> > > 4 files changed, 25 insertions(+), 1 deletion(-)
> > >
> > > diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
> > > index 13e8543..ec8018f 100644
> > > --- a/doc/guides/rel_notes/deprecation.rst
> > > +++ b/doc/guides/rel_notes/deprecation.rst
> > > @@ -8,6 +8,13 @@ API and ABI deprecation notices are to be posted here.
> > > Deprecation Notices
> > > -------------------
> > >
> > > +* eal: a mbuf specific API was part of eal APIs. This is now being
> > > + moved to librte_mbuf to be with other similar APIs.
> > > + The following API is target to be deprecated on 18.05.
> > > +
> > > + - ``rte_eal_mbuf_default_mempool_ops`` replaced by
> > > + ``rte_mbuf_user_mempool_ops''
> > > +
> >
> > I think, deprecation notice need to be in a separate 'doc" patch.
>
> Yes. you are right.
>
> <snip>..
>
> > > +const char *
> > > +rte_mbuf_user_mempool_ops(void)
> > > +{
> > > + return internal_config.user_mbuf_pool_ops_name;
> > > +}
> > > +
> > > /* Return mbuf pool ops name */
> > > static const char *
> > > rte_mbuf_best_mempool_ops(void)
> > > {
> > > /* User defined mempool ops takes the priority */
> > > - const char *best_ops = rte_eal_mbuf_default_mempool_ops();
> >
> > I think, we may need to remove the stale rte_eal_mbuf_default_mempool_ops() once
> > it is replaced.
>
> Do you mean that till the API is not deprecated, we shall keep the usage?
Yes
>
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 2/5] eal: add platform mempool ops name in internal config
2018-01-15 14:31 3% ` Hemant Agrawal
@ 2018-01-15 16:26 3% ` Jerin Jacob
2018-01-16 15:04 0% ` Olivier Matz
0 siblings, 1 reply; 200+ results
From: Jerin Jacob @ 2018-01-15 16:26 UTC (permalink / raw)
To: Hemant Agrawal; +Cc: dev, olivier.matz, santosh.shukla
-----Original Message-----
> Date: Mon, 15 Jan 2018 20:01:14 +0530
> From: Hemant Agrawal <hemant.agrawal@nxp.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: dev@dpdk.org, olivier.matz@6wind.com, santosh.shukla@caviumnetworks.com
> Subject: Re: [PATCH v2 2/5] eal: add platform mempool ops name in internal
> config
> User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101
> Thunderbird/45.8.0
>
> On 1/15/2018 5:54 PM, Jerin Jacob wrote:
> > > static int
> > > diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
> > > index 1169fcc..12c5b8a 100644
> > > --- a/lib/librte_eal/common/eal_internal_cfg.h
> > > +++ b/lib/librte_eal/common/eal_internal_cfg.h
> > > @@ -54,6 +54,8 @@ struct internal_config {
> > > const char *hugepage_dir; /**< specific hugetlbfs directory to use */
> > > const char *user_mbuf_pool_ops_name;
> > > /**< user defined mbuf pool ops name */
> > > + const char *plat_mbuf_pool_ops_name;
> > > + /**< platform configured mbuf pool ops name */
> > > unsigned num_hugepage_sizes; /**< how many sizes on this system */
> > > struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
> > > };
> > > diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
> > > index 3fa1e13..909691f 100644
> > > --- a/lib/librte_eal/rte_eal_version.map
> > > +++ b/lib/librte_eal/rte_eal_version.map
> > > @@ -203,6 +203,7 @@ DPDK_17.11 {
> > > DPDK_18.02 {
> > > global:
> > >
> > > + internal_config;
> >
> > I think, exposing the internal_config may not be a good idea. We may
> > need "plat_mbuf_pool_ops_name" value for multi process case too.
> > Considering the above points, How about adding it in
> > struct rte_config and then expose too rte_eal_get_configuration()
> > On the downside, it would be an ABI change.
>
> Yes! I was also not sure about exposing internal_config.
>
> rte_config is also a good option. If we add these options in the end, it
> should not break ABI?
I think, it does break the ABI.
>
>
> >
> > > rte_hypervisor_get;
> > > rte_hypervisor_get_name;
> > >
> > > --
> > > 2.7.4
> > >
> >
>
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer
2018-01-04 9:22 0% ` Jerin Jacob
@ 2018-01-15 16:29 0% ` Ananyev, Konstantin
0 siblings, 0 replies; 200+ results
From: Ananyev, Konstantin @ 2018-01-15 16:29 UTC (permalink / raw)
To: Jerin Jacob; +Cc: dev, shahafs
Hi Jerin,
>
> Hi Konstantin,
>
> > > > > > > > 2. Make it safe to remove rx/tx callback at runtime.
> > > > > > > > Right now it is not possible for the application to figure out
> > > > > > > > when it is safe to free removed callback handle and
> > > > > > > > associated with it resources(unless the queue is stopped).
> > > > > > > > That's probably not a big problem if all callbacks are static
> > > > > > > > hange through whole application lifetime)
> > > > > > > > and/or application doesn't allocate any resources for the callback handler.
> > > > > > > > Though if callbacks have to be added/removed dynamically and
> > > > > > > > callback handler would require more resources to operate properly -
> > > > > > > > then it might become an issue.
> > > > > > > > So patch #2 fixes that problem - now as soon as
> > > > > > > > rte_eth_remove_(rx|tx)_callback() completes successfully, application
> > > > > > > > can safely free all associated with the removed callback resources.
> > > > > > > >
> > > > > > > > Performance impact:
> > > > > > > > If application doesn't use RX/TX callbacks, then the tests I run didn't
> > > > > > > > reveal any performance degradation.
> > > > > > > > Though if application do use RX/TX callbacks - patch #2 does introduce
> > > > > > > > some slowdown.
> > > > > > > >
> > > > > > > > To be more specific here, on BDW (E5-2699 v4) 2.2GHz, 4x10Gb (X520-4)
> > > > > > > > with http://dpdk.org/dev/patchwork/patch/31864/ patch installed I got:
> > > > > > > > 1) testpmd ... --latencystats=1 - slowdown < 1%
> > > > > > > > 2) examples//l3fwd ... --parse-ptype - - slowdown < 1%
> > > > > > > > 3) examples/rxtx_callbacks - slowdown ~8%
> > > > > > > > All that in terms of packet throughput (Mpps).
> > > > > > >
> > > > > > > We tried on an arm64 machine; We got following result on host and guest
> > > > > > > using l3fwd.
> > > > > >
> > > > > > Thanks for testing it.
> > > > > > So these numbers below - are for l3fwd running with or without rx callback installed?
> > > > > > i.e. with or without '--parse-ptype' option (and on a NIC with/without ptype HW support)?
> > > > >
> > > > > without '--parse-ptype' option(i.e without rx callback installed).
> > > > > That makes it sad, Even though application is not using the rx callback,
> > > > > We need to pay on a average 3% drop in performance(based on the
> > > > > use case/arch/SoC/topology etc)
> > > >
> > > > Yes it is sad...
> > > > Do you have any idea why that happens?
> > > > Is that the same situation you described before: for arm compiler
> > > > often replaces small branches with conditional execution instructions
> > > > and miss-prediction for such instructions is not free?
> > >
> > > Yes.
> >
> > Probably a dumb question - is it possible to disable such optimization
> > for these particular functions (rx_burst/tx_burst)?
> > Or would it make things even worse?
> >
> > >
> > > Another thing I noticed on these inline functions(rx/tx burst)even if we add
> > > a lot of code which may note be executed, based on the parent
> > > function layout, the compete register access layout gets change(like
> > > push/pop from stack etc, as more code gets added).
> > > I.e This change does not have much impact with testpmd(iofwd) where the
> > > parent function is not doing much thing.It is showing up only on l3fwd.
> >
> > Ok sort of register spillage...
> > But if compiler does it unconditionally (for the code path when it never needed)
> > seems like a problem with the compile, no?
>
> I think, it will be depended on parent function usage.
>
> > Wonder if we'll move at least RX/TX CBs invocation into a separate function -
> > would it help somehow?
> > I.E. if (q->cb != NULL) execut_cbs(...);
> > ?
>
> Yes.I tried to move both (Rx, Tx) execut_cbs as separate in .c func ton.
> That is helping the regression in some extended(Reduced from 2.84% to 1.27%)
>
> example:
> +uint16_t
> +__rte_eth_execut_tx_cbs(uint16_t port_id, uint16_t queue_id,
> + struct rte_mbuf **pkts, uint16_t nb_pkts,
> + struct rte_eth_queue_local *ql);
> +
> static inline uint16_t
> rte_eth_tx_burst(uint16_t port_id, uint16_t queue_id,
> struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
> @@ -3256,19 +3259,11 @@ rte_eth_tx_burst(uint16_t port_id, uint16_t
> queue_id,
> #ifdef RTE_ETHDEV_RXTX_CALLBACKS
> {
> struct rte_eth_queue_local *ql;
> - struct rte_eth_rxtx_callback *cb;
>
> ql = dev->tx_ql + queue_id;
> - if (unlikely(ql->cbs.head != NULL)) {
> -
> - __rte_eth_rxtx_cbs_inuse(&ql->cbs);
> -
> - for (cb = ql->cbs.head; cb != NULL; cb = cb->next)
> - nb_pkts = cb->fn.tx(port_id, queue_id, tx_pkts,
> - nb_pkts, cb->param);
> -
> - __rte_eth_rxtx_cbs_unuse(&ql->cbs);
> - }
> + if (unlikely(ql->cbs.head != NULL))
> + nb_pkts = __rte_eth_execut_tx_cbs(port_id,queue_id,
> + tx_pkts, nb_pkts, ql);
> }
> #endif
>
>
> > Another thought - as I remember a while ago Bruce and other lads suggested to move
> > rx_burst/tx)burst (and whole struct rte_eth_dev) definitions into rte_ethdev.c...
> > That would help to avoid such problems, again we'll be able to modify rte_eth_dev
> > without breaking ABI...
> > Though it would mean extra call overhead, so don't know of-hand how expensive
> > it could be.
>
> From my experiments it shows more expensive than above scheme.
>
> >
> > >
> > > > Or is it something else?
> > > >
> > > > Another thing - the series contains 2 main patches:
> > > > 1) http://dpdk.org/dev/patchwork/patch/31866/
> > > > Introduces eth_queue_local and moves callback data into it.
> > > > That adds one extra memory reference for rx/tx function to read cb func and data.
> > > > 2) http://dpdk.org/dev/patchwork/patch/31867/
> > > > Introduces some synchronization for cb data.
> > > >
> > > > Is it possible to rerun your tests with just patch #1 installed?
> > > > Hopefully it would help us to figure out which of the patches (#1 or #2)
> > > > is the main source of slowdown on arm machines.
> > >
> > > I re ran the test as requested:
> > > With first patch - 1.17% regression
> > > With first patch + Second patch - 2.84% regression
> >
> > Thanks
> >
> > >
> > > I am fine with slowdown, but it should be effected only with those
> > > application which request the callback feature.
> >
> > Ok, but you do realize that if we'll go with rx/tx function per queue,
> > patch #1 slowdown (1.17%) will probably reappear anyway?
>
> May be not, it will be one more redirection to get the rx/tx function
> pointer(may be a additionally load instruction)
>
> >
> > >
> > > >
> > > > >
> > > > > >
> > > > > > >
> > > > > > >
> > > > > > > Note:
> > > > > > > +ve number means "Performance regression with patches"
> > > > > > > -ve number means "Performance improvement with patches"
> > > > > > >
> > > > > > > Relative performance difference in percentage:
> > > > > > >
> > > > > > > % difference on host (2 x 40G)
> > > > > > > pkt_sz 1c 2c 4c 8c
> > > > > > > 64 1.41 0.18 0.51 0.29
> > > > > > > 72 0.50 0.53 0.09 0.19
> > > > > > > 128 0.31 0.31 0.42 0.00
> > > > > > > 256 -0.44 -0.44 0.00 0.00
> > > > > > > 512 1.94 1.94 0.01 0.01
> > > > > > > 1024 0.00 0.01 0.00 0.01
> > > > > > > 1518 0.02 0.01 0.02 0.02
> > > > > > >
> > > > > > > % difference on guest (2 x 40G)
> > > > > > > pkt_sz 1c 2c 4c 8c
> > > > > > > 64 5.78 2.30 -2.45 -0.01
> > > > > > > 72 1.13 1.13 1.31 -4.29
> > > > > > > 128 1.36 1.36 1.54 -0.82
> > > > > > > 256 2.02 2.03 -0.01 -0.35
> > > > > > > 512 4.05 4.04 0.00 -0.46
> > > > > > > 1024 0.39 0.38 0.00 -0.74
> > > > > > > 1518 0.00 0.00 -0.05 -4.20
> > > > > > >
> > > > > > > I think, it is because we added more code under
> > > > > > > the RTE_ETHDEV_RXTX_CALLBACKS and it is enabled by
> > > > > > > default.
> > > > > > >
> > > > > > > I think, the impact will vary based on
> > > > > > > architecture and underneath i-cache, d-cache and IPC.
> > > > > > >
> > > > > > > I am just thinking, How we can avoid such impact?
> > > > > > > How about,
> > > > > > > # Remove RTE_ETHDEV_RXTX_CALLBACKS option
> > > > > > > # Hook Rx/TX callbacks under TX/RX offload flags
> > > > > > > # ethdev layer gives helper function to invoke
> > > > > > > callbacks to driver.
> > > > > >
> > > > > > I suppose you suggest that user would have to decide at queue_setup()
> > > > > > stage does he wants a callback(s) for RX/TX or no?
> > > > >
> > > > > Yes. queue_setup or configure() time.
> > > > >
> > > > > > As I can see, the main drawback with that approach - it would introduce new limitation.
> > > > > > Right now it is possible to add/remove RX/TX callback at runtime
> > > > > > (without stopping and reconfiguring the queue), and I suppose we do want to keep that ability.
> > > > >
> > > > > For those _application_ where it can not decide or it need to add without
> > > > > stopping and re configuring the queue still can configure/enable the ethdev
> > > > > device with RX/TX callback option(and pay price for it)
> > > > >
> > > > > > Again in some cases user can't decide does he wants a callback installed or not,
> > > > > > before he actually calls dev_start().
> > > > > > l3fwd ptype-parse callback is an example of such situation:
> > > > > > right now user has to start device first to figure out which ptypes are supported by this PMD
> > > > > > with desired configuration, then based on this information he will (or will not) setup the callback.
> > > > >
> > > > > Good point. Can we remove that limitation from PMD perspective? IMO, ptype-parse is more of HW feature,
> > > > > All we need to do a lookup(single load) to convert to DPDK packet type.
> > > > > http://dpdk.org/browse/dpdk/tree/drivers/net/thunderx/nicvf_rxtx.c#n258
> > > > >
> > > > > I see almost all the drivers has dummy check like this, I think, That makes it
> > > > > dependency with start().
> > > > >
> > > > > if (dev->rx_pkt_burst == i40e_recv_pkts ||
> > > > > dev->rx_pkt_burst == i40e_recv_pkts_bulk_alloc ||
> > > > > dev->rx_pkt_burst == i40e_recv_scattered_pkts ||
> > > > > dev->rx_pkt_burst == i40e_recv_scattered_pkts_vec ||
> > > > > dev->rx_pkt_burst == i40e_recv_pkts_vec)
> > > > > return ptypes;
> > > > >
> > > >
> > > > We probably can, but it would require extra work and changes inside the PMDs.
> > >
> > > Yes, If we want do it in clean way. Another intermediate solution could
> > > be return some valid error code on those PMD. On such error code, application can
> > > start the device and get the supported ptype and then stop/reconfigure it again
> > >
> > > > i40e is a good one - all rx functions support the same ptypes.
> > > > But let say for ixgbe ARM version of vRX doesn't support all ptypes that x86 vRX
> > > > and generic scalar RX do.
> > > > For fm10k - vector RX and scalar RX also support different ptype sets.
> > >
> > > >
> > > > >
> > > > > > What I thought in same direction - introduce a notion of 'static' and 'dynamic' callbacks.
> > > > > > Static ones can't be removed while queue is not stopped while dynamic can.
> > > > > > But that also requires user to select at queue_setup() stage does he wants dynamic
> > > > > > callbacks for that queue or not (new offload flag or extra field in rxconf/txconf structure).
> > > > > > So again - same limitation for the user.
> > > > > > Another possibility here - have a flag 'dynamic' or 'static' not per queue, but per individual callback.
> > > > > > Yes, that would mean API change for add/remove callback functions.
> > > > >
> > > > > At least on my test, the regression was caused because adding the code in
> > > > > tx_burst and rx_burst under the RTE_ETHDEV_RXTX_CALLBACKS(which enabled
> > > > > by default). By disabling the RTE_ETHDEV_RXTX_CALLBACKS option, I don't
> > > > > see any regression. If so, Will such regression fixed by introducing
> > > > > 'static' or 'dynamic' callbacks? I am happy to test and provide feedback.
> > > >
> > > > Probably no then, but let's try the experiment I mentioned above first.
> > > >
> > > > >
> > > > > For me, I think, The better option is request from application for the
> > > > > need for Rx/TX callbacks and set the handler appropriate in the driver to
> > > > > have zero impact for the application which does not need callback at all.
> > > >
> > > > It is possible, but:
> > > > - that would be quite significant change and would affect each RX and TX function in each PMD.
> > >
> > > May be not, assume if we have helper function which invoke the callbacks.
> > > PMD can just call that before returning it.
> >
> > Even with helpers it means we'll have to double number of RX/TX functions -
> > one with a CB support, another without.
>
> IMO, It is up to the PMD driver. It can still choose to enable callbacks
> all the time irrespective of input from application(i.e no need for double
> number of RX/TX functions).
Good point.
>
> But it will enable a PMD to choose do optimization if the PMD wants
> it. As a NW PMD maintainer, I will be OK to make minimal change(if the
> helper function is available) in my PMD, if I get 1-2%
> improvement. On the upside, We can remove RTE_ETHDEV_RXTX_CALLBACKS
> conditional complication flag.
Yes, removing RTE_ETHDEV_RXTX_CALLBACKS would definitely be a good thing.
I tried the approach you suggested for ixgbe PMD - on IA there seems no regression.
The only thing I don't really happy with it - it would require changes for every RX/TX function in each PMD.
Yes, changes are quite mechanical, but still every PMD will need to be retested.
Before going forward would be really interesting to hear other people opinions here.
Might be there are some other ways to overcome that problem.
Thanks
Konstantin
>
>
> >
> > >
> > > > - from other side - even now there are several libs inside DPDK that rely on ability to add/remove
> > > > callbacks on the fly - pdump, latencystats.
> > > I think, it is application who decides to use this API,then I think,
> > > application can request callback feature support. I think, we have
> > > followed the same method in latest RX/TX offload flag scheme as well.
> > >
> > > > ethdev rx profiling also relies on ability to install RX callback.
> > > >
> > > > With all these things I presume most apps will configure their devices with rx/tx callback support enabled anyway.
> > > > Which makes me think - is it worth to introduce such changes at all.
> > > > Anyway, my first suggestion would be let's try to figure out what exactly causes such big slowdown on ARM.
> > >
> > > It may not be ARM in general, Under our roof, We have different class of SoCs based
> > > on the use case like 4 cores, 16 core, 96 cores part etc with different
> > > micro architecture etc based on the use case(embedded/server etc) like
> > > Intel. So it may not very generic with all ARM machines, it is really
> > > based on micro architecture. ie. The same patch may behave
> > > differently(less than < 1%) on IA-Atom vs IA-XEON. So IMO, Common code
> > > change should use helper functions, it up to the driver to use it.
> >
> > Konstantin
> >
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2] ethdev: increase flow type limit from 32 to 64
2017-11-27 12:29 6% [dpdk-dev] [PATCH] ethdev: increase flow type limit from 32 to 64 Kirill Rybalchenko
@ 2018-01-15 16:58 7% ` Kirill Rybalchenko
2018-01-15 17:33 7% ` [dpdk-dev] [PATCH v3] " Kirill Rybalchenko
1 sibling, 1 reply; 200+ results
From: Kirill Rybalchenko @ 2018-01-15 16:58 UTC (permalink / raw)
To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, thomas, ferruh.yigit
Increase the internal limit for flow types from 32 to 64
to support future flow type extensions.
Change type of variables from uint32_t[] to uint64_t[]:
rte_eth_fdir_info.flow_types_mask
rte_eth_hash_global_conf.sym_hash_enable_mask
rte_eth_hash_global_conf.valid_bit_mask
This modification affects the following components:
net/i40e
net/ixgbe
app/testpmd
v2:
implement versioning of rte_eth_dev_filter_ctrl function
for ABI backward compatibility with version 17.11 and older
Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
app/test-pmd/cmdline.c | 22 ++---
drivers/net/i40e/i40e_ethdev.c | 38 ++++----
drivers/net/i40e/i40e_fdir.c | 25 ++---
drivers/net/ixgbe/ixgbe_fdir.c | 22 +++--
lib/librte_ether/rte_eth_ctrl.h | 12 +--
lib/librte_ether/rte_ethdev.c | 157 +++++++++++++++++++++++++++++++-
lib/librte_ether/rte_ethdev_version.map | 7 ++
7 files changed, 224 insertions(+), 59 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6d71a5f..964d4ed 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10803,7 +10803,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
struct rte_eth_fdir_info fdir_info;
struct rte_eth_fdir_flex_mask flex_mask;
struct rte_port *port;
- uint32_t flow_type_mask;
+ uint64_t flow_type_mask;
uint16_t i;
int ret;
@@ -10856,7 +10856,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
return;
}
for (i = RTE_ETH_FLOW_UNKNOWN; i < RTE_ETH_FLOW_MAX; i++) {
- if (flow_type_mask & (1 << i)) {
+ if (flow_type_mask & (1ULL << i)) {
flex_mask.flow_type = i;
fdir_set_flex_mask(res->port_id, &flex_mask);
}
@@ -10865,7 +10865,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
return;
}
flex_mask.flow_type = str2flowtype(res->flow_type);
- if (!(flow_type_mask & (1 << flex_mask.flow_type))) {
+ if (!(flow_type_mask & (1ULL << flex_mask.flow_type))) {
printf("Flow type %s not supported on port %d\n",
res->flow_type, res->port_id);
return;
@@ -11227,10 +11227,10 @@ cmd_get_hash_global_config_parsed(void *parsed_result,
}
for (i = 0; i < RTE_ETH_FLOW_MAX; i++) {
- idx = i / UINT32_BIT;
- offset = i % UINT32_BIT;
+ idx = i / UINT64_BIT;
+ offset = i % UINT64_BIT;
if (!(info.info.global_conf.valid_bit_mask[idx] &
- (1UL << offset)))
+ (1ULL << offset)))
continue;
str = flowtype_to_str(i);
if (!str)
@@ -11238,7 +11238,7 @@ cmd_get_hash_global_config_parsed(void *parsed_result,
printf("Symmetric hash is %s globally for flow type %s "
"by port %d\n",
((info.info.global_conf.sym_hash_enable_mask[idx] &
- (1UL << offset)) ? "enabled" : "disabled"), str,
+ (1ULL << offset)) ? "enabled" : "disabled"), str,
res->port_id);
}
}
@@ -11299,12 +11299,12 @@ cmd_set_hash_global_config_parsed(void *parsed_result,
RTE_ETH_HASH_FUNCTION_DEFAULT;
ftype = str2flowtype(res->flow_type);
- idx = ftype / (CHAR_BIT * sizeof(uint32_t));
- offset = ftype % (CHAR_BIT * sizeof(uint32_t));
- info.info.global_conf.valid_bit_mask[idx] |= (1UL << offset);
+ idx = ftype / UINT64_BIT;
+ offset = ftype % UINT64_BIT;
+ info.info.global_conf.valid_bit_mask[idx] |= (1ULL << offset);
if (!strcmp(res->enable, "enable"))
info.info.global_conf.sym_hash_enable_mask[idx] |=
- (1UL << offset);
+ (1ULL << offset);
ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
RTE_ETH_FILTER_SET, &info);
if (ret < 0)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7796e9e..d0473f0 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -8134,14 +8134,17 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
/*
- * We work only with lowest 32 bits which is not correct, but to work
- * properly the valid_bit_mask size should be increased up to 64 bits
- * and this will brake ABI. This modification will be done in next
- * release
+ * As i40e supports less than 64 flow types, only first 64 bits need to
+ * be checked.
*/
- g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_mask;
+ for (i = 1; i < RTE_SYM_HASH_MASK_ARRAY_SIZE; i++) {
+ g_cfg->valid_bit_mask[i] = 0ULL;
+ g_cfg->sym_hash_enable_mask[i] = 0ULL;
+ }
- for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT32_BIT; i++) {
+ g_cfg->valid_bit_mask[0] = adapter->flow_types_mask;
+
+ for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT64_BIT; i++) {
if (!adapter->pctypes_tbl[i])
continue;
for (j = I40E_FILTER_PCTYPE_INVALID + 1;
@@ -8150,7 +8153,7 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
g_cfg->sym_hash_enable_mask[0] |=
- (1UL << i);
+ (1ULL << i);
}
}
}
@@ -8164,7 +8167,7 @@ i40e_hash_global_config_check(const struct i40e_adapter *adapter,
const struct rte_eth_hash_global_conf *g_cfg)
{
uint32_t i;
- uint32_t mask0, i40e_mask = adapter->flow_types_mask;
+ uint64_t mask0, i40e_mask = adapter->flow_types_mask;
if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR &&
@@ -8175,7 +8178,7 @@ i40e_hash_global_config_check(const struct i40e_adapter *adapter,
}
/*
- * As i40e supports less than 32 flow types, only first 32 bits need to
+ * As i40e supports less than 64 flow types, only first 64 bits need to
* be checked.
*/
mask0 = g_cfg->valid_bit_mask[0];
@@ -8211,23 +8214,20 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
int ret;
uint16_t i, j;
uint32_t reg;
- /*
- * We work only with lowest 32 bits which is not correct, but to work
- * properly the valid_bit_mask size should be increased up to 64 bits
- * and this will brake ABI. This modification will be done in next
- * release
- */
- uint32_t mask0 = g_cfg->valid_bit_mask[0] &
- (uint32_t)adapter->flow_types_mask;
+ uint64_t mask0 = g_cfg->valid_bit_mask[0] & adapter->flow_types_mask;
/* Check the input parameters */
ret = i40e_hash_global_config_check(adapter, g_cfg);
if (ret < 0)
return ret;
- for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT32_BIT; i++) {
+ /*
+ * As i40e supports less than 64 flow types, only first 64 bits need to
+ * be configured.
+ */
+ for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT64_BIT; i++) {
if (mask0 & (1UL << i)) {
- reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
+ reg = (g_cfg->sym_hash_enable_mask[0] & (1ULL << i)) ?
I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
for (j = I40E_FILTER_PCTYPE_INVALID + 1;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 906c204..3a9e656 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -66,17 +66,17 @@
#define I40E_COUNTER_INDEX_FDIR(pf_id) (0 + (pf_id) * I40E_COUNTER_PF)
#define I40E_FDIR_FLOWS ( \
- (1 << RTE_ETH_FLOW_FRAG_IPV4) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
- (1 << RTE_ETH_FLOW_FRAG_IPV6) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) | \
- (1 << RTE_ETH_FLOW_L2_PAYLOAD))
+ (1ULL << RTE_ETH_FLOW_FRAG_IPV4) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
+ (1ULL << RTE_ETH_FLOW_FRAG_IPV6) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) | \
+ (1ULL << RTE_ETH_FLOW_L2_PAYLOAD))
static int i40e_fdir_filter_programming(struct i40e_pf *pf,
enum i40e_filter_pctype pctype,
@@ -1999,6 +1999,7 @@ i40e_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir)
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
uint16_t num_flex_set = 0;
uint16_t num_flex_mask = 0;
+ uint16_t i;
if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT)
fdir->mode = RTE_FDIR_MODE_PERFECT;
@@ -2011,6 +2012,8 @@ i40e_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir)
(uint32_t)hw->func_caps.fd_filters_best_effort;
fdir->max_flexpayload = I40E_FDIR_MAX_FLEX_LEN;
fdir->flow_types_mask[0] = I40E_FDIR_FLOWS;
+ for (i = 1; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
+ fdir->flow_types_mask[i] = 0ULL;
fdir->flex_payload_unit = sizeof(uint16_t);
fdir->flex_bitmask_unit = sizeof(uint16_t);
fdir->max_flex_payload_segment_num = I40E_MAX_FLXPLD_FIED;
diff --git a/drivers/net/ixgbe/ixgbe_fdir.c b/drivers/net/ixgbe/ixgbe_fdir.c
index 551580c..236ab8c 100644
--- a/drivers/net/ixgbe/ixgbe_fdir.c
+++ b/drivers/net/ixgbe/ixgbe_fdir.c
@@ -41,14 +41,14 @@
#define IXGBE_FDIRCMD_CMD_INTERVAL_US 10
#define IXGBE_FDIR_FLOW_TYPES ( \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER))
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER))
#define IPV6_ADDR_TO_MASK(ipaddr, ipv6m) do { \
uint8_t ipv6_addr[16]; \
@@ -1407,7 +1407,7 @@ ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_hw_fdir_info *info =
IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
- uint32_t fdirctrl, max_num;
+ uint32_t fdirctrl, max_num, i;
uint8_t offset;
fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
@@ -1439,9 +1439,11 @@ ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info
if (fdir_info->mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN ||
fdir_info->mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
- fdir_info->flow_types_mask[0] = 0;
+ fdir_info->flow_types_mask[0] = 0ULL;
else
fdir_info->flow_types_mask[0] = IXGBE_FDIR_FLOW_TYPES;
+ for (i = 1; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
+ fdir_info->flow_types_mask[i] = 0ULL;
fdir_info->flex_payload_unit = sizeof(uint16_t);
fdir_info->max_flex_payload_segment_num = 1;
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 7991efa..668f59a 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -662,9 +662,9 @@ enum rte_fdir_mode {
RTE_FDIR_MODE_PERFECT_TUNNEL, /**< Enable FDIR filter mode - tunnel. */
};
-#define UINT32_BIT (CHAR_BIT * sizeof(uint32_t))
+#define UINT64_BIT (CHAR_BIT * sizeof(uint64_t))
#define RTE_FLOW_MASK_ARRAY_SIZE \
- (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
+ (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
/**
* A structure used to get the information of flow director filter.
@@ -681,7 +681,7 @@ struct rte_eth_fdir_info {
uint32_t guarant_spc; /**< Guaranteed spaces.*/
uint32_t best_spc; /**< Best effort spaces.*/
/** Bit mask for every supported flow type. */
- uint32_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
+ uint64_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
uint32_t max_flexpayload; /**< Total flex payload in bytes. */
/** Flexible payload unit in bytes. Size and alignments of all flex
payload segments should be multiplies of this value. */
@@ -774,7 +774,7 @@ enum rte_eth_hash_function {
};
#define RTE_SYM_HASH_MASK_ARRAY_SIZE \
- (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
+ (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
/**
* A structure used to set or get global hash function configurations which
* include symmetric hash enable per flow type and hash function type.
@@ -787,9 +787,9 @@ enum rte_eth_hash_function {
struct rte_eth_hash_global_conf {
enum rte_eth_hash_function hash_func; /**< Hash function type */
/** Bit mask for symmetric hash enable per flow type */
- uint32_t sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
+ uint64_t sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
/** Bit mask indicates if the corresponding bit is valid */
- uint32_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
+ uint64_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
};
/**
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index b349599..d30eabc 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -34,6 +34,7 @@
#include <rte_errno.h>
#include <rte_spinlock.h>
#include <rte_string_fns.h>
+#include <rte_compat.h>
#include "rte_ether.h"
#include "rte_ethdev.h"
@@ -3148,8 +3149,154 @@ rte_eth_dev_filter_supported(uint16_t port_id,
}
int
-rte_eth_dev_filter_ctrl(uint16_t port_id, enum rte_filter_type filter_type,
- enum rte_filter_op filter_op, void *arg)
+rte_eth_dev_filter_ctrl_v22(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg);
+
+int
+rte_eth_dev_filter_ctrl_v22(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg)
+{
+ struct rte_eth_fdir_info_v22 {
+ enum rte_fdir_mode mode;
+ struct rte_eth_fdir_masks mask;
+ struct rte_eth_fdir_flex_conf flex_conf;
+ uint32_t guarant_spc;
+ uint32_t best_spc;
+ uint32_t flow_types_mask[1];
+ uint32_t max_flexpayload;
+ uint32_t flex_payload_unit;
+ uint32_t max_flex_payload_segment_num;
+ uint16_t flex_payload_limit;
+ uint32_t flex_bitmask_unit;
+ uint32_t max_flex_bitmask_num;
+ };
+
+ struct rte_eth_hash_global_conf_v22 {
+ enum rte_eth_hash_function hash_func;
+ uint32_t sym_hash_enable_mask[1];
+ uint32_t valid_bit_mask[1];
+ };
+
+ struct rte_eth_hash_filter_info_v22 {
+ enum rte_eth_hash_filter_info_type info_type;
+ union {
+ uint8_t enable;
+ struct rte_eth_hash_global_conf_v22 global_conf;
+ struct rte_eth_input_set_conf input_set_conf;
+ } info;
+ };
+
+ struct rte_eth_dev *dev;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+ dev = &rte_eth_devices[port_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->filter_ctrl, -ENOTSUP);
+ if (filter_op == RTE_ETH_FILTER_INFO) {
+ int retval;
+ struct rte_eth_fdir_info_v22 *fdir_info_v22;
+ struct rte_eth_fdir_info fdir_info;
+
+ fdir_info_v22 = (struct rte_eth_fdir_info_v22 *)arg;
+
+ retval = (*dev->dev_ops->filter_ctrl)(dev, filter_type,
+ filter_op, (void *)&fdir_info);
+ fdir_info_v22->mode = fdir_info.mode;
+ fdir_info_v22->mask = fdir_info.mask;
+ fdir_info_v22->flex_conf = fdir_info.flex_conf;
+ fdir_info_v22->guarant_spc = fdir_info.guarant_spc;
+ fdir_info_v22->best_spc = fdir_info.best_spc;
+ fdir_info_v22->flow_types_mask[0] =
+ (uint32_t)fdir_info.flow_types_mask[0];
+ fdir_info_v22->max_flexpayload = fdir_info.max_flexpayload;
+ fdir_info_v22->flex_payload_unit = fdir_info.flex_payload_unit;
+ fdir_info_v22->max_flex_payload_segment_num =
+ fdir_info.max_flex_payload_segment_num;
+ fdir_info_v22->flex_payload_limit =
+ fdir_info.flex_payload_limit;
+ fdir_info_v22->flex_bitmask_unit = fdir_info.flex_bitmask_unit;
+ fdir_info_v22->max_flex_bitmask_num =
+ fdir_info.max_flex_bitmask_num;
+ return retval;
+ } else if (filter_op == RTE_ETH_FILTER_GET) {
+ int retval;
+ struct rte_eth_hash_filter_info filter_info;
+ struct rte_eth_hash_filter_info_v22 *filter_info_v22 =
+ (struct rte_eth_hash_filter_info_v22 *)arg;
+
+ filter_info.info_type = filter_info_v22->info_type;
+ retval = (*dev->dev_ops->filter_ctrl)(dev, filter_type,
+ filter_op, (void *)&filter_info);
+
+ switch (filter_info_v22->info_type) {
+ case RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT:
+ filter_info_v22->info.enable = filter_info.info.enable;
+ break;
+ case RTE_ETH_HASH_FILTER_GLOBAL_CONFIG:
+ filter_info_v22->info.global_conf.hash_func =
+ filter_info.info.global_conf.hash_func;
+ filter_info_v22->
+ info.global_conf.sym_hash_enable_mask[0] =
+ (uint32_t)filter_info.info.
+ global_conf.sym_hash_enable_mask[0];
+ filter_info_v22->info.global_conf.valid_bit_mask[0] =
+ (uint32_t)filter_info.info.global_conf.
+ valid_bit_mask[0];
+ break;
+ case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
+ filter_info_v22->info.input_set_conf =
+ filter_info.info.input_set_conf;
+ break;
+ default:
+ break;
+ }
+ return retval;
+ } else if (filter_op == RTE_ETH_FILTER_SET) {
+ struct rte_eth_hash_filter_info filter_info;
+ struct rte_eth_hash_filter_info_v22 *filter_info_v22 =
+ (struct rte_eth_hash_filter_info_v22 *)arg;
+
+ filter_info.info_type = filter_info_v22->info_type;
+ switch (filter_info_v22->info_type) {
+ case RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT:
+ filter_info.info.enable = filter_info_v22->info.enable;
+ break;
+ case RTE_ETH_HASH_FILTER_GLOBAL_CONFIG:
+ filter_info.info.global_conf.hash_func =
+ filter_info_v22->info.global_conf.hash_func;
+ filter_info.info.global_conf.sym_hash_enable_mask[0] =
+ (uint32_t)filter_info_v22->
+ info.global_conf.sym_hash_enable_mask[0];
+ filter_info.info.global_conf.valid_bit_mask[0] =
+ (uint32_t)filter_info_v22->
+ info.global_conf.valid_bit_mask[0];
+ break;
+ case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
+ filter_info.info.input_set_conf =
+ filter_info_v22->info.input_set_conf;
+ break;
+ default:
+ break;
+ }
+ return (*dev->dev_ops->filter_ctrl)(dev, filter_type, filter_op,
+ (void *)&filter_info);
+ } else
+ return (*dev->dev_ops->filter_ctrl)(dev, filter_type, filter_op,
+ arg);
+}
+VERSION_SYMBOL(rte_eth_dev_filter_ctrl, _v22, 2.2);
+
+int
+rte_eth_dev_filter_ctrl_v1802(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg);
+
+int
+rte_eth_dev_filter_ctrl_v1802(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg)
{
struct rte_eth_dev *dev;
@@ -3159,6 +3306,12 @@ rte_eth_dev_filter_ctrl(uint16_t port_id, enum rte_filter_type filter_type,
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->filter_ctrl, -ENOTSUP);
return (*dev->dev_ops->filter_ctrl)(dev, filter_type, filter_op, arg);
}
+BIND_DEFAULT_SYMBOL(rte_eth_dev_filter_ctrl, _v1802, 18.02);
+MAP_STATIC_SYMBOL(int rte_eth_dev_filter_ctrl(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg),
+ rte_eth_dev_filter_ctrl_v1802);
+
void *
rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id,
diff --git a/lib/librte_ether/rte_ethdev_version.map b/lib/librte_ether/rte_ethdev_version.map
index e9681ac..2906a18 100644
--- a/lib/librte_ether/rte_ethdev_version.map
+++ b/lib/librte_ether/rte_ethdev_version.map
@@ -198,6 +198,13 @@ DPDK_17.11 {
} DPDK_17.08;
+DPDK_18.02 {
+ global:
+
+ rte_eth_dev_filter_ctrl;
+
+} DPDK_17.11;
+
EXPERIMENTAL {
global:
--
2.5.5
^ permalink raw reply [relevance 7%]
* [dpdk-dev] [PATCH v3] ethdev: increase flow type limit from 32 to 64
2018-01-15 16:58 7% ` [dpdk-dev] [PATCH v2] " Kirill Rybalchenko
@ 2018-01-15 17:33 7% ` Kirill Rybalchenko
2018-01-15 21:27 3% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Kirill Rybalchenko @ 2018-01-15 17:33 UTC (permalink / raw)
To: dev; +Cc: kirill.rybalchenko, andrey.chilikin, thomas, ferruh.yigit
Increase the internal limit for flow types from 32 to 64
to support future flow type extensions.
Change type of variables from uint32_t[] to uint64_t[]:
rte_eth_fdir_info.flow_types_mask
rte_eth_hash_global_conf.sym_hash_enable_mask
rte_eth_hash_global_conf.valid_bit_mask
This modification affects the following components:
net/i40e
net/ixgbe
app/testpmd
v2:
implement versioning of rte_eth_dev_filter_ctrl function
for ABI backward compatibility with version 17.11 and older
v3:
fix code style warnings
Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
---
app/test-pmd/cmdline.c | 22 ++---
drivers/net/i40e/i40e_ethdev.c | 38 ++++----
drivers/net/i40e/i40e_fdir.c | 25 ++---
drivers/net/ixgbe/ixgbe_fdir.c | 22 +++--
lib/librte_ether/rte_eth_ctrl.h | 12 +--
lib/librte_ether/rte_ethdev.c | 156 +++++++++++++++++++++++++++++++-
lib/librte_ether/rte_ethdev_version.map | 7 ++
7 files changed, 223 insertions(+), 59 deletions(-)
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 6d71a5f..964d4ed 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -10803,7 +10803,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
struct rte_eth_fdir_info fdir_info;
struct rte_eth_fdir_flex_mask flex_mask;
struct rte_port *port;
- uint32_t flow_type_mask;
+ uint64_t flow_type_mask;
uint16_t i;
int ret;
@@ -10856,7 +10856,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
return;
}
for (i = RTE_ETH_FLOW_UNKNOWN; i < RTE_ETH_FLOW_MAX; i++) {
- if (flow_type_mask & (1 << i)) {
+ if (flow_type_mask & (1ULL << i)) {
flex_mask.flow_type = i;
fdir_set_flex_mask(res->port_id, &flex_mask);
}
@@ -10865,7 +10865,7 @@ cmd_flow_director_flex_mask_parsed(void *parsed_result,
return;
}
flex_mask.flow_type = str2flowtype(res->flow_type);
- if (!(flow_type_mask & (1 << flex_mask.flow_type))) {
+ if (!(flow_type_mask & (1ULL << flex_mask.flow_type))) {
printf("Flow type %s not supported on port %d\n",
res->flow_type, res->port_id);
return;
@@ -11227,10 +11227,10 @@ cmd_get_hash_global_config_parsed(void *parsed_result,
}
for (i = 0; i < RTE_ETH_FLOW_MAX; i++) {
- idx = i / UINT32_BIT;
- offset = i % UINT32_BIT;
+ idx = i / UINT64_BIT;
+ offset = i % UINT64_BIT;
if (!(info.info.global_conf.valid_bit_mask[idx] &
- (1UL << offset)))
+ (1ULL << offset)))
continue;
str = flowtype_to_str(i);
if (!str)
@@ -11238,7 +11238,7 @@ cmd_get_hash_global_config_parsed(void *parsed_result,
printf("Symmetric hash is %s globally for flow type %s "
"by port %d\n",
((info.info.global_conf.sym_hash_enable_mask[idx] &
- (1UL << offset)) ? "enabled" : "disabled"), str,
+ (1ULL << offset)) ? "enabled" : "disabled"), str,
res->port_id);
}
}
@@ -11299,12 +11299,12 @@ cmd_set_hash_global_config_parsed(void *parsed_result,
RTE_ETH_HASH_FUNCTION_DEFAULT;
ftype = str2flowtype(res->flow_type);
- idx = ftype / (CHAR_BIT * sizeof(uint32_t));
- offset = ftype % (CHAR_BIT * sizeof(uint32_t));
- info.info.global_conf.valid_bit_mask[idx] |= (1UL << offset);
+ idx = ftype / UINT64_BIT;
+ offset = ftype % UINT64_BIT;
+ info.info.global_conf.valid_bit_mask[idx] |= (1ULL << offset);
if (!strcmp(res->enable, "enable"))
info.info.global_conf.sym_hash_enable_mask[idx] |=
- (1UL << offset);
+ (1ULL << offset);
ret = rte_eth_dev_filter_ctrl(res->port_id, RTE_ETH_FILTER_HASH,
RTE_ETH_FILTER_SET, &info);
if (ret < 0)
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 7796e9e..d0473f0 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -8134,14 +8134,17 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
(reg & I40E_GLQF_CTL_HTOEP_MASK) ? "Toeplitz" : "Simple XOR");
/*
- * We work only with lowest 32 bits which is not correct, but to work
- * properly the valid_bit_mask size should be increased up to 64 bits
- * and this will brake ABI. This modification will be done in next
- * release
+ * As i40e supports less than 64 flow types, only first 64 bits need to
+ * be checked.
*/
- g_cfg->valid_bit_mask[0] = (uint32_t)adapter->flow_types_mask;
+ for (i = 1; i < RTE_SYM_HASH_MASK_ARRAY_SIZE; i++) {
+ g_cfg->valid_bit_mask[i] = 0ULL;
+ g_cfg->sym_hash_enable_mask[i] = 0ULL;
+ }
- for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT32_BIT; i++) {
+ g_cfg->valid_bit_mask[0] = adapter->flow_types_mask;
+
+ for (i = RTE_ETH_FLOW_UNKNOWN + 1; i < UINT64_BIT; i++) {
if (!adapter->pctypes_tbl[i])
continue;
for (j = I40E_FILTER_PCTYPE_INVALID + 1;
@@ -8150,7 +8153,7 @@ i40e_get_hash_filter_global_config(struct i40e_hw *hw,
reg = i40e_read_rx_ctl(hw, I40E_GLQF_HSYM(j));
if (reg & I40E_GLQF_HSYM_SYMH_ENA_MASK) {
g_cfg->sym_hash_enable_mask[0] |=
- (1UL << i);
+ (1ULL << i);
}
}
}
@@ -8164,7 +8167,7 @@ i40e_hash_global_config_check(const struct i40e_adapter *adapter,
const struct rte_eth_hash_global_conf *g_cfg)
{
uint32_t i;
- uint32_t mask0, i40e_mask = adapter->flow_types_mask;
+ uint64_t mask0, i40e_mask = adapter->flow_types_mask;
if (g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
g_cfg->hash_func != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR &&
@@ -8175,7 +8178,7 @@ i40e_hash_global_config_check(const struct i40e_adapter *adapter,
}
/*
- * As i40e supports less than 32 flow types, only first 32 bits need to
+ * As i40e supports less than 64 flow types, only first 64 bits need to
* be checked.
*/
mask0 = g_cfg->valid_bit_mask[0];
@@ -8211,23 +8214,20 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
int ret;
uint16_t i, j;
uint32_t reg;
- /*
- * We work only with lowest 32 bits which is not correct, but to work
- * properly the valid_bit_mask size should be increased up to 64 bits
- * and this will brake ABI. This modification will be done in next
- * release
- */
- uint32_t mask0 = g_cfg->valid_bit_mask[0] &
- (uint32_t)adapter->flow_types_mask;
+ uint64_t mask0 = g_cfg->valid_bit_mask[0] & adapter->flow_types_mask;
/* Check the input parameters */
ret = i40e_hash_global_config_check(adapter, g_cfg);
if (ret < 0)
return ret;
- for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT32_BIT; i++) {
+ /*
+ * As i40e supports less than 64 flow types, only first 64 bits need to
+ * be configured.
+ */
+ for (i = RTE_ETH_FLOW_UNKNOWN + 1; mask0 && i < UINT64_BIT; i++) {
if (mask0 & (1UL << i)) {
- reg = (g_cfg->sym_hash_enable_mask[0] & (1UL << i)) ?
+ reg = (g_cfg->sym_hash_enable_mask[0] & (1ULL << i)) ?
I40E_GLQF_HSYM_SYMH_ENA_MASK : 0;
for (j = I40E_FILTER_PCTYPE_INVALID + 1;
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 906c204..3a9e656 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -66,17 +66,17 @@
#define I40E_COUNTER_INDEX_FDIR(pf_id) (0 + (pf_id) * I40E_COUNTER_PF)
#define I40E_FDIR_FLOWS ( \
- (1 << RTE_ETH_FLOW_FRAG_IPV4) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
- (1 << RTE_ETH_FLOW_FRAG_IPV6) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) | \
- (1 << RTE_ETH_FLOW_L2_PAYLOAD))
+ (1ULL << RTE_ETH_FLOW_FRAG_IPV4) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
+ (1ULL << RTE_ETH_FLOW_FRAG_IPV6) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER) | \
+ (1ULL << RTE_ETH_FLOW_L2_PAYLOAD))
static int i40e_fdir_filter_programming(struct i40e_pf *pf,
enum i40e_filter_pctype pctype,
@@ -1999,6 +1999,7 @@ i40e_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir)
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
uint16_t num_flex_set = 0;
uint16_t num_flex_mask = 0;
+ uint16_t i;
if (dev->data->dev_conf.fdir_conf.mode == RTE_FDIR_MODE_PERFECT)
fdir->mode = RTE_FDIR_MODE_PERFECT;
@@ -2011,6 +2012,8 @@ i40e_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir)
(uint32_t)hw->func_caps.fd_filters_best_effort;
fdir->max_flexpayload = I40E_FDIR_MAX_FLEX_LEN;
fdir->flow_types_mask[0] = I40E_FDIR_FLOWS;
+ for (i = 1; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
+ fdir->flow_types_mask[i] = 0ULL;
fdir->flex_payload_unit = sizeof(uint16_t);
fdir->flex_bitmask_unit = sizeof(uint16_t);
fdir->max_flex_payload_segment_num = I40E_MAX_FLXPLD_FIED;
diff --git a/drivers/net/ixgbe/ixgbe_fdir.c b/drivers/net/ixgbe/ixgbe_fdir.c
index 551580c..236ab8c 100644
--- a/drivers/net/ixgbe/ixgbe_fdir.c
+++ b/drivers/net/ixgbe/ixgbe_fdir.c
@@ -41,14 +41,14 @@
#define IXGBE_FDIRCMD_CMD_INTERVAL_US 10
#define IXGBE_FDIR_FLOW_TYPES ( \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
- (1 << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER))
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV4_OTHER) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_UDP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_TCP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_SCTP) | \
+ (1ULL << RTE_ETH_FLOW_NONFRAG_IPV6_OTHER))
#define IPV6_ADDR_TO_MASK(ipaddr, ipv6m) do { \
uint8_t ipv6_addr[16]; \
@@ -1407,7 +1407,7 @@ ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
struct ixgbe_hw_fdir_info *info =
IXGBE_DEV_PRIVATE_TO_FDIR_INFO(dev->data->dev_private);
- uint32_t fdirctrl, max_num;
+ uint32_t fdirctrl, max_num, i;
uint8_t offset;
fdirctrl = IXGBE_READ_REG(hw, IXGBE_FDIRCTRL);
@@ -1439,9 +1439,11 @@ ixgbe_fdir_info_get(struct rte_eth_dev *dev, struct rte_eth_fdir_info *fdir_info
if (fdir_info->mode == RTE_FDIR_MODE_PERFECT_MAC_VLAN ||
fdir_info->mode == RTE_FDIR_MODE_PERFECT_TUNNEL)
- fdir_info->flow_types_mask[0] = 0;
+ fdir_info->flow_types_mask[0] = 0ULL;
else
fdir_info->flow_types_mask[0] = IXGBE_FDIR_FLOW_TYPES;
+ for (i = 1; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
+ fdir_info->flow_types_mask[i] = 0ULL;
fdir_info->flex_payload_unit = sizeof(uint16_t);
fdir_info->max_flex_payload_segment_num = 1;
diff --git a/lib/librte_ether/rte_eth_ctrl.h b/lib/librte_ether/rte_eth_ctrl.h
index 7991efa..668f59a 100644
--- a/lib/librte_ether/rte_eth_ctrl.h
+++ b/lib/librte_ether/rte_eth_ctrl.h
@@ -662,9 +662,9 @@ enum rte_fdir_mode {
RTE_FDIR_MODE_PERFECT_TUNNEL, /**< Enable FDIR filter mode - tunnel. */
};
-#define UINT32_BIT (CHAR_BIT * sizeof(uint32_t))
+#define UINT64_BIT (CHAR_BIT * sizeof(uint64_t))
#define RTE_FLOW_MASK_ARRAY_SIZE \
- (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
+ (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
/**
* A structure used to get the information of flow director filter.
@@ -681,7 +681,7 @@ struct rte_eth_fdir_info {
uint32_t guarant_spc; /**< Guaranteed spaces.*/
uint32_t best_spc; /**< Best effort spaces.*/
/** Bit mask for every supported flow type. */
- uint32_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
+ uint64_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
uint32_t max_flexpayload; /**< Total flex payload in bytes. */
/** Flexible payload unit in bytes. Size and alignments of all flex
payload segments should be multiplies of this value. */
@@ -774,7 +774,7 @@ enum rte_eth_hash_function {
};
#define RTE_SYM_HASH_MASK_ARRAY_SIZE \
- (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
+ (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
/**
* A structure used to set or get global hash function configurations which
* include symmetric hash enable per flow type and hash function type.
@@ -787,9 +787,9 @@ enum rte_eth_hash_function {
struct rte_eth_hash_global_conf {
enum rte_eth_hash_function hash_func; /**< Hash function type */
/** Bit mask for symmetric hash enable per flow type */
- uint32_t sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
+ uint64_t sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
/** Bit mask indicates if the corresponding bit is valid */
- uint32_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
+ uint64_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
};
/**
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index b349599..9fb560e 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -34,6 +34,7 @@
#include <rte_errno.h>
#include <rte_spinlock.h>
#include <rte_string_fns.h>
+#include <rte_compat.h>
#include "rte_ether.h"
#include "rte_ethdev.h"
@@ -3148,8 +3149,153 @@ rte_eth_dev_filter_supported(uint16_t port_id,
}
int
-rte_eth_dev_filter_ctrl(uint16_t port_id, enum rte_filter_type filter_type,
- enum rte_filter_op filter_op, void *arg)
+rte_eth_dev_filter_ctrl_v22(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg);
+
+int
+rte_eth_dev_filter_ctrl_v22(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg)
+{
+ struct rte_eth_fdir_info_v22 {
+ enum rte_fdir_mode mode;
+ struct rte_eth_fdir_masks mask;
+ struct rte_eth_fdir_flex_conf flex_conf;
+ uint32_t guarant_spc;
+ uint32_t best_spc;
+ uint32_t flow_types_mask[1];
+ uint32_t max_flexpayload;
+ uint32_t flex_payload_unit;
+ uint32_t max_flex_payload_segment_num;
+ uint16_t flex_payload_limit;
+ uint32_t flex_bitmask_unit;
+ uint32_t max_flex_bitmask_num;
+ };
+
+ struct rte_eth_hash_global_conf_v22 {
+ enum rte_eth_hash_function hash_func;
+ uint32_t sym_hash_enable_mask[1];
+ uint32_t valid_bit_mask[1];
+ };
+
+ struct rte_eth_hash_filter_info_v22 {
+ enum rte_eth_hash_filter_info_type info_type;
+ union {
+ uint8_t enable;
+ struct rte_eth_hash_global_conf_v22 global_conf;
+ struct rte_eth_input_set_conf input_set_conf;
+ } info;
+ };
+
+ struct rte_eth_dev *dev;
+
+ RTE_ETH_VALID_PORTID_OR_ERR_RET(port_id, -ENODEV);
+
+ dev = &rte_eth_devices[port_id];
+ RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->filter_ctrl, -ENOTSUP);
+ if (filter_op == RTE_ETH_FILTER_INFO) {
+ int retval;
+ struct rte_eth_fdir_info_v22 *fdir_info_v22;
+ struct rte_eth_fdir_info fdir_info;
+
+ fdir_info_v22 = (struct rte_eth_fdir_info_v22 *)arg;
+
+ retval = (*dev->dev_ops->filter_ctrl)(dev, filter_type,
+ filter_op, (void *)&fdir_info);
+ fdir_info_v22->mode = fdir_info.mode;
+ fdir_info_v22->mask = fdir_info.mask;
+ fdir_info_v22->flex_conf = fdir_info.flex_conf;
+ fdir_info_v22->guarant_spc = fdir_info.guarant_spc;
+ fdir_info_v22->best_spc = fdir_info.best_spc;
+ fdir_info_v22->flow_types_mask[0] =
+ (uint32_t)fdir_info.flow_types_mask[0];
+ fdir_info_v22->max_flexpayload = fdir_info.max_flexpayload;
+ fdir_info_v22->flex_payload_unit = fdir_info.flex_payload_unit;
+ fdir_info_v22->max_flex_payload_segment_num =
+ fdir_info.max_flex_payload_segment_num;
+ fdir_info_v22->flex_payload_limit =
+ fdir_info.flex_payload_limit;
+ fdir_info_v22->flex_bitmask_unit = fdir_info.flex_bitmask_unit;
+ fdir_info_v22->max_flex_bitmask_num =
+ fdir_info.max_flex_bitmask_num;
+ return retval;
+ } else if (filter_op == RTE_ETH_FILTER_GET) {
+ int retval;
+ struct rte_eth_hash_filter_info f_info;
+ struct rte_eth_hash_filter_info_v22 *f_info_v22 =
+ (struct rte_eth_hash_filter_info_v22 *)arg;
+
+ f_info.info_type = f_info_v22->info_type;
+ retval = (*dev->dev_ops->filter_ctrl)(dev, filter_type,
+ filter_op, (void *)&f_info);
+
+ switch (f_info_v22->info_type) {
+ case RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT:
+ f_info_v22->info.enable = f_info.info.enable;
+ break;
+ case RTE_ETH_HASH_FILTER_GLOBAL_CONFIG:
+ f_info_v22->info.global_conf.hash_func =
+ f_info.info.global_conf.hash_func;
+ f_info_v22->info.global_conf.sym_hash_enable_mask[0] =
+ (uint32_t)
+ f_info.info.global_conf.sym_hash_enable_mask[0];
+ f_info_v22->info.global_conf.valid_bit_mask[0] =
+ (uint32_t)
+ f_info.info.global_conf.valid_bit_mask[0];
+ break;
+ case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
+ f_info_v22->info.input_set_conf =
+ f_info.info.input_set_conf;
+ break;
+ default:
+ break;
+ }
+ return retval;
+ } else if (filter_op == RTE_ETH_FILTER_SET) {
+ struct rte_eth_hash_filter_info f_info;
+ struct rte_eth_hash_filter_info_v22 *f_v22 =
+ (struct rte_eth_hash_filter_info_v22 *)arg;
+
+ f_info.info_type = f_v22->info_type;
+ switch (f_v22->info_type) {
+ case RTE_ETH_HASH_FILTER_SYM_HASH_ENA_PER_PORT:
+ f_info.info.enable = f_v22->info.enable;
+ break;
+ case RTE_ETH_HASH_FILTER_GLOBAL_CONFIG:
+ f_info.info.global_conf.hash_func =
+ f_v22->info.global_conf.hash_func;
+ f_info.info.global_conf.sym_hash_enable_mask[0] =
+ (uint32_t)
+ f_v22->info.global_conf.sym_hash_enable_mask[0];
+ f_info.info.global_conf.valid_bit_mask[0] =
+ (uint32_t)
+ f_v22->info.global_conf.valid_bit_mask[0];
+ break;
+ case RTE_ETH_HASH_FILTER_INPUT_SET_SELECT:
+ f_info.info.input_set_conf =
+ f_v22->info.input_set_conf;
+ break;
+ default:
+ break;
+ }
+ return (*dev->dev_ops->filter_ctrl)(dev, filter_type, filter_op,
+ (void *)&f_info);
+ } else
+ return (*dev->dev_ops->filter_ctrl)(dev, filter_type, filter_op,
+ arg);
+}
+VERSION_SYMBOL(rte_eth_dev_filter_ctrl, _v22, 2.2);
+
+int
+rte_eth_dev_filter_ctrl_v1802(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg);
+
+int
+rte_eth_dev_filter_ctrl_v1802(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg)
{
struct rte_eth_dev *dev;
@@ -3159,6 +3305,12 @@ rte_eth_dev_filter_ctrl(uint16_t port_id, enum rte_filter_type filter_type,
RTE_FUNC_PTR_OR_ERR_RET(*dev->dev_ops->filter_ctrl, -ENOTSUP);
return (*dev->dev_ops->filter_ctrl)(dev, filter_type, filter_op, arg);
}
+BIND_DEFAULT_SYMBOL(rte_eth_dev_filter_ctrl, _v1802, 18.02);
+MAP_STATIC_SYMBOL(int rte_eth_dev_filter_ctrl(uint16_t port_id,
+ enum rte_filter_type filter_type,
+ enum rte_filter_op filter_op, void *arg),
+ rte_eth_dev_filter_ctrl_v1802);
+
void *
rte_eth_add_rx_callback(uint16_t port_id, uint16_t queue_id,
diff --git a/lib/librte_ether/rte_ethdev_version.map b/lib/librte_ether/rte_ethdev_version.map
index e9681ac..2906a18 100644
--- a/lib/librte_ether/rte_ethdev_version.map
+++ b/lib/librte_ether/rte_ethdev_version.map
@@ -198,6 +198,13 @@ DPDK_17.11 {
} DPDK_17.08;
+DPDK_18.02 {
+ global:
+
+ rte_eth_dev_filter_ctrl;
+
+} DPDK_17.11;
+
EXPERIMENTAL {
global:
--
2.5.5
^ permalink raw reply [relevance 7%]
* [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition
@ 2018-01-15 19:05 4% Neil Horman
2018-01-15 21:52 7% ` Thomas Monjalon
` (2 more replies)
0 siblings, 3 replies; 200+ results
From: Neil Horman @ 2018-01-15 19:05 UTC (permalink / raw)
To: dev; +Cc: Neil Horman, thomas, john.mcnamara, bruce.richardson, Ferruh Yigit
Recently, some additional patches were added to allow for programmatic
marking of C symbols as experimental. The addition of these markers is
dependent on the manual addition of exported symbols to the EXPERIMENTAL
section of the corresponding libraries version map file. The consensus
on review is that, in addition to mandating the addition of symbols to
the EXPERIMENTAL version in the map, we need a mechanism to enforce our
documented process of mandating that addition when they are introduced.
To that end, I am proposing this change. It is an addition to the
checkpatches script, which scan incoming patches for additions and
removals of symbols to the map file, and warns the user appropriately
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: thomas@monjalon.net
CC: john.mcnamara@intel.com
CC: bruce.richardson@intel.com
CC: Ferruh Yigit <ferruh.yigit@intel.com>
---
devtools/checkpatches.sh | 89 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 88 insertions(+), 1 deletion(-)
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index 7676a6b50..d0e2120fe 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -61,6 +61,77 @@ print_usage () {
END_OF_HELP
}
+build_map_changes()
+{
+ local fname=$1
+ local mapdb=$2
+
+ cat $fname | filterdiff -i *.map | awk '
+ BEGIN {map="";sym="";ar="";sec=""; in_sec=0}
+ /[-+] a\/.*\.map/ {map=$2}
+ /+.*{/ {gsub("+","");sec=$1; in_sec=1}
+ /.*}/ {in_sec=0}
+ /^+.*[^:*];/ {gsub(";","");sym=$2;
+ if (in_sec == 1) {
+ print map " " sym " " sec " add"
+ }
+ }
+ /^-.*[^:*];/ {gsub(";","");sym=$2;
+ if (in_sec == 1) {
+ print map " " sym " " sec " del"
+ }
+ }' > ./$mapdb
+
+ sort $mapdb | uniq > ./$mapdb.2
+ mv -f $mapdb.2 $mapdb
+
+}
+
+check_for_rule_violations()
+{
+ local mapdb=$1
+ local mname
+ local symname
+ local secname
+ local ar
+
+ cat $mapdb | while read mname symname secname ar
+ do
+ if [ "$ar" == "add" -a "$secname" != "EXPERIMENTAL" ]
+ then
+ # Symbols that are getting added in a section other
+ # Than the experimental section need to be moving
+ # from an already supported section or its a violation
+ grep -q "$mname $symname [^EXPERIMENTAL] del" $mapdb
+ if [ $? -ne 0 ]
+ then
+ echo "ERROR: symbol $symname is added in a section other than the EXPERIMENTAL section of the version map"
+ fi
+ fi
+
+ if [ "$ar" == "del" -a "$secname" != "EXPERIMENTAL" ]
+ then
+ # Just inform users that non-experimenal symbols need
+ # to go through a deprecation process
+ echo "INFO: symbol $symname is being removed, ensure that it has gone through the deprecation process"
+ fi
+
+ done
+}
+
+validate_api_changes()
+{
+ mapfile=`mktemp mapdb.XXXXXX`
+ patch=$1
+
+ build_map_changes $patch $mapfile
+ result=$(check_for_rule_violations $mapfile)
+
+ rm -f $mapfile
+
+ echo $result
+}
+
number=0
quiet=false
verbose=false
@@ -96,9 +167,25 @@ check () { # <patch> <commit> <title>
else
report=$($DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
fi
- [ $? -ne 0 ] || return 0
+ reta=$?
+
$verbose || printf '\n### %s\n\n' "$3"
printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
+
+ echo
+ echo "Checking API additions/removals:"
+ if [ -n "$1" ] ; then
+ report=$(validate_api_changes $1)
+ elif [ -n "$2" ] ; then
+ report=$(git format-patch \
+ --find-renames --no-stat --stdout -1 $commit |
+ validate_api_changes /dev/stdin)
+ else
+ report=$(validate_api_changes /dev/stdin)
+ fi
+ [ $? -ne 0 -o $reta -ne 0 ] || return 0
+ printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
+
status=$(($status + 1))
}
--
2.14.3
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3] ethdev: increase flow type limit from 32 to 64
2018-01-15 17:33 7% ` [dpdk-dev] [PATCH v3] " Kirill Rybalchenko
@ 2018-01-15 21:27 3% ` Thomas Monjalon
2018-01-16 9:44 0% ` Rybalchenko, Kirill
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-15 21:27 UTC (permalink / raw)
To: Kirill Rybalchenko; +Cc: dev, andrey.chilikin, ferruh.yigit
15/01/2018 18:33, Kirill Rybalchenko:
> --- a/lib/librte_ether/rte_eth_ctrl.h
> +++ b/lib/librte_ether/rte_eth_ctrl.h
> @@ -662,9 +662,9 @@ enum rte_fdir_mode {
> RTE_FDIR_MODE_PERFECT_TUNNEL, /**< Enable FDIR filter mode - tunnel. */
> };
>
> -#define UINT32_BIT (CHAR_BIT * sizeof(uint32_t))
> +#define UINT64_BIT (CHAR_BIT * sizeof(uint64_t))
> #define RTE_FLOW_MASK_ARRAY_SIZE \
> - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
>
> /**
> * A structure used to get the information of flow director filter.
> @@ -681,7 +681,7 @@ struct rte_eth_fdir_info {
> uint32_t guarant_spc; /**< Guaranteed spaces.*/
> uint32_t best_spc; /**< Best effort spaces.*/
> /** Bit mask for every supported flow type. */
> - uint32_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> + uint64_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> uint32_t max_flexpayload; /**< Total flex payload in bytes. */
> /** Flexible payload unit in bytes. Size and alignments of all flex
> payload segments should be multiplies of this value. */
> @@ -774,7 +774,7 @@ enum rte_eth_hash_function {
> };
>
> #define RTE_SYM_HASH_MASK_ARRAY_SIZE \
> - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
> /**
> * A structure used to set or get global hash function configurations which
> * include symmetric hash enable per flow type and hash function type.
> @@ -787,9 +787,9 @@ enum rte_eth_hash_function {
> struct rte_eth_hash_global_conf {
> enum rte_eth_hash_function hash_func; /**< Hash function type */
> /** Bit mask for symmetric hash enable per flow type */
> - uint32_t sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> + uint64_t sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> /** Bit mask indicates if the corresponding bit is valid */
> - uint32_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> + uint64_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> };
This is still changing the ABI.
Am I missing something?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition
2018-01-15 19:05 4% [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition Neil Horman
@ 2018-01-15 21:52 7% ` Thomas Monjalon
2018-01-16 0:37 4% ` Neil Horman
2018-01-15 22:20 4% ` Stephen Hemminger
2018-01-16 18:22 3% ` [dpdk-dev] [PATCH v2] " Neil Horman
2 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-15 21:52 UTC (permalink / raw)
To: Neil Horman; +Cc: dev, john.mcnamara, bruce.richardson, Ferruh Yigit
15/01/2018 20:05, Neil Horman:
> Recently, some additional patches were added to allow for programmatic
> marking of C symbols as experimental. The addition of these markers is
> dependent on the manual addition of exported symbols to the EXPERIMENTAL
> section of the corresponding libraries version map file. The consensus
> on review is that, in addition to mandating the addition of symbols to
> the EXPERIMENTAL version in the map, we need a mechanism to enforce our
> documented process of mandating that addition when they are introduced.
> To that end, I am proposing this change. It is an addition to the
> checkpatches script, which scan incoming patches for additions and
> removals of symbols to the map file, and warns the user appropriately
Thanks for working on this.
I won't pretend that I understand anything in this awk script :)
I think it would be better to put this code in a new script,
let's say check-symbol-change.sh, and call it in checkpatches.sh.
It would be just moving functions, add your copyright, and list the new
script in your MAINTAINERS section "ABI versioning".
^ permalink raw reply [relevance 7%]
* Re: [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition
2018-01-15 19:05 4% [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition Neil Horman
2018-01-15 21:52 7% ` Thomas Monjalon
@ 2018-01-15 22:20 4% ` Stephen Hemminger
2018-01-16 0:36 4% ` Neil Horman
2018-01-16 18:22 3% ` [dpdk-dev] [PATCH v2] " Neil Horman
2 siblings, 1 reply; 200+ results
From: Stephen Hemminger @ 2018-01-15 22:20 UTC (permalink / raw)
To: Neil Horman; +Cc: dev, thomas, john.mcnamara, bruce.richardson, Ferruh Yigit
On Mon, 15 Jan 2018 14:05:45 -0500
Neil Horman <nhorman@tuxdriver.com> wrote:
>
> +build_map_changes()
> +{
> + local fname=$1
> + local mapdb=$2
> +
> + cat $fname | filterdiff -i *.map | awk '
You don't need cat, use shell redirection same for later while loop.
> + BEGIN {map="";sym="";ar="";sec=""; in_sec=0}
> + /[-+] a\/.*\.map/ {map=$2}
> + /+.*{/ {gsub("+","");sec=$1; in_sec=1}
Add some whitespace and indentation to awk?
> + /.*}/ {in_sec=0}
> + /^+.*[^:*];/ {gsub(";","");sym=$2;
> + if (in_sec == 1) {
> + print map " " sym " " sec " add"
> + }
> + }
> + /^-.*[^:*];/ {gsub(";","");sym=$2;
> + if (in_sec == 1) {
> + print map " " sym " " sec " del"
> + }
> + }' > ./$mapdb
> +
> + sort $mapdb | uniq > ./$mapdb.2
sort -u
> + mv -f $mapdb.2 $mapdb
> +
> +}
> +
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition
2018-01-15 22:20 4% ` Stephen Hemminger
@ 2018-01-16 0:36 4% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2018-01-16 0:36 UTC (permalink / raw)
To: Stephen Hemminger
Cc: dev, thomas, john.mcnamara, bruce.richardson, Ferruh Yigit
On Mon, Jan 15, 2018 at 02:20:38PM -0800, Stephen Hemminger wrote:
> On Mon, 15 Jan 2018 14:05:45 -0500
> Neil Horman <nhorman@tuxdriver.com> wrote:
>
> >
> > +build_map_changes()
> > +{
> > + local fname=$1
> > + local mapdb=$2
> > +
> > + cat $fname | filterdiff -i *.map | awk '
>
> You don't need cat, use shell redirection same for later while loop.
>
This is likely moot given Thomas' request to put this in a separate script, but
point taken
> > + BEGIN {map="";sym="";ar="";sec=""; in_sec=0}
> > + /[-+] a\/.*\.map/ {map=$2}
> > + /+.*{/ {gsub("+","");sec=$1; in_sec=1}
> Add some whitespace and indentation to awk?
Yeah, I can document this block as a whole as well
>
> > + /.*}/ {in_sec=0}
> > + /^+.*[^:*];/ {gsub(";","");sym=$2;
> > + if (in_sec == 1) {
> > + print map " " sym " " sec " add"
> > + }
> > + }
> > + /^-.*[^:*];/ {gsub(";","");sym=$2;
> > + if (in_sec == 1) {
> > + print map " " sym " " sec " del"
> > + }
> > + }' > ./$mapdb
> > +
> > + sort $mapdb | uniq > ./$mapdb.2
>
> sort -u
Copy that.
>
> > + mv -f $mapdb.2 $mapdb
> > +
> > +}
> > +
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition
2018-01-15 21:52 7% ` Thomas Monjalon
@ 2018-01-16 0:37 4% ` Neil Horman
0 siblings, 0 replies; 200+ results
From: Neil Horman @ 2018-01-16 0:37 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, john.mcnamara, bruce.richardson, Ferruh Yigit
On Mon, Jan 15, 2018 at 10:52:25PM +0100, Thomas Monjalon wrote:
> 15/01/2018 20:05, Neil Horman:
> > Recently, some additional patches were added to allow for programmatic
> > marking of C symbols as experimental. The addition of these markers is
> > dependent on the manual addition of exported symbols to the EXPERIMENTAL
> > section of the corresponding libraries version map file. The consensus
> > on review is that, in addition to mandating the addition of symbols to
> > the EXPERIMENTAL version in the map, we need a mechanism to enforce our
> > documented process of mandating that addition when they are introduced.
> > To that end, I am proposing this change. It is an addition to the
> > checkpatches script, which scan incoming patches for additions and
> > removals of symbols to the map file, and warns the user appropriately
>
> Thanks for working on this.
Sure.
> I won't pretend that I understand anything in this awk script :)
>
Stephen suggested that I clean it up and document it a bit, which is probably a good idea.
> I think it would be better to put this code in a new script,
> let's say check-symbol-change.sh, and call it in checkpatches.sh.
> It would be just moving functions, add your copyright, and list the new
> script in your MAINTAINERS section "ABI versioning".
Yeah, I can do that. New version in the AM
Neil
>
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v3] ethdev: increase flow type limit from 32 to 64
2018-01-15 21:27 3% ` Thomas Monjalon
@ 2018-01-16 9:44 0% ` Rybalchenko, Kirill
2018-01-16 9:47 3% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Rybalchenko, Kirill @ 2018-01-16 9:44 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, Chilikin, Andrey, Yigit, Ferruh
Hi Thomas,
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Monday 15 January 2018 21:27
> To: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>
> Cc: dev@dpdk.org; Chilikin, Andrey <andrey.chilikin@intel.com>; Yigit,
> Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [PATCH v3] ethdev: increase flow type limit from 32 to 64
>
> 15/01/2018 18:33, Kirill Rybalchenko:
> > --- a/lib/librte_ether/rte_eth_ctrl.h
> > +++ b/lib/librte_ether/rte_eth_ctrl.h
> > @@ -662,9 +662,9 @@ enum rte_fdir_mode {
> > RTE_FDIR_MODE_PERFECT_TUNNEL, /**< Enable FDIR filter mode -
> tunnel. */
> > };
> >
> > -#define UINT32_BIT (CHAR_BIT * sizeof(uint32_t))
> > +#define UINT64_BIT (CHAR_BIT * sizeof(uint64_t))
> > #define RTE_FLOW_MASK_ARRAY_SIZE \
> > - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> > + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
> >
> > /**
> > * A structure used to get the information of flow director filter.
> > @@ -681,7 +681,7 @@ struct rte_eth_fdir_info {
> > uint32_t guarant_spc; /**< Guaranteed spaces.*/
> > uint32_t best_spc; /**< Best effort spaces.*/
> > /** Bit mask for every supported flow type. */
> > - uint32_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> > + uint64_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> > uint32_t max_flexpayload; /**< Total flex payload in bytes. */
> > /** Flexible payload unit in bytes. Size and alignments of all flex
> > payload segments should be multiplies of this value. */ @@
> > -774,7 +774,7 @@ enum rte_eth_hash_function { };
> >
> > #define RTE_SYM_HASH_MASK_ARRAY_SIZE \
> > - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> > + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
> > /**
> > * A structure used to set or get global hash function configurations which
> > * include symmetric hash enable per flow type and hash function type.
> > @@ -787,9 +787,9 @@ enum rte_eth_hash_function { struct
> > rte_eth_hash_global_conf {
> > enum rte_eth_hash_function hash_func; /**< Hash function type */
> > /** Bit mask for symmetric hash enable per flow type */
> > - uint32_t
> sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > + uint64_t
> sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > /** Bit mask indicates if the corresponding bit is valid */
> > - uint32_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > + uint64_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > };
>
> This is still changing the ABI.
> Am I missing something?
>
We change size of structures rte_eth_fdir_info and rte_eth_hash_filter_info.
Application can use these structures for DPDK library API call only in
rte_eth_dev_filter_ctrl() function call. In the patch this function is
modified in the way that it will be compatible with user binary applications
compiled with previous versions of DPDK library.
Thanks,
Kirill.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] ethdev: increase flow type limit from 32 to 64
2018-01-16 9:44 0% ` Rybalchenko, Kirill
@ 2018-01-16 9:47 3% ` Thomas Monjalon
2018-01-16 10:31 0% ` Rybalchenko, Kirill
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-16 9:47 UTC (permalink / raw)
To: Rybalchenko, Kirill; +Cc: dev, Chilikin, Andrey, Yigit, Ferruh
16/01/2018 10:44, Rybalchenko, Kirill:
> Hi Thomas,
>
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > 15/01/2018 18:33, Kirill Rybalchenko:
> > > --- a/lib/librte_ether/rte_eth_ctrl.h
> > > +++ b/lib/librte_ether/rte_eth_ctrl.h
> > > @@ -662,9 +662,9 @@ enum rte_fdir_mode {
> > > RTE_FDIR_MODE_PERFECT_TUNNEL, /**< Enable FDIR filter mode -
> > tunnel. */
> > > };
> > >
> > > -#define UINT32_BIT (CHAR_BIT * sizeof(uint32_t))
> > > +#define UINT64_BIT (CHAR_BIT * sizeof(uint64_t))
> > > #define RTE_FLOW_MASK_ARRAY_SIZE \
> > > - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> > > + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
> > >
> > > /**
> > > * A structure used to get the information of flow director filter.
> > > @@ -681,7 +681,7 @@ struct rte_eth_fdir_info {
> > > uint32_t guarant_spc; /**< Guaranteed spaces.*/
> > > uint32_t best_spc; /**< Best effort spaces.*/
> > > /** Bit mask for every supported flow type. */
> > > - uint32_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> > > + uint64_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> > > uint32_t max_flexpayload; /**< Total flex payload in bytes. */
> > > /** Flexible payload unit in bytes. Size and alignments of all flex
> > > payload segments should be multiplies of this value. */ @@
> > > -774,7 +774,7 @@ enum rte_eth_hash_function { };
> > >
> > > #define RTE_SYM_HASH_MASK_ARRAY_SIZE \
> > > - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> > > + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
> > > /**
> > > * A structure used to set or get global hash function configurations which
> > > * include symmetric hash enable per flow type and hash function type.
> > > @@ -787,9 +787,9 @@ enum rte_eth_hash_function { struct
> > > rte_eth_hash_global_conf {
> > > enum rte_eth_hash_function hash_func; /**< Hash function type */
> > > /** Bit mask for symmetric hash enable per flow type */
> > > - uint32_t
> > sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > + uint64_t
> > sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > /** Bit mask indicates if the corresponding bit is valid */
> > > - uint32_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > + uint64_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > };
> >
> > This is still changing the ABI.
> > Am I missing something?
> >
> We change size of structures rte_eth_fdir_info and rte_eth_hash_filter_info.
Yes, and these structures are allocated and read by the application?
So it is an ABI break.
> Application can use these structures for DPDK library API call only in
> rte_eth_dev_filter_ctrl() function call. In the patch this function is
> modified in the way that it will be compatible with user binary applications
> compiled with previous versions of DPDK library.
Have you tried to use a patched DPDK with a binary compiled with DPDK 17.11?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v3] ethdev: increase flow type limit from 32 to 64
2018-01-16 9:47 3% ` Thomas Monjalon
@ 2018-01-16 10:31 0% ` Rybalchenko, Kirill
2018-01-16 10:38 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Rybalchenko, Kirill @ 2018-01-16 10:31 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev, Chilikin, Andrey, Yigit, Ferruh
> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Tuesday 16 January 2018 09:48
> To: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>
> Cc: dev@dpdk.org; Chilikin, Andrey <andrey.chilikin@intel.com>; Yigit,
> Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [PATCH v3] ethdev: increase flow type limit from 32 to 64
>
> 16/01/2018 10:44, Rybalchenko, Kirill:
> > Hi Thomas,
> >
> > From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > > 15/01/2018 18:33, Kirill Rybalchenko:
> > > > --- a/lib/librte_ether/rte_eth_ctrl.h
> > > > +++ b/lib/librte_ether/rte_eth_ctrl.h
> > > > @@ -662,9 +662,9 @@ enum rte_fdir_mode {
> > > > RTE_FDIR_MODE_PERFECT_TUNNEL, /**< Enable FDIR filter mode
> -
> > > tunnel. */
> > > > };
> > > >
> > > > -#define UINT32_BIT (CHAR_BIT * sizeof(uint32_t))
> > > > +#define UINT64_BIT (CHAR_BIT * sizeof(uint64_t))
> > > > #define RTE_FLOW_MASK_ARRAY_SIZE \
> > > > - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> > > > + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
> > > >
> > > > /**
> > > > * A structure used to get the information of flow director filter.
> > > > @@ -681,7 +681,7 @@ struct rte_eth_fdir_info {
> > > > uint32_t guarant_spc; /**< Guaranteed spaces.*/
> > > > uint32_t best_spc; /**< Best effort spaces.*/
> > > > /** Bit mask for every supported flow type. */
> > > > - uint32_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> > > > + uint64_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> > > > uint32_t max_flexpayload; /**< Total flex payload in bytes. */
> > > > /** Flexible payload unit in bytes. Size and alignments of all flex
> > > > payload segments should be multiplies of this value.
> > > > */ @@
> > > > -774,7 +774,7 @@ enum rte_eth_hash_function { };
> > > >
> > > > #define RTE_SYM_HASH_MASK_ARRAY_SIZE \
> > > > - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> > > > + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
> > > > /**
> > > > * A structure used to set or get global hash function configurations
> which
> > > > * include symmetric hash enable per flow type and hash function type.
> > > > @@ -787,9 +787,9 @@ enum rte_eth_hash_function { struct
> > > > rte_eth_hash_global_conf {
> > > > enum rte_eth_hash_function hash_func; /**< Hash function type
> */
> > > > /** Bit mask for symmetric hash enable per flow type */
> > > > - uint32_t
> > > sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > > + uint64_t
> > > sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > > /** Bit mask indicates if the corresponding bit is valid */
> > > > - uint32_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > > + uint64_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > > };
> > >
> > > This is still changing the ABI.
> > > Am I missing something?
> > >
> > We change size of structures rte_eth_fdir_info and
> rte_eth_hash_filter_info.
>
> Yes, and these structures are allocated and read by the application?
> So it is an ABI break.
If application binary was compiled with previous version of DPDK it makes
no difference if these structures were used internally there - it still will work.
If application binary was recompiled with new version of DPDK - again,
It will work.
The only issue is if application binary was compiled with old version of DPDK
library, but used with new version of DPDK shared library and uses those
structures to call functions from this DPDK library. But it can be done
only by rte_eth_dev_filter_ctrl() function, which handles this case properly.
>
> > Application can use these structures for DPDK library API call only in
> > rte_eth_dev_filter_ctrl() function call. In the patch this function is
> > modified in the way that it will be compatible with user binary
> > applications compiled with previous versions of DPDK library.
>
> Have you tried to use a patched DPDK with a binary compiled with DPDK
> 17.11?
Yes, actually, I did run testpmd from 17.08 with patched DPDK shared library.
It works fine, as described.
Thanks,
Kirill.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v3] ethdev: increase flow type limit from 32 to 64
2018-01-16 10:31 0% ` Rybalchenko, Kirill
@ 2018-01-16 10:38 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-01-16 10:38 UTC (permalink / raw)
To: Rybalchenko, Kirill; +Cc: dev, Chilikin, Andrey, Yigit, Ferruh
16/01/2018 11:31, Rybalchenko, Kirill:
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > 16/01/2018 10:44, Rybalchenko, Kirill:
> > > Hi Thomas,
> > >
> > > From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > > > 15/01/2018 18:33, Kirill Rybalchenko:
> > > > > --- a/lib/librte_ether/rte_eth_ctrl.h
> > > > > +++ b/lib/librte_ether/rte_eth_ctrl.h
> > > > > @@ -662,9 +662,9 @@ enum rte_fdir_mode {
> > > > > RTE_FDIR_MODE_PERFECT_TUNNEL, /**< Enable FDIR filter mode
> > -
> > > > tunnel. */
> > > > > };
> > > > >
> > > > > -#define UINT32_BIT (CHAR_BIT * sizeof(uint32_t))
> > > > > +#define UINT64_BIT (CHAR_BIT * sizeof(uint64_t))
> > > > > #define RTE_FLOW_MASK_ARRAY_SIZE \
> > > > > - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> > > > > + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
> > > > >
> > > > > /**
> > > > > * A structure used to get the information of flow director filter.
> > > > > @@ -681,7 +681,7 @@ struct rte_eth_fdir_info {
> > > > > uint32_t guarant_spc; /**< Guaranteed spaces.*/
> > > > > uint32_t best_spc; /**< Best effort spaces.*/
> > > > > /** Bit mask for every supported flow type. */
> > > > > - uint32_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> > > > > + uint64_t flow_types_mask[RTE_FLOW_MASK_ARRAY_SIZE];
> > > > > uint32_t max_flexpayload; /**< Total flex payload in bytes. */
> > > > > /** Flexible payload unit in bytes. Size and alignments of all flex
> > > > > payload segments should be multiplies of this value.
> > > > > */ @@
> > > > > -774,7 +774,7 @@ enum rte_eth_hash_function { };
> > > > >
> > > > > #define RTE_SYM_HASH_MASK_ARRAY_SIZE \
> > > > > - (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT32_BIT)/UINT32_BIT)
> > > > > + (RTE_ALIGN(RTE_ETH_FLOW_MAX, UINT64_BIT)/UINT64_BIT)
> > > > > /**
> > > > > * A structure used to set or get global hash function configurations
> > which
> > > > > * include symmetric hash enable per flow type and hash function type.
> > > > > @@ -787,9 +787,9 @@ enum rte_eth_hash_function { struct
> > > > > rte_eth_hash_global_conf {
> > > > > enum rte_eth_hash_function hash_func; /**< Hash function type
> > */
> > > > > /** Bit mask for symmetric hash enable per flow type */
> > > > > - uint32_t
> > > > sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > > > + uint64_t
> > > > sym_hash_enable_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > > > /** Bit mask indicates if the corresponding bit is valid */
> > > > > - uint32_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > > > + uint64_t valid_bit_mask[RTE_SYM_HASH_MASK_ARRAY_SIZE];
> > > > > };
> > > >
> > > > This is still changing the ABI.
> > > > Am I missing something?
> > > >
> > > We change size of structures rte_eth_fdir_info and
> > rte_eth_hash_filter_info.
> >
> > Yes, and these structures are allocated and read by the application?
> > So it is an ABI break.
> If application binary was compiled with previous version of DPDK it makes
> no difference if these structures were used internally there - it still will work.
> If application binary was recompiled with new version of DPDK - again,
> It will work.
> The only issue is if application binary was compiled with old version of DPDK
> library, but used with new version of DPDK shared library and uses those
> structures to call functions from this DPDK library. But it can be done
> only by rte_eth_dev_filter_ctrl() function, which handles this case properly.
OK got it.
Thanks for your patience :)
> > > Application can use these structures for DPDK library API call only in
> > > rte_eth_dev_filter_ctrl() function call. In the patch this function is
> > > modified in the way that it will be compatible with user binary
> > > applications compiled with previous versions of DPDK library.
> >
> > Have you tried to use a patched DPDK with a binary compiled with DPDK
> > 17.11?
>
> Yes, actually, I did run testpmd from 17.08 with patched DPDK shared library.
> It works fine, as described.
>
> Thanks,
> Kirill.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: increase flow type limit from 32 to 64
2018-01-09 15:16 3% ` Rybalchenko, Kirill
2018-01-10 13:50 3% ` Thomas Monjalon
@ 2018-01-16 11:13 0% ` Adrien Mazarguil
2018-01-16 17:23 0% ` Rybalchenko, Kirill
1 sibling, 1 reply; 200+ results
From: Adrien Mazarguil @ 2018-01-16 11:13 UTC (permalink / raw)
To: Rybalchenko, Kirill
Cc: dev, Wu, Jingjing, Xing, Beilei, johndale, neescoba,
nelio.laranjeiro, yskoh, Lu, Wenzhuo, Ananyev, Konstantin,
Chilikin, Andrey
On Tue, Jan 09, 2018 at 03:16:13PM +0000, Rybalchenko, Kirill wrote:
> > -----Original Message-----
> > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > Sent: Monday 4 December 2017 17:43
> > To: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>
> > Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> > <beilei.xing@intel.com>; johndale@cisco.com; neescoba@cisco.com;
> > nelio.laranjeiro@6wind.com; yskoh@mellanox.com; Lu, Wenzhuo
> > <wenzhuo.lu@intel.com>; Ananyev, Konstantin
> > <konstantin.ananyev@intel.com>; Chilikin, Andrey
> > <andrey.chilikin@intel.com>
> > Subject: Re: [PATCH] ethdev: increase flow type limit from 32 to 64
> >
> > Hi Kirill,
> >
> > On Mon, Nov 27, 2017 at 12:29:47PM +0000, Kirill Rybalchenko wrote:
> > > Increase the internal limit for flow types from 32 to 64 to support
> > > future flow type extensions.
> > > Change type of variables from uint32_t[] to uint64_t[]:
> > > rte_eth_fdir_info.flow_types_mask
> > > rte_eth_hash_global_conf.sym_hash_enable_mask
> > > rte_eth_hash_global_conf.valid_bit_mask
> > >
> > > This modification affects the following components:
> > > net/i40e
> > > net/enic
> > > net/mlx5
> > > net/ixgbe
> > > app/testpmd
> > >
> > > Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> >
> > Can you elaborate a bit on the need for these changes?
> > Have you considered implementing those future extensions through
> > rte_flow instead?
>
> Hi Adrien, this is not a new feature but rather fix of existing limitation.
> In current implementation the symmetric hash mask and flow mask are
> represented by 32-bit variable, while hardware bitmask has 64 bits.
> Unfortunately, this modification changes ABI of the library as it changes size
> of rte_eth_fdir_info structure. All related PMDs (listed above) had to be modified
> accordingly.
OK, no problem with this change. I assume you'll re-submit it since you sent
a deprecation notice, we'll review/ack subsequent mlx5 patches.
--
Adrien Mazarguil
6WIND
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] eal: add function to return number of detected sockets
2018-01-12 11:50 0% ` Thomas Monjalon
@ 2018-01-16 11:56 4% ` Burakov, Anatoly
2018-01-16 12:20 3% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Burakov, Anatoly @ 2018-01-16 11:56 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On 12-Jan-18 11:50 AM, Thomas Monjalon wrote:
> 12/01/2018 12:44, Burakov, Anatoly:
>> On 11-Jan-18 10:20 PM, Thomas Monjalon wrote:
>>> 22/12/2017 13:41, Anatoly Burakov:
>>>> During lcore scan, find maximum socket ID and store it.
>>>>
>>>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
>>>> ---
>>>> --- a/lib/librte_eal/common/include/rte_eal.h
>>>> +++ b/lib/librte_eal/common/include/rte_eal.h
>>>> @@ -83,6 +83,7 @@ enum rte_proc_type_t {
>>>> struct rte_config {
>>>> uint32_t master_lcore; /**< Id of the master lcore */
>>>> uint32_t lcore_count; /**< Number of available logical cores. */
>>>> + uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
>>>> uint32_t service_lcore_count;/**< Number of available service cores. */
>>>> enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
>>>
>>> isn't it breaking the ABI?
>>>
>>>
>>
>> Yep, you're right, forgot to add that. I didn't expect this to get
>> merged in 18.02 anyway, so v2 will follow.
>
> Please write 18.05 in the subject to show your expectation.
> Thanks
>
Does it have to be an ABI change though? We can put numa_node_count
after pointer to mem_config, in which case it won't be an ABI break.
Would that be better?
--
Thanks,
Anatoly
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2] eal: add function to return number of detected sockets
2018-01-16 11:56 4% ` Burakov, Anatoly
@ 2018-01-16 12:20 3% ` Thomas Monjalon
2018-01-16 15:05 4% ` Burakov, Anatoly
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-16 12:20 UTC (permalink / raw)
To: Burakov, Anatoly; +Cc: dev
16/01/2018 12:56, Burakov, Anatoly:
> On 12-Jan-18 11:50 AM, Thomas Monjalon wrote:
> > 12/01/2018 12:44, Burakov, Anatoly:
> >> On 11-Jan-18 10:20 PM, Thomas Monjalon wrote:
> >>> 22/12/2017 13:41, Anatoly Burakov:
> >>>> During lcore scan, find maximum socket ID and store it.
> >>>>
> >>>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> >>>> ---
> >>>> --- a/lib/librte_eal/common/include/rte_eal.h
> >>>> +++ b/lib/librte_eal/common/include/rte_eal.h
> >>>> @@ -83,6 +83,7 @@ enum rte_proc_type_t {
> >>>> struct rte_config {
> >>>> uint32_t master_lcore; /**< Id of the master lcore */
> >>>> uint32_t lcore_count; /**< Number of available logical cores. */
> >>>> + uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
> >>>> uint32_t service_lcore_count;/**< Number of available service cores. */
> >>>> enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
> >>>
> >>> isn't it breaking the ABI?
> >>>
> >>>
> >>
> >> Yep, you're right, forgot to add that. I didn't expect this to get
> >> merged in 18.02 anyway, so v2 will follow.
> >
> > Please write 18.05 in the subject to show your expectation.
> > Thanks
> >
>
> Does it have to be an ABI change though? We can put numa_node_count
> after pointer to mem_config, in which case it won't be an ABI break.
> Would that be better?
Changing the size of a struct which is allocated by the app,
is an ABI break.
Is your solution changing the size?
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v1 6/6] net: fix rte_ether conflicts with libc
2017-12-22 14:25 3% ` Adrien Mazarguil
@ 2018-01-16 13:04 0% ` Olivier Matz
0 siblings, 0 replies; 200+ results
From: Olivier Matz @ 2018-01-16 13:04 UTC (permalink / raw)
To: Adrien Mazarguil; +Cc: dev, Bruce Richardson
Hi Adrien,
On Fri, Dec 22, 2017 at 03:25:27PM +0100, Adrien Mazarguil wrote:
> On Fri, Dec 22, 2017 at 02:34:21PM +0100, Olivier MATZ wrote:
> > On Thu, Dec 21, 2017 at 02:00:06PM +0100, Adrien Mazarguil wrote:
...
> > > +#if defined(__FreeBSD__)
> > > +#define addr_bytes octet
> > > +#else
> > > +#define addr_bytes ether_addr_octet
> > > +#endif
> > > +
> > > #define ETHER_LOCAL_ADMIN_ADDR 0x02 /**< Locally assigned Eth. address. */
> > > #define ETHER_GROUP_ADDR 0x01 /**< Multicast or broadcast Eth. address. */
> >
> > This kind of #define looks a bit dangerous to me: it can trigger
> > strange bugs because it will replace all occurences of addr_bytes
> > after this header is included.
>
> Understandable, I checked before settling on this macro though, there's no
> other usage of addr_bytes inside DPDK.
>
> As for applications, there's no way to be completely sure. If we consider
> they have to explicitly include rte_ether.h to get this definition, there
> are chances addr_bytes is exclusively used with MAC addresses.
>
> This change results in an API change (addr_bytes now documented as a
> reserved macro) but has no ABI impact. I think it's a rather harmless
> workaround pending your next suggestion:
>
> > Wouldn't it be a good opportunity to think about adding the rte_ prefix
> > to all variables/functions of rte_ether.h?
>
> That would be ideal, however since almost all definitions in librte_net
> (rte_ip.h, rte_udp.h etc.) also lack this prefix and can still technically
> trigger conflicts with outside definitions (I'm aware work was done to avoid
> that, but it doesn't change the fact they're not in the official DPDK
> namespace), a massive API change would be needed for consistency.
>
> Such a change is unlikely to be accepted for 18.02 in any case, therefore if
> the proposed workaround is deemed too risky, I offer to remove this patch
> from the series. What do you suggest?
I think the only good long term solution is to have a proper namespace
for all rte_net structures and definitions. If there is no blocking issue
requiring this patch now, we can consider the following:
- 18.02: announce an api change for 18.05
- 18.05:
- add new net structures and definitions with rte_ prefix
- mark the old ones as deprecated
- removes the structures or definitions that conflicts with system headers
- 18.08: remove the old structures and definitions
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/3] app/testpmd: Moved cmdline_flow to librte_cmdline
@ 2018-01-16 14:31 3% ` Adrien Mazarguil
2018-01-16 14:54 0% ` george.dit
0 siblings, 1 reply; 200+ results
From: Adrien Mazarguil @ 2018-01-16 14:31 UTC (permalink / raw)
To: george.dit; +Cc: Olivier Matz, Lu, Wenzhuo, dev
George,
I missed the original RFC thread [1][2] (you should have used it as a cover
letter for this series BTW) please see below.
On Tue, Jan 16, 2018 at 10:24:25AM +0100, Olivier Matz wrote:
> Hi,
>
> > On Tue, Jan 16, 2018 at 9:40 AM Olivier Matz <olivier.matz@6wind.com> wrote:
> >
> > On Tue, Jan 16, 2018 at 08:45:32AM +0000, george.dit@gmail.com wrote:
> > > Hi Georgios,
> > >
> > > On Mon, Jan 15, 2018 at 01:30:35AM +0000, Lu, Wenzhuo wrote:
> > > > Hi,
> > > >
> > > > > -----Original Message-----
> > > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Georgios Katsikas
> > > > > Sent: Saturday, January 13, 2018 5:01 AM
> > > > > To: olivier.matz@6wind.com
> > > > > Cc: dev@dpdk.org; Georgios Katsikas <george.dit@gmail.com>
> > > > > Subject: [dpdk-dev] [PATCH 1/3] app/testpmd: Moved cmdline_flow to
> > > > > librte_cmdline
> > > > >
> > > > > Signed-off-by: Georgios Katsikas <george.dit@gmail.com>
> > > > Looks like a good idea to move this code to the lib.
> > > > cc Adrien the author of this file, app/test-pmd/cmdline_flow.c.
> > >
> > > If the command line parsing of rte_flow is something that has some
> > > chances to be shared among multiple applications, I agree it makes sense
> > > to move it in a library.
> > >
> > > However, my opinion is that it would be better to have a specific
> > > library for it, like librte_flow_cmdline, because I'm not sure that
> > > people linking with librte_cmdline always want to pull the rte_flow
> > > parsing code.
In my opinion the entire flow command parser has nothing to do outside
testpmd, it's way too specific, even if another application finds it useful.
Code duplication being a bad thing, your application could as well compile
or even #include app/test-pmd/cmdline_flow.c directly (not pretty, I know)
since it would have the same internal layout as testpmd. Testpmd's Makefile
could be modified to spit it out as a separate library if needed.
What could make more sense would be to extract the parser engine for
librte_cmdline's dynamic tokens (e.g. struct context, struct arg, struct
token) and possibly various generic helpers (e.g. parse_string,
parse_mac_addr), but not enum index nor token_list[] and friends which
define the layout of testpmd's flow command.
This would enable other flow-like commands without duplicating the engine
every time, however I'm still not sure if making it available outside
testpmd is a good idea. Extracting and making it fully generic will require
a considerable amount of work.
> > Hi Lu, Oliver,
> >
> > Thanks for your feedback!
> > You have a point here, flow commands are only a subset of the parser.
> > Do you want me to create this new library and send another patch?
>
> Let's first wait for Adrien's feedback, he can have counter-arguments.
>
> > I guess I have to use librte_cmdline as a template/example for creating the
> > librte_flow_cmdline library.
>
> It can be used as an example for Makefile and .map file.
I'm not opposed to the idea of exporting the parser engine after making it
properly generic, but please reconsider. Testpmd is an application made to
validate PMD functionality. The flow command implementation, as neat as it
is, remains a complex wrapper on top of the cmdline_parse API which wasn't
originally designed for dynamic tokens. Its syntax may evolve without
warning if deemed necessary. Making it public will subject it to exported
API/ABI constraints and likely impede future evolution.
Assuming your application is not dragging testpmd's legacy, I think it would
be wiser to re-implement a simpler flow command look-alike on top of a more
suitable command-line handling library if you like its syntax.
[1] http://dpdk.org/ml/archives/dev/2018-January/086872.html
[2] Message-ID: CAN9HtFDz+imqbCKfs6a0NE0W7iF8C+-KiNB0nCRywimspjfEDg@mail.gmail.com
--
Adrien Mazarguil
6WIND
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH 1/3] app/testpmd: Moved cmdline_flow to librte_cmdline
2018-01-16 14:31 3% ` Adrien Mazarguil
@ 2018-01-16 14:54 0% ` george.dit
2018-01-16 17:54 0% ` Adrien Mazarguil
0 siblings, 1 reply; 200+ results
From: george.dit @ 2018-01-16 14:54 UTC (permalink / raw)
To: Adrien Mazarguil; +Cc: Olivier Matz, Lu, Wenzhuo, dev
Hi Adrien,
Thanks for your insights and sorry for omitting the cover letter (this is
my first patch in DPDK).
I understand your concerns. The reason I proposed this patch is to
facilitate a more high level vendor agnostic API for configuring and
monitoring DPDK-based NICs.
To avoid just copying thousands of lines of code into my application, do
you think it is feasible to move at least the components (struct context,
struct arg, struct token and the parse_* helpers) you mentioned and
restructure testpmd in a way that allows applications to re-use all of its
parsing features?
I could give it a try and come back with a new patch, otherwise I am
perfectly ok if you want to do it instead.
Best regards,
Georgios
On Tue, Jan 16, 2018 at 3:31 PM, Adrien Mazarguil <
adrien.mazarguil@6wind.com> wrote:
> George,
>
> I missed the original RFC thread [1][2] (you should have used it as a cover
> letter for this series BTW) please see below.
>
> On Tue, Jan 16, 2018 at 10:24:25AM +0100, Olivier Matz wrote:
> > Hi,
> >
> > > On Tue, Jan 16, 2018 at 9:40 AM Olivier Matz <olivier.matz@6wind.com>
> wrote:
> > >
> > > On Tue, Jan 16, 2018 at 08:45:32AM +0000, george.dit@gmail.com wrote:
> > > > Hi Georgios,
> > > >
> > > > On Mon, Jan 15, 2018 at 01:30:35AM +0000, Lu, Wenzhuo wrote:
> > > > > Hi,
> > > > >
> > > > > > -----Original Message-----
> > > > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Georgios
> Katsikas
> > > > > > Sent: Saturday, January 13, 2018 5:01 AM
> > > > > > To: olivier.matz@6wind.com
> > > > > > Cc: dev@dpdk.org; Georgios Katsikas <george.dit@gmail.com>
> > > > > > Subject: [dpdk-dev] [PATCH 1/3] app/testpmd: Moved cmdline_flow
> to
> > > > > > librte_cmdline
> > > > > >
> > > > > > Signed-off-by: Georgios Katsikas <george.dit@gmail.com>
> > > > > Looks like a good idea to move this code to the lib.
> > > > > cc Adrien the author of this file, app/test-pmd/cmdline_flow.c.
> > > >
> > > > If the command line parsing of rte_flow is something that has some
> > > > chances to be shared among multiple applications, I agree it makes
> sense
> > > > to move it in a library.
> > > >
> > > > However, my opinion is that it would be better to have a specific
> > > > library for it, like librte_flow_cmdline, because I'm not sure that
> > > > people linking with librte_cmdline always want to pull the rte_flow
> > > > parsing code.
>
> In my opinion the entire flow command parser has nothing to do outside
> testpmd, it's way too specific, even if another application finds it
> useful.
>
> Code duplication being a bad thing, your application could as well compile
> or even #include app/test-pmd/cmdline_flow.c directly (not pretty, I know)
> since it would have the same internal layout as testpmd. Testpmd's Makefile
> could be modified to spit it out as a separate library if needed.
>
> What could make more sense would be to extract the parser engine for
> librte_cmdline's dynamic tokens (e.g. struct context, struct arg, struct
> token) and possibly various generic helpers (e.g. parse_string,
> parse_mac_addr), but not enum index nor token_list[] and friends which
> define the layout of testpmd's flow command.
>
> This would enable other flow-like commands without duplicating the engine
> every time, however I'm still not sure if making it available outside
> testpmd is a good idea. Extracting and making it fully generic will require
> a considerable amount of work.
>
> > > Hi Lu, Oliver,
> > >
> > > Thanks for your feedback!
> > > You have a point here, flow commands are only a subset of the parser.
> > > Do you want me to create this new library and send another patch?
> >
> > Let's first wait for Adrien's feedback, he can have counter-arguments.
> >
> > > I guess I have to use librte_cmdline as a template/example for
> creating the
> > > librte_flow_cmdline library.
> >
> > It can be used as an example for Makefile and .map file.
>
> I'm not opposed to the idea of exporting the parser engine after making it
> properly generic, but please reconsider. Testpmd is an application made to
> validate PMD functionality. The flow command implementation, as neat as it
> is, remains a complex wrapper on top of the cmdline_parse API which wasn't
> originally designed for dynamic tokens. Its syntax may evolve without
> warning if deemed necessary. Making it public will subject it to exported
> API/ABI constraints and likely impede future evolution.
>
> Assuming your application is not dragging testpmd's legacy, I think it
> would
> be wiser to re-implement a simpler flow command look-alike on top of a more
> suitable command-line handling library if you like its syntax.
>
> [1] http://dpdk.org/ml/archives/dev/2018-January/086872.html
> [2] Message-ID: CAN9HtFDz+imqbCKfs6a0NE0W7iF8C+-KiNB0nCRywimspjfEDg@mail.
> gmail.com
>
> --
> Adrien Mazarguil
> 6WIND
>
--
Georgios Katsikas
Industrial Ph.D. Student
Network Intelligence Group
Decision, Networks, and Analytics (DNA) Lab
RISE SICS
E-Mail: georgios.katsikas@ri.se
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2 2/5] eal: add platform mempool ops name in internal config
2018-01-15 16:26 3% ` Jerin Jacob
@ 2018-01-16 15:04 0% ` Olivier Matz
2018-01-16 15:08 0% ` Jerin Jacob
0 siblings, 1 reply; 200+ results
From: Olivier Matz @ 2018-01-16 15:04 UTC (permalink / raw)
To: Jerin Jacob; +Cc: Hemant Agrawal, dev, santosh.shukla
On Mon, Jan 15, 2018 at 09:56:36PM +0530, Jerin Jacob wrote:
> -----Original Message-----
> > Date: Mon, 15 Jan 2018 20:01:14 +0530
> > From: Hemant Agrawal <hemant.agrawal@nxp.com>
> > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > CC: dev@dpdk.org, olivier.matz@6wind.com, santosh.shukla@caviumnetworks.com
> > Subject: Re: [PATCH v2 2/5] eal: add platform mempool ops name in internal
> > config
> > User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101
> > Thunderbird/45.8.0
> >
> > On 1/15/2018 5:54 PM, Jerin Jacob wrote:
> > > > static int
> > > > diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
> > > > index 1169fcc..12c5b8a 100644
> > > > --- a/lib/librte_eal/common/eal_internal_cfg.h
> > > > +++ b/lib/librte_eal/common/eal_internal_cfg.h
> > > > @@ -54,6 +54,8 @@ struct internal_config {
> > > > const char *hugepage_dir; /**< specific hugetlbfs directory to use */
> > > > const char *user_mbuf_pool_ops_name;
> > > > /**< user defined mbuf pool ops name */
> > > > + const char *plat_mbuf_pool_ops_name;
> > > > + /**< platform configured mbuf pool ops name */
> > > > unsigned num_hugepage_sizes; /**< how many sizes on this system */
> > > > struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
> > > > };
> > > > diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
> > > > index 3fa1e13..909691f 100644
> > > > --- a/lib/librte_eal/rte_eal_version.map
> > > > +++ b/lib/librte_eal/rte_eal_version.map
> > > > @@ -203,6 +203,7 @@ DPDK_17.11 {
> > > > DPDK_18.02 {
> > > > global:
> > > >
> > > > + internal_config;
> > >
> > > I think, exposing the internal_config may not be a good idea. We may
> > > need "plat_mbuf_pool_ops_name" value for multi process case too.
> > > Considering the above points, How about adding it in
> > > struct rte_config and then expose too rte_eal_get_configuration()
> > > On the downside, it would be an ABI change.
> >
> > Yes! I was also not sure about exposing internal_config.
> >
> > rte_config is also a good option. If we add these options in the end, it
> > should not break ABI?
>
> I think, it does break the ABI.
What about a new API in librte_mbuf as suggested as a reply to the cover
letter?
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] eal: add function to return number of detected sockets
2018-01-16 12:20 3% ` Thomas Monjalon
@ 2018-01-16 15:05 4% ` Burakov, Anatoly
2018-01-16 17:34 3% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Burakov, Anatoly @ 2018-01-16 15:05 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On 16-Jan-18 12:20 PM, Thomas Monjalon wrote:
> 16/01/2018 12:56, Burakov, Anatoly:
>> On 12-Jan-18 11:50 AM, Thomas Monjalon wrote:
>>> 12/01/2018 12:44, Burakov, Anatoly:
>>>> On 11-Jan-18 10:20 PM, Thomas Monjalon wrote:
>>>>> 22/12/2017 13:41, Anatoly Burakov:
>>>>>> During lcore scan, find maximum socket ID and store it.
>>>>>>
>>>>>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
>>>>>> ---
>>>>>> --- a/lib/librte_eal/common/include/rte_eal.h
>>>>>> +++ b/lib/librte_eal/common/include/rte_eal.h
>>>>>> @@ -83,6 +83,7 @@ enum rte_proc_type_t {
>>>>>> struct rte_config {
>>>>>> uint32_t master_lcore; /**< Id of the master lcore */
>>>>>> uint32_t lcore_count; /**< Number of available logical cores. */
>>>>>> + uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
>>>>>> uint32_t service_lcore_count;/**< Number of available service cores. */
>>>>>> enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
>>>>>
>>>>> isn't it breaking the ABI?
>>>>>
>>>>>
>>>>
>>>> Yep, you're right, forgot to add that. I didn't expect this to get
>>>> merged in 18.02 anyway, so v2 will follow.
>>>
>>> Please write 18.05 in the subject to show your expectation.
>>> Thanks
>>>
>>
>> Does it have to be an ABI change though? We can put numa_node_count
>> after pointer to mem_config, in which case it won't be an ABI break.
>> Would that be better?
>
> Changing the size of a struct which is allocated by the app,
> is an ABI break.
> Is your solution changing the size?
>
It's not really allocated as such. rte_config is a global static
variable, and we only ever get pointers to it from the user code. If we
add the new value at the end, all of the old data layout would be intact
and work as before, so nothing would change as far as old code is concerned.
However, if that's still considered an ABI break, then OK, break it is.
Some background for why this is needed - for the memory hotplug, we need
to know how many sockets we can allocate memory at, to distinguish
between socket that doesn't exist, and socket that exists but has no
memory allocated on it. I'm OK with trying other approaches (such as
storing numa nodes in a static variable somewhere) if breaking ABI for
this is too much to ask for such a minute change.
--
Thanks,
Anatoly
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH v2 2/5] eal: add platform mempool ops name in internal config
2018-01-16 15:04 0% ` Olivier Matz
@ 2018-01-16 15:08 0% ` Jerin Jacob
0 siblings, 0 replies; 200+ results
From: Jerin Jacob @ 2018-01-16 15:08 UTC (permalink / raw)
To: Olivier Matz; +Cc: Hemant Agrawal, dev, santosh.shukla
-----Original Message-----
> Date: Tue, 16 Jan 2018 16:04:20 +0100
> From: Olivier Matz <olivier.matz@6wind.com>
> To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> CC: Hemant Agrawal <hemant.agrawal@nxp.com>, dev@dpdk.org,
> santosh.shukla@caviumnetworks.com
> Subject: Re: [PATCH v2 2/5] eal: add platform mempool ops name in internal
> config
> User-Agent: NeoMutt/20170113 (1.7.2)
>
> On Mon, Jan 15, 2018 at 09:56:36PM +0530, Jerin Jacob wrote:
> > -----Original Message-----
> > > Date: Mon, 15 Jan 2018 20:01:14 +0530
> > > From: Hemant Agrawal <hemant.agrawal@nxp.com>
> > > To: Jerin Jacob <jerin.jacob@caviumnetworks.com>
> > > CC: dev@dpdk.org, olivier.matz@6wind.com, santosh.shukla@caviumnetworks.com
> > > Subject: Re: [PATCH v2 2/5] eal: add platform mempool ops name in internal
> > > config
> > > User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:45.0) Gecko/20100101
> > > Thunderbird/45.8.0
> > >
> > > On 1/15/2018 5:54 PM, Jerin Jacob wrote:
> > > > > static int
> > > > > diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
> > > > > index 1169fcc..12c5b8a 100644
> > > > > --- a/lib/librte_eal/common/eal_internal_cfg.h
> > > > > +++ b/lib/librte_eal/common/eal_internal_cfg.h
> > > > > @@ -54,6 +54,8 @@ struct internal_config {
> > > > > const char *hugepage_dir; /**< specific hugetlbfs directory to use */
> > > > > const char *user_mbuf_pool_ops_name;
> > > > > /**< user defined mbuf pool ops name */
> > > > > + const char *plat_mbuf_pool_ops_name;
> > > > > + /**< platform configured mbuf pool ops name */
> > > > > unsigned num_hugepage_sizes; /**< how many sizes on this system */
> > > > > struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
> > > > > };
> > > > > diff --git a/lib/librte_eal/rte_eal_version.map b/lib/librte_eal/rte_eal_version.map
> > > > > index 3fa1e13..909691f 100644
> > > > > --- a/lib/librte_eal/rte_eal_version.map
> > > > > +++ b/lib/librte_eal/rte_eal_version.map
> > > > > @@ -203,6 +203,7 @@ DPDK_17.11 {
> > > > > DPDK_18.02 {
> > > > > global:
> > > > >
> > > > > + internal_config;
> > > >
> > > > I think, exposing the internal_config may not be a good idea. We may
> > > > need "plat_mbuf_pool_ops_name" value for multi process case too.
> > > > Considering the above points, How about adding it in
> > > > struct rte_config and then expose too rte_eal_get_configuration()
> > > > On the downside, it would be an ABI change.
> > >
> > > Yes! I was also not sure about exposing internal_config.
> > >
> > > rte_config is also a good option. If we add these options in the end, it
> > > should not break ABI?
> >
> > I think, it does break the ABI.
>
> What about a new API in librte_mbuf as suggested as a reply to the cover
> letter?
Looks good to me.
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: increase flow type limit from 32 to 64
2018-01-16 11:13 0% ` Adrien Mazarguil
@ 2018-01-16 17:23 0% ` Rybalchenko, Kirill
2018-01-16 18:03 0% ` Adrien Mazarguil
0 siblings, 1 reply; 200+ results
From: Rybalchenko, Kirill @ 2018-01-16 17:23 UTC (permalink / raw)
To: Adrien Mazarguil
Cc: dev, Wu, Jingjing, Xing, Beilei, johndale, neescoba,
nelio.laranjeiro, yskoh, Lu, Wenzhuo, Ananyev, Konstantin,
Chilikin, Andrey
Hi Adrien,
after some discussion we found that change I've done
in Mellanox PMD is not really necessary: size of array
flow_types_mask[] is still 1 and the loop in patch
for (i = 0; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
info->flow_types_mask[i] = 0ULL;
will work exactly in the same way as assignment
fdir_info->flow_types_mask[0] = 0;
in old version, though new version looks more proper
from programming style point of view.
So what do you think, shall I modify Mellanox PMD,
or better leave it as it is?
Thanks,
Kirill.
> -----Original Message-----
> From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> Sent: Tuesday 16 January 2018 11:13
> To: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>
> Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> <beilei.xing@intel.com>; johndale@cisco.com; neescoba@cisco.com;
> nelio.laranjeiro@6wind.com; yskoh@mellanox.com; Lu, Wenzhuo
> <wenzhuo.lu@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; Chilikin, Andrey
> <andrey.chilikin@intel.com>
> Subject: Re: [PATCH] ethdev: increase flow type limit from 32 to 64
>
> On Tue, Jan 09, 2018 at 03:16:13PM +0000, Rybalchenko, Kirill wrote:
> > > -----Original Message-----
> > > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > > Sent: Monday 4 December 2017 17:43
> > > To: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>
> > > Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> > > <beilei.xing@intel.com>; johndale@cisco.com; neescoba@cisco.com;
> > > nelio.laranjeiro@6wind.com; yskoh@mellanox.com; Lu, Wenzhuo
> > > <wenzhuo.lu@intel.com>; Ananyev, Konstantin
> > > <konstantin.ananyev@intel.com>; Chilikin, Andrey
> > > <andrey.chilikin@intel.com>
> > > Subject: Re: [PATCH] ethdev: increase flow type limit from 32 to 64
> > >
> > > Hi Kirill,
> > >
> > > On Mon, Nov 27, 2017 at 12:29:47PM +0000, Kirill Rybalchenko wrote:
> > > > Increase the internal limit for flow types from 32 to 64 to
> > > > support future flow type extensions.
> > > > Change type of variables from uint32_t[] to uint64_t[]:
> > > > rte_eth_fdir_info.flow_types_mask
> > > > rte_eth_hash_global_conf.sym_hash_enable_mask
> > > > rte_eth_hash_global_conf.valid_bit_mask
> > > >
> > > > This modification affects the following components:
> > > > net/i40e
> > > > net/enic
> > > > net/mlx5
> > > > net/ixgbe
> > > > app/testpmd
> > > >
> > > > Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> > >
> > > Can you elaborate a bit on the need for these changes?
> > > Have you considered implementing those future extensions through
> > > rte_flow instead?
> >
> > Hi Adrien, this is not a new feature but rather fix of existing limitation.
> > In current implementation the symmetric hash mask and flow mask are
> > represented by 32-bit variable, while hardware bitmask has 64 bits.
> > Unfortunately, this modification changes ABI of the library as it
> > changes size of rte_eth_fdir_info structure. All related PMDs (listed
> > above) had to be modified accordingly.
>
> OK, no problem with this change. I assume you'll re-submit it since you sent a
> deprecation notice, we'll review/ack subsequent mlx5 patches.
>
> --
> Adrien Mazarguil
> 6WIND
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH v2] eal: add function to return number of detected sockets
2018-01-16 15:05 4% ` Burakov, Anatoly
@ 2018-01-16 17:34 3% ` Thomas Monjalon
2018-01-16 17:38 0% ` Burakov, Anatoly
0 siblings, 1 reply; 200+ results
From: Thomas Monjalon @ 2018-01-16 17:34 UTC (permalink / raw)
To: Burakov, Anatoly; +Cc: dev
16/01/2018 16:05, Burakov, Anatoly:
> On 16-Jan-18 12:20 PM, Thomas Monjalon wrote:
> > 16/01/2018 12:56, Burakov, Anatoly:
> >> On 12-Jan-18 11:50 AM, Thomas Monjalon wrote:
> >>> 12/01/2018 12:44, Burakov, Anatoly:
> >>>> On 11-Jan-18 10:20 PM, Thomas Monjalon wrote:
> >>>>> 22/12/2017 13:41, Anatoly Burakov:
> >>>>>> During lcore scan, find maximum socket ID and store it.
> >>>>>>
> >>>>>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> >>>>>> ---
> >>>>>> --- a/lib/librte_eal/common/include/rte_eal.h
> >>>>>> +++ b/lib/librte_eal/common/include/rte_eal.h
> >>>>>> @@ -83,6 +83,7 @@ enum rte_proc_type_t {
> >>>>>> struct rte_config {
> >>>>>> uint32_t master_lcore; /**< Id of the master lcore */
> >>>>>> uint32_t lcore_count; /**< Number of available logical cores. */
> >>>>>> + uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
> >>>>>> uint32_t service_lcore_count;/**< Number of available service cores. */
> >>>>>> enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
> >>>>>
> >>>>> isn't it breaking the ABI?
> >>>>>
> >>>>>
> >>>>
> >>>> Yep, you're right, forgot to add that. I didn't expect this to get
> >>>> merged in 18.02 anyway, so v2 will follow.
> >>>
> >>> Please write 18.05 in the subject to show your expectation.
> >>> Thanks
> >>>
> >>
> >> Does it have to be an ABI change though? We can put numa_node_count
> >> after pointer to mem_config, in which case it won't be an ABI break.
> >> Would that be better?
> >
> > Changing the size of a struct which is allocated by the app,
> > is an ABI break.
> > Is your solution changing the size?
> >
>
> It's not really allocated as such. rte_config is a global static
> variable, and we only ever get pointers to it from the user code. If we
> add the new value at the end, all of the old data layout would be intact
> and work as before, so nothing would change as far as old code is concerned.
>
> However, if that's still considered an ABI break, then OK, break it is.
Maybe that assuming it is never allocated (not copied for instance)
we could consider it is not an ABI break.
> Some background for why this is needed - for the memory hotplug, we need
> to know how many sockets we can allocate memory at, to distinguish
> between socket that doesn't exist, and socket that exists but has no
> memory allocated on it. I'm OK with trying other approaches (such as
> storing numa nodes in a static variable somewhere) if breaking ABI for
> this is too much to ask for such a minute change.
Why is it important for 18.02?
Memory hotplug will be integrated only in 18.05.
I think it is better to just wait (and announce the deprecation).
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2] eal: add function to return number of detected sockets
2018-01-16 17:34 3% ` Thomas Monjalon
@ 2018-01-16 17:38 0% ` Burakov, Anatoly
2018-01-16 18:26 0% ` Thomas Monjalon
0 siblings, 1 reply; 200+ results
From: Burakov, Anatoly @ 2018-01-16 17:38 UTC (permalink / raw)
To: Thomas Monjalon; +Cc: dev
On 16-Jan-18 5:34 PM, Thomas Monjalon wrote:
> 16/01/2018 16:05, Burakov, Anatoly:
>> On 16-Jan-18 12:20 PM, Thomas Monjalon wrote:
>>> 16/01/2018 12:56, Burakov, Anatoly:
>>>> On 12-Jan-18 11:50 AM, Thomas Monjalon wrote:
>>>>> 12/01/2018 12:44, Burakov, Anatoly:
>>>>>> On 11-Jan-18 10:20 PM, Thomas Monjalon wrote:
>>>>>>> 22/12/2017 13:41, Anatoly Burakov:
>>>>>>>> During lcore scan, find maximum socket ID and store it.
>>>>>>>>
>>>>>>>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
>>>>>>>> ---
>>>>>>>> --- a/lib/librte_eal/common/include/rte_eal.h
>>>>>>>> +++ b/lib/librte_eal/common/include/rte_eal.h
>>>>>>>> @@ -83,6 +83,7 @@ enum rte_proc_type_t {
>>>>>>>> struct rte_config {
>>>>>>>> uint32_t master_lcore; /**< Id of the master lcore */
>>>>>>>> uint32_t lcore_count; /**< Number of available logical cores. */
>>>>>>>> + uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
>>>>>>>> uint32_t service_lcore_count;/**< Number of available service cores. */
>>>>>>>> enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
>>>>>>>
>>>>>>> isn't it breaking the ABI?
>>>>>>>
>>>>>>>
>>>>>>
>>>>>> Yep, you're right, forgot to add that. I didn't expect this to get
>>>>>> merged in 18.02 anyway, so v2 will follow.
>>>>>
>>>>> Please write 18.05 in the subject to show your expectation.
>>>>> Thanks
>>>>>
>>>>
>>>> Does it have to be an ABI change though? We can put numa_node_count
>>>> after pointer to mem_config, in which case it won't be an ABI break.
>>>> Would that be better?
>>>
>>> Changing the size of a struct which is allocated by the app,
>>> is an ABI break.
>>> Is your solution changing the size?
>>>
>>
>> It's not really allocated as such. rte_config is a global static
>> variable, and we only ever get pointers to it from the user code. If we
>> add the new value at the end, all of the old data layout would be intact
>> and work as before, so nothing would change as far as old code is concerned.
>>
>> However, if that's still considered an ABI break, then OK, break it is.
>
> Maybe that assuming it is never allocated (not copied for instance)
> we could consider it is not an ABI break.
>
>> Some background for why this is needed - for the memory hotplug, we need
>> to know how many sockets we can allocate memory at, to distinguish
>> between socket that doesn't exist, and socket that exists but has no
>> memory allocated on it. I'm OK with trying other approaches (such as
>> storing numa nodes in a static variable somewhere) if breaking ABI for
>> this is too much to ask for such a minute change.
>
> Why is it important for 18.02?
> Memory hotplug will be integrated only in 18.05.
> I think it is better to just wait (and announce the deprecation).
>
It isn't, i've already marked this patch as deferred. However, we'll
have to have this discussion anyway :)
--
Thanks,
Anatoly
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH] doc: add ABI change notice for numa_node_count in eal
2018-01-11 22:20 3% ` Thomas Monjalon
@ 2018-01-16 17:53 17% ` Anatoly Burakov
1 sibling, 0 replies; 200+ results
From: Anatoly Burakov @ 2018-01-16 17:53 UTC (permalink / raw)
To: dev; +Cc: Neil Horman, John McNamara, Marko Kovacevic
There will be a new function added in v18.05 that will return
number of detected sockets, which will change the ABI.
Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
doc/guides/rel_notes/deprecation.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 13e8543..9662150 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -8,6 +8,8 @@ API and ABI deprecation notices are to be posted here.
Deprecation Notices
-------------------
+* eal: new ``numa_node_count`` member will be added to ``rte_config`` structure
+ in v18.05.
* eal: several API and ABI changes are planned for ``rte_devargs`` in v18.02.
The format of device command line parameters will change. The bus will need
to be explicitly stated in the device declaration. The enum ``rte_devtype``
--
2.7.4
^ permalink raw reply [relevance 17%]
* Re: [dpdk-dev] [PATCH 1/3] app/testpmd: Moved cmdline_flow to librte_cmdline
2018-01-16 14:54 0% ` george.dit
@ 2018-01-16 17:54 0% ` Adrien Mazarguil
0 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-01-16 17:54 UTC (permalink / raw)
To: george.dit; +Cc: Olivier Matz, Lu, Wenzhuo, dev
On Tue, Jan 16, 2018 at 03:54:57PM +0100, george.dit@gmail.com wrote:
> Hi Adrien,
>
> Thanks for your insights and sorry for omitting the cover letter (this is
> my first patch in DPDK).
No problem, don't worry about that. Remember to put as much context as close
as possible to the related changes. The commit log of a patch is in fact a
more appropriate place since a cover letter is simply a summary of a
subsequent series and is discarded once applied.
> I understand your concerns. The reason I proposed this patch is to
> facilitate a more high level vendor agnostic API for configuring and
> monitoring DPDK-based NICs.
>
> To avoid just copying thousands of lines of code into my application, do
> you think it is feasible to move at least the components (struct context,
> struct arg, struct token and the parse_* helpers) you mentioned and
> restructure testpmd in a way that allows applications to re-use all of its
> parsing features?
Yes I think it's feasible, although at the cost of great effort because
you'd need to untangle engine code from parser code to expose the former,
the flow command being a mix of both. Proper APIs must be devised for that,
hence my question: is it really worth the trouble?
Other contributors already asked me how they could reuse the flow command
parser to implement similar testpmd commands without copy/pasting the entire
file, so I'm already convinced separating at least the engine part makes
sense at the testpmd level. Moving it to librte_cmdline for external
applications seems more complex though.
> I could give it a try and come back with a new patch, otherwise I am
> perfectly ok if you want to do it instead.
While I'd certainly like to do it (at least at the testpmd level), it's
unlikely to happen anytime soon due to other priorities.
Feel free to take care of it if you're motivated enough, just keep in mind
right now I don't think this should be exposed as a public API. I can change
my mind if you manage to make it generic enough.
> On Tue, Jan 16, 2018 at 3:31 PM, Adrien Mazarguil <
> adrien.mazarguil@6wind.com> wrote:
>
> > George,
> >
> > I missed the original RFC thread [1][2] (you should have used it as a cover
> > letter for this series BTW) please see below.
> >
> > On Tue, Jan 16, 2018 at 10:24:25AM +0100, Olivier Matz wrote:
> > > Hi,
> > >
> > > > On Tue, Jan 16, 2018 at 9:40 AM Olivier Matz <olivier.matz@6wind.com>
> > wrote:
> > > >
> > > > On Tue, Jan 16, 2018 at 08:45:32AM +0000, george.dit@gmail.com wrote:
> > > > > Hi Georgios,
> > > > >
> > > > > On Mon, Jan 15, 2018 at 01:30:35AM +0000, Lu, Wenzhuo wrote:
> > > > > > Hi,
> > > > > >
> > > > > > > -----Original Message-----
> > > > > > > From: dev [mailto:dev-bounces@dpdk.org] On Behalf Of Georgios
> > Katsikas
> > > > > > > Sent: Saturday, January 13, 2018 5:01 AM
> > > > > > > To: olivier.matz@6wind.com
> > > > > > > Cc: dev@dpdk.org; Georgios Katsikas <george.dit@gmail.com>
> > > > > > > Subject: [dpdk-dev] [PATCH 1/3] app/testpmd: Moved cmdline_flow
> > to
> > > > > > > librte_cmdline
> > > > > > >
> > > > > > > Signed-off-by: Georgios Katsikas <george.dit@gmail.com>
> > > > > > Looks like a good idea to move this code to the lib.
> > > > > > cc Adrien the author of this file, app/test-pmd/cmdline_flow.c.
> > > > >
> > > > > If the command line parsing of rte_flow is something that has some
> > > > > chances to be shared among multiple applications, I agree it makes
> > sense
> > > > > to move it in a library.
> > > > >
> > > > > However, my opinion is that it would be better to have a specific
> > > > > library for it, like librte_flow_cmdline, because I'm not sure that
> > > > > people linking with librte_cmdline always want to pull the rte_flow
> > > > > parsing code.
> >
> > In my opinion the entire flow command parser has nothing to do outside
> > testpmd, it's way too specific, even if another application finds it
> > useful.
> >
> > Code duplication being a bad thing, your application could as well compile
> > or even #include app/test-pmd/cmdline_flow.c directly (not pretty, I know)
> > since it would have the same internal layout as testpmd. Testpmd's Makefile
> > could be modified to spit it out as a separate library if needed.
> >
> > What could make more sense would be to extract the parser engine for
> > librte_cmdline's dynamic tokens (e.g. struct context, struct arg, struct
> > token) and possibly various generic helpers (e.g. parse_string,
> > parse_mac_addr), but not enum index nor token_list[] and friends which
> > define the layout of testpmd's flow command.
> >
> > This would enable other flow-like commands without duplicating the engine
> > every time, however I'm still not sure if making it available outside
> > testpmd is a good idea. Extracting and making it fully generic will require
> > a considerable amount of work.
> >
> > > > Hi Lu, Oliver,
> > > >
> > > > Thanks for your feedback!
> > > > You have a point here, flow commands are only a subset of the parser.
> > > > Do you want me to create this new library and send another patch?
> > >
> > > Let's first wait for Adrien's feedback, he can have counter-arguments.
> > >
> > > > I guess I have to use librte_cmdline as a template/example for
> > creating the
> > > > librte_flow_cmdline library.
> > >
> > > It can be used as an example for Makefile and .map file.
> >
> > I'm not opposed to the idea of exporting the parser engine after making it
> > properly generic, but please reconsider. Testpmd is an application made to
> > validate PMD functionality. The flow command implementation, as neat as it
> > is, remains a complex wrapper on top of the cmdline_parse API which wasn't
> > originally designed for dynamic tokens. Its syntax may evolve without
> > warning if deemed necessary. Making it public will subject it to exported
> > API/ABI constraints and likely impede future evolution.
> >
> > Assuming your application is not dragging testpmd's legacy, I think it
> > would
> > be wiser to re-implement a simpler flow command look-alike on top of a more
> > suitable command-line handling library if you like its syntax.
> >
> > [1] http://dpdk.org/ml/archives/dev/2018-January/086872.html
> > [2] Message-ID: CAN9HtFDz+imqbCKfs6a0NE0W7iF8C+-KiNB0nCRywimspjfEDg@mail.
> > gmail.com
> >
> > --
> > Adrien Mazarguil
> > 6WIND
> >
>
>
>
> --
> Georgios Katsikas
> Industrial Ph.D. Student
> Network Intelligence Group
> Decision, Networks, and Analytics (DNA) Lab
> RISE SICS
> E-Mail: georgios.katsikas@ri.se
--
Adrien Mazarguil
6WIND
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH] ethdev: increase flow type limit from 32 to 64
2018-01-16 17:23 0% ` Rybalchenko, Kirill
@ 2018-01-16 18:03 0% ` Adrien Mazarguil
0 siblings, 0 replies; 200+ results
From: Adrien Mazarguil @ 2018-01-16 18:03 UTC (permalink / raw)
To: Rybalchenko, Kirill
Cc: dev, Wu, Jingjing, Xing, Beilei, johndale, neescoba,
nelio.laranjeiro, yskoh, Lu, Wenzhuo, Ananyev, Konstantin,
Chilikin, Andrey
Hi Kirill,
On Tue, Jan 16, 2018 at 05:23:05PM +0000, Rybalchenko, Kirill wrote:
> Hi Adrien,
> after some discussion we found that change I've done
> in Mellanox PMD is not really necessary: size of array
> flow_types_mask[] is still 1 and the loop in patch
>
> for (i = 0; i < RTE_FLOW_MASK_ARRAY_SIZE; i++)
> info->flow_types_mask[i] = 0ULL;
>
> will work exactly in the same way as assignment
>
> fdir_info->flow_types_mask[0] = 0;
>
> in old version, though new version looks more proper
> from programming style point of view.
> So what do you think, shall I modify Mellanox PMD,
> or better leave it as it is?
If functionally the same, just drop the mlx change (involving fewer
reviewers is a good thing, right? :)
If it addressed a bug, it should have come as a separate "Fixes" patch
anyway.
> > -----Original Message-----
> > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > Sent: Tuesday 16 January 2018 11:13
> > To: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>
> > Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> > <beilei.xing@intel.com>; johndale@cisco.com; neescoba@cisco.com;
> > nelio.laranjeiro@6wind.com; yskoh@mellanox.com; Lu, Wenzhuo
> > <wenzhuo.lu@intel.com>; Ananyev, Konstantin
> > <konstantin.ananyev@intel.com>; Chilikin, Andrey
> > <andrey.chilikin@intel.com>
> > Subject: Re: [PATCH] ethdev: increase flow type limit from 32 to 64
> >
> > On Tue, Jan 09, 2018 at 03:16:13PM +0000, Rybalchenko, Kirill wrote:
> > > > -----Original Message-----
> > > > From: Adrien Mazarguil [mailto:adrien.mazarguil@6wind.com]
> > > > Sent: Monday 4 December 2017 17:43
> > > > To: Rybalchenko, Kirill <kirill.rybalchenko@intel.com>
> > > > Cc: dev@dpdk.org; Wu, Jingjing <jingjing.wu@intel.com>; Xing, Beilei
> > > > <beilei.xing@intel.com>; johndale@cisco.com; neescoba@cisco.com;
> > > > nelio.laranjeiro@6wind.com; yskoh@mellanox.com; Lu, Wenzhuo
> > > > <wenzhuo.lu@intel.com>; Ananyev, Konstantin
> > > > <konstantin.ananyev@intel.com>; Chilikin, Andrey
> > > > <andrey.chilikin@intel.com>
> > > > Subject: Re: [PATCH] ethdev: increase flow type limit from 32 to 64
> > > >
> > > > Hi Kirill,
> > > >
> > > > On Mon, Nov 27, 2017 at 12:29:47PM +0000, Kirill Rybalchenko wrote:
> > > > > Increase the internal limit for flow types from 32 to 64 to
> > > > > support future flow type extensions.
> > > > > Change type of variables from uint32_t[] to uint64_t[]:
> > > > > rte_eth_fdir_info.flow_types_mask
> > > > > rte_eth_hash_global_conf.sym_hash_enable_mask
> > > > > rte_eth_hash_global_conf.valid_bit_mask
> > > > >
> > > > > This modification affects the following components:
> > > > > net/i40e
> > > > > net/enic
> > > > > net/mlx5
> > > > > net/ixgbe
> > > > > app/testpmd
> > > > >
> > > > > Signed-off-by: Kirill Rybalchenko <kirill.rybalchenko@intel.com>
> > > >
> > > > Can you elaborate a bit on the need for these changes?
> > > > Have you considered implementing those future extensions through
> > > > rte_flow instead?
> > >
> > > Hi Adrien, this is not a new feature but rather fix of existing limitation.
> > > In current implementation the symmetric hash mask and flow mask are
> > > represented by 32-bit variable, while hardware bitmask has 64 bits.
> > > Unfortunately, this modification changes ABI of the library as it
> > > changes size of rte_eth_fdir_info structure. All related PMDs (listed
> > > above) had to be modified accordingly.
> >
> > OK, no problem with this change. I assume you'll re-submit it since you sent a
> > deprecation notice, we'll review/ack subsequent mlx5 patches.
> >
> > --
> > Adrien Mazarguil
> > 6WIND
--
Adrien Mazarguil
6WIND
^ permalink raw reply [relevance 0%]
* [dpdk-dev] [PATCH v2] checkpatches.sh: Add checks for ABI symbol addition
2018-01-15 19:05 4% [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition Neil Horman
2018-01-15 21:52 7% ` Thomas Monjalon
2018-01-15 22:20 4% ` Stephen Hemminger
@ 2018-01-16 18:22 3% ` Neil Horman
2 siblings, 0 replies; 200+ results
From: Neil Horman @ 2018-01-16 18:22 UTC (permalink / raw)
To: dev
Cc: Neil Horman, thomas, john.mcnamara, bruce.richardson,
Ferruh Yigit, Stephen Hemminger
Recently, some additional patches were added to allow for programmatic
marking of C symbols as experimental. The addition of these markers is
dependent on the manual addition of exported symbols to the EXPERIMENTAL
section of the corresponding libraries version map file. The consensus
on review is that, in addition to mandating the addition of symbols to
the EXPERIMENTAL version in the map, we need a mechanism to enforce our
documented process of mandating that addition when they are introduced.
To that end, I am proposing this change. It is an addition to the
checkpatches script, which scan incoming patches for additions and
removals of symbols to the map file, and warns the user appropriately
Signed-off-by: Neil Horman <nhorman@tuxdriver.com>
CC: thomas@monjalon.net
CC: john.mcnamara@intel.com
CC: bruce.richardson@intel.com
CC: Ferruh Yigit <ferruh.yigit@intel.com>
CC: Stephen Hemminger <stephen@networkplumber.org>
---
Change notes
v2)
* Cleaned up and documented awk script (shemminger)
* fixed sort/uniq usage (shemminger)
* moved checking to new script (tmonjalon)
* added maintainer entry (tmonjalon)
* added license (tmonjalon)
---
MAINTAINERS | 2 +
devtools/checkpatches.sh | 22 ++++++-
devtools/validate-new-api.sh | 138 +++++++++++++++++++++++++++++++++++++++++++
3 files changed, 161 insertions(+), 1 deletion(-)
create mode 100755 devtools/validate-new-api.sh
diff --git a/MAINTAINERS b/MAINTAINERS
index b51c2d096..d3a3c245e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -42,6 +42,7 @@ F: doc/
Developers and Maintainers Tools
M: Thomas Monjalon <thomas@monjalon.net>
+M: Neil Horman <nhorman@tuxdriver.com>
F: MAINTAINERS
F: devtools/check-dup-includes.sh
F: devtools/check-maintainers.sh
@@ -52,6 +53,7 @@ F: devtools/get-maintainer.sh
F: devtools/git-log-fixes.sh
F: devtools/load-devel-config
F: devtools/test-build.sh
+F: devtools/validate-new-api.sh
F: license/
diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index 7676a6b50..cf5c67b09 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -35,6 +35,8 @@
# - DPDK_CHECKPATCH_LINE_LENGTH
. $(dirname $(readlink -e $0))/load-devel-config
+export VALIDATE_NEW_API=$(dirname $(readlink -e $0))/validate-new-api.sh
+
length=${DPDK_CHECKPATCH_LINE_LENGTH:-80}
# override default Linux options
@@ -51,6 +53,7 @@ NEW_TYPEDEFS,COMPARISON_TO_NULL"
print_usage () {
cat <<- END_OF_HELP
+ $(dirname $0)
usage: $(basename $0) [-q] [-v] [-nX|patch1 [patch2] ...]]
Run Linux kernel checkpatch.pl with DPDK options.
@@ -61,6 +64,7 @@ print_usage () {
END_OF_HELP
}
+
number=0
quiet=false
verbose=false
@@ -96,9 +100,25 @@ check () { # <patch> <commit> <title>
else
report=$($DPDK_CHECKPATCH_PATH $options - 2>/dev/null)
fi
- [ $? -ne 0 ] || return 0
+ reta=$?
+
$verbose || printf '\n### %s\n\n' "$3"
printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
+
+ echo
+ echo "Checking API additions/removals:"
+ if [ -n "$1" ] ; then
+ report=$($VALIDATE_NEW_API $1)
+ elif [ -n "$2" ] ; then
+ report=$(git format-patch \
+ --find-renames --no-stat --stdout -1 $commit |
+ $VALIDATE_NEW_API -)
+ else
+ report=$($VALIDATE_NEW_API -)
+ fi
+ [ $? -ne 0 -o $reta -ne 0 ] || return 0
+ printf '%s\n' "$report" | sed -n '1,/^total:.*lines checked$/p'
+
status=$(($status + 1))
}
diff --git a/devtools/validate-new-api.sh b/devtools/validate-new-api.sh
new file mode 100755
index 000000000..3499f5f8b
--- /dev/null
+++ b/devtools/validate-new-api.sh
@@ -0,0 +1,138 @@
+#!/bin/sh
+
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright(c) 2018 Neil Horman <nhorman@tuxdriver.com>
+
+build_map_changes()
+{
+ local fname=$1
+ local mapdb=$2
+
+ cat $fname | filterdiff -i *.map | awk '
+ # Initialize our variables
+ BEGIN {map="";sym="";ar="";sec=""; in_sec=0}
+
+ # Anything that starts with + or -, followed by an a
+ # and ends in the string .map is the name of our map file
+ # This may appear multiple times in a patch if multiple
+ # map files are altered, and all section/symbol names
+ # appearing between a triggering of this rule and the
+ # next trigger of this rule are associated with this file
+ /[-+] a\/.*\.map/ {map=$2}
+
+ # Triggering this rule, which starts a line with a + and ends it
+ # with a { identifies a versioned section. The section name is
+ # the rest of the line with the + and { symbols remvoed.
+ # Triggering this rule sets in_sec to 1, which actives the
+ # symbol rule below
+ /+.*{/ {gsub("+","");sec=$1; in_sec=1}
+
+ # This rule idenfies the end of a section, and disables the
+ # symbol rule
+ /.*}/ {in_sec=0}
+
+ # This rule matches on a + followed by any characters except a :
+ # (which denotes a global vs local segment), and ends with a ;.
+ # The semicolon is removed and the symbol is printed with its
+ # association file name and version section, along with an
+ # indicator that the symbol is a new addition. Note this rule
+ # only works if we have found a version section in the rule
+ # above (hence the in_sec check). Otherwise we flag it as an
+ # unknown section
+ /^+[^}].*[^:*];/ {gsub(";","");sym=$2;
+ if (in_sec == 1) {
+ print map " " sym " " sec " add"
+ } else {
+ print map " " sym " unknown add"
+ }
+ }
+
+ # This is the same rule as above, but the rule matches on a
+ # leading - rather than a +, denoting that the symbol is being
+ # removed.
+ /^-[^}].*[^:*];/ {gsub(";","");sym=$2;
+ if (in_sec == 1) {
+ print map " " sym " " sec " del"
+ } else {
+ print map " " sym " unknown del"
+ }
+ }' > ./$mapdb
+
+ sort -u $mapdb > ./$mapdb.2
+ mv -f $mapdb.2 $mapdb
+
+}
+
+check_for_rule_violations()
+{
+ local mapdb=$1
+ local mname
+ local symname
+ local secname
+ local ar
+ local ret=0
+
+ while read mname symname secname ar
+ do
+ if [ "$ar" == "add" ]
+ then
+
+ if [ "$secname" == "unknown" ]
+ then
+ # Just inform the user of this occurrence, but
+ # don't flag it as an error
+ echo -n "INFO: symbol $syname is added but "
+ echo -n "patch has insuficient context "
+ echo -n "to determine the section name "
+ echo -n "please ensure the version is "
+ echo "EXPERIMENTAL"
+ continue
+ fi
+
+ if [ "$secname" != "EXPERIMENTAL" ]
+ then
+ # Symbols that are getting added in a section
+ # other ithan the experimental section
+ # to be moving from an already supported
+ # section or its a violation
+ grep -q \
+ "$mname $symname [^EXPERIMENTAL] del" $mapdb
+ if [ $? -ne 0 ]
+ then
+ echo -n "ERROR: symbol $symname "
+ echo -n "is added in a section "
+ echo -n "other than the EXPERIMENTAL "
+ echo "section of the version map"
+ ret=1
+ fi
+ fi
+ else
+
+ if [ "$secname" != "EXPERIMENTAL" ]
+ then
+ # Just inform users that non-experimenal
+ # symbols need to go through a deprecation
+ # process
+ echo -n "INFO: symbol $symname is being "
+ echo -n "removed, ensure that it has "
+ echo "gone through the deprecation process"
+ fi
+ fi
+ done < $mapdb
+
+ return $ret
+}
+
+
+mapfile=`mktemp mapdb.XXXXXX`
+patch=$1
+
+build_map_changes $patch $mapfile
+check_for_rule_violations $mapfile
+exit_code=$?
+
+rm -f $mapfile
+
+exit $exit_code
+
+
--
2.14.3
^ permalink raw reply [relevance 3%]
* Re: [dpdk-dev] [PATCH v2] eal: add function to return number of detected sockets
2018-01-16 17:38 0% ` Burakov, Anatoly
@ 2018-01-16 18:26 0% ` Thomas Monjalon
0 siblings, 0 replies; 200+ results
From: Thomas Monjalon @ 2018-01-16 18:26 UTC (permalink / raw)
To: Burakov, Anatoly; +Cc: dev
16/01/2018 18:38, Burakov, Anatoly:
> On 16-Jan-18 5:34 PM, Thomas Monjalon wrote:
> > 16/01/2018 16:05, Burakov, Anatoly:
> >> On 16-Jan-18 12:20 PM, Thomas Monjalon wrote:
> >>> 16/01/2018 12:56, Burakov, Anatoly:
> >>>> On 12-Jan-18 11:50 AM, Thomas Monjalon wrote:
> >>>>> 12/01/2018 12:44, Burakov, Anatoly:
> >>>>>> On 11-Jan-18 10:20 PM, Thomas Monjalon wrote:
> >>>>>>> 22/12/2017 13:41, Anatoly Burakov:
> >>>>>>>> During lcore scan, find maximum socket ID and store it.
> >>>>>>>>
> >>>>>>>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> >>>>>>>> ---
> >>>>>>>> --- a/lib/librte_eal/common/include/rte_eal.h
> >>>>>>>> +++ b/lib/librte_eal/common/include/rte_eal.h
> >>>>>>>> @@ -83,6 +83,7 @@ enum rte_proc_type_t {
> >>>>>>>> struct rte_config {
> >>>>>>>> uint32_t master_lcore; /**< Id of the master lcore */
> >>>>>>>> uint32_t lcore_count; /**< Number of available logical cores. */
> >>>>>>>> + uint32_t numa_node_count; /**< Number of detected NUMA nodes. */
> >>>>>>>> uint32_t service_lcore_count;/**< Number of available service cores. */
> >>>>>>>> enum rte_lcore_role_t lcore_role[RTE_MAX_LCORE]; /**< State of cores. */
> >>>>>>>
> >>>>>>> isn't it breaking the ABI?
> >>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>> Yep, you're right, forgot to add that. I didn't expect this to get
> >>>>>> merged in 18.02 anyway, so v2 will follow.
> >>>>>
> >>>>> Please write 18.05 in the subject to show your expectation.
> >>>>> Thanks
> >>>>>
> >>>>
> >>>> Does it have to be an ABI change though? We can put numa_node_count
> >>>> after pointer to mem_config, in which case it won't be an ABI break.
> >>>> Would that be better?
> >>>
> >>> Changing the size of a struct which is allocated by the app,
> >>> is an ABI break.
> >>> Is your solution changing the size?
> >>>
> >>
> >> It's not really allocated as such. rte_config is a global static
> >> variable, and we only ever get pointers to it from the user code. If we
> >> add the new value at the end, all of the old data layout would be intact
> >> and work as before, so nothing would change as far as old code is concerned.
> >>
> >> However, if that's still considered an ABI break, then OK, break it is.
> >
> > Maybe that assuming it is never allocated (not copied for instance)
> > we could consider it is not an ABI break.
> >
> >> Some background for why this is needed - for the memory hotplug, we need
> >> to know how many sockets we can allocate memory at, to distinguish
> >> between socket that doesn't exist, and socket that exists but has no
> >> memory allocated on it. I'm OK with trying other approaches (such as
> >> storing numa nodes in a static variable somewhere) if breaking ABI for
> >> this is too much to ask for such a minute change.
> >
> > Why is it important for 18.02?
> > Memory hotplug will be integrated only in 18.05.
> > I think it is better to just wait (and announce the deprecation).
> >
>
> It isn't, i've already marked this patch as deferred. However, we'll
> have to have this discussion anyway :)
To be on the safe side, you announce a deprecation.
And there will be no debate in 18.05 (except if someone has a better idea).
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/2] lib/cryptodev: add support to set session private data
@ 2018-01-17 9:46 4% ` De Lara Guarch, Pablo
2018-01-17 10:05 0% ` Gujjar, Abhinandan S
0 siblings, 1 reply; 200+ results
From: De Lara Guarch, Pablo @ 2018-01-17 9:46 UTC (permalink / raw)
To: Gujjar, Abhinandan S, Akhil Goyal, Doherty, Declan, Jacob, Jerin
Cc: dev, Vangati, Narender, Rao, Nikhil
Hi Abhinandan,
> -----Original Message-----
> From: Gujjar, Abhinandan S
> Sent: Wednesday, January 17, 2018 6:35 AM
> To: Akhil Goyal <akhil.goyal@nxp.com>; Doherty, Declan
> <declan.doherty@intel.com>; De Lara Guarch, Pablo
> <pablo.de.lara.guarch@intel.com>; Jacob, Jerin
> <Jerin.JacobKollanukkaran@cavium.com>
> Cc: dev@dpdk.org; Vangati, Narender <narender.vangati@intel.com>; Rao,
> Nikhil <nikhil.rao@intel.com>
> Subject: RE: [PATCH 1/2] lib/cryptodev: add support to set session private
> data
>
> Hi Akhil,
>
...
> I guess, you are suggesting below changes:
> diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> b/lib/librte_cryptodev/rte_cryptodev.h
> index 56958a6..057c39a 100644
> --- a/lib/librte_cryptodev/rte_cryptodev.h
> +++ b/lib/librte_cryptodev/rte_cryptodev.h
> @@ -892,6 +892,8 @@ struct rte_cryptodev_data {
>
> /** Cryptodev symmetric crypto session */ struct
> rte_cryptodev_sym_session {
> + uint16_t private_data_offset;
> + /**< Private data offset */
> __extension__ void *sess_private_data[0];
> /**< Private session material */ }; I am ok with this.
>
> Declan/Pablo,
> Is this ok? Do you see any impact on performance or anything else has to be
> considered?
This is breaking ABI, and since there is a zero length array, this latter has to be at the end of the structure.
Therefore, this is not a valid option unless ABI deprecation is announced and then it could be merged in the next release.
Pablo
^ permalink raw reply [relevance 4%]
* Re: [dpdk-dev] [PATCH 1/2] lib/cryptodev: add support to set session private data
2018-01-17 9:46 4% ` De Lara Guarch, Pablo
@ 2018-01-17 10:05 0% ` Gujjar, Abhinandan S
2018-01-17 10:52 0% ` Akhil Goyal
0 siblings, 1 reply; 200+ results
From: Gujjar, Abhinandan S @ 2018-01-17 10:05 UTC (permalink / raw)
To: De Lara Guarch, Pablo, Akhil Goyal, Doherty, Declan, Jacob, Jerin
Cc: dev, Vangati, Narender, Rao, Nikhil
Hi Akhil,
> -----Original Message-----
> From: De Lara Guarch, Pablo
> Sent: Wednesday, January 17, 2018 3:16 PM
> To: Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>; Akhil Goyal
> <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>; Jacob,
> Jerin <Jerin.JacobKollanukkaran@cavium.com>
> Cc: dev@dpdk.org; Vangati, Narender <narender.vangati@intel.com>; Rao,
> Nikhil <nikhil.rao@intel.com>
> Subject: RE: [PATCH 1/2] lib/cryptodev: add support to set session private data
>
> Hi Abhinandan,
>
> > -----Original Message-----
> > From: Gujjar, Abhinandan S
> > Sent: Wednesday, January 17, 2018 6:35 AM
> > To: Akhil Goyal <akhil.goyal@nxp.com>; Doherty, Declan
> > <declan.doherty@intel.com>; De Lara Guarch, Pablo
> > <pablo.de.lara.guarch@intel.com>; Jacob, Jerin
> > <Jerin.JacobKollanukkaran@cavium.com>
> > Cc: dev@dpdk.org; Vangati, Narender <narender.vangati@intel.com>; Rao,
> > Nikhil <nikhil.rao@intel.com>
> > Subject: RE: [PATCH 1/2] lib/cryptodev: add support to set session
> > private data
> >
> > Hi Akhil,
> >
>
> ...
>
> > I guess, you are suggesting below changes:
> > diff --git a/lib/librte_cryptodev/rte_cryptodev.h
> > b/lib/librte_cryptodev/rte_cryptodev.h
> > index 56958a6..057c39a 100644
> > --- a/lib/librte_cryptodev/rte_cryptodev.h
> > +++ b/lib/librte_cryptodev/rte_cryptodev.h
> > @@ -892,6 +892,8 @@ struct rte_cryptodev_data {
> >
> > /** Cryptodev symmetric crypto session */ struct
> > rte_cryptodev_sym_session {
> > + uint16_t private_data_offset;
> > + /**< Private data offset */
> > __extension__ void *sess_private_data[0];
> > /**< Private session material */ }; I am ok with this.
> >
> > Declan/Pablo,
> > Is this ok? Do you see any impact on performance or anything else has
> > to be considered?
>
> This is breaking ABI, and since there is a zero length array, this latter has to be at
> the end of the structure.
> Therefore, this is not a valid option unless ABI deprecation is announced and
> then it could be merged in the next release.
What is your opinion on this?
Should we consider retaining the enum rte_crypto_op_private_data_type?
>
> Pablo
Abhinandan
^ permalink raw reply [relevance 0%]
* Re: [dpdk-dev] [PATCH 1/2] lib/cryptodev: add support to set session private data
2018-01-17 10:05 0% ` Gujjar, Abhinandan S
@ 2018-01-17 10:52 0% ` Akhil Goyal
0 siblings, 0 replies; 200+ results
From: Akhil Goyal @ 2018-01-17 10:52 UTC (permalink / raw)
To: Gujjar, Abhinandan S, De Lara Guarch, Pablo, Doherty, Declan,
Jacob, Jerin
Cc: dev, Vangati, Narender, Rao, Nikhil
Hi Abhinandan,
On 1/17/2018 3:35 PM, Gujjar, Abhinandan S wrote:
> Hi Akhil,
>
>> -----Original Message-----
>> From: De Lara Guarch, Pablo
>> Sent: Wednesday, January 17, 2018 3:16 PM
>> To: Gujjar, Abhinandan S <abhinandan.gujjar@intel.com>; Akhil Goyal
>> <akhil.goyal@nxp.com>; Doherty, Declan <declan.doherty@intel.com>; Jacob,
>> Jerin <Jerin.JacobKollanukkaran@cavium.com>
>> Cc: dev@dpdk.org; Vangati, Narender <narender.vangati@intel.com>; Rao,
>> Nikhil <nikhil.rao@intel.com>
>> Subject: RE: [PATCH 1/2] lib/cryptodev: add support to set session private data
>>
>> Hi Abhinandan,
>>
>>> -----Original Message-----
>>> From: Gujjar, Abhinandan S
>>> Sent: Wednesday, January 17, 2018 6:35 AM
>>> To: Akhil Goyal <akhil.goyal@nxp.com>; Doherty, Declan
>>> <declan.doherty@intel.com>; De Lara Guarch, Pablo
>>> <pablo.de.lara.guarch@intel.com>; Jacob, Jerin
>>> <Jerin.JacobKollanukkaran@cavium.com>
>>> Cc: dev@dpdk.org; Vangati, Narender <narender.vangati@intel.com>; Rao,
>>> Nikhil <nikhil.rao@intel.com>
>>> Subject: RE: [PATCH 1/2] lib/cryptodev: add support to set session
>>> private data
>>>
>>> Hi Akhil,
>>>
>>
>> ...
>>
>>> I guess, you are suggesting below changes:
>>> diff --git a/lib/librte_cryptodev/rte_cryptodev.h
>>> b/lib/librte_cryptodev/rte_cryptodev.h
>>> index 56958a6..057c39a 100644
>>> --- a/lib/librte_cryptodev/rte_cryptodev.h
>>> +++ b/lib/librte_cryptodev/rte_cryptodev.h
>>> @@ -892,6 +892,8 @@ struct rte_cryptodev_data {
>>>
>>> /** Cryptodev symmetric crypto session */ struct
>>> rte_cryptodev_sym_session {
>>> + uint16_t private_data_offset;
>>> + /**< Private data offset */
>>> __extension__ void *sess_private_data[0];
>>> /**< Private session material */ }; I am ok with this.
>>>
>>> Declan/Pablo,
>>> Is this ok? Do you see any impact on performance or anything else has
>>> to be considered?
>>
>> This is breaking ABI, and since there is a zero length array, this latter has to be at
>> the end of the structure.
>> Therefore, this is not a valid option unless ABI deprecation is announced and
>> then it could be merged in the next release.
> What is your opinion on this?
> Should we consider retaining the enum rte_crypto_op_private_data_type?
As per our previous discussion we are anyway pushing crypto adapter to
next release, then we do have time for the deprecation notice to be sent.
Or you can reserve the first byte of private data (internal to library)
in the session to check whether the private data is valid or not.
IMO, private data offset in session is a better approach instead of
adding one more enum. Others can suggest.
-Akhil
>>
>> Pablo
> Abhinandan
>
^ permalink raw reply [relevance 0%]
Results 3601-3800 of ~18000 next (newer) | prev (older) | reverse | sort options + mbox downloads above
-- links below jump to the message on this page --
2017-07-04 12:22 [dpdk-dev] [PATCH 0/2] Multiple Pktmbuf mempool support Hemant Agrawal
2017-12-15 10:24 ` [dpdk-dev] [PATCH 0/2] Dynamic HW Mempool Detection Support Hemant Agrawal
2017-12-15 10:24 ` [dpdk-dev] [PATCH 1/2] mbuf: update default Mempool ops with HW active pool Hemant Agrawal
2017-12-18 8:55 ` Jerin Jacob
2017-12-18 9:36 ` Hemant Agrawal
2017-12-22 14:59 ` Olivier MATZ
2017-12-28 12:07 3% ` Hemant Agrawal
2018-01-10 12:49 0% ` Hemant Agrawal
2018-01-15 6:11 ` [dpdk-dev] [PATCH v2 0/5] Dynamic HW Mempool Detection Support Hemant Agrawal
2018-01-15 6:11 ` [dpdk-dev] [PATCH v2 2/5] eal: add platform mempool ops name in internal config Hemant Agrawal
2018-01-15 12:24 3% ` Jerin Jacob
2018-01-15 14:31 3% ` Hemant Agrawal
2018-01-15 16:26 3% ` Jerin Jacob
2018-01-16 15:04 0% ` Olivier Matz
2018-01-16 15:08 0% ` Jerin Jacob
2018-01-15 6:11 10% ` [dpdk-dev] [PATCH v2 5/5] mbuf: add user command line config mempools ops API Hemant Agrawal
2018-01-15 12:29 0% ` Jerin Jacob
2018-01-15 14:35 0% ` Hemant Agrawal
2018-01-15 16:23 0% ` Jerin Jacob
2017-08-23 11:36 [dpdk-dev] [PATCH 1/4] meter: add meter configuration profile Cristian Dumitrescu
2017-12-12 9:53 ` [dpdk-dev] [PATCH v2 0/4] meter: add meter configuration profile api Jasvinder Singh
2017-12-12 9:53 2% ` [dpdk-dev] [PATCH v2 1/4] lib/librte_meter: add meter configuration profile Jasvinder Singh
2018-01-08 10:00 ` [dpdk-dev] [PATCH v3] meter: add meter configuration profile api Jasvinder Singh
2018-01-08 10:00 1% ` [dpdk-dev] [PATCH v3] lib/librte_meter: add meter configuration profile Jasvinder Singh
2018-01-08 15:43 1% ` [dpdk-dev] [PATCH v4] " Jasvinder Singh
2017-08-25 16:07 [dpdk-dev] [PATCH 0/6] devargs cleanup Gaetan Rivet
2017-10-12 8:21 ` [dpdk-dev] [PATCH v2 00/18] " Gaetan Rivet
2017-10-12 8:21 ` [dpdk-dev] [PATCH v2 18/18] doc: remove devargs deprecation notices Gaetan Rivet
2017-12-13 10:17 0% ` Shreyansh Jain
2017-12-13 10:25 0% ` Gaëtan Rivet
2017-12-13 10:54 0% ` Shreyansh Jain
2017-09-11 13:39 [dpdk-dev] [PATCH] doc: announce ABI change for ring structure Olivier Matz
2017-12-08 14:14 4% ` Olivier MATZ
2017-12-08 17:01 7% ` Thomas Monjalon
2017-10-12 8:18 [dpdk-dev] [PATCH v1 0/8] Bus control framework Gaetan Rivet
2017-10-12 8:18 ` [dpdk-dev] [PATCH v1 2/8] bus: introduce opaque " Gaetan Rivet
2017-12-11 12:00 0% ` Shreyansh Jain
2017-12-11 12:43 4% ` Gaëtan Rivet
2017-12-11 13:36 4% ` Shreyansh Jain
2017-12-11 14:38 4% ` Gaëtan Rivet
2017-12-12 7:21 0% ` Shreyansh Jain
2017-12-11 11:53 3% ` [dpdk-dev] [PATCH v1 0/8] Bus " Shreyansh Jain
2017-11-09 6:54 [dpdk-dev] [RFC] eventdev: add crypto adapter API header Abhinandan Gujjar
2017-11-29 11:41 ` Jerin Jacob
2017-12-13 23:35 ` Eads, Gage
2017-12-14 2:49 ` Jerin Jacob
2017-12-14 18:52 ` Eads, Gage
2017-12-18 6:30 4% ` Jerin Jacob
2017-12-18 16:33 3% ` Eads, Gage
2017-12-19 8:47 0% ` Jerin Jacob
2017-11-09 13:43 [dpdk-dev] [RFC] cmdline: rework as a wrapper to libedit Adrien Mazarguil
2017-11-15 4:12 ` Wiles, Keith
2017-11-15 8:04 ` Olivier MATZ
2017-11-15 16:31 0% ` Wiles, Keith
2017-11-16 9:23 0% ` Adrien Mazarguil
2017-11-16 16:48 0% ` Wiles, Keith
2017-11-16 16:53 0% ` Jim Thompson
2017-11-14 15:37 [dpdk-dev] [PATCH v2] examples/ipsec-secgw: fix usage of incorrect port Anoob Joseph
2017-11-15 9:41 ` [dpdk-dev] [PATCH v3] " Anoob Joseph
2017-11-24 9:28 ` Akhil Goyal
2017-11-24 9:58 ` Anoob
2017-11-24 10:49 ` Akhil Goyal
2017-11-29 4:21 ` Anoob Joseph
2017-12-04 7:49 ` Akhil Goyal
2017-12-06 11:08 3% ` Anoob
2017-12-11 10:26 0% ` Radu Nicolau
2017-12-11 10:38 0% ` Anoob Joseph
2017-11-15 15:45 [dpdk-dev] [PATCH 0/3] enable echo when CLI loading from file Xueming Li
2017-11-15 15:45 ` [dpdk-dev] [PATCH 1/3] lib/cmdline: add echo support in batch " Xueming Li
2017-12-19 10:30 3% ` Olivier MATZ
2017-12-19 11:20 0% ` Xueming(Steven) Li
2017-11-17 17:10 1% [dpdk-dev] [PATCH] virtio: add new driver for crypto devices Jay Zhou
2017-11-17 22:41 6% [dpdk-dev] [PATCH v1] doc: add template release notes for 18.02 John McNamara
2017-11-22 17:38 6% ` [dpdk-dev] [PATCH v2] " John McNamara
2017-11-20 8:21 3% [dpdk-dev] [PATCH 0/2] ethdev: add GENEVE to flow API Andrew Rybchenko
2017-11-20 8:22 ` [dpdk-dev] [PATCH 1/2] ethdev: add GENEVE flow pattern item Andrew Rybchenko
2017-11-23 9:39 3% ` Adrien Mazarguil
2017-11-20 8:22 ` [dpdk-dev] [PATCH 2/2] app/testpmd: support GENEVE pattern item in flow rules Andrew Rybchenko
2017-11-23 9:40 3% ` Adrien Mazarguil
2017-11-23 9:39 4% ` [dpdk-dev] [PATCH 0/2] ethdev: add GENEVE to flow API Adrien Mazarguil
2017-11-23 10:07 0% ` Andrew Rybchenko
2017-12-01 10:43 3% ` [dpdk-dev] [PATCH v2 " Andrew Rybchenko
2017-11-20 10:31 [dpdk-dev] [PATCH 0/2] add inline protocol support Anoob Joseph
2017-11-22 6:55 ` [dpdk-dev] [PATCH v2 " Anoob Joseph
2017-11-22 6:55 ` [dpdk-dev] [PATCH v2 1/2] lib/security: add support for get metadata Anoob Joseph
2017-11-22 13:27 3% ` Neil Horman
2017-11-22 14:13 0% ` Anoob
2017-11-27 13:55 0% ` Neil Horman
2017-11-22 8:10 [dpdk-dev] [PATCH 1/3] security: fix device operation type Nelio Laranjeiro
2017-11-22 8:10 ` [dpdk-dev] [PATCH 2/3] crypto: fix pedentic compilation errors Nelio Laranjeiro
2017-11-22 13:56 3% ` Neil Horman
2017-11-22 14:31 0% ` Gaëtan Rivet
2017-11-22 16:50 0% ` De Lara Guarch, Pablo
2017-11-23 12:02 [dpdk-dev] [PATCH 0/6] convert mlx PMDs to new ethdev offloads API Shahaf Shuler
2018-01-03 7:16 ` [dpdk-dev] [PATCH v2 0/7] " Shahaf Shuler
2018-01-03 7:16 ` [dpdk-dev] [PATCH v2 6/7] net/mlx4: convert to new Tx " Shahaf Shuler
2018-01-03 17:29 ` Adrien Mazarguil
2018-01-04 11:55 ` Shahaf Shuler
2018-01-09 10:35 3% ` Nelio Laranjeiro
2017-11-24 16:06 4% [dpdk-dev] [RFC PATCH 0/6] mempool: add bucket mempool driver Andrew Rybchenko
2017-12-14 13:36 3% ` Olivier MATZ
2017-11-27 12:21 2% [dpdk-dev] 17.08.1 patches review and test Yuanhan Liu
2017-11-30 19:09 0% ` Patil, Harish
2017-12-04 20:40 0% ` Patil, Harish
2017-12-07 13:46 0% ` Yuanhan Liu
2017-11-27 12:29 6% [dpdk-dev] [PATCH] ethdev: increase flow type limit from 32 to 64 Kirill Rybalchenko
2017-12-04 17:43 ` Adrien Mazarguil
2018-01-09 15:16 3% ` Rybalchenko, Kirill
2018-01-10 13:50 3% ` Thomas Monjalon
2018-01-16 11:13 0% ` Adrien Mazarguil
2018-01-16 17:23 0% ` Rybalchenko, Kirill
2018-01-16 18:03 0% ` Adrien Mazarguil
2018-01-15 16:58 7% ` [dpdk-dev] [PATCH v2] " Kirill Rybalchenko
2018-01-15 17:33 7% ` [dpdk-dev] [PATCH v3] " Kirill Rybalchenko
2018-01-15 21:27 3% ` Thomas Monjalon
2018-01-16 9:44 0% ` Rybalchenko, Kirill
2018-01-16 9:47 3% ` Thomas Monjalon
2018-01-16 10:31 0% ` Rybalchenko, Kirill
2018-01-16 10:38 0% ` Thomas Monjalon
2017-11-28 11:57 [dpdk-dev] [PATCH 0/5] ethdev: Port ownership Matan Azrad
2017-11-28 11:57 ` [dpdk-dev] [PATCH 2/5] ethdev: add port ownership Matan Azrad
2017-11-30 12:36 ` Neil Horman
2017-11-30 13:24 ` Gaëtan Rivet
2017-11-30 14:30 3% ` Matan Azrad
2017-11-30 15:09 3% ` Gaëtan Rivet
2017-11-30 15:43 3% ` Matan Azrad
2017-11-28 22:13 [dpdk-dev] [PATCH] ethdev: add notifications for probing and removal Thomas Monjalon
2018-01-02 11:35 ` [dpdk-dev] [PATCH v3 1/5] ethdev: remove useless parameter in callback process Iremonger, Bernard
2018-01-02 12:21 ` Neil Horman
2018-01-03 8:17 3% ` Thomas Monjalon
2017-11-30 8:01 1% [dpdk-dev] [RFC 1/2] net/tap: add eBPF to TAP device Ophir Munk
2017-11-30 8:01 1% ` [dpdk-dev] [RFC 2/2] net/tap: add eBPF instructions Ophir Munk
2017-12-05 7:53 0% ` [dpdk-dev] [RFC 1/2] net/tap: add eBPF to TAP device Pascal Mazon
2017-11-30 11:46 [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Hemant Agrawal
2017-11-30 11:46 ` [dpdk-dev] [PATCH 2/3] kni: add support for promisc mode set Hemant Agrawal
2017-12-22 21:57 3% ` Ferruh Yigit
2017-11-30 11:46 ` [dpdk-dev] [PATCH 3/3] kni: set initial value for MTU Hemant Agrawal
2017-12-22 22:01 4% ` Ferruh Yigit
2017-12-22 21:55 3% ` [dpdk-dev] [PATCH 1/3] kni: support for MAC addr change Ferruh Yigit
2017-12-26 10:08 0% ` Hemant Agrawal
2017-12-26 10:36 2% ` [dpdk-dev] [PATCH v2 " Hemant Agrawal
2017-12-26 10:36 3% ` [dpdk-dev] [PATCH v2 2/3] kni: add support for promisc mode set Hemant Agrawal
2017-12-26 10:36 3% ` [dpdk-dev] [PATCH v2 3/3] kni: set initial value for MTU Hemant Agrawal
2017-12-01 2:29 [dpdk-dev] [PATCH 1/7] ethdev: remove unused flag from header Ferruh Yigit
2017-12-01 2:29 ` [dpdk-dev] [PATCH 7/7] ethdev: use opaque user callback object Ferruh Yigit
2017-12-01 10:33 ` Bruce Richardson
2017-12-01 11:22 ` Ananyev, Konstantin
2017-12-01 13:17 ` Bruce Richardson
2017-12-01 23:51 ` Ferruh Yigit
2017-12-04 10:31 3% ` Bruce Richardson
2017-12-04 17:49 0% ` Ferruh Yigit
2017-12-01 14:47 4% [dpdk-dev] [RFC PATCH 0/3] *** SUBJECT HERE *** Konstantin Ananyev
2017-12-01 14:48 19% ` [dpdk-dev] [RFC PATCH 3/3] doc: ethdev ABI change deprecation notice Konstantin Ananyev
2017-12-12 14:55 4% ` Kovacevic, Marko
2017-12-01 14:56 0% ` [dpdk-dev] [RFC PATCH 0/3] *** SUBJECT HERE *** Ananyev, Konstantin
2017-12-01 14:55 4% [dpdk-dev] [RFC PATCH 0/3] ethdev: few changes in rte_ethdev layer Konstantin Ananyev
2017-12-14 4:54 0% ` Jerin Jacob
2017-12-14 13:57 3% ` Ananyev, Konstantin
2017-12-18 16:38 0% ` Jerin Jacob
2017-12-19 15:27 0% ` Ananyev, Konstantin
2017-12-20 7:28 ` Jerin Jacob
2017-12-20 18:23 3% ` Ananyev, Konstantin
2018-01-04 9:22 0% ` Jerin Jacob
2018-01-15 16:29 0% ` Ananyev, Konstantin
2017-12-01 18:56 4% [dpdk-dev] [PATCH 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
2017-12-01 18:56 5% ` [dpdk-dev] [PATCH 2/4] compat: Add __experimental macro Neil Horman
2017-12-08 17:14 4% ` [dpdk-dev] [PATCHv2 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
2017-12-08 17:14 5% ` [dpdk-dev] [PATCHv2 2/4] compat: Add __experimental macro Neil Horman
2017-12-11 19:36 4% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Neil Horman
2017-12-11 19:36 5% ` [dpdk-dev] [PATCHv3 2/4] compat: Add __experimental macro Neil Horman
2017-12-12 14:07 0% ` [dpdk-dev] [PATCHv3 0/4] dpdk: enhance EXPERIMENTAL api tagging Bruce Richardson
2017-12-30 17:15 0% ` Neil Horman
2018-01-04 12:56 0% ` Neil Horman
2017-12-12 14:33 0% ` Mcnamara, John
2017-12-12 20:18 0% ` Neil Horman
2017-12-12 15:11 3% ` Wiles, Keith
2017-12-12 20:14 0% ` Neil Horman
2017-12-13 15:17 4% ` [dpdk-dev] [PATCHv4 " Neil Horman
2017-12-13 15:17 5% ` [dpdk-dev] [PATCHv4 2/5] compat: Add __experimental macro Neil Horman
2017-12-13 15:17 ` [dpdk-dev] [PATCHv4 4/5] dpdk: add __experimental tag to appropriate api calls Neil Horman
2018-01-11 20:06 ` Ferruh Yigit
2018-01-11 21:24 5% ` Neil Horman
2018-01-12 11:50 0% ` Ferruh Yigit
2018-01-12 14:25 3% ` Neil Horman
2018-01-12 15:53 0% ` Ferruh Yigit
2017-12-13 15:17 10% ` [dpdk-dev] [PATCHv4 5/5] doc: Add ABI __experimental tag documentation Neil Horman
2017-12-13 15:32 4% ` Bruce Richardson
2018-01-11 20:06 4% ` Ferruh Yigit
2018-01-11 21:29 4% ` Neil Horman
2018-01-12 11:50 7% ` Ferruh Yigit
2018-01-12 14:37 4% ` Neil Horman
2018-01-12 15:55 4% ` Ferruh Yigit
2018-01-13 0:28 4% ` Neil Horman
2018-01-13 15:56 4% ` Thomas Monjalon
2018-01-14 14:36 4% ` Neil Horman
2018-01-14 16:27 4% ` Thomas Monjalon
2017-12-13 15:32 0% ` [dpdk-dev] [PATCHv4 0/4] dpdk: enhance EXPERIMENTAL api tagging Bruce Richardson
2017-12-21 14:21 0% ` Neil Horman
2017-12-30 19:20 0% ` Luca Boccassi
2017-12-31 1:57 0% ` Neil Horman
2017-12-04 15:55 8% [dpdk-dev] [PATCH] relicense various bits of the dpdk Neil Horman
2017-12-05 10:44 0% ` Hemant Agrawal
2017-12-07 15:47 1% [dpdk-dev] [dpdk-announce] DPDK 17.08.1 released Yuanhan Liu
2017-12-10 5:35 [dpdk-dev] Guidelines for moving PMDs to new ethdev offloads API Shahaf Shuler
2017-12-10 5:52 3% ` Stephen Hemminger
2017-12-10 6:04 0% ` Shahaf Shuler
2017-12-12 10:05 [dpdk-dev] [PATCH 1/3] ethdev: add max burst size to device info Nikhil Agarwal
2017-12-12 10:45 ` Matan Azrad
2017-12-12 11:03 3% ` Ananyev, Konstantin
2017-12-12 13:43 0% ` Shreyansh Jain
2017-12-13 12:52 0% ` Ananyev, Konstantin
2017-12-13 15:22 3% ` Shreyansh Jain
2017-12-14 17:15 [dpdk-dev] [PATCH] ethdev: fix setting of MAC address Olivier Matz
2017-12-18 10:35 ` Andrew Rybchenko
2017-12-18 10:53 ` Igor Ryzhov
2017-12-18 11:38 ` Andrew Rybchenko
2017-12-19 9:29 ` Olivier MATZ
2017-12-19 9:47 ` Andrew Rybchenko
2017-12-20 10:00 ` Andrew Rybchenko
2018-01-03 13:43 3% ` Olivier Matz
2018-01-03 13:54 0% ` Olivier Matz
2018-01-03 14:12 4% ` Andrew Rybchenko
2018-01-08 11:59 3% ` Ferruh Yigit
2018-01-08 14:23 0% ` Olivier Matz
2017-12-15 10:20 4% [dpdk-dev] [PATCH] doc: announce ABI change for pktmbuf pool create API Hemant Agrawal
2017-12-15 10:41 4% ` [dpdk-dev] [PATCH v2] " Hemant Agrawal
2017-12-18 8:58 4% ` Jerin Jacob
2017-12-18 13:51 8% ` Wiles, Keith
2017-12-18 14:43 4% ` Neil Horman
2017-12-19 5:40 4% ` Hemant Agrawal
2017-12-19 13:41 4% ` Wiles, Keith
2017-12-22 15:26 4% ` Olivier MATZ
2017-12-15 12:29 3% [dpdk-dev] Inline/look-aside transformation API (Crypto, IPsec, VLAN insertion, Compression, ...) Nelio Laranjeiro
2017-12-21 12:59 [dpdk-dev] [PATCH v1 0/6] Address various issues with exported headers Adrien Mazarguil
2017-12-21 13:00 ` [dpdk-dev] [PATCH v1 6/6] net: fix rte_ether conflicts with libc Adrien Mazarguil
2017-12-22 13:34 ` Olivier MATZ
2017-12-22 14:25 3% ` Adrien Mazarguil
2018-01-16 13:04 0% ` Olivier Matz
2017-12-22 11:30 3% [dpdk-dev] [PATCH] mbuf: pktmbuf pool create helper for specific mempool ops Hemant Agrawal
2017-12-22 13:53 0% ` Wiles, Keith
2017-12-22 11:58 [dpdk-dev] [PATCH] eal: add function to return number of detected sockets Anatoly Burakov
2017-12-22 12:41 ` [dpdk-dev] [PATCH v2] " Anatoly Burakov
2018-01-11 22:20 3% ` Thomas Monjalon
2018-01-12 11:44 0% ` Burakov, Anatoly
2018-01-12 11:50 0% ` Thomas Monjalon
2018-01-16 11:56 4% ` Burakov, Anatoly
2018-01-16 12:20 3% ` Thomas Monjalon
2018-01-16 15:05 4% ` Burakov, Anatoly
2018-01-16 17:34 3% ` Thomas Monjalon
2018-01-16 17:38 0% ` Burakov, Anatoly
2018-01-16 18:26 0% ` Thomas Monjalon
2018-01-16 17:53 17% ` [dpdk-dev] [PATCH] doc: add ABI change notice for numa_node_count in eal Anatoly Burakov
2018-01-02 9:31 [dpdk-dev] [PATCH v2 0/2] vhost: introduce rte_vhost_vring_call() Stefan Hajnoczi
2018-01-02 10:27 ` Maxime Coquelin
[not found] ` <20180102181141.GC22252@stefanha-x1.localdomain>
2018-01-03 8:17 0% ` Maxime Coquelin
2018-01-08 13:46 0% ` Yuanhan Liu
2018-01-03 18:43 [dpdk-dev] [PATCH 0/1] eal: return true or false from lcore role check function Erik Gabriel Carrillo
2018-01-03 18:43 ` [dpdk-dev] [PATCH 1/1] " Erik Gabriel Carrillo
2018-01-09 16:44 4% ` Aaron Conole
2018-01-11 23:09 4% ` Carrillo, Erik G
2018-01-11 23:17 3% ` Thomas Monjalon
2018-01-12 18:01 0% ` Carrillo, Erik G
2018-01-12 18:04 0% ` Thomas Monjalon
2018-01-04 23:48 3% [dpdk-dev] [PATCH] MAINTAINERS fix style Stephen Hemminger
2018-01-08 13:08 [dpdk-dev] Napatech pmd Finn Christensen
2018-01-08 15:15 ` Thomas Monjalon
2018-01-08 15:31 3% ` Stephen Hemminger
2018-01-10 3:30 [dpdk-dev] [PATCH V8 3/3] app/testpmd: use uevent to monitor hotplug Jeff Guo
2018-01-10 9:12 ` [dpdk-dev] [PATCH V9 0/5] add uevent mechanism in eal framework Jeff Guo
2018-01-10 9:12 ` [dpdk-dev] [PATCH V9 1/5] eal: add uevent monitor api and callback func Jeff Guo
2018-01-11 1:43 4% ` Thomas Monjalon
2018-01-11 14:24 0% ` Guo, Jia
2018-01-11 14:47 11% [dpdk-dev] [PATCH] doc: ethdev ABI change deprecation notice Kirill Rybalchenko
2018-01-12 10:19 4% ` Kovacevic, Marko
2018-01-12 10:27 11% ` [dpdk-dev] [PATCH v2] " Kirill Rybalchenko
2018-01-12 10:29 11% ` [dpdk-dev] [PATCH v3] " Kirill Rybalchenko
2018-01-12 14:38 4% ` Neil Horman
2018-01-12 20:45 3% [dpdk-dev] [PATCH 1/1] doc: announce API change to lcore role function Erik Gabriel Carrillo
2018-01-12 21:01 [dpdk-dev] [PATCH 1/3] app/testpmd: Moved cmdline_flow to librte_cmdline Georgios Katsikas
2018-01-15 1:30 ` Lu, Wenzhuo
2018-01-16 8:39 ` Olivier Matz
2018-01-16 8:45 ` george.dit
2018-01-16 9:24 ` Olivier Matz
2018-01-16 14:31 3% ` Adrien Mazarguil
2018-01-16 14:54 0% ` george.dit
2018-01-16 17:54 0% ` Adrien Mazarguil
2018-01-15 11:51 [dpdk-dev] [PATCH 1/2] lib/cryptodev: add support to set session private data Abhinandan Gujjar
2018-01-15 12:18 ` Akhil Goyal
2018-01-16 6:09 ` Gujjar, Abhinandan S
2018-01-16 6:24 ` Akhil Goyal
2018-01-16 7:05 ` Gujjar, Abhinandan S
2018-01-16 7:26 ` Akhil Goyal
2018-01-16 9:03 ` Gujjar, Abhinandan S
2018-01-16 9:21 ` Akhil Goyal
2018-01-16 11:36 ` Gujjar, Abhinandan S
2018-01-16 12:00 ` Akhil Goyal
2018-01-16 12:29 ` Gujjar, Abhinandan S
2018-01-16 13:02 ` Akhil Goyal
2018-01-17 6:35 ` Gujjar, Abhinandan S
2018-01-17 9:46 4% ` De Lara Guarch, Pablo
2018-01-17 10:05 0% ` Gujjar, Abhinandan S
2018-01-17 10:52 0% ` Akhil Goyal
2018-01-15 19:05 4% [dpdk-dev] [PATCH] checkpatches.sh: Add checks for ABI symbol addition Neil Horman
2018-01-15 21:52 7% ` Thomas Monjalon
2018-01-16 0:37 4% ` Neil Horman
2018-01-15 22:20 4% ` Stephen Hemminger
2018-01-16 0:36 4% ` Neil Horman
2018-01-16 18:22 3% ` [dpdk-dev] [PATCH v2] " Neil Horman
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).