RE: [PATCH v2] dts: Change hugepage runtime config to 2MB Exclusively

2024-04-10 Thread Morten Brørup
> From: Nicholas Pratte [mailto:npra...@iol.unh.edu]
> Sent: Tuesday, 9 April 2024 19.28
> 
> The previous implementation configures and allocates hugepage sizes
> based on a system default. This can lead to two problems: overallocation of
> hugepages (which may crash the remote host), and configuration of hugepage
> sizes that are not recommended during runtime. This new implementation
> allows only 2MB hugepage allocation during runtime; any other unique
> hugepage size must be configured by the end-user for initializing DTS.
> 
> If the amount of 2MB hugepages requested exceeds the amount of 2MB
> hugepages already configured on the system, then the system will remount
> hugepages to cover the difference. If the amount of hugepages requested is
> either less than or equal to the amount already configured on the system,
> then nothing is done.
> 
> Bugzilla ID: 1370
> Signed-off-by: Nicholas Pratte 
> Reviewed-by: Jeremy Spewock 
> ---
>  dts/conf.yaml|  4 ++--
>  dts/framework/config/__init__.py |  4 ++--
>  dts/framework/config/conf_yaml_schema.json   |  6 +++---
>  dts/framework/config/types.py|  2 +-
>  dts/framework/testbed_model/linux_session.py | 15 ++-
>  5 files changed, 14 insertions(+), 17 deletions(-)
> 
> diff --git a/dts/conf.yaml b/dts/conf.yaml
> index 8068345dd5..56c3ae6f4c 100644
> --- a/dts/conf.yaml
> +++ b/dts/conf.yaml
> @@ -35,7 +35,7 @@ nodes:
>  lcores: "" # use all the available logical cores
>  use_first_core: false # tells DPDK to use any physical core
>  memory_channels: 4 # tells DPDK to use 4 memory channels
> -hugepages:  # optional; if removed, will use system hugepage
> configuration
> +hugepages_2mb: # optional; if removed, will use system hugepage
> configuration
>  amount: 256
>  force_first_numa: false
>  ports:
> @@ -71,7 +71,7 @@ nodes:
>  os_driver: rdma
>  peer_node: "SUT 1"
>  peer_pci: ":00:08.1"
> -hugepages:  # optional; if removed, will use system hugepage
> configuration
> +hugepages_2mb: # optional; if removed, will use system hugepage
> configuration
>  amount: 256
>  force_first_numa: false
>  traffic_generator:
> diff --git a/dts/framework/config/__init__.py
> b/dts/framework/config/__init__.py
> index 4cb5c74059..b6f820e39e 100644
> --- a/dts/framework/config/__init__.py
> +++ b/dts/framework/config/__init__.py
> @@ -255,8 +255,8 @@ def from_dict(
>  Either an SUT or TG configuration instance.
>  """
>  hugepage_config = None
> -if "hugepages" in d:
> -hugepage_config_dict = d["hugepages"]
> +if "hugepages_2mb" in d:
> +hugepage_config_dict = d["hugepages_2mb"]
>  if "force_first_numa" not in hugepage_config_dict:
>  hugepage_config_dict["force_first_numa"] = False
>  hugepage_config = HugepageConfiguration(**hugepage_config_dict)
> diff --git a/dts/framework/config/conf_yaml_schema.json
> b/dts/framework/config/conf_yaml_schema.json
> index 4731f4511d..f4d7199523 100644
> --- a/dts/framework/config/conf_yaml_schema.json
> +++ b/dts/framework/config/conf_yaml_schema.json
> @@ -146,7 +146,7 @@
>  "compiler"
>]
>  },
> -"hugepages": {
> +"hugepages_2mb": {
>"type": "object",
>"description": "Optional hugepage configuration. If not specified,
> hugepages won't be configured and DTS will use system configuration.",
>"properties": {
> @@ -253,8 +253,8 @@
>  "type": "integer",
>  "description": "How many memory channels to use. Optional,
> defaults to 1."
>},
> -  "hugepages": {
> -"$ref": "#/definitions/hugepages"
> +  "hugepages_2mb": {
> +"$ref": "#/definitions/hugepages_2mb"
>},
>"ports": {
>  "type": "array",
> diff --git a/dts/framework/config/types.py b/dts/framework/config/types.py
> index 1927910d88..016e0c3dbd 100644
> --- a/dts/framework/config/types.py
> +++ b/dts/framework/config/types.py
> @@ -46,7 +46,7 @@ class NodeConfigDict(TypedDict):
>  """Allowed keys and values."""
> 
>  #:
> -hugepages: HugepageConfigurationDict
> +hugepages_2mb: HugepageConfigurationDict
>  #:
>  name: str
>  #:
> diff --git a/dts/framework/testbed_model/linux_session.py
> b/dts/framework/testbed_model/linux_session.py
> index 5d24030c3d..37f5eacb21 100644
> --- a/dts/framework/testbed_model/linux_session.py
> +++ b/dts/framework/testbed_model/linux_session.py
> @@ -15,7 +15,7 @@
> 
>  from typing_extensions import NotRequired
> 
> -from framework.exception import RemoteCommandExecutionError
> +from framework.exception import ConfigurationError,
> RemoteCommandExecutionError
>  from framework.utils import expand_range
> 
>  from .cpu import LogicalCore
> @@ -87,25 +87,22 @@ def get_dpdk_file_prefix(self, dpdk

Re: [PATCH 0/4] RFC samples converting VLA to alloca

2024-04-10 Thread Mattias Rönnblom

On 2024-04-08 17:27, Tyler Retzlaff wrote:

For next technboard meeting.

On Sun, Apr 07, 2024 at 10:03:06AM -0700, Stephen Hemminger wrote:

On Sun, 7 Apr 2024 13:07:06 +0200
Morten Brørup  wrote:


From: Mattias Rönnblom [mailto:hof...@lysator.liu.se]
Sent: Sunday, 7 April 2024 11.32

On 2024-04-04 19:15, Tyler Retzlaff wrote:

This series is not intended for merge.  It insteat provides examples

of

converting use of VLAs to alloca() would look like.

what's the advantages of VLA over alloca()?

* sizeof(array) works as expected.

* multi-dimensional arrays are still arrays instead of pointers to
dynamically allocated space. this means multiple subscript syntax
works (unlike on a pointer) and calculation of addresses into

allocated

space in ascending order is performed by the compiler instead of

manually.
  


alloca() is a pretty obscure mechanism, and also not a part of the C
standard. VLAs are C99, and well-known and understood, and very
efficient.


The RFC fails to mention why we need to replace VLAs with something else:

VLAs are C99, but not C++; VLAs were made optional in C11.

MSVC doesn't support VLAs, and is not going to:
https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/#variable-length-arrays


I dislike alloca() too, and the notes section in the alloca(3) man page even 
discourages the use of alloca():
https://man7.org/linux/man-pages/man3/alloca.3.html

But I guess alloca() is the simplest replacement for VLAs.
This RFC patch series opens the discussion for alternatives in different use 
cases.



The other issue with VLA's is that if the number is something that can be 
externally
input, then it can be a source of stack overflow bugs. That is why the Linux 
kernel
has stopped using them; for security reasons. DPDK has much less of a security
trust domain. Mostly need to make sure that no data from network is being
used to compute VLA size.



Looks like we need to discuss this at the next techboard meeting.

* MSVC doesn't support C11 optional VLAs (and never will).


This is due to dogmatism, or what? Surely, a lot of Open Source projects 
written for C99 will use VLAs.



* alloca() is an alternative that is available on all platforms/toolchain
   combinations.


alloca() is a poor alternative. The use of alloca() should be restricted 
to situations where statically sized arrays can't do the job.



* it's reasonable for some VLAs to be turned into regular arrays but it
   would be unsatisfactory to be stuck waiting discussions of defining new
   constant expression macros on a per-use basis.
* there is resistance to using alloca() vs VLA so my proposal is to
   change only the code that is built to target windows.


Re: [PATCH 0/4] RFC samples converting VLA to alloca

2024-04-10 Thread Mattias Rönnblom

On 2024-04-08 17:53, Morten Brørup wrote:

From: Tyler Retzlaff [mailto:roret...@linux.microsoft.com]
Sent: Monday, 8 April 2024 17.27

For next technboard meeting.

On Sun, Apr 07, 2024 at 10:03:06AM -0700, Stephen Hemminger wrote:

On Sun, 7 Apr 2024 13:07:06 +0200
Morten Brørup  wrote:


From: Mattias Rönnblom [mailto:hof...@lysator.liu.se]
Sent: Sunday, 7 April 2024 11.32

On 2024-04-04 19:15, Tyler Retzlaff wrote:

This series is not intended for merge.  It insteat provides examples

of

converting use of VLAs to alloca() would look like.

what's the advantages of VLA over alloca()?

* sizeof(array) works as expected.

* multi-dimensional arrays are still arrays instead of pointers to
dynamically allocated space. this means multiple subscript syntax
works (unlike on a pointer) and calculation of addresses into

allocated

space in ascending order is performed by the compiler instead of

manually.




alloca() is a pretty obscure mechanism, and also not a part of the C
standard. VLAs are C99, and well-known and understood, and very
efficient.


The RFC fails to mention why we need to replace VLAs with something else:

VLAs are C99, but not C++; VLAs were made optional in C11.

MSVC doesn't support VLAs, and is not going to:
https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-

arriving-in-msvc/#variable-length-arrays



I dislike alloca() too, and the notes section in the alloca(3) man page

even discourages the use of alloca():

https://man7.org/linux/man-pages/man3/alloca.3.html

But I guess alloca() is the simplest replacement for VLAs.
This RFC patch series opens the discussion for alternatives in different

use cases.




The other issue with VLA's is that if the number is something that can be

externally

input, then it can be a source of stack overflow bugs. That is why the Linux

kernel

has stopped using them; for security reasons. DPDK has much less of a

security

trust domain. Mostly need to make sure that no data from network is being
used to compute VLA size.



Looks like we need to discuss this at the next techboard meeting.

* MSVC doesn't support C11 optional VLAs (and never will).
* alloca() is an alternative that is available on all platforms/toolchain
   combinations.
* it's reasonable for some VLAs to be turned into regular arrays but it
   would be unsatisfactory to be stuck waiting discussions of defining new
   constant expression macros on a per-use basis.


We must generally stop using VLAs, for many reasons.


What reasons would that be? And which of those reasons are not also 
reasons to stop using alloca().



The only available 1:1 replacement is alloca(), so we have to accept that.

If anyone still cares about improvements, we can turn alloca()'d arrays into 
regular arrays after this patch series.

Alternatives to VLAs are very interesting discussions, but let's not stall MSVC 
progress because of it!



What is this supposed to mean? Finding alternatives to VLAs are required 
to make progress of MSVC support in DPDK.



* there is resistance to using alloca() vs VLA so my proposal is to
   change only the code that is built to target windows.


I would prefer to get rid of them all, so the CI can build with -Wvla to 
prevent them from being introduced again.
Not a strong preference.
On the other hand, the CI's MSVC builds will catch them if used for a Windows 
target.
And limiting to Windows code reduces the amount of work, so that's probably the 
most realistic solution.



Re: [PATCH 6/6] dts: add statefulness to TestPmdShell

2024-04-10 Thread Juraj Linkeš
On Thu, Mar 28, 2024 at 5:49 PM Jeremy Spewock  wrote:
>
> On Tue, Mar 26, 2024 at 3:04 PM Luca Vizzarro  wrote:
> >
> > This commit provides a state container for TestPmdShell. It currently
> > only indicates whether the packet forwarding has started
> > or not, and the number of ports which were given to the shell.
> >
> > This also fixes the behaviour of `wait_link_status_up` to use the
> > command timeout as inherited from InteractiveShell.
> >
> > Signed-off-by: Luca Vizzarro 
> > Reviewed-by: Jack Bond-Preston 
> > Reviewed-by: Honnappa Nagarahalli 
> > ---
> 
> > @@ -723,7 +731,13 @@ def _start_application(self, get_privileged_command: 
> > Callable[[str], str] | None
> >  if self._app_args.app_params is None:
> >  self._app_args.app_params = TestPmdParameters()
> >
> > -self.number_of_ports = len(self._app_args.ports) if 
> > self._app_args.ports is not None else 0
> > +assert isinstance(self._app_args.app_params, TestPmdParameters)
> > +
>
> This is tricky because ideally we wouldn't have the assertion here,
> but I understand why it is needed because Eal parameters have app args
> which can be any instance of params. I'm not sure of the best way to
> solve this, because making testpmd parameters extend from eal would
> break the general scheme that you have in place, and having an
> extension of EalParameters that enforces this app_args is
> TestPmdParameters would solve the issues, but might be a little
> clunky. Is there a way we can use a generic to get python to just
> understand that, in this case, this will always be TestPmdParameters?
> If not I might prefer making a private class where this is
> TestPmdParameters, just because there aren't really any other
> assertions that we use elsewhere and an unexpected exception from this
> (even though I don't think that can happen) could cause people some
> issues.
>
> It might be the case that an assertion is the easiest way to deal with
> it though, what do you think?
>

We could change the signature (just the type of app_args) of the init
method - I think we should be able to create a type that's
EalParameters with .app_params being TestPmdParameters or None. The
init method would just call super().

Something like the above is basically necessary with inheritance where
subclasses are all extensions (not just implementations) of the
superclass (having differences in API).

> > +if self._app_args.app_params.auto_start:
> > +self.state.packet_forwarding_started = True
> > +
> > +if self._app_args.ports is not None:
> > +self.state.number_of_ports = len(self._app_args.ports)
> >
> >  super()._start_application(get_privileged_command)
> >
> 
> > 2.34.1
> >


Re: [PATCH 6/6] dts: add statefulness to TestPmdShell

2024-04-10 Thread Juraj Linkeš
On Tue, Mar 26, 2024 at 8:04 PM Luca Vizzarro  wrote:
>
> This commit provides a state container for TestPmdShell. It currently
> only indicates whether the packet forwarding has started
> or not, and the number of ports which were given to the shell.
>

A reminder, the commit message should explain why we're doing this
change, not what the change is.

> This also fixes the behaviour of `wait_link_status_up` to use the
> command timeout as inherited from InteractiveShell.
>
> Signed-off-by: Luca Vizzarro 
> Reviewed-by: Jack Bond-Preston 
> Reviewed-by: Honnappa Nagarahalli 
> ---
>  dts/framework/remote_session/testpmd_shell.py | 41 +--
>  1 file changed, 28 insertions(+), 13 deletions(-)
>
> diff --git a/dts/framework/remote_session/testpmd_shell.py 
> b/dts/framework/remote_session/testpmd_shell.py
> index a823dc53be..ea1d254f86 100644
> --- a/dts/framework/remote_session/testpmd_shell.py
> +++ b/dts/framework/remote_session/testpmd_shell.py
> @@ -678,19 +678,27 @@ def __str__(self) -> str:
>  return self.pci_address
>
>
> +@dataclass(slots=True)
> +class TestPmdState:
> +"""Session state container."""
> +
> +#:
> +packet_forwarding_started: bool = False

The same question as in the previous patch, do you anticipate this
being needed and should we add this only when it's actually used?

> +
> +#: The number of ports which were allowed on the command-line when 
> testpmd was started.
> +number_of_ports: int = 0
> +
> +
>  class TestPmdShell(InteractiveShell):
>  """Testpmd interactive shell.
>
>  The testpmd shell users should never use
>  the :meth:`~.interactive_shell.InteractiveShell.send_command` method 
> directly, but rather
>  call specialized methods. If there isn't one that satisfies a need, it 
> should be added.
> -
> -Attributes:
> -number_of_ports: The number of ports which were allowed on the 
> command-line when testpmd
> -was started.
>  """
>
> -number_of_ports: int
> +#: Current state
> +state: TestPmdState = TestPmdState()

Assigning a value makes this a class variable, shared across all
instances. This should be initialized in __init__().

But do we actually want to do this via composition? We'd need to
access the attributes via .state all the time and I don't really like
that. We could just put them into TestPmdShell directly, initializing
them in __init__().

>
>  #: The path to the testpmd executable.
>  path: ClassVar[PurePath] = PurePath("app", "dpdk-testpmd")


RE: [PATCH 0/4] RFC samples converting VLA to alloca

2024-04-10 Thread Morten Brørup
> From: Mattias Rönnblom [mailto:hof...@lysator.liu.se]
> Sent: Wednesday, 10 April 2024 09.32
> 
> On 2024-04-08 17:53, Morten Brørup wrote:
> >> From: Tyler Retzlaff [mailto:roret...@linux.microsoft.com]
> >> Sent: Monday, 8 April 2024 17.27
> >>

[...]

> >> Looks like we need to discuss this at the next techboard meeting.
> >>
> >> * MSVC doesn't support C11 optional VLAs (and never will).
> >> * alloca() is an alternative that is available on all platforms/toolchain
> >>combinations.
> >> * it's reasonable for some VLAs to be turned into regular arrays but it
> >>would be unsatisfactory to be stuck waiting discussions of defining new
> >>constant expression macros on a per-use basis.
> >
> > We must generally stop using VLAs, for many reasons.
> 
> What reasons would that be? And which of those reasons are not also
> reasons to stop using alloca().

The reasons against VLAs are the same as why MSVC doesn’t support them; 
primarily that they are insecure.

The reasons against VLAs and alloca() are the same, except MSVC supports 
alloca().

> 
> > The only available 1:1 replacement is alloca(), so we have to accept that.
> >
> > If anyone still cares about improvements, we can turn alloca()'d arrays into
> regular arrays after this patch series.
> >
> > Alternatives to VLAs are very interesting discussions, but let's not stall
> MSVC progress because of it!
> >
> 
> What is this supposed to mean? Finding alternatives to VLAs are required
> to make progress of MSVC support in DPDK.

It means that not enough people contribute to discussing and implementing 
alternatives, so we have to use the 1:1 replacement alternative, alloca(), to 
avoid stalling DPDK support for MSVC.

We can discuss and implement alternatives at any time, if anybody cares.

> 
> >> * there is resistance to using alloca() vs VLA so my proposal is to
> >>change only the code that is built to target windows.
> >
> > I would prefer to get rid of them all, so the CI can build with -Wvla to
> prevent them from being introduced again.
> > Not a strong preference.
> > On the other hand, the CI's MSVC builds will catch them if used for a
> Windows target.
> > And limiting to Windows code reduces the amount of work, so that's probably
> the most realistic solution.
> >


Re: [PATCH 1/6] dts: add parameters data structure

2024-04-10 Thread Juraj Linkeš
On Tue, Apr 9, 2024 at 6:28 PM Luca Vizzarro  wrote:
>
> Thank you so much for your review Juraj!
>

You're welcome!

> >> +
> >> +def value_only(metadata: dict[str, Any] = {}) -> dict[str, Any]:
> >> +"""Injects the value of the attribute as-is without flag. Metadata 
> >> modifier for :func:`dataclasses.field`."""
> >> +return {**metadata, META_VALUE_ONLY: True}
> >
> > These methods, on the other hand, are used outside this module, so it
> > makes sense to have them outside Params. It could be better to have
> > them inside as static methods, as they're closely related. Looking at
> > how they're used, we should unite the imports:
> > 1. In testpmd_shell, they're imported directly (from framework.params
> > import long)
> > 2. In sut_node, just the params module is imported (from framework
> > import params and then accessed via it: metadata=params.short("l"))
> >
> Having a shorter version may look less verbose. I agree that we can make
> everything a static method of Params, but then having to do Params.short
> etc everytime will make it look more verbose. So what option do we
> prefer? The functions do belong to the params module nonetheless, and
> therefore are meant to be used in conjunction with the Params class.
>

When I first saw the code, I liked the usage in sut_node better, e.g.:
prefix: str = field(metadata=params.long("file-prefix")). I think this
is because it's obvious where the function comes from. I'd do the
longer version because I think most people are just going to glance at
the code when they want to know how to properly implement an argument
so the explicit nature could help with understanding how it should be
done.

> > If we move these to Params, we could import Params and use them
> > similarly to 2. Not sure which one is better.
> >
>
>
> >> +def field_mixins(*mixins: Mixin, metadata: dict[str, Any] = {}) -> 
> >> dict[str, Any]:
> >
> > Any reason why mixins are plural? I've only seen this used with one
> > argument, do you anticipate we'd need to use more than one? We could
> > make this singular and if we ever need to do two things, we could just
> > pass a function that does those two things (or calls two different
> > functions). Also, I'd just rename the mixin the func or something like
> > that.
> >
> > The default of an argument should not be mutable, here's a quick
> > explanation: 
> > https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
>
>
> Indeed the reason for which I create dictionaries, as I am treating them
> as read only. I wanted to avoid to bloat the code with lots of `is None`
> checks. But we can sacrifice this optimization for better code.
>

This would be the only place where we'd do the check, as I don't think
we need the metadata argument in any of the other functions - those
seem to be mutually exclusive, but maybe they're not? In any case,
we'd need to fix this, I don't think treating them as read-only avoids
the problem.

> > I don't really like the name. The positional arguments are applied to
> > the value and that should be reflected in the name - I'd like to see
> > something like convert in the name.
>
> What this does is effectively just add the mixins to dataclass.field
> metadata, hence "field"_mixins. This is meant to represent a chain of
> mixins, in my original code this appeared more often. Not so much in
> this post, as I made more optimisations. Which takes me to the plural
> bit, for testpmd specifically this plurality appears only when
> decorating another class using `str_mixins`, see TestPmdRingNUMAConfig.
> So for consistency I kept both to ingest a chain of "mixins", as maybe
> it'll be needed in the future.
>
> Are you suggesting to just make the name as singular? But still take
> multiple function pointers?

Singular with one function, as that was what I saw being used. The one
function could do multiple things (or call multiple other functions)
if a need arises. The str_mixins could be used this way as well.

I don't know which one is better, maybe keeping the plural is fine.

> The term "mixin" specifically just means a
> middleware that manipulates the output value when using __str__.

Aren't all of the other functions mixins as well, at least in some
sense? They change the option, not the value, but could still be
thought of as mixins in some respect.

> Here we
> are just chaining them for reusability. Do you have any better name in mind?
>

I don't know, so let's brainstorm a bit. Let's start with the usage:
portmask: int | None = field(default=None, metadata=field_mixins(hex))

Here it's not clear at all why it's called field_mixins, at least
compared to the other functions which are not called mixins. I guess
the other functions are predefined option mixins whereas we're
supplying our own value mixins here. I also noticed that there's a bit
of an inconsistency with the naming. The basic functions (long etc.)
don't have the "field_" prefix, but this one does. Maybe a better name
would be cus

Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread fengchengwen
Hi All,

We have a problem introduced by a compiler upgrade (from gcc10 to gcc12.3), 
we've done some
research but haven't been able to figure out why. We'd like the community's 
help.

Environment:
1. Source: DPDK 23.11
2. GCC: 12.3.1 [1]
3. Compiled with target kunpeng SoC (ARM64)
4. Run on kunpeng SoC


Problem & Debug:
1. We found the hns3 driver fails to update the link status. The corresponding 
function is
hns3_update_linkstatus_and_event [2], and we found the rte_eth_linkstatus_set 
[3] always return zero.
2. After disassembly the hns3_update_linkstatus_and_event, and found 
rte_eth_linkstatus_set's
rte_atomic_exchange_explicit return to xzr register (which is zero register):
 1239fec:   3900f3e0strbw0, [sp, #60]
 1239ff0:   9101a041add x1, x2, #0x68  ---x2 seem not the 
variable new_link
 1239ff4:   f8ff8022swpal   xzr, x2, [x1]  ---this instr 
corresponding rte_atomic_exchange_explicit,
  it will place the 
resut in xzr which always zero,
  and this will 
lead to rte_eth_linkstatus_set return 0.
 1239ff8:   3940f3e0ldrbw0, [sp, #60]
 1239ffc:   d3609c41ubfxx1, x2, #32, #8
 123a000:   4a01eor w0, w0, w1
 123a004:   36100080tbz w0, #2, 123a014 

3. We checked other "ret = rte_eth_linkstatus_set" calls, and can't find 
similar problem.
4. After reading a lot of documents, we preliminarily think that the problem is 
caused by -fstrict-aliasing
(which was enabled default with O2 or O3), if compiled with 
-fno-strict-aliasing, then this problem don't
exist. We guest this maybe strict-aliasing's bug which only happened in our 
function.
5. We also try to use union to avoid such aliasing in rte_eth_linkstatus_set, 
we changed the struct
rte_eth_link define, and it works:
  -__extension__
  -struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64 read/write 
*/
  -   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_ */
  -   uint16_t link_duplex  : 1;  /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
  -   uint16_t link_autoneg : 1;  /**< RTE_ETH_LINK_[AUTONEG/FIXED] */
  -   uint16_t link_status  : 1;  /**< RTE_ETH_LINK_[DOWN/UP] */
  +struct rte_eth_link { /**< aligned for atomic64 read/write */
  +   union {
  +   uint64_t val64;
  +   struct {
  +   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_ */
  +   uint16_t link_duplex  : 1;  /**< 
RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
  +   uint16_t link_autoneg : 1;  /**< 
RTE_ETH_LINK_[AUTONEG/FIXED] */
  +   uint16_t link_status  : 1;  /**< 
RTE_ETH_LINK_[DOWN/UP] */
  +   };
  +   };
  };
the corresponding rte_eth_linkstatus_set:
  @@ -1674,18 +1674,13 @@ static inline int
   rte_eth_linkstatus_set(struct rte_eth_dev *dev,
 const struct rte_eth_link *new_link)
   {
  -   RTE_ATOMIC(uint64_t) *dev_link = (uint64_t __rte_atomic 
*)&(dev->data->dev_link);
  -   union {
  -   uint64_t val64;
  -   struct rte_eth_link link;
  -   } orig;
  -
  -   RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
  +   struct rte_eth_link old_link;

  -   orig.val64 = rte_atomic_exchange_explicit(dev_link, *(const uint64_t 
*)new_link,
  +   old_link.val64 = 
rte_atomic_exchange_explicit(&dev->data->dev_link.val64,
  +   new_link->val64,
  rte_memory_order_seq_cst);

  -   return (orig.link.link_status == new_link->link_status) ? -1 : 0;
  +   return (old_link.link_status == new_link->link_status) ? -1 : 0;
   }
6. BTW: the linux kernel enabled "-fno-strict-aliasing" default, please see [4] 
for more.


Last: We think there are two ways to solve this problem.
1. Add the compilation option '-fno-strict-aliasing' for hold DPDK project.
2. Use union to avoid such aliasing in rte_eth_linkstatus_set (please see 
above).
PS: We prefer first way.

Hope for more discuess.

Thanks


[1] https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads/12-3-rel1
[2] void
hns3_update_linkstatus_and_event(struct hns3_hw *hw, bool query)
{
struct rte_eth_dev *dev = &rte_eth_devices[hw->data->port_id];
struct rte_eth_link new_link;
int ret;

if (query)
hns3_update_port_link_info(dev);

memset(&new_link, 0, sizeof(new_link));
hns3_setup_linkstatus(dev, &new_link);

ret = rte_eth_linkstatus_set(dev, &new_link);
if (ret == 0 && dev->data->dev_conf.intr_conf.lsc != 0)
hns3_start_report_lse(dev);
}
[3] static inline int
rte_eth_linkstatus_set(struct rte_eth_dev *dev,
   const struct rte_eth_link *new_link)
{
RTE_ATOMIC(uint64_t) *dev_l

Re: [PATCH 2/6] dts: use Params for interactive shells

2024-04-10 Thread Luca Vizzarro

On 09/04/2024 15:56, Juraj Linkeš wrote:

On Thu, Mar 28, 2024 at 5:48 PM Jeremy Spewock  wrote:


I'm not sure if allowing None should be the solution for these shells
as opposed to just supplying an empty parameter object. Maybe
something that could be done is the factory method in sut_node allows
it to be None, but when it comes time to make the abstract shell it
creates an empty one if it doesn't exist, or the init method makes
this an optional parameter but creates it if it doesn't exist.

I suppose this logic would have to exist somewhere because the
parameters aren't always required, it's just a question of where we
should put it and if we should just assume that the interactive shell
class just knows how to accept some parameters and put them into the
shell. I would maybe leave this as something that cannot be None and
handle it outside of the shell, but I'm not sure it's something really
required and I don't have a super strong opinion on it.



I think this is an excellent idea. An empty Params (or StrParams or
EalParams if we want to make Params truly abstract and thus not
instantiable) would work as the default value and it would be an
elegant solution since dev will only pass non-empty Params.



I left it as generic as it could get as I honestly couldn't grasp the 
full picture. I am really keen to ditch everything else and use an empty 
Params object instead for defaults. And as Juraj said, if I am making 
Params a true abstract object, then it'd be picking one of the Params 
subclasses mentioned above.


I guess EalParams could only be used with shells are that sure to be 
DPDK apps, and I presume that's only TestPmdShell for now.



+from framework.testbed_model.sut_node import EalParameters
+
+assert isinstance(self._app_args, EalParameters)
+
+if isinstance(self._app_args.app_params, StrParams):
+self._app_args.app_params.value += " -i --mask-event intr_lsc"
+
+self.number_of_ports = len(self._app_args.ports) if 
self._app_args.ports is not None else 0


I we should override the _app_args parameter in the testpmd shell to
always be EalParameters instead of doing this import and assertion.
It's a DPDK app, so we will always need EalParameters anyway, so we
might as well put that as our typehint to start off as what we expect
instead.

The checking of an instance of StrParams also feels a little strange
here, it might be more ideal if we could just add the parameters
without this check. Maybe something we can do, just because these
parameters are meant to be CLI commands anyway and will be rendered as
a string, is replace the StrParams object with a method on the base
Params dataclass that allows you to just add any string as a value
only field. Then, we don't have to bother validating anything about
the app parameters and we don't care what they are, we can just add a
string to them of new parameters.

I think this is something that likely also gets solved when you
replace this with testpmd parameters, but it might be a good way to
make the Params object more versatile in general so that people can
diverge and add their own flags to it if needed.


Jeremy, I agree this is not ideal. Although this was meant only to be 
transitionary for the next commit (as you say it gets resolved with 
TestPmdParams). But I agree with you that we can integrate the StrParams 
facility within Params. This means no longer making Params a true 
abstract class though, which is something I can live with, especially if 
we can make it simpler.



I'd say this is done because of circular imports. If so, we could move
EalParameters to params.py, that should help. And when we're at it,
either rename it to EalParams or rename the other classes to use the
whole word.


Yeah, the circular imports are the main problem indeed. I considered 
refactoring but noticed it'd take more than just moving EalParam(eter)s 
to params.py. Nonetheless, keen to make a bigger refactoring to make 
this happen.

+
  super()._start_application(get_privileged_command)

  def start(self, verify: bool = True) -> None:

  

@@ -134,7 +136,7 @@ def create_interactive_shell(
  shell_cls: Type[InteractiveShellType],
  timeout: float,
  privileged: bool,
-app_args: str,
+app_args: Params | None,


This also falls in line with what I was saying before about where this
logic is handled. This was made to always be a string originally
because by this point it being optional was already handled by the
sut_node.create_interactive_shell() and we should have some kind of
value here (even if that value is an empty parameters dataclass) to
pass into the application. It sort of semantically doesn't really
change much, but at this point it might as well not be None, so we can
simplify this type.

Ack.

  ) -> InteractiveShellType:
  """Factory for interactive session handlers.




+@dataclass(kw_only=True)
+class EalParameters(Params):
  """The en

Re: [PATCH v2 1/3] dts: rework arguments framework

2024-04-10 Thread Juraj Linkeš
On Tue, Apr 9, 2024 at 5:14 PM Luca Vizzarro  wrote:
>
> On 04/04/2024 10:25, Juraj Linkeš wrote:
> > Judging from the code, this patch seems like a convoluted way to implement:
> > 1. An association between an Argument and the corresponding
> > environment variable,
> > 2. A better way to add the env vars names to the help message of each
> > argument as well as adding the current value if set,
> > 3. A better error message where we replace argument names with env var
> > names for args where env vars are used.
> >
> > But maybe there's more.
> >
> > In any case, isn't there a simpler way to implement the above? I
> > originally thought extending something in the argparse module (like
> > the add_argument methods in ArgumentParser and
> > _MutuallyExclusiveGroup), but that doesn't seem as simple as maybe
> > just augmenting the actions that are returned with the add_argument
> > methods (maybe we could subclass ArgumentParser and add some method
> > for this, such as add_dts_argument?), where we could just add the
> > env_var_name (and maybe arg_name if needed) and modify the help
> > message the same way we do now (modifying the self._action.help
> > attribute). This should also be enough for 3, but even if not, we
> > could store what we need in the subclass.
>
> I agree that the solutions appears somewhat convoluted, and I am indeed
> open to ideas on how to simplify the approach. I initially considered
> extending the argparse module, but as you said it's no particularly
> simple, and it wasn't written to be particularly extendable either. If
> we want to go down this route, it would be somewhat hacky. I am not
> against it though. But, yeah, in retrospective some things can be easily
> integrated.
>

Great, let's get a v2 and see where we end up.

> > Also, what seems to be missing is the modification of actual values of
> > SETTING with the env var values (this could be done somewhere in the
> > add_dts_argument method).
>
> I don't think I am following what you mean by this. If you refer to
> updating the values of `SETTING` with the environment ones, this is done
> using `inject_env_variable` before the arguments are parsed. In a few
> words, that method just injects the environment arguments in sys.argv.
> Therefore to the ArgumentParser it just looks like they were supplied on
> the command line.
>

My bad, I must've made a mistake when verifying this. It is working fine.

> > But overall I like this approach as it gives us the knowledge of
> > whether an env var was used or not. I have some comments that
> > illustrate why I think the patch is a bit convoluted.
> >
> 
> >
> > Looking at this, this class could've been just a subclassed dict. We
> > could set the attributes with setattr in __init__(). But at that
> > point, it looks to be the same as the namespace returned by
> > parser.parse_args(), apart from the environment_fed_arguments property
> > (more below), which we could do without.
> >
>
> Yes, definitely. The main reason to store the namespaced values was in
> case this could turn out to be useful when debugging in the future. But
> if we think it's not worthwhile, it can reduce complexity.
>
> >
> > We're already storing the arguments in the class, so we could just add
> > whatever is in ArgumentEnvPair to the argument and we have the
> > correspondence (looking at the Argument class again, we already have
> > that). The pair class seems redundant.
> >
> >
> > And then we could get all of this from the stored arguments. Could be
> > just a tuple of (var_name, arg_name) of args with from_env == True.
> >
>
> And storing a pre-made list of environment-fed arguments. Yes, we could
> definitely walk through every argument as needed. Given the context and
> usage of this, I guess yeah, you are right in saying it's redundant.
> Happy to remove it.
>
> >
> > I think this should also contain the env var value to be consistent
> > with the help message.
> >
>
> Ack.
>
> >
> > We're going through all of the args here so we could just do this when
> > creating the argument. I guess we'd need to modify the top-level error
> > message afterwards with the current class structure, but I'm sure even
> > that could be done when creating the argument with some refactoring.
> >
>
> Yeah. I decided to do this separately to avoid duplicating the code for
> the mutual exclusion group (as per the next commit).
>
> >
> > The values attribute seems superfluous as we're only using it locally.
> >
>
> Ack.
>
> >
> > This is here so that we don't use both arguments from the mutual
> > group, right? We could add a short comment explaining this.
> > Also, I think we don't need to use vars() here, the result should be the 
> > same.
> >
>
> Yes, and any other argument we may want to add in the future that don't
> belong in SETTINGS. It's only selecting the arguments that already exist
> in SETTING and write values for that. Can add a comment.
>
> Namespace doesn't appear to implement iteration. As per the doc pag

Re: [PATCH 1/6] dts: add parameters data structure

2024-04-10 Thread Luca Vizzarro

On 10/04/2024 10:15, Juraj Linkeš wrote:

+
+def value_only(metadata: dict[str, Any] = {}) -> dict[str, Any]:
+"""Injects the value of the attribute as-is without flag. Metadata modifier for 
:func:`dataclasses.field`."""
+return {**metadata, META_VALUE_ONLY: True}


These methods, on the other hand, are used outside this module, so it
makes sense to have them outside Params. It could be better to have
them inside as static methods, as they're closely related. Looking at
how they're used, we should unite the imports:
1. In testpmd_shell, they're imported directly (from framework.params
import long)
2. In sut_node, just the params module is imported (from framework
import params and then accessed via it: metadata=params.short("l"))


Having a shorter version may look less verbose. I agree that we can make
everything a static method of Params, but then having to do Params.short
etc everytime will make it look more verbose. So what option do we
prefer? The functions do belong to the params module nonetheless, and
therefore are meant to be used in conjunction with the Params class.



When I first saw the code, I liked the usage in sut_node better, e.g.:
prefix: str = field(metadata=params.long("file-prefix")). I think this
is because it's obvious where the function comes from. I'd do the
longer version because I think most people are just going to glance at
the code when they want to know how to properly implement an argument
so the explicit nature could help with understanding how it should be
done.


Ack.


If we move these to Params, we could import Params and use them
similarly to 2. Not sure which one is better.





+def field_mixins(*mixins: Mixin, metadata: dict[str, Any] = {}) -> dict[str, 
Any]:


Any reason why mixins are plural? I've only seen this used with one
argument, do you anticipate we'd need to use more than one? We could
make this singular and if we ever need to do two things, we could just
pass a function that does those two things (or calls two different
functions). Also, I'd just rename the mixin the func or something like
that.

The default of an argument should not be mutable, here's a quick
explanation: 
https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments



Indeed the reason for which I create dictionaries, as I am treating them
as read only. I wanted to avoid to bloat the code with lots of `is None`
checks. But we can sacrifice this optimization for better code.



This would be the only place where we'd do the check, as I don't think
we need the metadata argument in any of the other functions - those
seem to be mutually exclusive, but maybe they're not? In any case,
we'd need to fix this, I don't think treating them as read-only avoids
the problem.



They are not mutually exclusive. But thinking of it we can spare every 
problem with having to chain "metadata" by letting the user do it 
through the use of the pipe operator.



Here we
are just chaining them for reusability. Do you have any better name in mind?



I don't know, so let's brainstorm a bit. Let's start with the usage:
portmask: int | None = field(default=None, metadata=field_mixins(hex))

Here it's not clear at all why it's called field_mixins, at least
compared to the other functions which are not called mixins. I guess
the other functions are predefined option mixins whereas we're
supplying our own value mixins here. I also noticed that there's a bit
of an inconsistency with the naming. The basic functions (long etc.)
don't have the "field_" prefix, but this one does. Maybe a better name
would be custom_mixins? Or value_mixins? Or custom_value? Or maybe
convert_value? I like the last one:
portmask: int | None = field(default=None, metadata=convert_value(hex))
metadata=params.convert_value(_port_to_pci,
metadata=params.multiple(params.short("a"))), # in sut_node

I think this is easier to grasp. I'm thinking about whether we need to
have mixin(s) in the name and I don't think it adds much. If I'm a
developer, I'm looking at these functions and I stumble upon
convert_value, what I'm thinking is "Nice, I can do some conversion on
the values I pass, how do I do that?", then I look at the signature
and find out that I expect, that is I need to pass a function (or
multiple function if I want to). I guess this comes down to the
function name (field_mixins) not conveying what it's doing, rather
what you're passing to it.

So my conclusion from this brainstorming is that a better name would
be convert_value. :-)

Also, unrelated, but the context is lost. Another thing I just noticed
is in the docstring:
The ``metadata`` keyword argument can be used to chain metadata
modifiers together.

We're missing the Args: section in all of the docstrings (where we
could put the above). Also the Returns: section.


Sure, we can do convert_value. I am honestly not too fussed about 
naming, and your proposal makes more sense. And as above, we can spare 
the whole metadata problem. Using your example:


  met

RE: [PATCH 0/4] RFC samples converting VLA to alloca

2024-04-10 Thread Konstantin Ananyev



> >
> > > > From: Tyler Retzlaff [mailto:roret...@linux.microsoft.com]
> > > > Sent: Monday, 8 April 2024 17.27
> > > >
> > > > For next technboard meeting.
> > > >
> > > > On Sun, Apr 07, 2024 at 10:03:06AM -0700, Stephen Hemminger wrote:
> > > > > On Sun, 7 Apr 2024 13:07:06 +0200
> > > > > Morten Brørup  wrote:
> > > > >
> > > > > > > From: Mattias Rönnblom [mailto:hof...@lysator.liu.se]
> > > > > > > Sent: Sunday, 7 April 2024 11.32
> > > > > > >
> > > > > > > On 2024-04-04 19:15, Tyler Retzlaff wrote:
> > > > > > > > This series is not intended for merge.  It insteat provides 
> > > > > > > > examples
> > > > > > > of
> > > > > > > > converting use of VLAs to alloca() would look like.
> > > > > > > >
> > > > > > > > what's the advantages of VLA over alloca()?
> > > > > > > >
> > > > > > > > * sizeof(array) works as expected.
> > > > > > > >
> > > > > > > > * multi-dimensional arrays are still arrays instead of pointers 
> > > > > > > > to
> > > > > > > >dynamically allocated space. this means multiple subscript 
> > > > > > > > syntax
> > > > > > > >works (unlike on a pointer) and calculation of addresses into
> > > > > > > allocated
> > > > > > > >space in ascending order is performed by the compiler 
> > > > > > > > instead of
> > > > > > > manually.
> > > > > > > >
> > > > > > >
> > > > > > > alloca() is a pretty obscure mechanism, and also not a part of 
> > > > > > > the C
> > > > > > > standard. VLAs are C99, and well-known and understood, and very
> > > > > > > efficient.
> > > > > >
> > > > > > The RFC fails to mention why we need to replace VLAs with something 
> > > > > > else:
> > > > > >
> > > > > > VLAs are C99, but not C++; VLAs were made optional in C11.
> > > > > >
> > > > > > MSVC doesn't support VLAs, and is not going to:
> > > > > > https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-
> > > > arriving-in-msvc/#variable-length-arrays
> > > > > >
> > > > > >
> > > > > > I dislike alloca() too, and the notes section in the alloca(3) man 
> > > > > > page
> > > > even discourages the use of alloca():
> > > > > > https://man7.org/linux/man-pages/man3/alloca.3.html
> > > > > >
> > > > > > But I guess alloca() is the simplest replacement for VLAs.
> > > > > > This RFC patch series opens the discussion for alternatives in 
> > > > > > different
> > > > use cases.
> > > > > >
> > > > >
> > > > > The other issue with VLA's is that if the number is something that 
> > > > > can be
> > > > externally
> > > > > input, then it can be a source of stack overflow bugs. That is why 
> > > > > the Linux
> > > > kernel
> > > > > has stopped using them; for security reasons. DPDK has much less of a
> > > > security
> > > > > trust domain. Mostly need to make sure that no data from network is 
> > > > > being
> > > > > used to compute VLA size.
> > > > >
> > > >
> > > > Looks like we need to discuss this at the next techboard meeting.
> > > >
> > > > * MSVC doesn't support C11 optional VLAs (and never will).
> > > > * alloca() is an alternative that is available on all 
> > > > platforms/toolchain
> > > >   combinations.
> > > > * it's reasonable for some VLAs to be turned into regular arrays but it
> > > >   would be unsatisfactory to be stuck waiting discussions of defining 
> > > > new
> > > >   constant expression macros on a per-use basis.
> > >
> > > We must generally stop using VLAs, for many reasons.
> > > The only available 1:1 replacement is alloca(), so we have to accept that.
> > >
> > > If anyone still cares about improvements, we can turn alloca()'d arrays 
> > > into regular arrays after this patch series.
> > >
> > > Alternatives to VLAs are very interesting discussions, but let's not 
> > > stall MSVC progress because of it!
> >
> > Ok, but why we have to rush into 'alloca()' solution if none of us really 
> > fond of it?
> 
> for the trivial case it is no worse than a VLA. while it isn't
> standardized it is available for all platform/toolchains unlike VLA.
> most of the code needed to be changed for windows falls into the trivial
> case when converted.

Personally, I think VLA is much more convenient then alloca().
At least you can do sizeof(vla_array) without a problem.

> 
> there do appear to be cases where VLAs have just been unintentional.
> i previously linked a patch where i fixed a case where they were
> instantiated inside a cast and there are other cases i'm aware of in the
> mlx5 driver where i believe they are unintended. at least with alloca
> it is obvious but with a VLA if the expression used to determine the
> size is wrapped up in something non-trivial and the author doesn't check
> that it is truly a constant expression you get one by surprise.
> 
> > As you already noted majority of these cases can be replaced with static 
> > sized arrays.
> 
> unfortunately i don't think this is the case if we are talking about the
> entire source tree.

Ok, probably I misunderstood this RFC intention:
My first thought that it was all you need to make

Re: [PATCH 2/6] dts: use Params for interactive shells

2024-04-10 Thread Juraj Linkeš
On Wed, Apr 10, 2024 at 11:34 AM Luca Vizzarro  wrote:
>
> On 09/04/2024 15:56, Juraj Linkeš wrote:
> > On Thu, Mar 28, 2024 at 5:48 PM Jeremy Spewock  wrote:
> >>
> >> I'm not sure if allowing None should be the solution for these shells
> >> as opposed to just supplying an empty parameter object. Maybe
> >> something that could be done is the factory method in sut_node allows
> >> it to be None, but when it comes time to make the abstract shell it
> >> creates an empty one if it doesn't exist, or the init method makes
> >> this an optional parameter but creates it if it doesn't exist.
> >>
> >> I suppose this logic would have to exist somewhere because the
> >> parameters aren't always required, it's just a question of where we
> >> should put it and if we should just assume that the interactive shell
> >> class just knows how to accept some parameters and put them into the
> >> shell. I would maybe leave this as something that cannot be None and
> >> handle it outside of the shell, but I'm not sure it's something really
> >> required and I don't have a super strong opinion on it.
> >>
> >
> > I think this is an excellent idea. An empty Params (or StrParams or
> > EalParams if we want to make Params truly abstract and thus not
> > instantiable) would work as the default value and it would be an
> > elegant solution since dev will only pass non-empty Params.
> >
>
> I left it as generic as it could get as I honestly couldn't grasp the
> full picture. I am really keen to ditch everything else and use an empty
> Params object instead for defaults. And as Juraj said, if I am making
> Params a true abstract object, then it'd be picking one of the Params
> subclasses mentioned above.
>
> I guess EalParams could only be used with shells are that sure to be
> DPDK apps, and I presume that's only TestPmdShell for now.
>
> >>> +from framework.testbed_model.sut_node import EalParameters
> >>> +
> >>> +assert isinstance(self._app_args, EalParameters)
> >>> +
> >>> +if isinstance(self._app_args.app_params, StrParams):
> >>> +self._app_args.app_params.value += " -i --mask-event 
> >>> intr_lsc"
> >>> +
> >>> +self.number_of_ports = len(self._app_args.ports) if 
> >>> self._app_args.ports is not None else 0
> >>
> >> I we should override the _app_args parameter in the testpmd shell to
> >> always be EalParameters instead of doing this import and assertion.
> >> It's a DPDK app, so we will always need EalParameters anyway, so we
> >> might as well put that as our typehint to start off as what we expect
> >> instead.
> >>
> >> The checking of an instance of StrParams also feels a little strange
> >> here, it might be more ideal if we could just add the parameters
> >> without this check. Maybe something we can do, just because these
> >> parameters are meant to be CLI commands anyway and will be rendered as
> >> a string, is replace the StrParams object with a method on the base
> >> Params dataclass that allows you to just add any string as a value
> >> only field. Then, we don't have to bother validating anything about
> >> the app parameters and we don't care what they are, we can just add a
> >> string to them of new parameters.
> >>
> >> I think this is something that likely also gets solved when you
> >> replace this with testpmd parameters, but it might be a good way to
> >> make the Params object more versatile in general so that people can
> >> diverge and add their own flags to it if needed.
>
> Jeremy, I agree this is not ideal. Although this was meant only to be
> transitionary for the next commit (as you say it gets resolved with
> TestPmdParams). But I agree with you that we can integrate the StrParams
> facility within Params. This means no longer making Params a true
> abstract class though, which is something I can live with, especially if
> we can make it simpler.
>

No problem with it not being a true abstract class if it's not going
to have abstract methods/properties. I guess making it instantiable
actually makes sense, since it's always going to be empty (as there
are no fields), which should make the usage mostly error-free.

> > I'd say this is done because of circular imports. If so, we could move
> > EalParameters to params.py, that should help. And when we're at it,
> > either rename it to EalParams or rename the other classes to use the
> > whole word.
>
> Yeah, the circular imports are the main problem indeed. I considered
> refactoring but noticed it'd take more than just moving EalParam(eter)s
> to params.py. Nonetheless, keen to make a bigger refactoring to make
> this happen.

Please do. My thinking was if we made params.py standalone we could
import from it anywhere but I guess it's not that simple. :-) In any
case, refactoring is always welcome - please put moved files into a
separate commit.

> >>> +
> >>>   super()._start_application(get_privileged_command)
> >>>
> >>>   def start(self, verify: bool = True) -> None:
> >>   
> >>>

Re: [PATCH 1/6] dts: add parameters data structure

2024-04-10 Thread Juraj Linkeš
On Wed, Apr 10, 2024 at 11:51 AM Luca Vizzarro  wrote:
>
> On 10/04/2024 10:15, Juraj Linkeš wrote:
>  +
>  +def value_only(metadata: dict[str, Any] = {}) -> dict[str, Any]:
>  +"""Injects the value of the attribute as-is without flag. Metadata 
>  modifier for :func:`dataclasses.field`."""
>  +return {**metadata, META_VALUE_ONLY: True}
> >>>
> >>> These methods, on the other hand, are used outside this module, so it
> >>> makes sense to have them outside Params. It could be better to have
> >>> them inside as static methods, as they're closely related. Looking at
> >>> how they're used, we should unite the imports:
> >>> 1. In testpmd_shell, they're imported directly (from framework.params
> >>> import long)
> >>> 2. In sut_node, just the params module is imported (from framework
> >>> import params and then accessed via it: metadata=params.short("l"))
> >>>
> >> Having a shorter version may look less verbose. I agree that we can make
> >> everything a static method of Params, but then having to do Params.short
> >> etc everytime will make it look more verbose. So what option do we
> >> prefer? The functions do belong to the params module nonetheless, and
> >> therefore are meant to be used in conjunction with the Params class.
> >>
> >
> > When I first saw the code, I liked the usage in sut_node better, e.g.:
> > prefix: str = field(metadata=params.long("file-prefix")). I think this
> > is because it's obvious where the function comes from. I'd do the
> > longer version because I think most people are just going to glance at
> > the code when they want to know how to properly implement an argument
> > so the explicit nature could help with understanding how it should be
> > done.
>
> Ack.
>
> >>> If we move these to Params, we could import Params and use them
> >>> similarly to 2. Not sure which one is better.
> >>>
> >>
> >>
>  +def field_mixins(*mixins: Mixin, metadata: dict[str, Any] = {}) -> 
>  dict[str, Any]:
> >>>
> >>> Any reason why mixins are plural? I've only seen this used with one
> >>> argument, do you anticipate we'd need to use more than one? We could
> >>> make this singular and if we ever need to do two things, we could just
> >>> pass a function that does those two things (or calls two different
> >>> functions). Also, I'd just rename the mixin the func or something like
> >>> that.
> >>>
> >>> The default of an argument should not be mutable, here's a quick
> >>> explanation: 
> >>> https://docs.python-guide.org/writing/gotchas/#mutable-default-arguments
> >>
> >>
> >> Indeed the reason for which I create dictionaries, as I am treating them
> >> as read only. I wanted to avoid to bloat the code with lots of `is None`
> >> checks. But we can sacrifice this optimization for better code.
> >>
> >
> > This would be the only place where we'd do the check, as I don't think
> > we need the metadata argument in any of the other functions - those
> > seem to be mutually exclusive, but maybe they're not? In any case,
> > we'd need to fix this, I don't think treating them as read-only avoids
> > the problem.
> >
>
> They are not mutually exclusive. But thinking of it we can spare every
> problem with having to chain "metadata" by letting the user do it
> through the use of the pipe operator.
>

Sounds good.

> >> Here we
> >> are just chaining them for reusability. Do you have any better name in 
> >> mind?
> >>
> >
> > I don't know, so let's brainstorm a bit. Let's start with the usage:
> > portmask: int | None = field(default=None, metadata=field_mixins(hex))
> >
> > Here it's not clear at all why it's called field_mixins, at least
> > compared to the other functions which are not called mixins. I guess
> > the other functions are predefined option mixins whereas we're
> > supplying our own value mixins here. I also noticed that there's a bit
> > of an inconsistency with the naming. The basic functions (long etc.)
> > don't have the "field_" prefix, but this one does. Maybe a better name
> > would be custom_mixins? Or value_mixins? Or custom_value? Or maybe
> > convert_value? I like the last one:
> > portmask: int | None = field(default=None, metadata=convert_value(hex))
> > metadata=params.convert_value(_port_to_pci,
> > metadata=params.multiple(params.short("a"))), # in sut_node
> >
> > I think this is easier to grasp. I'm thinking about whether we need to
> > have mixin(s) in the name and I don't think it adds much. If I'm a
> > developer, I'm looking at these functions and I stumble upon
> > convert_value, what I'm thinking is "Nice, I can do some conversion on
> > the values I pass, how do I do that?", then I look at the signature
> > and find out that I expect, that is I need to pass a function (or
> > multiple function if I want to). I guess this comes down to the
> > function name (field_mixins) not conveying what it's doing, rather
> > what you're passing to it.
> >
> > So my conclusion from this brainstorming is that a better name would
> > be conv

Re: [PATCH v1 1/2] dts: Improve output gathering in interactive shells

2024-04-10 Thread Juraj Linkeš
On Mon, Apr 8, 2024 at 6:20 PM Jeremy Spewock  wrote:
>
> On Wed, Apr 3, 2024 at 5:00 AM Juraj Linkeš  
> wrote:
> >
> > On Tue, Mar 12, 2024 at 6:26 PM  wrote:
> > >
> > > From: Jeremy Spewock 
> > >
> > > The current implementation of consuming output from interactive shells
> > > relies on being able to find an expected prompt somewhere within the
> > > output buffer after sending the command. This is useful in situations
> > > where the prompt does not appear in the output itself, but in some
> > > practical cases (such as the starting of an XML-RPC server for scapy)
> > > the prompt exists in one of the commands sent to the shell and this can
> > > cause the command to exit early and creates a race condition between the
> > > server starting and the first command being sent to the server.
> > >
> > > This patch addresses this problem by searching for a line that strictly
> > > ends with the provided prompt, rather than one that simply contains it,
> > > so that the detection that a command is finished is more consistent. It
> > > also adds a catch to detect when a command times out before finding the
> > > prompt so that the exception can be wrapped into a more explicit one and
> > > display the output that it did manage to gather before timing out.
> > >
> >
> > This could still cause problems if the prompt appears at the end of a
> > line in the output. Maybe we don't need to worry about that until we
> > actually hit that problem. In any case, I'd like to test this, so
> > please rebase the patch. :-)
>
> I will rebase and send out a v2, but that is a good point. it would be
> just as easy to instead check to see that the prompt is the only thing
> on the line, so we could do that instead, which do you think is
> better?

Would this work? I'm thinking we may need to send another extra
newline character to put the solitary prompt into the buffer if the
command output doesn't contain a newline.

> I'm sort of indifferent, I can see how verifying that the line
> only contains the prompt would be useful in cases like it appears in a
> docstring or something similar (and it's nice to be more explicit in
> general), and I think that leaving it as the end of the line could
> potentially save some verbosity if the line you are looking for is
> long so you can just detect the end of it. Another problem that I
> could think of with long lines potentially is if, somehow, you were
> looking for a prompt that the pseudo-terminal split across a few lines
> and it split your prompt, but I'm not sure this is really relevant to
> us at all since we only really expect prompts that are usually short.
>

If it works with checking just the end of the line let's leave it like
this (because of the possibility above). I think there shouldn't be
any prompts without something after them in docstrings.

> >
> 
> > > +try:
> > > +for line in self._stdout:
> > > +out += line
> > > +if line.rstrip().endswith(prompt):
> > > +break
> > > +except TimeoutError:
> >
> > I like this addition, but maybe we could do better. In the regular SSH
> > session, we're expected to raise:
> > * SSHSessionDeadError if the session is not alive,
> > * SSHTimeoutError if the command execution times out.
> >
> > Can we do that here as well?
>
> This is a good point, I don't see why we couldn't and thinking about
> it I like the idea of making this more consistent, good catch.
>
> >
> > > +raise InteractiveCommandExecutionError(
> >
> > We could just reuse the SSHTimeoutError exception. Is there a reason
> > to distinguish between interactive and non-interactive timeouts?
>
> I wanted to add a distinction between interactive and non-interactive
> just because in general the way we log messages when sending commands
> to interactive shells looks pretty close to what it looks like when
> you do the same for non-interactive, so if there was an error I
> thought it might be more helpful in the logs to know which session you
> were sending the command to when an error was encountered. Maybe,
> however, a better approach to this would just be keep the exception
> types the same but change the messages.
>

There is probably some value to distinguish between them. We could
just mirror the non-interactive exceptions and keep the messages the
same.

> >
> 
> > > 2.43.2
> > >


RE: Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread Morten Brørup
> From: fengchengwen [mailto:fengcheng...@huawei.com]
> Sent: Wednesday, 10 April 2024 11.34
> 
> Hi All,
> 
> We have a problem introduced by a compiler upgrade (from gcc10 to gcc12.3),
> we've done some
> research but haven't been able to figure out why. We'd like the community's
> help.
> 
> Environment:
> 1. Source: DPDK 23.11
> 2. GCC: 12.3.1 [1]
> 3. Compiled with target kunpeng SoC (ARM64)
> 4. Run on kunpeng SoC
> 
> 
> Problem & Debug:
> 1. We found the hns3 driver fails to update the link status. The corresponding
> function is
> hns3_update_linkstatus_and_event [2], and we found the rte_eth_linkstatus_set
> [3] always return zero.
> 2. After disassembly the hns3_update_linkstatus_and_event, and found
> rte_eth_linkstatus_set's
> rte_atomic_exchange_explicit return to xzr register (which is zero register):
>  1239fec:   3900f3e0strbw0, [sp, #60]
>  1239ff0:   9101a041add x1, x2, #0x68  ---x2 seem not the
> variable new_link
>  1239ff4:   f8ff8022swpal   xzr, x2, [x1]  ---this instr
> corresponding rte_atomic_exchange_explicit,
>   it will place
> the resut in xzr which always zero,
>   and this will
> lead to rte_eth_linkstatus_set return 0.
>  1239ff8:   3940f3e0ldrbw0, [sp, #60]
>  1239ffc:   d3609c41ubfxx1, x2, #32, #8
>  123a000:   4a01eor w0, w0, w1
>  123a004:   36100080tbz w0, #2, 123a014
> 
> 3. We checked other "ret = rte_eth_linkstatus_set" calls, and can't find
> similar problem.
> 4. After reading a lot of documents, we preliminarily think that the problem
> is caused by -fstrict-aliasing
> (which was enabled default with O2 or O3), if compiled with -fno-strict-
> aliasing, then this problem don't
> exist. We guest this maybe strict-aliasing's bug which only happened in our
> function.
> 5. We also try to use union to avoid such aliasing in rte_eth_linkstatus_set,
> we changed the struct
> rte_eth_link define, and it works:
>   -__extension__
>   -struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64 read/write
> */
>   -   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_ */
>   -   uint16_t link_duplex  : 1;  /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
>   -   uint16_t link_autoneg : 1;  /**< RTE_ETH_LINK_[AUTONEG/FIXED] */
>   -   uint16_t link_status  : 1;  /**< RTE_ETH_LINK_[DOWN/UP] */
>   +struct rte_eth_link { /**< aligned for atomic64 read/write */
>   +   union {
>   +   uint64_t val64;
>   +   struct {
>   +   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_
> */
>   +   uint16_t link_duplex  : 1;  /**<
> RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
>   +   uint16_t link_autoneg : 1;  /**<
> RTE_ETH_LINK_[AUTONEG/FIXED] */
>   +   uint16_t link_status  : 1;  /**<
> RTE_ETH_LINK_[DOWN/UP] */
>   +   };
>   +   };
>   };
> the corresponding rte_eth_linkstatus_set:
>   @@ -1674,18 +1674,13 @@ static inline int
>rte_eth_linkstatus_set(struct rte_eth_dev *dev,
>  const struct rte_eth_link *new_link)
>{
>   -   RTE_ATOMIC(uint64_t) *dev_link = (uint64_t __rte_atomic *)&(dev-
> >data->dev_link);
>   -   union {
>   -   uint64_t val64;
>   -   struct rte_eth_link link;
>   -   } orig;
>   -
>   -   RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
>   +   struct rte_eth_link old_link;
> 
>   -   orig.val64 = rte_atomic_exchange_explicit(dev_link, *(const uint64_t
> *)new_link,
>   +   old_link.val64 = rte_atomic_exchange_explicit(&dev->data-
> >dev_link.val64,
>   +   new_link->val64,
>   rte_memory_order_seq_cst);
> 
>   -   return (orig.link.link_status == new_link->link_status) ? -1 : 0;
>   +   return (old_link.link_status == new_link->link_status) ? -1 : 0;
>}
> 6. BTW: the linux kernel enabled "-fno-strict-aliasing" default, please see
> [4] for more.
> 

Thank you for the detailed analysis.
Looking at the GCC documentation for -fstrict-aliasing supports your conclusion.

Just out of curiosity:
Does building with -Wstrict-aliasing=3 or -Wstrict-aliasing=1 provide any 
useful information?
And are the any differences in the strict-aliasing warnings without/with your 
fix?

> 
> Last: We think there are two ways to solve this problem.
> 1. Add the compilation option '-fno-strict-aliasing' for hold DPDK project.
> 2. Use union to avoid such aliasing in rte_eth_linkstatus_set (please see
> above).
> PS: We prefer first way.
> 
> Hope for more discuess.
> 
> Thanks

Unfortunately, DPDK uses a lot of type casting where other methods would be 
formally more correct.
I fear that you only found one of potentially many more bugs like th

RE: [PATCH v2 3/8] mbuf: fix Tx checksum offload examples

2024-04-10 Thread Konstantin Ananyev



> > From: Konstantin Ananyev [mailto:konstantin.anan...@huawei.com]
> > Sent: Tuesday, 9 April 2024 15.39
> >
> > > > From: David Marchand [mailto:david.march...@redhat.com]
> > > > Sent: Friday, 5 April 2024 16.46
> > > >
> > > > Mandate use of rte_eth_tx_prepare() in the mbuf Tx checksum offload
> > > > examples.
> > >
> > > I strongly disagree with this change!
> > >
> > > It will cause a huge performance degradation for shaping applications:
> > >
> > > A packet will be processed and finalized at an output or forwarding
> > pipeline stage, where some other fields might also be written, so
> > > zeroing e.g. the out_ip checksum at this stage has low cost (no new
> > cache misses).
> > >
> > > Then, the packet might be queued for QoS or similar.
> > >
> > > If rte_eth_tx_prepare() must be called at the egress pipeline stage,
> > it has to write to the packet and cause a cache miss per packet,
> > > instead of simply passing on the packet to the NIC hardware.
> > >
> > > It must be possible to finalize the packet at the output/forwarding
> > pipeline stage!
> >
> > If you can finalize your packet on  output/forwarding, then why you
> > can't invoke tx_prepare() on the same stage?
> > There seems to be some misunderstanding about what tx_prepare() does -
> > in fact it doesn't communicate with HW queue (doesn't update TXD ring,
> > etc.), what it does - just make changes in mbuf itself.
> > Yes, it reads some fields in SW TX queue struct (max number of TXDs per
> > packet, etc.), but AFAIK it is safe
> > to call tx_prepare() and tx_burst() from different threads.
> > At least on implementations I am aware about.
> > Just checked the docs - it seems not stated explicitly anywhere, might
> > be that's why it causing such misunderstanding.
> >
> > >
> > > Also, how is rte_eth_tx_prepare() supposed to work for cloned packets
> > egressing on different NIC hardware?
> >
> > If you create a clone of full packet (including L2/L3) headers then
> > obviously such construction might not
> > work properly with tx_prepare() over two different NICs.
> > Though In majority of cases you do clone segments with data, while at
> > least L2 headers are put into different segments.
> > One simple approach would be to keep L3 header in that separate segment.
> > But yes, there is a problem when you'll need to send exactly the same
> > packet over different NICs.
> > As I remember, for bonding PMD things don't work quite well here - you
> > might have a bond over 2 NICs with
> > different tx_prepare() and which one to call might be not clear till
> > actual PMD tx_burst() is invoked.
> >
> > >
> > > In theory, it might get even worse if we make this opaque instead of
> > transparent and standardized:
> > > One PMD might reset out_ip checksum to 0x, and another PMD might
> > reset it to 0x.
> >
> > >
> > > I can only see one solution:
> > > We need to standardize on common minimum requirements for how to
> > prepare packets for each TX offload.
> >
> > If we can make each and every vendor to agree here - that definitely
> > will help to simplify things quite a bit.
> 
> An API is more than a function name and parameters.
> It also has preconditions and postconditions.
> 
> All major NIC vendors are contributing to DPDK.
> It should be possible to reach consensus for reasonable minimum requirements 
> for offloads.
> Hardware- and driver-specific exceptions can be documented with the offload 
> flag, or with rte_eth_rx/tx_burst(), like the note to
> rte_eth_rx_burst():
> "Some drivers using vector instructions require that nb_pkts is divisible by 
> 4 or 8, depending on the driver implementation."

If we introduce a rule that everyone supposed to follow and then straightway 
allow people to have a 'documented exceptions',
for me it means like 'no rule' in practice.
A 'documented exceptions' approach might work if you have 5 different PMDs to 
support, but not when you have 50+.
No-one would write an app with possible 10 different exception cases in his 
head.
Again, with such approach we can forget about backward compatibility.
I think we already had this discussion before, my opinion remains the same here 
-
'documented exceptions' approach is a way to trouble.

> You mention the bonding driver, which is a good example.
> The rte_eth_tx_burst() documentation has a note about the API postcondition 
> exception for the bonding driver:
> "This function must not modify mbufs (including packets data) unless the 
> refcnt is 1. An exception is the bonding PMD, [...], mbufs
> may be modified."

For me, what we've done for bonding tx_prepare/tx_burst() is a really bad 
example.
Initial agreement and design choice was that tx_burst() should not modify 
contents of the packets
(that actually was one of the reasons why tx_prepare() was introduced).
The only reason I agreed on that exception - because I couldn't come-up with 
something less uglier.

Actually, these problems with bonding PMD made me to start thinking that curr

Re: [PATCH v2] dts: Change hugepage runtime config to 2MB Exclusively

2024-04-10 Thread Juraj Linkeš
> diff --git a/dts/framework/testbed_model/linux_session.py 
> b/dts/framework/testbed_model/linux_session.py
> index 5d24030c3d..37f5eacb21 100644
> --- a/dts/framework/testbed_model/linux_session.py
> +++ b/dts/framework/testbed_model/linux_session.py
> @@ -15,7 +15,7 @@
>
>  from typing_extensions import NotRequired
>
> -from framework.exception import RemoteCommandExecutionError
> +from framework.exception import ConfigurationError, 
> RemoteCommandExecutionError
>  from framework.utils import expand_range
>
>  from .cpu import LogicalCore
> @@ -87,25 +87,22 @@ def get_dpdk_file_prefix(self, dpdk_prefix: str) -> str:
>  def setup_hugepages(self, hugepage_count: int, force_first_numa: bool) 
> -> None:
>  """Overrides :meth:`~.os_session.OSSession.setup_hugepages`."""
>  self._logger.info("Getting Hugepage information.")
> -hugepage_size = self._get_hugepage_size()
> +if "hugepages-2048kB" not in self.send_command("ls 
> /sys/kernel/mm/hugepages").stdout:

I have one extra point on top of Morten's suggestions (which I like).
Let's create a class variable where we store the hugepage size (2048)
and use that across the code.

> +raise ConfigurationError("2MB hugepages not supported by 
> operating system")
>  hugepages_total = self._get_hugepages_total()
>  self._numa_nodes = self._get_numa_nodes()
>
> -if force_first_numa or hugepages_total != hugepage_count:
> +if force_first_numa or hugepages_total < hugepage_count:
>  # when forcing numa, we need to clear existing hugepages 
> regardless
>  # of size, so they can be moved to the first numa node
> -self._configure_huge_pages(hugepage_count, hugepage_size, 
> force_first_numa)
> +self._configure_huge_pages(hugepage_count, 2048, 
> force_first_numa)
>  else:
>  self._logger.info("Hugepages already configured.")
>  self._mount_huge_pages()
>
> -def _get_hugepage_size(self) -> int:
> -hugepage_size = self.send_command("awk '/Hugepagesize/ {print $2}' 
> /proc/meminfo").stdout
> -return int(hugepage_size)
> -
>  def _get_hugepages_total(self) -> int:
>  hugepages_total = self.send_command(
> -"awk '/HugePages_Total/ { print $2 }' /proc/meminfo"
> +"cat /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages"
>  ).stdout
>  return int(hugepages_total)
>
> --
> 2.44.0
>


Re: [PATCH 3/6] dts: add testpmd shell params

2024-04-10 Thread Luca Vizzarro

On 09/04/2024 17:37, Juraj Linkeš wrote:

As Jeremy pointed out, going forward, this is likely to become bloated
and moving it to params.py (for example) may be better.

There's a lot of testpmd args here. I commented on the implementation
of some of them. I didn't verify that the actual values match the docs
or, god forbid, tested all of it. :-) Doing that as we start using
them is going to be good enough.


It is indeed a lot of args. I double checked most of them, so it should 
be mostly correct, but unfortunately I am not 100% sure. I did notice 
discrepancies between the docs and the source code of testpmd too. 
Although not ideal, I am inclining to update the definitions whenever a 
newly implemented test case hits a roadblock.


One thing that I don't remember if I mentioned so far, is the "XYPair". 
You see --flag=X,[Y] in the docs, but I am sure to have read somewhere 
this is potentially just a comma-separated multiple value.



On Tue, Mar 26, 2024 at 8:04 PM Luca Vizzarro  wrote:


Implement all the testpmd shell parameters into a data structure.

Signed-off-by: Luca Vizzarro 
Reviewed-by: Jack Bond-Preston 
Reviewed-by: Honnappa Nagarahalli 
---
  dts/framework/remote_session/testpmd_shell.py | 633 +-
  1 file changed, 615 insertions(+), 18 deletions(-)

diff --git a/dts/framework/remote_session/testpmd_shell.py 
b/dts/framework/remote_session/testpmd_shell.py
index db3abb7600..a823dc53be 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py





+@str_mixins(bracketed, comma_separated)
+class TestPmdRingNUMAConfig(NamedTuple):
+"""Tuple associating DPDK port, direction of the flow and NUMA socket."""


Is there any particular order for these various classes?


No, there is no actual order, potential dependencies aside.


+
+port: int
+direction: TestPmdFlowDirection
+socket: int
+
+





+@dataclass(kw_only=True)
+class TestPmdTXOnlyForwardingMode(Params):


The three special forwarding modes should really be moved right after
TestPmdForwardingModes. Do we actually need these three in
TestPmdForwardingModes? Looks like we could just remove those from
TestPmdForwardingModes since they have to be passed separately, not as
that Enum.


Can move and no we don't really need them in TestPmdForwardingModes, 
they can be hardcoded in their own special classes.



+__forward_mode: Literal[TestPmdForwardingModes.txonly] = field(
+default=TestPmdForwardingModes.txonly, init=False, 
metadata=long("forward-mode")
+)


I guess this is here so that "--forward-mode=txonly" gets rendered,
right? Why the two underscored? Is that because we want to hammer home
the fact that this is init=False, a kind of internal field? I'd like
to make it like the other fields, without any underscores (or maybe
just one underscore), and documented (definitely documented).
If we remove txonly from the Enum, we could just have the string value
here. The Enums are mostly useful to give users the proper range of
values.



Correct and correct. A double underscore would ensure no access to this 
field, which is fixed and only there for rendering purposes... (also the 
developer doesn't get a hint from the IDE, at least not on VS code) and 
in the case of TestPmdForwardingModes it would remove a potential 
conflict. It can definitely be documented though.



+multi_flow: Option = field(default=None, 
metadata=long("txonly-multi-flow"))
+"""Generate multiple flows."""
+segments_length: XYPair | None = field(default=None, 
metadata=long("txpkts"))
+"""Set TX segment sizes or total packet length."""
+
+
+@dataclass(kw_only=True)
+class TestPmdFlowGenForwardingMode(Params):
+__forward_mode: Literal[TestPmdForwardingModes.flowgen] = field(
+default=TestPmdForwardingModes.flowgen, init=False, 
metadata=long("forward-mode")
+)
+clones: int | None = field(default=None, metadata=long("flowgen-clones"))
+"""Set the number of each packet clones to be sent. Sending clones reduces 
host CPU load on
+creating packets and may help in testing extreme speeds or maxing out Tx 
packet performance.
+N should be not zero, but less than ‘burst’ parameter.
+"""
+flows: int | None = field(default=None, metadata=long("flowgen-flows"))
+"""Set the number of flows to be generated, where 1 <= N <= INT32_MAX."""
+segments_length: XYPair | None = field(default=None, 
metadata=long("txpkts"))
+"""Set TX segment sizes or total packet length."""
+
+
+@dataclass(kw_only=True)
+class TestPmdNoisyForwardingMode(Params):
+__forward_mode: Literal[TestPmdForwardingModes.noisy] = field(
+default=TestPmdForwardingModes.noisy, init=False, 
metadata=long("forward-mode")
+)


Are both of __forward_mode and forward_mode needed because we need to
render both?


Yes, this would render as `--forward-mode=noisy --noisy-forward-mode=io` 
using IO as example.



+forward_mode: (
+Liter

Re: [PATCH 4/6] dts: use testpmd params for scatter test suite

2024-04-10 Thread Luca Vizzarro

On 09/04/2024 20:12, Juraj Linkeš wrote:

@@ -104,16 +108,15 @@ def pmd_scatter(self, mbsize: int) -> None:
  """
  testpmd = self.sut_node.create_interactive_shell(
  TestPmdShell,
-app_parameters=StrParams(
-"--mbcache=200 "
-f"--mbuf-size={mbsize} "
-"--max-pkt-len=9000 "
-"--port-topology=paired "
-"--tx-offloads=0x8000"
+app_parameters=TestPmdParameters(
+forward_mode=TestPmdForwardingModes.mac,
+mbcache=200,
+mbuf_size=[mbsize],
+max_pkt_len=9000,
+tx_offloads=0x8000,
  ),
  privileged=True,
  )
-testpmd.set_forward_mode(TestPmdForwardingModes.mac)


Jeremy, does this change the test? Instead of configuring the fw mode
after starting testpmd, we're starting testpmd with fw mode
configured.


I am not Jeremy (please Jeremy still reply), but we discussed this on 
Slack. Reading through the testpmd source code, setting arguments like 
forward-mode in the command line, is the exact equivalent of calling 
`set forward mode` right after start-up. So it is equivalent in theory.



If not, we should remove the testpmd.set_forward_mode method, as it's
not used anymore.


Could there be test cases that change the forward mode multiple times in 
the same shell, though? As this could still be needed to cover this.


Re: [PATCH 5/6] dts: add statefulness to InteractiveShell

2024-04-10 Thread Luca Vizzarro

On 10/04/2024 07:53, Juraj Linkeš wrote:

I have a general question. What are these changes for? Do you
anticipate us needing this in the future? Wouldn't it be better to add
it only when we need it?


It's been sometime since we raised this task internally. This patch and 
the next one arise from some survey done on old DTS test cases.

Unfortunately, I can't pinpoint.

Specifically for this patch though, the timeout bit is useful in 
conjunction with the related change in the next. Instead of giving an 
optional timeout argument to all the commands where we may want to 
change it, aren't we better off with providing a facility to temporarily 
change this for the current scope?




On Thu, Mar 28, 2024 at 5:48 PM Jeremy Spewock  wrote:


On Tue, Mar 26, 2024 at 3:04 PM Luca Vizzarro  wrote:


diff --git a/dts/framework/remote_session/interactive_shell.py 
b/dts/framework/remote_session/interactive_shell.py
index a2c7b30d9f..5d80061e8d 100644
--- a/dts/framework/remote_session/interactive_shell.py
+++ b/dts/framework/remote_session/interactive_shell.py
@@ -41,8 +41,10 @@ class InteractiveShell(ABC):
  _stdout: channel.ChannelFile
  _ssh_channel: Channel
  _logger: DTSLogger
+__default_timeout: float


Only single underscores are used for other private variables, probably
better to keep that consistent with this one.



I agree, I don't see a reason for the double underscore.


Ack.




  _timeout: float
  _app_args: Params | None
+_is_privileged: bool = False



2.34.1





Re: [PATCH 6/6] dts: add statefulness to TestPmdShell

2024-04-10 Thread Luca Vizzarro

On 10/04/2024 08:41, Juraj Linkeš wrote:



@@ -723,7 +731,13 @@ def _start_application(self, get_privileged_command: 
Callable[[str], str] | None
  if self._app_args.app_params is None:
  self._app_args.app_params = TestPmdParameters()

-self.number_of_ports = len(self._app_args.ports) if 
self._app_args.ports is not None else 0
+assert isinstance(self._app_args.app_params, TestPmdParameters)
+


This is tricky because ideally we wouldn't have the assertion here,
but I understand why it is needed because Eal parameters have app args
which can be any instance of params. I'm not sure of the best way to
solve this, because making testpmd parameters extend from eal would
break the general scheme that you have in place, and having an
extension of EalParameters that enforces this app_args is
TestPmdParameters would solve the issues, but might be a little
clunky. Is there a way we can use a generic to get python to just
understand that, in this case, this will always be TestPmdParameters?
If not I might prefer making a private class where this is
TestPmdParameters, just because there aren't really any other
assertions that we use elsewhere and an unexpected exception from this
(even though I don't think that can happen) could cause people some
issues.

It might be the case that an assertion is the easiest way to deal with
it though, what do you think?



We could change the signature (just the type of app_args) of the init
method - I think we should be able to create a type that's
EalParameters with .app_params being TestPmdParameters or None. The
init method would just call super().

Something like the above is basically necessary with inheritance where
subclasses are all extensions (not just implementations) of the
superclass (having differences in API).



I believe this is indeed a tricky one. But, unfortunately, I am not 
understanding the solution that is being proposed. To me, it just feels 
like using a generic factory like:


  self.sut_node.create_interactive_shell(..)

is one of the reasons to bring in the majority of these complexities.

What do you mean by creating this new type that combines EalParams and 
TestPmdParams?


question about eth and vlan item in flow pattern

2024-04-10 Thread Jie Hai

Hi, all,

I have some questions about the sub-options for ``VLAN`` and ``ETH`` item.

According to the documentation, ``has_vlan`` is sub-option of ``ETH``
item and it means that the pattern contains at least one vlan.
The ``VLAN`` item is used to match tagged packets and have some
sub-options such as ``vid``, ``tci``, etc.

If we combine them, what should the effect be?
For instance,

rule-0: flow create 0 ingress pattern  eth  has_vlan is 1 / vlan  / end 
actions queue index 2 / end
rule-1: flow create 0 ingress pattern  eth  has_vlan is 1 / vlan vid is 
10 / end actions queue index 2 / end


For rule-0, should it match single-tagged packets only or multi-tagged 
only or both?
That is to say, which one will take effect, `has_vlan is 1`  or `vlan` 
or both?


For rule-2, which packets should it match, with inner VLAN id 10, or 
outer VLAN id 10, or both 10?


The hns3 driver supports only the exact matching of VLAN numer.
And it is planned to adapt ``has_vlan`` and ``has_more_vlan`` to the
meaning of one VLAN for hns3 driver. Therefore, if the preceding 
combinations are supported, we need to confirm the exact meanings.


So, what are your views on the above question?





Re: [PATCH 6/6] dts: add statefulness to TestPmdShell

2024-04-10 Thread Luca Vizzarro

On 10/04/2024 08:50, Juraj Linkeš wrote:

On Tue, Mar 26, 2024 at 8:04 PM Luca Vizzarro  wrote:


This commit provides a state container for TestPmdShell. It currently
only indicates whether the packet forwarding has started
or not, and the number of ports which were given to the shell.



A reminder, the commit message should explain why we're doing this
change, not what the change is.


This also fixes the behaviour of `wait_link_status_up` to use the
command timeout as inherited from InteractiveShell.

Signed-off-by: Luca Vizzarro 
Reviewed-by: Jack Bond-Preston 
Reviewed-by: Honnappa Nagarahalli 
---
  dts/framework/remote_session/testpmd_shell.py | 41 +--
  1 file changed, 28 insertions(+), 13 deletions(-)

diff --git a/dts/framework/remote_session/testpmd_shell.py 
b/dts/framework/remote_session/testpmd_shell.py
index a823dc53be..ea1d254f86 100644
--- a/dts/framework/remote_session/testpmd_shell.py
+++ b/dts/framework/remote_session/testpmd_shell.py
@@ -678,19 +678,27 @@ def __str__(self) -> str:
  return self.pci_address


+@dataclass(slots=True)
+class TestPmdState:
+"""Session state container."""
+
+#:
+packet_forwarding_started: bool = False


The same question as in the previous patch, do you anticipate this
being needed and should we add this only when it's actually used?



As answered in the previous patch. We can always drop it and do it as 
needed of course.



+
+#: The number of ports which were allowed on the command-line when testpmd 
was started.
+number_of_ports: int = 0
+
+
  class TestPmdShell(InteractiveShell):
  """Testpmd interactive shell.

  The testpmd shell users should never use
  the :meth:`~.interactive_shell.InteractiveShell.send_command` method 
directly, but rather
  call specialized methods. If there isn't one that satisfies a need, it 
should be added.
-
-Attributes:
-number_of_ports: The number of ports which were allowed on the 
command-line when testpmd
-was started.
  """

-number_of_ports: int
+#: Current state
+state: TestPmdState = TestPmdState()


Assigning a value makes this a class variable, shared across all
instances. This should be initialized in __init__().

But do we actually want to do this via composition? We'd need to
access the attributes via .state all the time and I don't really like
that. We could just put them into TestPmdShell directly, initializing
them in __init__().


No problem. I separated them in fear of bloating TestPmdShell. But I 
agree on the bother of adding .state




  #: The path to the testpmd executable.
  path: ClassVar[PurePath] = PurePath("app", "dpdk-testpmd")




RE: [PATCH v2 3/8] mbuf: fix Tx checksum offload examples

2024-04-10 Thread Morten Brørup
> From: Konstantin Ananyev [mailto:konstantin.anan...@huawei.com]
> Sent: Wednesday, 10 April 2024 12.35
> 
> > > From: Konstantin Ananyev [mailto:konstantin.anan...@huawei.com]
> > > Sent: Tuesday, 9 April 2024 15.39
> > >
> > > > > From: David Marchand [mailto:david.march...@redhat.com]
> > > > > Sent: Friday, 5 April 2024 16.46
> > > > >
> > > > > Mandate use of rte_eth_tx_prepare() in the mbuf Tx checksum offload
> > > > > examples.
> > > >
> > > > I strongly disagree with this change!
> > > >
> > > > It will cause a huge performance degradation for shaping applications:
> > > >
> > > > A packet will be processed and finalized at an output or forwarding
> > > pipeline stage, where some other fields might also be written, so
> > > > zeroing e.g. the out_ip checksum at this stage has low cost (no new
> > > cache misses).
> > > >
> > > > Then, the packet might be queued for QoS or similar.
> > > >
> > > > If rte_eth_tx_prepare() must be called at the egress pipeline stage,
> > > it has to write to the packet and cause a cache miss per packet,
> > > > instead of simply passing on the packet to the NIC hardware.
> > > >
> > > > It must be possible to finalize the packet at the output/forwarding
> > > pipeline stage!
> > >
> > > If you can finalize your packet on  output/forwarding, then why you
> > > can't invoke tx_prepare() on the same stage?
> > > There seems to be some misunderstanding about what tx_prepare() does -
> > > in fact it doesn't communicate with HW queue (doesn't update TXD ring,
> > > etc.), what it does - just make changes in mbuf itself.
> > > Yes, it reads some fields in SW TX queue struct (max number of TXDs per
> > > packet, etc.), but AFAIK it is safe
> > > to call tx_prepare() and tx_burst() from different threads.
> > > At least on implementations I am aware about.
> > > Just checked the docs - it seems not stated explicitly anywhere, might
> > > be that's why it causing such misunderstanding.
> > >
> > > >
> > > > Also, how is rte_eth_tx_prepare() supposed to work for cloned packets
> > > egressing on different NIC hardware?
> > >
> > > If you create a clone of full packet (including L2/L3) headers then
> > > obviously such construction might not
> > > work properly with tx_prepare() over two different NICs.
> > > Though In majority of cases you do clone segments with data, while at
> > > least L2 headers are put into different segments.
> > > One simple approach would be to keep L3 header in that separate segment.
> > > But yes, there is a problem when you'll need to send exactly the same
> > > packet over different NICs.
> > > As I remember, for bonding PMD things don't work quite well here - you
> > > might have a bond over 2 NICs with
> > > different tx_prepare() and which one to call might be not clear till
> > > actual PMD tx_burst() is invoked.
> > >
> > > >
> > > > In theory, it might get even worse if we make this opaque instead of
> > > transparent and standardized:
> > > > One PMD might reset out_ip checksum to 0x, and another PMD might
> > > reset it to 0x.
> > >
> > > >
> > > > I can only see one solution:
> > > > We need to standardize on common minimum requirements for how to
> > > prepare packets for each TX offload.
> > >
> > > If we can make each and every vendor to agree here - that definitely
> > > will help to simplify things quite a bit.
> >
> > An API is more than a function name and parameters.
> > It also has preconditions and postconditions.
> >
> > All major NIC vendors are contributing to DPDK.
> > It should be possible to reach consensus for reasonable minimum requirements
> for offloads.
> > Hardware- and driver-specific exceptions can be documented with the offload
> flag, or with rte_eth_rx/tx_burst(), like the note to
> > rte_eth_rx_burst():
> > "Some drivers using vector instructions require that nb_pkts is divisible by
> 4 or 8, depending on the driver implementation."
> 
> If we introduce a rule that everyone supposed to follow and then straightway
> allow people to have a 'documented exceptions',
> for me it means like 'no rule' in practice.
> A 'documented exceptions' approach might work if you have 5 different PMDs to
> support, but not when you have 50+.
> No-one would write an app with possible 10 different exception cases in his
> head.
> Again, with such approach we can forget about backward compatibility.
> I think we already had this discussion before, my opinion remains the same
> here -
> 'documented exceptions' approach is a way to trouble.

The "minimum requirements" should be the lowest common denominator of all NICs.
Exceptions should be extremely few, for outlier NICs that still want to provide 
an offload and its driver is unable to live up to the minimum requirements.
Any exception should require techboard approval. If a NIC/driver does not 
support the "minimum requirements" for an offload feature, it is not allowed to 
claim support for that offload feature, or needs to seek approval for an 
exception.

As another opti

Re: question about eth and vlan item in flow pattern

2024-04-10 Thread Thomas Monjalon
Hello,

10/04/2024 13:37, Jie Hai:
> Hi, all,
> 
> I have some questions about the sub-options for ``VLAN`` and ``ETH`` item.

If it is not clear in the doxygen documentation,
please do not hesitate to submit a patch to make it more explicit.

> According to the documentation, ``has_vlan`` is sub-option of ``ETH``
> item and it means that the pattern contains at least one vlan.

Yes

> The ``VLAN`` item is used to match tagged packets and have some
> sub-options such as ``vid``, ``tci``, etc.
> 
> If we combine them, what should the effect be?
> For instance,
> 
> rule-0: flow create 0 ingress pattern  eth  has_vlan is 1 / vlan  / end 
> actions queue index 2 / end

I don't think the item "vlan" has any impact here.
I mean it is redundant with "has_vlan".

> rule-1: flow create 0 ingress pattern  eth  has_vlan is 1 / vlan vid is 
> 10 / end actions queue index 2 / end
> 
> For rule-0, should it match single-tagged packets only or multi-tagged 
> only or both?

I would say it matches 1 VLAN or more.

> That is to say, which one will take effect, `has_vlan is 1`  or `vlan` 
> or both?

I think it is redundant.
The real interesting usage of "has_vlan" would be for matching untagged packets.

> For rule-2, which packets should it match, with inner VLAN id 10, or 

You mean rule-1

> outer VLAN id 10, or both 10?

In case of QinQ, I suppose specifying only 1 VLAN allows to match either inner 
or outer.


> The hns3 driver supports only the exact matching of VLAN numer.
> And it is planned to adapt ``has_vlan`` and ``has_more_vlan`` to the
> meaning of one VLAN for hns3 driver. Therefore, if the preceding 
> combinations are supported, we need to confirm the exact meanings.
> 
> So, what are your views on the above question?

I'm adding Ori Kam, maintainer of rte_flow API to confirm.




[PATCH] net/cnxk: add RSS config via ethdev configure API

2024-04-10 Thread skori
From: Sunil Kumar Kori 

Currently user passed RSS configuration is ignored via
rte_eth_dev_configure() API. Instead default RSS setup is done by
driver.

Adding handling for user passed RSS configuration too via
rte_eth_dev_configure().

Signed-off-by: Sunil Kumar Kori 
---
 drivers/net/cnxk/cnxk_ethdev.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/cnxk/cnxk_ethdev.c b/drivers/net/cnxk/cnxk_ethdev.c
index 6b37bd877f..95a3d8aaf9 100644
--- a/drivers/net/cnxk/cnxk_ethdev.c
+++ b/drivers/net/cnxk/cnxk_ethdev.c
@@ -1384,6 +1384,13 @@ cnxk_nix_configure(struct rte_eth_dev *eth_dev)
goto free_nix_lf;
}
 
+   /* Overwrite default RSS setup if requested by user */
+   rc = cnxk_nix_rss_hash_update(eth_dev, &conf->rx_adv_conf.rss_conf);
+   if (rc) {
+   plt_err("Failed to configure rss rc=%d", rc);
+   goto free_nix_lf;
+   }
+
/* Init the default TM scheduler hierarchy */
rc = roc_nix_tm_init(nix);
if (rc) {
-- 
2.25.1



Re: [PATCH v2] MAINTAINERS: remove maintainers that bounce

2024-04-10 Thread Bruce Richardson
On Mon, Apr 08, 2024 at 09:49:54AM -0700, Stephen Hemminger wrote:
> Recent patch set for rte_memcpy, discovered that the
> mail addresses for yuying.zh...@intel.com and zhouguoy...@huawei.com
> could not be found.
> 
> Signed-off-by: Stephen Hemminger 
> ---

Acked-by: Bruce Richardson 

If doing a V3, the email address "lijuan...@intel.com" is also invalid and
will bounce. I believe all other Intel email addresses in the MAINTAINERS
file are at least valid emails that won't bounce.

/Bruce



Re: [PATCH 3/6] dts: add testpmd shell params

2024-04-10 Thread Juraj Linkeš
On Wed, Apr 10, 2024 at 12:49 PM Luca Vizzarro  wrote:
>
> On 09/04/2024 17:37, Juraj Linkeš wrote:
> > As Jeremy pointed out, going forward, this is likely to become bloated
> > and moving it to params.py (for example) may be better.
> >
> > There's a lot of testpmd args here. I commented on the implementation
> > of some of them. I didn't verify that the actual values match the docs
> > or, god forbid, tested all of it. :-) Doing that as we start using
> > them is going to be good enough.
>
> It is indeed a lot of args. I double checked most of them, so it should
> be mostly correct, but unfortunately I am not 100% sure. I did notice
> discrepancies between the docs and the source code of testpmd too.
> Although not ideal, I am inclining to update the definitions whenever a
> newly implemented test case hits a roadblock.
>
> One thing that I don't remember if I mentioned so far, is the "XYPair".
> You see --flag=X,[Y] in the docs, but I am sure to have read somewhere
> this is potentially just a comma-separated multiple value.
>
> > On Tue, Mar 26, 2024 at 8:04 PM Luca Vizzarro  wrote:
> >>
> >> Implement all the testpmd shell parameters into a data structure.
> >>
> >> Signed-off-by: Luca Vizzarro 
> >> Reviewed-by: Jack Bond-Preston 
> >> Reviewed-by: Honnappa Nagarahalli 
> >> ---
> >>   dts/framework/remote_session/testpmd_shell.py | 633 +-
> >>   1 file changed, 615 insertions(+), 18 deletions(-)
> >>
> >> diff --git a/dts/framework/remote_session/testpmd_shell.py 
> >> b/dts/framework/remote_session/testpmd_shell.py
> >> index db3abb7600..a823dc53be 100644
> >> --- a/dts/framework/remote_session/testpmd_shell.py
> >> +++ b/dts/framework/remote_session/testpmd_shell.py
> >
> > 
> >
> >> +@str_mixins(bracketed, comma_separated)
> >> +class TestPmdRingNUMAConfig(NamedTuple):
> >> +"""Tuple associating DPDK port, direction of the flow and NUMA 
> >> socket."""
> >
> > Is there any particular order for these various classes?
>
> No, there is no actual order, potential dependencies aside.
>

Ok, can we order them according to when they appear in the code? Maybe
they already are.

> >> +
> >> +port: int
> >> +direction: TestPmdFlowDirection
> >> +socket: int
> >> +
> >> +
> >
> > 
> >
> >> +@dataclass(kw_only=True)
> >> +class TestPmdTXOnlyForwardingMode(Params):
> >
> > The three special forwarding modes should really be moved right after
> > TestPmdForwardingModes. Do we actually need these three in
> > TestPmdForwardingModes? Looks like we could just remove those from
> > TestPmdForwardingModes since they have to be passed separately, not as
> > that Enum.
>
> Can move and no we don't really need them in TestPmdForwardingModes,
> they can be hardcoded in their own special classes.
>
> >> +__forward_mode: Literal[TestPmdForwardingModes.txonly] = field(
> >> +default=TestPmdForwardingModes.txonly, init=False, 
> >> metadata=long("forward-mode")
> >> +)
> >
> > I guess this is here so that "--forward-mode=txonly" gets rendered,
> > right? Why the two underscored? Is that because we want to hammer home
> > the fact that this is init=False, a kind of internal field? I'd like
> > to make it like the other fields, without any underscores (or maybe
> > just one underscore), and documented (definitely documented).
> > If we remove txonly from the Enum, we could just have the string value
> > here. The Enums are mostly useful to give users the proper range of
> > values.
> >
>
> Correct and correct. A double underscore would ensure no access to this
> field, which is fixed and only there for rendering purposes... (also the
> developer doesn't get a hint from the IDE, at least not on VS code) and
> in the case of TestPmdForwardingModes it would remove a potential
> conflict. It can definitely be documented though.
>

Ok, can we do a single underscore? I don't really see a reason for two
underscores.

> >> +multi_flow: Option = field(default=None, 
> >> metadata=long("txonly-multi-flow"))
> >> +"""Generate multiple flows."""
> >> +segments_length: XYPair | None = field(default=None, 
> >> metadata=long("txpkts"))
> >> +"""Set TX segment sizes or total packet length."""
> >> +
> >> +
> >> +@dataclass(kw_only=True)
> >> +class TestPmdFlowGenForwardingMode(Params):
> >> +__forward_mode: Literal[TestPmdForwardingModes.flowgen] = field(
> >> +default=TestPmdForwardingModes.flowgen, init=False, 
> >> metadata=long("forward-mode")
> >> +)
> >> +clones: int | None = field(default=None, 
> >> metadata=long("flowgen-clones"))
> >> +"""Set the number of each packet clones to be sent. Sending clones 
> >> reduces host CPU load on
> >> +creating packets and may help in testing extreme speeds or maxing out 
> >> Tx packet performance.
> >> +N should be not zero, but less than ‘burst’ parameter.
> >> +"""
> >> +flows: int | None = field(default=None, 
> >> metadata=long("flowgen-flows"))
> >> +"""Set the number of flows to

Re: [PATCH 4/6] dts: use testpmd params for scatter test suite

2024-04-10 Thread Juraj Linkeš
On Wed, Apr 10, 2024 at 12:53 PM Luca Vizzarro  wrote:
>
> On 09/04/2024 20:12, Juraj Linkeš wrote:
> >> @@ -104,16 +108,15 @@ def pmd_scatter(self, mbsize: int) -> None:
> >>   """
> >>   testpmd = self.sut_node.create_interactive_shell(
> >>   TestPmdShell,
> >> -app_parameters=StrParams(
> >> -"--mbcache=200 "
> >> -f"--mbuf-size={mbsize} "
> >> -"--max-pkt-len=9000 "
> >> -"--port-topology=paired "
> >> -"--tx-offloads=0x8000"
> >> +app_parameters=TestPmdParameters(
> >> +forward_mode=TestPmdForwardingModes.mac,
> >> +mbcache=200,
> >> +mbuf_size=[mbsize],
> >> +max_pkt_len=9000,
> >> +tx_offloads=0x8000,
> >>   ),
> >>   privileged=True,
> >>   )
> >> -testpmd.set_forward_mode(TestPmdForwardingModes.mac)
> >
> > Jeremy, does this change the test? Instead of configuring the fw mode
> > after starting testpmd, we're starting testpmd with fw mode
> > configured.
>
> I am not Jeremy (please Jeremy still reply), but we discussed this on
> Slack. Reading through the testpmd source code, setting arguments like
> forward-mode in the command line, is the exact equivalent of calling
> `set forward mode` right after start-up. So it is equivalent in theory.
>
> > If not, we should remove the testpmd.set_forward_mode method, as it's
> > not used anymore.
>
> Could there be test cases that change the forward mode multiple times in
> the same shell, though? As this could still be needed to cover this.

Yes, but we don't have such a test now. It's good practice to remove
unused code. We can still bring it back anytime, it'll be in git
history.


Re: question about eth and vlan item in flow pattern

2024-04-10 Thread Ivan Malov

Hi Jie,

Consider the following examples:
1) flow create 0 ingress pattern eth / ipv4 proto is 17 / udp / end \
   actions queue index 1 / end
2) flow create 0 ingress pattern eth / ipv4 / udp / end \
   actions queue index 1 / end

Generally speaking, these two rules might be equivalent, with "proto is 17" in
the first one probably being redundant (the very presence of "udp" item might
stand for the same match criterion -- the protocol ID being 17).

And I'd be tempted to treat the "has_vlan" case similarly. Consider:
3) flow create 0 ingress pattern eth has_vlan is 1 / vlan / end \
   actions queue index 1 / end
4) flow create 0 ingress pattern eth / vlan / end \
   actions queue index 1 / end

(rule (3) is similar to "rule-0" from your example)

Rules (3) and (4) seem equivalent to me -- the "has_vlan is 1" bit might be
redundant in flow (3) -- the presence of item "vlan" sort of means the same.

Rule (3) and (4) should probably match both single-tagged and double-tagged
packets because, in both cases, the pattern does not clarify which protocol
follows the outermost VLAN tag. If one needs to exclude double-tag match,
they should clarify the rule in one of the possible ways, in example:

- pattern eth / vlan has_more_vlan is 0 / end
- pattern eth / vlan tpid is 0x0800 / end
- pattern eth / vlan / ipv4 / end

(the "tpid" goes to the "hdr.eth_proto" of "struct rte_flow_item_vlan").

With regard to the question about VLAN ID match, "pattern eth / vlan vid is 10",
as well as "pattern eth has_vlan is 1 / vlan vid is 10", should probably match
only on the outermost tag ID, -- that is, not on the inner one and not on both.
That is because the "vid is 10" criterion relates to the specific header,
as per the match item it sits in. If the user wants to match on the
inner VLAN ID (say, 11), they should clarify specify it as follows:

- pattern eth / vlan vid is 10 / vlan vid is 11 / end
- pattern eth / vlan / vlan vid is 11 / end

Hopefully, the rest of DPDK vendor community can correct me in case I got
that wrong. Should you have more questions, please feel free to ask such.

Thank you.

On Wed, 10 Apr 2024, Jie Hai wrote:


Hi, all,

I have some questions about the sub-options for ``VLAN`` and ``ETH`` item.

According to the documentation, ``has_vlan`` is sub-option of ``ETH``
item and it means that the pattern contains at least one vlan.
The ``VLAN`` item is used to match tagged packets and have some
sub-options such as ``vid``, ``tci``, etc.

If we combine them, what should the effect be?
For instance,

rule-0: flow create 0 ingress pattern  eth  has_vlan is 1 / vlan  / end 
actions queue index 2 / end
rule-1: flow create 0 ingress pattern  eth  has_vlan is 1 / vlan vid is 10 / 
end actions queue index 2 / end


For rule-0, should it match single-tagged packets only or multi-tagged only 
or both?
That is to say, which one will take effect, `has_vlan is 1`  or `vlan` or 
both?


For rule-2, which packets should it match, with inner VLAN id 10, or outer 
VLAN id 10, or both 10?


The hns3 driver supports only the exact matching of VLAN numer.
And it is planned to adapt ``has_vlan`` and ``has_more_vlan`` to the
meaning of one VLAN for hns3 driver. Therefore, if the preceding combinations 
are supported, we need to confirm the exact meanings.


So, what are your views on the above question?






Re: [PATCH 5/6] dts: add statefulness to InteractiveShell

2024-04-10 Thread Juraj Linkeš
On Wed, Apr 10, 2024 at 1:27 PM Luca Vizzarro  wrote:
>
> On 10/04/2024 07:53, Juraj Linkeš wrote:
> > I have a general question. What are these changes for? Do you
> > anticipate us needing this in the future? Wouldn't it be better to add
> > it only when we need it?
>
> It's been sometime since we raised this task internally. This patch and
> the next one arise from some survey done on old DTS test cases.
> Unfortunately, I can't pinpoint.
>
> Specifically for this patch though, the timeout bit is useful in
> conjunction with the related change in the next. Instead of giving an
> optional timeout argument to all the commands where we may want to
> change it, aren't we better off with providing a facility to temporarily
> change this for the current scope?
>

This is a good question. If the scope is just one command, then no. If
it's more than one, then maybe yes. I don't know which is better.

We should also consider that this would introduce a difference in API
between the interactive and non-interactive sessions. Do we want to do
this there as well?

Also, maybe set_timeout should be a property or we could just make
_timeout public.
And is_privileged should just be privileged, as it's a property (which
shouldn't contain a verb; if it was a method it would be a good name).

> >
> > On Thu, Mar 28, 2024 at 5:48 PM Jeremy Spewock  wrote:
> >>
> >> On Tue, Mar 26, 2024 at 3:04 PM Luca Vizzarro  
> >> wrote:
> >> 
> >>> diff --git a/dts/framework/remote_session/interactive_shell.py 
> >>> b/dts/framework/remote_session/interactive_shell.py
> >>> index a2c7b30d9f..5d80061e8d 100644
> >>> --- a/dts/framework/remote_session/interactive_shell.py
> >>> +++ b/dts/framework/remote_session/interactive_shell.py
> >>> @@ -41,8 +41,10 @@ class InteractiveShell(ABC):
> >>>   _stdout: channel.ChannelFile
> >>>   _ssh_channel: Channel
> >>>   _logger: DTSLogger
> >>> +__default_timeout: float
> >>
> >> Only single underscores are used for other private variables, probably
> >> better to keep that consistent with this one.
> >>
> >
> > I agree, I don't see a reason for the double underscore.
>
> Ack.
>
> >
> >>>   _timeout: float
> >>>   _app_args: Params | None
> >>> +_is_privileged: bool = False
> >> 
> >>> 2.34.1
> >>>
>


Re: [PATCH v2] dts: Change hugepage runtime config to 2MB Exclusively

2024-04-10 Thread Patrick Robb
On Wed, Apr 10, 2024 at 3:23 AM Morten Brørup  
wrote:
>
> > From: Nicholas Pratte [mailto:npra...@iol.unh.edu]
> > Sent: Tuesday, 9 April 2024 19.28
> >
> > The previous implementation configures and allocates hugepage sizes
> > based on a system default. This can lead to two problems: overallocation of
> > hugepages (which may crash the remote host), and configuration of hugepage
> > sizes that are not recommended during runtime. This new implementation
> > allows only 2MB hugepage allocation during runtime; any other unique
> > hugepage size must be configured by the end-user for initializing DTS.
> >
> > If the amount of 2MB hugepages requested exceeds the amount of 2MB
> > hugepages already configured on the system, then the system will remount
> > hugepages to cover the difference. If the amount of hugepages requested is
> > either less than or equal to the amount already configured on the system,
> > then nothing is done.
> >
> > Bugzilla ID: 1370
> > Signed-off-by: Nicholas Pratte 
> > Reviewed-by: Jeremy Spewock 
> > ---
> >  dts/conf.yaml|  4 ++--
> >  dts/framework/config/__init__.py |  4 ++--
> >  dts/framework/config/conf_yaml_schema.json   |  6 +++---
> >  dts/framework/config/types.py|  2 +-
> >  dts/framework/testbed_model/linux_session.py | 15 ++-
> >  5 files changed, 14 insertions(+), 17 deletions(-)
> >
> > diff --git a/dts/conf.yaml b/dts/conf.yaml
> > index 8068345dd5..56c3ae6f4c 100644
> > --- a/dts/conf.yaml
> > +++ b/dts/conf.yaml
> > @@ -35,7 +35,7 @@ nodes:
> >  lcores: "" # use all the available logical cores
> >  use_first_core: false # tells DPDK to use any physical core
> >  memory_channels: 4 # tells DPDK to use 4 memory channels
> > -hugepages:  # optional; if removed, will use system hugepage
> > configuration
> > +hugepages_2mb: # optional; if removed, will use system hugepage
> > configuration
> >  amount: 256
> >  force_first_numa: false
> >  ports:
> > @@ -71,7 +71,7 @@ nodes:
> >  os_driver: rdma
> >  peer_node: "SUT 1"
> >  peer_pci: ":00:08.1"
> > -hugepages:  # optional; if removed, will use system hugepage
> > configuration
> > +hugepages_2mb: # optional; if removed, will use system hugepage
> > configuration
> >  amount: 256
> >  force_first_numa: false
> >  traffic_generator:
> > diff --git a/dts/framework/config/__init__.py
> > b/dts/framework/config/__init__.py
> > index 4cb5c74059..b6f820e39e 100644
> > --- a/dts/framework/config/__init__.py
> > +++ b/dts/framework/config/__init__.py
> > @@ -255,8 +255,8 @@ def from_dict(
> >  Either an SUT or TG configuration instance.
> >  """
> >  hugepage_config = None
> > -if "hugepages" in d:
> > -hugepage_config_dict = d["hugepages"]
> > +if "hugepages_2mb" in d:
> > +hugepage_config_dict = d["hugepages_2mb"]
> >  if "force_first_numa" not in hugepage_config_dict:
> >  hugepage_config_dict["force_first_numa"] = False
> >  hugepage_config = HugepageConfiguration(**hugepage_config_dict)
> > diff --git a/dts/framework/config/conf_yaml_schema.json
> > b/dts/framework/config/conf_yaml_schema.json
> > index 4731f4511d..f4d7199523 100644
> > --- a/dts/framework/config/conf_yaml_schema.json
> > +++ b/dts/framework/config/conf_yaml_schema.json
> > @@ -146,7 +146,7 @@
> >  "compiler"
> >]
> >  },
> > -"hugepages": {
> > +"hugepages_2mb": {
> >"type": "object",
> >"description": "Optional hugepage configuration. If not specified,
> > hugepages won't be configured and DTS will use system configuration.",
> >"properties": {
> > @@ -253,8 +253,8 @@
> >  "type": "integer",
> >  "description": "How many memory channels to use. Optional,
> > defaults to 1."
> >},
> > -  "hugepages": {
> > -"$ref": "#/definitions/hugepages"
> > +  "hugepages_2mb": {
> > +"$ref": "#/definitions/hugepages_2mb"
> >},
> >"ports": {
> >  "type": "array",
> > diff --git a/dts/framework/config/types.py b/dts/framework/config/types.py
> > index 1927910d88..016e0c3dbd 100644
> > --- a/dts/framework/config/types.py
> > +++ b/dts/framework/config/types.py
> > @@ -46,7 +46,7 @@ class NodeConfigDict(TypedDict):
> >  """Allowed keys and values."""
> >
> >  #:
> > -hugepages: HugepageConfigurationDict
> > +hugepages_2mb: HugepageConfigurationDict
> >  #:
> >  name: str
> >  #:
> > diff --git a/dts/framework/testbed_model/linux_session.py
> > b/dts/framework/testbed_model/linux_session.py
> > index 5d24030c3d..37f5eacb21 100644
> > --- a/dts/framework/testbed_model/linux_session.py
> > +++ b/dts/framework/testbed_model/linux_session.py
> > @@ -15,7 +15,7 @@
> >
> >  from typing_extensions import NotRequired
> 

Re: [PATCH 5/6] dts: add statefulness to InteractiveShell

2024-04-10 Thread Luca Vizzarro

On 10/04/2024 14:35, Juraj Linkeš wrote:

We should also consider that this would introduce a difference in API
between the interactive and non-interactive sessions. Do we want to do
this there as well?


Could definitely add it there as well. You are referring to 
RemoteSession I presume, right?


[PATCH 0/1] fix GCC 13 build errors on 32-bit targets

2024-04-10 Thread Luca Vizzarro
Hi everyone,

sending in a patch to resolve some build issues encountered with
GCC 13.2 when building against 32-bit targets. These issues were
originally reported by Luca Boccassi in one of his stable builds[1].
Although, I have noticed that this problem presents itself on
more versions (e.g. 21.11) as well, and it's not specific to armv7-a as
the build suggests.

I haven't actually noticed the problem present itself on mainline,
but it doesn't mean that it won't appear in the future. This patch
should correctly fix this problem.

This patch is meant to target mainline, and all the currently
supported stable versions.

[1] 
https://build.opensuse.org/package/live_build_log/home:bluca:dpdk/dpdk-22.11/Debian_Next/armv7l

Luca Vizzarro (1):
  vhost: fix GCC 13 build error

 lib/vhost/virtio_net.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

-- 
2.34.1



[PATCH 1/1] vhost: fix GCC 13 build error

2024-04-10 Thread Luca Vizzarro
This patch resolves a build error with GCC 13 and arm/aarch32 as
targets:

In function ‘mbuf_to_desc’,
inlined from ‘vhost_enqueue_async_packed’ at
  ../lib/vhost/virtio_net.c:1828:6,
inlined from ‘virtio_dev_rx_async_packed’ at
  ../lib/vhost/virtio_net.c:1842:6,
inlined from ‘virtio_dev_rx_async_submit_packed’ at
  ../lib/vhost/virtio_net.c:1900:7:
../lib/vhost/virtio_net.c:1159:18: error: ‘buf_vec[0].buf_addr’ may
be used uninitialized [-Werror=maybe-uninitialized]
 1159 | buf_addr = buf_vec[vec_idx].buf_addr;
  | ~^~~

../lib/vhost/virtio_net.c:1160:18: error: ‘buf_vec[0].buf_iova’ may
be used uninitialized [-Werror=maybe-uninitialized]
 1160 | buf_iova = buf_vec[vec_idx].buf_iova;
  | ~^~~

../lib/vhost/virtio_net.c:1161:35: error: ‘buf_vec[0].buf_len’ may
be used uninitialized [-Werror=maybe-uninitialized]
 1161 | buf_len = buf_vec[vec_idx].buf_len;
  |   ^~~~

GCC complains about the possible runtime path where the while loop
which fills buf_vec (in vhost_enqueue_async_packed) is not run. As a
consequence it correctly thinks that buf_vec is not initialized while
being accessed anyways.

This scenario is actually very unlikely as the only way this can occur
is if size has overflowed to 0. Meaning that the total packet length
would be close to UINT64_MAX (or actually UINT32_MAX). At first glance,
the code suggests that this may never happen as the type of size has
been changed to 64-bit. For a 32-bit architecture such as arm
(e.g. armv7-a) and aarch32, this still happens because the operand types
(pkt->pkt_len and sizeof) are 32-bit wide, performing 32-bit arithmetic
first (where the overflow can happen) and widening to 64-bit later.

The proposed fix simply guarantees to the compiler that the scope which
fills buf_vec is accessed at least once, while not disrupting the actual
logic. This is based on the assumption that size will always be greater
than 0, as suggested by the sizeof, and the packet length will never be
as big as UINT32_MAX, and causing an overflow.

Fixes: 873e8dad6f49 ("vhost: support packed ring in async datapath")
Cc: sta...@dpdk.org

Signed-off-by: Luca Vizzarro 
Reviewed-by: Paul Szczepanek 
Reviewed-by: Nick Connolly 
---
 lib/vhost/virtio_net.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/vhost/virtio_net.c b/lib/vhost/virtio_net.c
index 1359c5fb1f..6a2ca295f5 100644
--- a/lib/vhost/virtio_net.c
+++ b/lib/vhost/virtio_net.c
@@ -1935,7 +1935,7 @@ vhost_enqueue_async_packed(struct virtio_net *dev,
else
max_tries = 1;
 
-   while (size > 0) {
+   do {
/*
 * if we tried all available ring items, and still
 * can't get enough buf, it means something abnormal
@@ -1962,7 +1962,7 @@ vhost_enqueue_async_packed(struct virtio_net *dev,
avail_idx += desc_count;
if (avail_idx >= vq->size)
avail_idx -= vq->size;
-   }
+   } while (size > 0);
 
if (unlikely(mbuf_to_desc(dev, vq, pkt, buf_vec, nr_vec, *nr_buffers, 
true) < 0))
return -1;
-- 
2.34.1



Re: Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread Stephen Hemminger
On Wed, 10 Apr 2024 17:33:53 +0800
fengchengwen  wrote:

> Last: We think there are two ways to solve this problem.
> 1. Add the compilation option '-fno-strict-aliasing' for hold DPDK project.
> 2. Use union to avoid such aliasing in rte_eth_linkstatus_set (please see 
> above).
> PS: We prefer first way.
> 

Please send a patch to replace alias with union.

PS: you can also override aliasing for a few lines of code with either pragma's
or lots of casting. Both are messy and hard to maintain.


RE: [PATCH 01/83] examples: move alignment attribute on types

2024-04-10 Thread Akhil Goyal
> +To: David Hunt, Distributor maintainer
> +To: Radu Nicolau and Akhil Goyal, IPsec security gateway example maintainers
> 
> > From: Tyler Retzlaff [mailto:roret...@linux.microsoft.com]
> > Sent: Wednesday, 20 March 2024 16.37
> >
> > Move location of __rte_aligned(a) to new conventional location. The new
> > placement between {struct,union} and the tag allows the desired
> > alignment to be imparted on the type regardless of the toolchain being
> > used for both C and C++. Additionally, it avoids confusion by Doxygen
> > when generating documentation.
> >
> > Signed-off-by: Tyler Retzlaff 
> > ---
> 
> Reviewed-by: Morten Brørup 
> 
> A few comments for the above mentioned maintainers inline below.
> 
> > diff --git a/examples/ipsec-secgw/ipsec.h b/examples/ipsec-secgw/ipsec.h
> > index bdcada1..4cf4c9d 100644
> > --- a/examples/ipsec-secgw/ipsec.h
> > +++ b/examples/ipsec-secgw/ipsec.h
> > @@ -112,7 +112,7 @@ enum {
> > return (struct ipsec_sa *)i;
> >  }
> >
> > -struct ipsec_sa {
> > +struct __rte_cache_aligned ipsec_sa {
> > struct rte_ipsec_session sessions[IPSEC_SESSION_MAX];
> > uint32_t spi;
> > struct cdev_qp *cqp[RTE_MAX_LCORE];
> > @@ -170,7 +170,7 @@ struct ipsec_sa {
> > struct rte_flow_item_esp esp_spec;
> > struct rte_flow *flow;
> > struct rte_security_session_conf sess_conf;
> > -} __rte_cache_aligned;
> > +};
> >
> >  struct ipsec_xf {
> > struct rte_crypto_sym_xform a;
> > @@ -190,12 +190,12 @@ struct sa_ctx {
> > struct ipsec_sa sa[];
> >  };
> >
> > -struct ipsec_mbuf_metadata {
> > +struct __rte_cache_aligned ipsec_mbuf_metadata {
> > struct ipsec_sa *sa;
> > struct rte_crypto_op cop;
> > struct rte_crypto_sym_op sym_cop;
> > uint8_t buf[32];
> > -} __rte_cache_aligned;
> > +};
> >
> >  #define IS_TRANSPORT(flags) ((flags) & TRANSPORT)
> >
> > @@ -224,7 +224,7 @@ struct cdev_qp {
> > uint16_t qp;
> > uint16_t in_flight;
> > uint16_t len;
> > -   struct rte_crypto_op *buf[MAX_PKT_BURST] __rte_aligned(sizeof(void
> > *));
> > +   alignas(sizeof(void *)) struct rte_crypto_op *buf[MAX_PKT_BURST];
> 
> Aligning a pointer to the size of a pointer is superfluous, unless the 
> structure is
> packed.
> 
> @Radu, @Akhil: You might want to remove these in a future patch.

Agreed, these can be removed.

> 
> >  };
> >
> >  struct ipsec_ctx {
> > @@ -235,7 +235,7 @@ struct ipsec_ctx {
> > uint16_t nb_qps;
> > uint16_t last_qp;
> > struct cdev_qp tbl[MAX_QP_PER_LCORE];
> > -   struct rte_mbuf *ol_pkts[MAX_PKT_BURST] __rte_aligned(sizeof(void
> > *));
> > +   alignas(sizeof(void *)) struct rte_mbuf *ol_pkts[MAX_PKT_BURST];
> > uint16_t ol_pkts_cnt;
> > uint64_t ipv4_offloads;
> > uint64_t ipv6_offloads;
> > @@ -283,18 +283,18 @@ struct cnt_blk {
> > uint32_t cnt;
> >  } __rte_packed;
> >
> > -struct lcore_rx_queue {
> > +struct __rte_cache_aligned lcore_rx_queue {
> > uint16_t port_id;
> > uint8_t queue_id;
> > void *sec_ctx;
> > -} __rte_cache_aligned;
> > +};
> >
> >  struct buffer {
> > uint16_t len;
> > -   struct rte_mbuf *m_table[MAX_PKT_BURST] __rte_aligned(sizeof(void
> > *));
> > +   alignas(sizeof(void *)) struct rte_mbuf *m_table[MAX_PKT_BURST];
> >  };
> >
> > -struct lcore_conf {
> > +struct __rte_cache_aligned lcore_conf {
> > uint16_t nb_rx_queue;
> > struct lcore_rx_queue rx_queue_list[MAX_RX_QUEUE_PER_LCORE];
> > uint16_t tx_queue_id[RTE_MAX_ETHPORTS];


RE: [EXTERNAL] [PATCH v4 13/30] security: replace use of fixed size rte_memcpy

2024-04-10 Thread Akhil Goyal
> Automatically generated by devtools/cocci/rte_memcpy.cocci
> 
> Signed-off-by: Stephen Hemminger 
> ---
Acked-by: Akhil Goyal 


RE: [EXTERNAL] [PATCH v4 05/30] cryptodev: replace use of fixed size rte_memcpy

2024-04-10 Thread Akhil Goyal
> Automatically generated by devtools/cocci/rte_memcpy.cocci
> 
> Signed-off-by: Stephen Hemminger 
> ---
>  lib/cryptodev/rte_cryptodev.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
Acked-by: Akhil Goyal 


Re: Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread Ferruh Yigit
On 4/10/2024 11:30 AM, Morten Brørup wrote:
>> From: fengchengwen [mailto:fengcheng...@huawei.com]
>> Sent: Wednesday, 10 April 2024 11.34
>>
>> Hi All,
>>
>> We have a problem introduced by a compiler upgrade (from gcc10 to gcc12.3),
>> we've done some
>> research but haven't been able to figure out why. We'd like the community's
>> help.
>>
>> Environment:
>> 1. Source: DPDK 23.11
>> 2. GCC: 12.3.1 [1]
>> 3. Compiled with target kunpeng SoC (ARM64)
>> 4. Run on kunpeng SoC
>>
>>
>> Problem & Debug:
>> 1. We found the hns3 driver fails to update the link status. The 
>> corresponding
>> function is
>> hns3_update_linkstatus_and_event [2], and we found the rte_eth_linkstatus_set
>> [3] always return zero.
>> 2. After disassembly the hns3_update_linkstatus_and_event, and found
>> rte_eth_linkstatus_set's
>> rte_atomic_exchange_explicit return to xzr register (which is zero register):
>>  1239fec:   3900f3e0strbw0, [sp, #60]
>>  1239ff0:   9101a041add x1, x2, #0x68  ---x2 seem not the
>> variable new_link
>>  1239ff4:   f8ff8022swpal   xzr, x2, [x1]  ---this instr
>> corresponding rte_atomic_exchange_explicit,
>>   it will place
>> the resut in xzr which always zero,
>>   and this will
>> lead to rte_eth_linkstatus_set return 0.
>>  1239ff8:   3940f3e0ldrbw0, [sp, #60]
>>  1239ffc:   d3609c41ubfxx1, x2, #32, #8
>>  123a000:   4a01eor w0, w0, w1
>>  123a004:   36100080tbz w0, #2, 123a014
>> 
>> 3. We checked other "ret = rte_eth_linkstatus_set" calls, and can't find
>> similar problem.
>> 4. After reading a lot of documents, we preliminarily think that the problem
>> is caused by -fstrict-aliasing
>> (which was enabled default with O2 or O3), if compiled with -fno-strict-
>> aliasing, then this problem don't
>> exist. We guest this maybe strict-aliasing's bug which only happened in our
>> function.
>> 5. We also try to use union to avoid such aliasing in rte_eth_linkstatus_set,
>> we changed the struct
>> rte_eth_link define, and it works:
>>   -__extension__
>>   -struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64 
>> read/write
>> */
>>   -   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_ */
>>   -   uint16_t link_duplex  : 1;  /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
>>   -   uint16_t link_autoneg : 1;  /**< RTE_ETH_LINK_[AUTONEG/FIXED] */
>>   -   uint16_t link_status  : 1;  /**< RTE_ETH_LINK_[DOWN/UP] */
>>   +struct rte_eth_link { /**< aligned for atomic64 read/write */
>>   +   union {
>>   +   uint64_t val64;
>>   +   struct {
>>   +   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_
>> */
>>   +   uint16_t link_duplex  : 1;  /**<
>> RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
>>   +   uint16_t link_autoneg : 1;  /**<
>> RTE_ETH_LINK_[AUTONEG/FIXED] */
>>   +   uint16_t link_status  : 1;  /**<
>> RTE_ETH_LINK_[DOWN/UP] */
>>   +   };
>>   +   };
>>   };
>> the corresponding rte_eth_linkstatus_set:
>>   @@ -1674,18 +1674,13 @@ static inline int
>>rte_eth_linkstatus_set(struct rte_eth_dev *dev,
>>  const struct rte_eth_link *new_link)
>>{
>>   -   RTE_ATOMIC(uint64_t) *dev_link = (uint64_t __rte_atomic *)&(dev-
>>> data->dev_link);
>>   -   union {
>>   -   uint64_t val64;
>>   -   struct rte_eth_link link;
>>   -   } orig;
>>   -
>>   -   RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
>>   +   struct rte_eth_link old_link;
>>
>>   -   orig.val64 = rte_atomic_exchange_explicit(dev_link, *(const 
>> uint64_t
>> *)new_link,
>>   +   old_link.val64 = rte_atomic_exchange_explicit(&dev->data-
>>> dev_link.val64,
>>   +   new_link->val64,
>>   rte_memory_order_seq_cst);
>>
>>   -   return (orig.link.link_status == new_link->link_status) ? -1 : 0;
>>   +   return (old_link.link_status == new_link->link_status) ? -1 : 0;
>>}
>> 6. BTW: the linux kernel enabled "-fno-strict-aliasing" default, please see
>> [4] for more.
>>
> 
> Thank you for the detailed analysis.
> Looking at the GCC documentation for -fstrict-aliasing supports your 
> conclusion.
> 

Agree that issue looks like strict aliasing violation.

> Just out of curiosity:
> Does building with -Wstrict-aliasing=3 or -Wstrict-aliasing=1 provide any 
> useful information?
> And are the any differences in the strict-aliasing warnings without/with your 
> fix?
> 
>>
>> Last: We think there are two ways to solve this problem.
>> 1. Add the compilation option '-fno-strict-aliasing' for hold DPDK project.
>> 2. Use union to avoid such aliasing in rte_eth_linkstatus_set (please see
>> above).
>> PS

Re: Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread Ferruh Yigit
On 4/10/2024 4:27 PM, Stephen Hemminger wrote:
> On Wed, 10 Apr 2024 17:33:53 +0800
> fengchengwen  wrote:
> 
>> Last: We think there are two ways to solve this problem.
>> 1. Add the compilation option '-fno-strict-aliasing' for hold DPDK project.
>> 2. Use union to avoid such aliasing in rte_eth_linkstatus_set (please see 
>> above).
>> PS: We prefer first way.
>>
> 
> Please send a patch to replace alias with union.
> 

+1

I am not sure about ABI implications, as size is not changing I expect
it won't be an issue but may be good to verify with libabigail.

> PS: you can also override aliasing for a few lines of code with either 
> pragma's
> or lots of casting. Both are messy and hard to maintain.



DTS WG Meeting Minutes - April 10, 2024

2024-04-10 Thread Patrick Robb
#
Attendees
* Patrick Robb
* Jeremy Spewock
* Paul Szczepanek
* Luca Vizzarro
* Juraj Linkeš

#
Minutes

=
General Announcements
* AT UNH IOL, Nick installed some Broadcom 25G nics on our DTS dev
servers which the team will be able to use for testing their patches
going forward.

=
Patch discussions
* Hugepages patch:
   * Morten noted on the mailing list that 2mb pages may not be
supported on all arches, and suggested 32 bit x86 required >4mb
  * Bruce noted that most distros use PAE mode to allow physical
addresses >4gb, and this also means that 32 bit hugepages can be 2mb.
Based on this information we are able to proceed without tracking
supported hugepage sizes per arch
  * Juraj notes that PAE allows 32 bit systems to allow for use of
more than 4GB of memory.
  * If we hit problems in the future with the current
implementation, it can be refactored at that point to allow for more
configurability.
   * Morten also requested that “suggested” hugepages count which
conf.yaml ships with be kept at 256
  * If we want to change it, we need to writeup the specific
reasons why. We were originally basing it on the 1024 hugepages
example given in DPDK docs system requirements, and then doubling it +
buffer since users may run on 2 socket systems in which hugepages are
split between numa nodes.
  * This justification should be in the commit message
  * Juraj is also going to test increasing his allocation from 256
pages and see if he can run smoke tests successfully (current failing
some unit tests)
   * Various functions need to be renamed to clarify they are
hardcoded to set 2mb huge page sizes specifically
   * Juraj recommends simply setting a class variable for the time
being which stores HUGEPAGE_SIZE
   * We need to document some of the assumptions we are making, like:
  * If you are setting hugepages from DTS, we assume you are
trying to set 2mb pages
  * This can be set from /doc/guides/tools/dts.rst
* Improve output gathering patch:
   * Current process for gathering output relies on finding expected
prompt within output buffer
  * When the output itself contains the prompt, it is a false positive
  * So, check for the prompt at the end of the output.
 * There could still be this prompt at the end of normal
output, so it’s not 100% bulletproof, but watching for this should be
easy to maintain
  * Jeremy will update this patch to make it consistent with other
error messages
* Testpmd statefullness / params class
   * Juraj provided some feedback, and Luca will submit another patch
later in the month
   * How do we handle timeouts? Old strategy is setting a timeout per
sent command.
  * The only place where we change the timeout is when we build dpdk
  * In almost all cases, we do not need to set some custom timeout
for sending a command for interactive or noninteractive shells.
  * Assumption is that when we implement testsuites, new testpmd
shell is launched every time we start a new testcase. So, changing the
timeout on an instance of the testpmd shell will not affect another
testcase.
 * If for any reason testpmd HAS to be reused for two checks,
those two checks need to be within the same testcase.
   * Should testcases be self contained?
  * Paul notes that his understanding based on his experience is
that testcases should be self contained, and run in any order.
   * From here we can set a new rule, which is that we need to open
and close testpmd every time we start a new testcase
  * This rule needs to be documented. Just mentioning it in the
testpmd class is fine.
  * The isolation should be enforced by the system, not a
requirement placed on developers and requiring human validation
 * This is essentially forced anyways by having developers use
the testpmd context manager
   * This patch also adding some features which are not used in DTS
right now. Usually we don’t want to do this, but these are based on
previous discussions and we want to lay the groundwork for further
development in the future. The group agrees there is a high likelihood
that these features will be required, thus we are comfortable bringing
them in now.
   * https://patchwork.dpdk.org/project/dpdk/list/?series=31622
* Skip test cases based on capabilities
   * Jeremy has rebased his new scatter testcase off of this patch
  * He will run this
   * Jeremy is concerned that “show rxq info” is not giving correct
capability information for scatter on all NICs.
   * We could compose a list of capabilities which we expect we will
need in the near future, and Juraj could add support for those.
  * How to compose it? We have a rough idea of what testsuites we
want to por

DTS 24.07 Roadmap

2024-04-10 Thread Patrick Robb
Honnappa approved this a couple weeks ago, but this was never emailed
out to the DTS mailing list, so doing that now.

1) Write ethdev testsuites:
Jumboframes: 
https://git.dpdk.org/tools/dts/tree/test_plans/jumboframes_test_plan.rst
Mac Filter: 
https://git.dpdk.org/tools/dts/tree/test_plans/mac_filter_test_plan.rst
Dynamic Queue: 
https://git.dpdk.org/tools/dts/tree/test_plans/dynamic_queue_test_plan.rst

2)
Replace XMLRPC server with Scapy interactive shell:
https://bugs.dpdk.org/show_bug.cgi?id=1374

3)
Configuration schema updates:
DTS Hugepages refactor:
https://patchwork.dpdk.org/project/dpdk/patch/20240409172811.27866-1-npra...@iol.unh.edu/
Cut down total configuration options in schema (not all we originally
added are needed): https://bugs.dpdk.org/show_bug.cgi?id=1360
Split testbed and test configuration to different files:
https://bugs.dpdk.org/show_bug.cgi?id=1344

4)API Docs generation:
https://patchwork.dpdk.org/project/dpdk/list/?series=30877

5)Skip test cases based on testbed capabilities:
https://patches.dpdk.org/project/dpdk/patch/20240301155416.96960-1-juraj.lin...@pantheon.tech/
Bugzilla: https://bugs.dpdk.org/show_bug.cgi?id=1351

6)Rename the execution section/stage:
Bugzilla: https://bugs.dpdk.org/show_bug.cgi?id=1355

7)Add support for externally compiled DPDK:
Bugzilla: https://bugs.dpdk.org/show_bug.cgi?id=136


[DPDK/DTS Bug 1413] Build initial list of device capabilities required by testsuites we are trying to write this year

2024-04-10 Thread bugzilla
https://bugs.dpdk.org/show_bug.cgi?id=1413

Bug ID: 1413
   Summary: Build initial list of device capabilities required by
testsuites we are trying to write this year
   Product: DPDK
   Version: 24.07
  Hardware: All
OS: All
Status: UNCONFIRMED
  Severity: minor
  Priority: Normal
 Component: DTS
  Assignee: dev@dpdk.org
  Reporter: pr...@iol.unh.edu
CC: juraj.lin...@pantheon.tech, pr...@iol.unh.edu
  Target Milestone: ---

https://patchwork.dpdk.org/project/dpdk/patch/20240301155416.96960-1-juraj.lin...@pantheon.tech/

Juraj has this RFC for skipping testcases based on capabilities, but it only
checks for scattered_rx. He has requested a more comprehensive list of what
capabilities we may need to check for going forward. 

I think this is a good first ticket for Prince at UNH to work on.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Re: [PATCH 0/4] RFC samples converting VLA to alloca

2024-04-10 Thread Tyler Retzlaff
On Wed, Apr 10, 2024 at 09:58:34AM +, Konstantin Ananyev wrote:
> 
> 
> > >
> > > > > From: Tyler Retzlaff [mailto:roret...@linux.microsoft.com]
> > > > > Sent: Monday, 8 April 2024 17.27
> > > > >
> > > > > For next technboard meeting.
> > > > >
> > > > > On Sun, Apr 07, 2024 at 10:03:06AM -0700, Stephen Hemminger wrote:
> > > > > > On Sun, 7 Apr 2024 13:07:06 +0200
> > > > > > Morten Brørup  wrote:
> > > > > >
> > > > > > > > From: Mattias Rönnblom [mailto:hof...@lysator.liu.se]
> > > > > > > > Sent: Sunday, 7 April 2024 11.32
> > > > > > > >
> > > > > > > > On 2024-04-04 19:15, Tyler Retzlaff wrote:
> > > > > > > > > This series is not intended for merge.  It insteat provides 
> > > > > > > > > examples
> > > > > > > > of
> > > > > > > > > converting use of VLAs to alloca() would look like.
> > > > > > > > >
> > > > > > > > > what's the advantages of VLA over alloca()?
> > > > > > > > >
> > > > > > > > > * sizeof(array) works as expected.
> > > > > > > > >
> > > > > > > > > * multi-dimensional arrays are still arrays instead of 
> > > > > > > > > pointers to
> > > > > > > > >dynamically allocated space. this means multiple subscript 
> > > > > > > > > syntax
> > > > > > > > >works (unlike on a pointer) and calculation of addresses 
> > > > > > > > > into
> > > > > > > > allocated
> > > > > > > > >space in ascending order is performed by the compiler 
> > > > > > > > > instead of
> > > > > > > > manually.
> > > > > > > > >
> > > > > > > >
> > > > > > > > alloca() is a pretty obscure mechanism, and also not a part of 
> > > > > > > > the C
> > > > > > > > standard. VLAs are C99, and well-known and understood, and very
> > > > > > > > efficient.
> > > > > > >
> > > > > > > The RFC fails to mention why we need to replace VLAs with 
> > > > > > > something else:
> > > > > > >
> > > > > > > VLAs are C99, but not C++; VLAs were made optional in C11.
> > > > > > >
> > > > > > > MSVC doesn't support VLAs, and is not going to:
> > > > > > > https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-
> > > > > arriving-in-msvc/#variable-length-arrays
> > > > > > >
> > > > > > >
> > > > > > > I dislike alloca() too, and the notes section in the alloca(3) 
> > > > > > > man page
> > > > > even discourages the use of alloca():
> > > > > > > https://man7.org/linux/man-pages/man3/alloca.3.html
> > > > > > >
> > > > > > > But I guess alloca() is the simplest replacement for VLAs.
> > > > > > > This RFC patch series opens the discussion for alternatives in 
> > > > > > > different
> > > > > use cases.
> > > > > > >
> > > > > >
> > > > > > The other issue with VLA's is that if the number is something that 
> > > > > > can be
> > > > > externally
> > > > > > input, then it can be a source of stack overflow bugs. That is why 
> > > > > > the Linux
> > > > > kernel
> > > > > > has stopped using them; for security reasons. DPDK has much less of 
> > > > > > a
> > > > > security
> > > > > > trust domain. Mostly need to make sure that no data from network is 
> > > > > > being
> > > > > > used to compute VLA size.
> > > > > >
> > > > >
> > > > > Looks like we need to discuss this at the next techboard meeting.
> > > > >
> > > > > * MSVC doesn't support C11 optional VLAs (and never will).
> > > > > * alloca() is an alternative that is available on all 
> > > > > platforms/toolchain
> > > > >   combinations.
> > > > > * it's reasonable for some VLAs to be turned into regular arrays but 
> > > > > it
> > > > >   would be unsatisfactory to be stuck waiting discussions of defining 
> > > > > new
> > > > >   constant expression macros on a per-use basis.
> > > >
> > > > We must generally stop using VLAs, for many reasons.
> > > > The only available 1:1 replacement is alloca(), so we have to accept 
> > > > that.
> > > >
> > > > If anyone still cares about improvements, we can turn alloca()'d arrays 
> > > > into regular arrays after this patch series.
> > > >
> > > > Alternatives to VLAs are very interesting discussions, but let's not 
> > > > stall MSVC progress because of it!
> > >
> > > Ok, but why we have to rush into 'alloca()' solution if none of us really 
> > > fond of it?
> > 
> > for the trivial case it is no worse than a VLA. while it isn't
> > standardized it is available for all platform/toolchains unlike VLA.
> > most of the code needed to be changed for windows falls into the trivial
> > case when converted.
> 
> Personally, I think VLA is much more convenient then alloca().
> At least you can do sizeof(vla_array) without a problem.
> 
> > 
> > there do appear to be cases where VLAs have just been unintentional.
> > i previously linked a patch where i fixed a case where they were
> > instantiated inside a cast and there are other cases i'm aware of in the
> > mlx5 driver where i believe they are unintended. at least with alloca
> > it is obvious but with a VLA if the expression used to determine the
> > size is wrapped up in something non-trivial and the author doesn't check
> > that it is trul

Re: [PATCH 0/4] RFC samples converting VLA to alloca

2024-04-10 Thread Tyler Retzlaff
On Wed, Apr 10, 2024 at 09:32:10AM +0200, Mattias Rönnblom wrote:
> On 2024-04-08 17:53, Morten Brørup wrote:
> >>From: Tyler Retzlaff [mailto:roret...@linux.microsoft.com]
> >>Sent: Monday, 8 April 2024 17.27
> >>
> >>For next technboard meeting.
> >>
> >>On Sun, Apr 07, 2024 at 10:03:06AM -0700, Stephen Hemminger wrote:
> >>>On Sun, 7 Apr 2024 13:07:06 +0200
> >>>Morten Brørup  wrote:
> >>>
> >From: Mattias Rönnblom [mailto:hof...@lysator.liu.se]
> >Sent: Sunday, 7 April 2024 11.32
> >
> >On 2024-04-04 19:15, Tyler Retzlaff wrote:
> >>This series is not intended for merge.  It insteat provides examples
> >of
> >>converting use of VLAs to alloca() would look like.
> >>
> >>what's the advantages of VLA over alloca()?
> >>
> >>* sizeof(array) works as expected.
> >>
> >>* multi-dimensional arrays are still arrays instead of pointers to
> >>dynamically allocated space. this means multiple subscript syntax
> >>works (unlike on a pointer) and calculation of addresses into
> >allocated
> >>space in ascending order is performed by the compiler instead of
> >manually.
> >>
> >
> >alloca() is a pretty obscure mechanism, and also not a part of the C
> >standard. VLAs are C99, and well-known and understood, and very
> >efficient.
> 
> The RFC fails to mention why we need to replace VLAs with something else:
> 
> VLAs are C99, but not C++; VLAs were made optional in C11.
> 
> MSVC doesn't support VLAs, and is not going to:
> https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-
> >>arriving-in-msvc/#variable-length-arrays
> 
> 
> I dislike alloca() too, and the notes section in the alloca(3) man page
> >>even discourages the use of alloca():
> https://man7.org/linux/man-pages/man3/alloca.3.html
> 
> But I guess alloca() is the simplest replacement for VLAs.
> This RFC patch series opens the discussion for alternatives in different
> >>use cases.
> 
> >>>
> >>>The other issue with VLA's is that if the number is something that can be
> >>externally
> >>>input, then it can be a source of stack overflow bugs. That is why the 
> >>>Linux
> >>kernel
> >>>has stopped using them; for security reasons. DPDK has much less of a
> >>security
> >>>trust domain. Mostly need to make sure that no data from network is being
> >>>used to compute VLA size.
> >>>
> >>
> >>Looks like we need to discuss this at the next techboard meeting.
> >>
> >>* MSVC doesn't support C11 optional VLAs (and never will).
> >>* alloca() is an alternative that is available on all platforms/toolchain
> >>   combinations.
> >>* it's reasonable for some VLAs to be turned into regular arrays but it
> >>   would be unsatisfactory to be stuck waiting discussions of defining new
> >>   constant expression macros on a per-use basis.
> >
> >We must generally stop using VLAs, for many reasons.
> 
> What reasons would that be? And which of those reasons are not also
> reasons to stop using alloca().

truncated the sentence, probably should have said where static array is
not practical.



Re: [PATCH 0/4] RFC samples converting VLA to alloca

2024-04-10 Thread Tyler Retzlaff
On Wed, Apr 10, 2024 at 09:27:10AM +0200, Mattias Rönnblom wrote:
> On 2024-04-08 17:27, Tyler Retzlaff wrote:
> >For next technboard meeting.
> >
> >On Sun, Apr 07, 2024 at 10:03:06AM -0700, Stephen Hemminger wrote:
> >>On Sun, 7 Apr 2024 13:07:06 +0200
> >>Morten Brørup  wrote:
> >>
> From: Mattias Rönnblom [mailto:hof...@lysator.liu.se]
> Sent: Sunday, 7 April 2024 11.32
> 
> On 2024-04-04 19:15, Tyler Retzlaff wrote:
> >This series is not intended for merge.  It insteat provides examples
> of
> >converting use of VLAs to alloca() would look like.
> >
> >what's the advantages of VLA over alloca()?
> >
> >* sizeof(array) works as expected.
> >
> >* multi-dimensional arrays are still arrays instead of pointers to
> >dynamically allocated space. this means multiple subscript syntax
> >works (unlike on a pointer) and calculation of addresses into
> allocated
> >space in ascending order is performed by the compiler instead of
> manually.
> 
> alloca() is a pretty obscure mechanism, and also not a part of the C
> standard. VLAs are C99, and well-known and understood, and very
> efficient.
> >>>
> >>>The RFC fails to mention why we need to replace VLAs with something else:
> >>>
> >>>VLAs are C99, but not C++; VLAs were made optional in C11.
> >>>
> >>>MSVC doesn't support VLAs, and is not going to:
> >>>https://devblogs.microsoft.com/cppblog/c11-and-c17-standard-support-arriving-in-msvc/#variable-length-arrays
> >>>
> >>>
> >>>I dislike alloca() too, and the notes section in the alloca(3) man page 
> >>>even discourages the use of alloca():
> >>>https://man7.org/linux/man-pages/man3/alloca.3.html
> >>>
> >>>But I guess alloca() is the simplest replacement for VLAs.
> >>>This RFC patch series opens the discussion for alternatives in different 
> >>>use cases.
> >>>
> >>
> >>The other issue with VLA's is that if the number is something that can be 
> >>externally
> >>input, then it can be a source of stack overflow bugs. That is why the 
> >>Linux kernel
> >>has stopped using them; for security reasons. DPDK has much less of a 
> >>security
> >>trust domain. Mostly need to make sure that no data from network is being
> >>used to compute VLA size.
> >>
> >
> >Looks like we need to discuss this at the next techboard meeting.
> >
> >* MSVC doesn't support C11 optional VLAs (and never will).
> 
> This is due to dogmatism, or what? Surely, a lot of Open Source
> projects written for C99 will use VLAs.

well the statement from the MSVC team was

  "VLAs provide attack vectors comparable to those of the infamous
   gets() — deprecated and destined to removal — for opportunities of
   “shifting the stack” and other exploits.
   For these reasons we intend not to support VLAs as an optional
   feature in C11"

i'm only communicating that they will neve be supported not debating the
reasons why. it's simply a statement in fact.

> 
> >* alloca() is an alternative that is available on all platforms/toolchain
> >   combinations.
> 
> alloca() is a poor alternative. The use of alloca() should be
> restricted to situations where statically sized arrays can't do the
> job.

agree comletely.


RE: Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread Morten Brørup
> From: Stephen Hemminger [mailto:step...@networkplumber.org]
> Sent: Wednesday, 10 April 2024 17.27
> 
> On Wed, 10 Apr 2024 17:33:53 +0800
> fengchengwen  wrote:
> 
> > Last: We think there are two ways to solve this problem.
> > 1. Add the compilation option '-fno-strict-aliasing' for hold DPDK
> project.
> > 2. Use union to avoid such aliasing in rte_eth_linkstatus_set (please
> see above).
> > PS: We prefer first way.
> >
> 
> Please send a patch to replace alias with union.

+1

Fixing this specific bug would be good.

Instinctively, I think we should build with -fno-strict-aliasing, so the 
compiler doesn't make the same mistake with similar code elsewhere in DPDK. I 
fear there is more than this instance.
I also wonder if -Wstrict-aliasing could help us instead, if we don't want 
-fno-strict-aliasing.



RE: [EXTERNAL] [PATCH v4 27/30] app/test: replace use of fixed size rte_memcpy

2024-04-10 Thread Akhil Goyal
> Automatically generated by devtools/cocci/rte_memcpy.cocci
> 
> Signed-off-by: Stephen Hemminger 
> ---
>  app/test/commands.c |  1 -
>  app/test/packet_burst_generator.c   |  4 +--
>  app/test/test_crc.c |  5 ++--
>  app/test/test_cryptodev.c   | 18 ++---
>  app/test/test_cryptodev_asym.c  |  1 -
>  app/test/test_cryptodev_security_pdcp.c |  1 -

>  app/test/test_ipsec.c   |  6 ++---

>  app/test/test_security_inline_proto.c   | 36 -

For above changes
Acked-by: Akhil Goyal 



Re: Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread Tyler Retzlaff
On Wed, Apr 10, 2024 at 07:54:27PM +0200, Morten Brørup wrote:
> > From: Stephen Hemminger [mailto:step...@networkplumber.org]
> > Sent: Wednesday, 10 April 2024 17.27
> > 
> > On Wed, 10 Apr 2024 17:33:53 +0800
> > fengchengwen  wrote:
> > 
> > > Last: We think there are two ways to solve this problem.
> > > 1. Add the compilation option '-fno-strict-aliasing' for hold DPDK
> > project.
> > > 2. Use union to avoid such aliasing in rte_eth_linkstatus_set (please
> > see above).
> > > PS: We prefer first way.
> > >
> > 
> > Please send a patch to replace alias with union.
> 
> +1
> 
> Fixing this specific bug would be good.
> 
> Instinctively, I think we should build with -fno-strict-aliasing, so the 
> compiler doesn't make the same mistake with similar code elsewhere in DPDK. I 
> fear there is more than this instance.
> I also wonder if -Wstrict-aliasing could help us instead, if we don't want 
> -fno-strict-aliasing.

agree, union is the correct way to get defined behavior. there are
valuable optimizatons that the compiler can make with strict aliasing
enabled so -Wstrict-aliasing is a good suggestion as opposed to
disabling it.

also the union won't break the abi if introduced correctly.


UNH Lab downtime

2024-04-10 Thread Patrick Robb
Hello,

The DPDK Community Lab will be offline for a couple hours tomorrow,
April 11, starting at 16:00 UTC. We are doing some Community Lab
dashboard maintenance. We should be able to catch up on all
patchseries submitted during that time as soon as we're back online.

Thanks,
Patrick


Re: Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread Stephen Hemminger
On Wed, 10 Apr 2024 19:54:27 +0200
Morten Brørup  wrote:

> > Please send a patch to replace alias with union.  
> 
> +1
> 
> Fixing this specific bug would be good.
> 
> Instinctively, I think we should build with -fno-strict-aliasing, so the 
> compiler doesn't make the same mistake with similar code elsewhere in DPDK. I 
> fear there is more than this instance.
> I also wonder if -Wstrict-aliasing could help us instead, if we don't want 
> -fno-strict-aliasing.


Strict aliasing checks should be enabled already if you use warning_level 2
and default (debugoptimized) or release build types. Unless some part of DPDK
meson config is not overriding that.

  https://mesonbuild.com/Builtin-options.html

Warning level 2 sets -Wall and -Wextra
From gcc man page

   -Wstrict-aliasing
   This option is only active when -fstrict-aliasing  is  active.   It
   warns  about  code  that might break the strict aliasing rules that
   the compiler is using for optimization.  The warning does not catch
   all cases, but does attempt to catch the more common pitfalls.   It
   is included in -Wall.  It is equivalent to -Wstrict-aliasing=3

and
   The -fstrict-aliasing option is enabled at levels -O2, -O3, -Os.




RE: [PATCH] config/arm: add Ampere AmpereOneX platform

2024-04-10 Thread Wathsala Wathawana Vithanage



> -Original Message-
> From: Yutang Jiang 
> Sent: Sunday, April 7, 2024 1:36 AM
> To: dev@dpdk.org
> Cc: patc...@amperecomputing.com; yutang.ji...@amperecomputing.com;
> jiangyut...@os.amperecomputing.com; Ruifeng Wang
> ; nd ; juraj.lin...@pantheon.tech
> Subject: [PATCH] config/arm: add Ampere AmpereOneX platform
> 
> Signed-off-by: Yutang Jiang 
> Signed-off-by: Yutang Jiang 
> ---
>  config/arm/arm64_ampereonex_linux_gcc | 16 
>  config/arm/meson.build| 19 +++

Acked-by: Wathsala Vithanage 


RE: [PATCH] ARM64: Cross-Compilation Support

2024-04-10 Thread Wathsala Wathawana Vithanage
> From: Krishna Kanth Reddy 
> 
> Modified the Configuration file to use the latest ARM Cross-Compiler.
> 
> Fixed the linker errors for the undefined references to the APIs
> isal_deflate_init, isal_deflate, isal_inflate_init, isal_inflate,
> isal_inflate_stateless, isal_deflate_stateless, isal_deflate_set_hufftables 
> in the
> case of ARM Cross-Compilation.
> 
> Signed-off-by: Krishna Kanth Reddy 
> Signed-off-by: Sebastian Brzezinka 
> ---
>  config/arm/arm64_armv8_linux_gcc  | 10 +-
> drivers/compress/isal/meson.build |  4 

Acked-by: Wathsala Vithanage 



RE: [PATCH] config/arm: add Ampere AmpereOneX platform

2024-04-10 Thread Wathsala Wathawana Vithanage
> >
> > Signed-off-by: Yutang Jiang 
> > Signed-off-by: Yutang Jiang 
> > ---

Looks like this patch is signed off by Yutang twice with two different emails.
Please remove one and submit again. 

Thank you.


Re: Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread fengchengwen
Hi Morten,

On 2024/4/10 18:30, Morten Brørup wrote:
>> From: fengchengwen [mailto:fengcheng...@huawei.com]
>> Sent: Wednesday, 10 April 2024 11.34
>>
>> Hi All,
>>
>> We have a problem introduced by a compiler upgrade (from gcc10 to gcc12.3),
>> we've done some
>> research but haven't been able to figure out why. We'd like the community's
>> help.
>>
>> Environment:
>> 1. Source: DPDK 23.11
>> 2. GCC: 12.3.1 [1]
>> 3. Compiled with target kunpeng SoC (ARM64)
>> 4. Run on kunpeng SoC
>>
>>
>> Problem & Debug:
>> 1. We found the hns3 driver fails to update the link status. The 
>> corresponding
>> function is
>> hns3_update_linkstatus_and_event [2], and we found the rte_eth_linkstatus_set
>> [3] always return zero.
>> 2. After disassembly the hns3_update_linkstatus_and_event, and found
>> rte_eth_linkstatus_set's
>> rte_atomic_exchange_explicit return to xzr register (which is zero register):
>>  1239fec:   3900f3e0strbw0, [sp, #60]
>>  1239ff0:   9101a041add x1, x2, #0x68  ---x2 seem not the
>> variable new_link
>>  1239ff4:   f8ff8022swpal   xzr, x2, [x1]  ---this instr
>> corresponding rte_atomic_exchange_explicit,
>>   it will place
>> the resut in xzr which always zero,
>>   and this will
>> lead to rte_eth_linkstatus_set return 0.
>>  1239ff8:   3940f3e0ldrbw0, [sp, #60]
>>  1239ffc:   d3609c41ubfxx1, x2, #32, #8
>>  123a000:   4a01eor w0, w0, w1
>>  123a004:   36100080tbz w0, #2, 123a014
>> 
>> 3. We checked other "ret = rte_eth_linkstatus_set" calls, and can't find
>> similar problem.
>> 4. After reading a lot of documents, we preliminarily think that the problem
>> is caused by -fstrict-aliasing
>> (which was enabled default with O2 or O3), if compiled with -fno-strict-
>> aliasing, then this problem don't
>> exist. We guest this maybe strict-aliasing's bug which only happened in our
>> function.
>> 5. We also try to use union to avoid such aliasing in rte_eth_linkstatus_set,
>> we changed the struct
>> rte_eth_link define, and it works:
>>   -__extension__
>>   -struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64 
>> read/write
>> */
>>   -   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_ */
>>   -   uint16_t link_duplex  : 1;  /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
>>   -   uint16_t link_autoneg : 1;  /**< RTE_ETH_LINK_[AUTONEG/FIXED] */
>>   -   uint16_t link_status  : 1;  /**< RTE_ETH_LINK_[DOWN/UP] */
>>   +struct rte_eth_link { /**< aligned for atomic64 read/write */
>>   +   union {
>>   +   uint64_t val64;
>>   +   struct {
>>   +   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_
>> */
>>   +   uint16_t link_duplex  : 1;  /**<
>> RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
>>   +   uint16_t link_autoneg : 1;  /**<
>> RTE_ETH_LINK_[AUTONEG/FIXED] */
>>   +   uint16_t link_status  : 1;  /**<
>> RTE_ETH_LINK_[DOWN/UP] */
>>   +   };
>>   +   };
>>   };
>> the corresponding rte_eth_linkstatus_set:
>>   @@ -1674,18 +1674,13 @@ static inline int
>>rte_eth_linkstatus_set(struct rte_eth_dev *dev,
>>  const struct rte_eth_link *new_link)
>>{
>>   -   RTE_ATOMIC(uint64_t) *dev_link = (uint64_t __rte_atomic *)&(dev-
>>> data->dev_link);
>>   -   union {
>>   -   uint64_t val64;
>>   -   struct rte_eth_link link;
>>   -   } orig;
>>   -
>>   -   RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
>>   +   struct rte_eth_link old_link;
>>
>>   -   orig.val64 = rte_atomic_exchange_explicit(dev_link, *(const 
>> uint64_t
>> *)new_link,
>>   +   old_link.val64 = rte_atomic_exchange_explicit(&dev->data-
>>> dev_link.val64,
>>   +   new_link->val64,
>>   rte_memory_order_seq_cst);
>>
>>   -   return (orig.link.link_status == new_link->link_status) ? -1 : 0;
>>   +   return (old_link.link_status == new_link->link_status) ? -1 : 0;
>>}
>> 6. BTW: the linux kernel enabled "-fno-strict-aliasing" default, please see
>> [4] for more.
>>
> 
> Thank you for the detailed analysis.
> Looking at the GCC documentation for -fstrict-aliasing supports your 
> conclusion.
> 
> Just out of curiosity:
> Does building with -Wstrict-aliasing=3 or -Wstrict-aliasing=1 provide any 
> useful information?

There are no any useful information with -Wstrict-aliasing=3

But for -Wstrict-aliasing=1, there are plenty of warnings, below is 
rte_eth_linkstatus_set:

In file included from ../../dpdk/lib/ethdev/rte_ethdev.c:32:
../../dpdk/lib/ethdev/ethdev_driver.h: In function ‘rte_eth_linkstatus_set’:
../../dpdk/lib/ethdev/ethdev_driver.h:1677:67: warning: dereferencing 
type-pun

[PATCH] ethdev: fix strict aliasing lead to link cannot be up

2024-04-10 Thread Chengwen Feng
Fix a problem introduced by a compiler upgrade (from gcc10 to gcc12.3),
which will lead the hns3 NIC can't link up. The root cause is strict
aliasing violation in rte_eth_linkstatus_set() with hns3 driver, see
[1] for more details.

This commit use union to avoid such aliasing violation.

[1] Strict aliasing problem with rte_eth_linkstatus_set()
https://marc.info/?l=dpdk-dev&m=171274148514777&w=3

Cc: sta...@dpdk.org

Signed-off-by: Chengwen Feng 
Signed-off-by: Dengdui Huang 
---
 lib/ethdev/ethdev_driver.h | 23 +++
 lib/ethdev/rte_ethdev.h| 16 ++--
 2 files changed, 17 insertions(+), 22 deletions(-)

diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
index 0dbf2dd6a2..9d831d5c84 100644
--- a/lib/ethdev/ethdev_driver.h
+++ b/lib/ethdev/ethdev_driver.h
@@ -1674,18 +1674,13 @@ static inline int
 rte_eth_linkstatus_set(struct rte_eth_dev *dev,
   const struct rte_eth_link *new_link)
 {
-   RTE_ATOMIC(uint64_t) *dev_link = (uint64_t __rte_atomic 
*)&(dev->data->dev_link);
-   union {
-   uint64_t val64;
-   struct rte_eth_link link;
-   } orig;
-
-   RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
+   struct rte_eth_link old_link;
 
-   orig.val64 = rte_atomic_exchange_explicit(dev_link, *(const uint64_t 
*)new_link,
-   rte_memory_order_seq_cst);
+   old_link.val64 = 
rte_atomic_exchange_explicit(&dev->data->dev_link.val64,
+ new_link->val64,
+ rte_memory_order_seq_cst);
 
-   return (orig.link.link_status == new_link->link_status) ? -1 : 0;
+   return (old_link.link_status == new_link->link_status) ? -1 : 0;
 }
 
 /**
@@ -1701,12 +1696,8 @@ static inline void
 rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
   struct rte_eth_link *link)
 {
-   RTE_ATOMIC(uint64_t) *src = (uint64_t __rte_atomic 
*)&(dev->data->dev_link);
-   uint64_t *dst = (uint64_t *)link;
-
-   RTE_BUILD_BUG_ON(sizeof(*link) != sizeof(uint64_t));
-
-   *dst = rte_atomic_load_explicit(src, rte_memory_order_seq_cst);
+   link->val64 = rte_atomic_load_explicit(&dev->data->dev_link.val64,
+  rte_memory_order_seq_cst);
 }
 
 /**
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index 147257d6a2..0b5d3d2318 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -332,12 +332,16 @@ struct rte_eth_stats {
 /**
  * A structure used to retrieve link-level information of an Ethernet port.
  */
-__extension__
-struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64 read/write */
-   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_ */
-   uint16_t link_duplex  : 1;  /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
-   uint16_t link_autoneg : 1;  /**< RTE_ETH_LINK_[AUTONEG/FIXED] */
-   uint16_t link_status  : 1;  /**< RTE_ETH_LINK_[DOWN/UP] */
+struct rte_eth_link {
+   union {
+   uint64_t val64; /**< used for atomic64 read/write */
+   struct {
+   uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_ */
+   uint16_t link_duplex  : 1;  /**< 
RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
+   uint16_t link_autoneg : 1;  /**< 
RTE_ETH_LINK_[AUTONEG/FIXED] */
+   uint16_t link_status  : 1;  /**< RTE_ETH_LINK_[DOWN/UP] 
*/
+   };
+   };
 };
 
 /**@{@name Link negotiation
-- 
2.17.1



Re: Strict aliasing problem with rte_eth_linkstatus_set()

2024-04-10 Thread fengchengwen
Hi All,

On 2024/4/11 3:58, Tyler Retzlaff wrote:
> On Wed, Apr 10, 2024 at 07:54:27PM +0200, Morten Brørup wrote:
>>> From: Stephen Hemminger [mailto:step...@networkplumber.org]
>>> Sent: Wednesday, 10 April 2024 17.27
>>>
>>> On Wed, 10 Apr 2024 17:33:53 +0800
>>> fengchengwen  wrote:
>>>
 Last: We think there are two ways to solve this problem.
 1. Add the compilation option '-fno-strict-aliasing' for hold DPDK
>>> project.
 2. Use union to avoid such aliasing in rte_eth_linkstatus_set (please
>>> see above).
 PS: We prefer first way.

>>>
>>> Please send a patch to replace alias with union.
>>
>> +1
>>
>> Fixing this specific bug would be good.

OK for this,
and I already send a bugfix which use union.

Thanks

>>
>> Instinctively, I think we should build with -fno-strict-aliasing, so the 
>> compiler doesn't make the same mistake with similar code elsewhere in DPDK. 
>> I fear there is more than this instance.
>> I also wonder if -Wstrict-aliasing could help us instead, if we don't want 
>> -fno-strict-aliasing.
> 
> agree, union is the correct way to get defined behavior. there are
> valuable optimizatons that the compiler can make with strict aliasing
> enabled so -Wstrict-aliasing is a good suggestion as opposed to
> disabling it.
> 
> also the union won't break the abi if introduced correctly.
> .
> 


Re: [PATCH v2] build: exclude rather than include libs in MSVC build

2024-04-10 Thread Patrick Robb
Recheck-request: iol-intel-Functional


On Wed, Apr 3, 2024 at 2:23 PM Tyler Retzlaff
 wrote:
>
> Some libraries that could be built with MSVC were not being built.
>
> Switch from explicit include to exclude of libs to get immediate CI
> coverage of libraries that already work with MSVC Windows builds.
>
> Signed-off-by: Tyler Retzlaff 
> Acked-by: Stephen Hemminger 
> ---
>  lib/argparse/meson.build |  6 ++
>  lib/dmadev/meson.build   |  6 ++
>  lib/fib/meson.build  |  6 ++
>  lib/lpm/meson.build  |  6 ++
>  lib/mbuf/meson.build |  6 ++
>  lib/mempool/meson.build  |  6 ++
>  lib/meson.build  | 10 --
>  lib/mldev/meson.build|  6 ++
>  lib/rcu/meson.build  |  6 ++
>  lib/stack/meson.build|  6 ++
>  10 files changed, 54 insertions(+), 10 deletions(-)
>
> diff --git a/lib/argparse/meson.build b/lib/argparse/meson.build
> index b6a08ca..8ab4c40 100644
> --- a/lib/argparse/meson.build
> +++ b/lib/argparse/meson.build
> @@ -1,6 +1,12 @@
>  # SPDX-License-Identifier: BSD-3-Clause
>  # Copyright(c) 2024 HiSilicon Limited.
>
> +if is_ms_compiler
> +build = false
> +reason = 'not supported building with Visual Studio Toolset'
> +subdir_done()
> +endif
> +
>  sources = files('rte_argparse.c')
>  headers = files('rte_argparse.h')
>
> diff --git a/lib/dmadev/meson.build b/lib/dmadev/meson.build
> index 62b0650..e66dcb6 100644
> --- a/lib/dmadev/meson.build
> +++ b/lib/dmadev/meson.build
> @@ -1,6 +1,12 @@
>  # SPDX-License-Identifier: BSD-3-Clause
>  # Copyright(c) 2021 HiSilicon Limited.
>
> +if is_ms_compiler
> +build = false
> +reason = 'not supported building with Visual Studio Toolset'
> +subdir_done()
> +endif
> +
>  sources = files('rte_dmadev.c', 'rte_dmadev_trace_points.c')
>  headers = files('rte_dmadev.h')
>  indirect_headers += files('rte_dmadev_core.h', 'rte_dmadev_trace_fp.h')
> diff --git a/lib/fib/meson.build b/lib/fib/meson.build
> index ddcae06..6795f41 100644
> --- a/lib/fib/meson.build
> +++ b/lib/fib/meson.build
> @@ -2,6 +2,12 @@
>  # Copyright(c) 2018 Vladimir Medvedkin 
>  # Copyright(c) 2019 Intel Corporation
>
> +if is_ms_compiler
> +build = false
> +reason = 'not supported building with Visual Studio Toolset'
> +subdir_done()
> +endif
> +
>  sources = files('rte_fib.c', 'rte_fib6.c', 'dir24_8.c', 'trie.c')
>  headers = files('rte_fib.h', 'rte_fib6.h')
>  deps += ['rib']
> diff --git a/lib/lpm/meson.build b/lib/lpm/meson.build
> index 4cd4888..ae30f80 100644
> --- a/lib/lpm/meson.build
> +++ b/lib/lpm/meson.build
> @@ -1,6 +1,12 @@
>  # SPDX-License-Identifier: BSD-3-Clause
>  # Copyright(c) 2017 Intel Corporation
>
> +if is_ms_compiler
> +build = false
> +reason = 'not supported building with Visual Studio Toolset'
> +subdir_done()
> +endif
> +
>  sources = files('rte_lpm.c', 'rte_lpm6.c')
>  headers = files('rte_lpm.h', 'rte_lpm6.h')
>  # since header files have different names, we can install all vector headers
> diff --git a/lib/mbuf/meson.build b/lib/mbuf/meson.build
> index 0435c5e..2cee905 100644
> --- a/lib/mbuf/meson.build
> +++ b/lib/mbuf/meson.build
> @@ -1,6 +1,12 @@
>  # SPDX-License-Identifier: BSD-3-Clause
>  # Copyright(c) 2017 Intel Corporation
>
> +if is_ms_compiler
> +build = false
> +reason = 'not supported building with Visual Studio Toolset'
> +subdir_done()
> +endif
> +
>  sources = files(
>  'rte_mbuf.c',
>  'rte_mbuf_ptype.c',
> diff --git a/lib/mempool/meson.build b/lib/mempool/meson.build
> index 8099a56..acce66c 100644
> --- a/lib/mempool/meson.build
> +++ b/lib/mempool/meson.build
> @@ -1,6 +1,12 @@
>  # SPDX-License-Identifier: BSD-3-Clause
>  # Copyright(c) 2017 Intel Corporation
>
> +if is_ms_compiler
> +build = false
> +reason = 'not supported building with Visual Studio Toolset'
> +subdir_done()
> +endif
> +
>  extra_flags = []
>
>  foreach flag: extra_flags
> diff --git a/lib/meson.build b/lib/meson.build
> index 179a272..94d2b72 100644
> --- a/lib/meson.build
> +++ b/lib/meson.build
> @@ -68,16 +68,6 @@ libraries = [
>  'node',
>  ]
>
> -if is_ms_compiler
> -libraries = [
> -'log',
> -'kvargs',
> -'telemetry',
> -'eal',
> -'ring',
> -]
> -endif
> -
>  always_enable = [
>  'cmdline',
>  'eal',
> diff --git a/lib/mldev/meson.build b/lib/mldev/meson.build
> index 0079ccd..2c933ba 100644
> --- a/lib/mldev/meson.build
> +++ b/lib/mldev/meson.build
> @@ -1,6 +1,12 @@
>  # SPDX-License-Identifier: BSD-3-Clause
>  # Copyright (c) 2022 Marvell.
>
> +if is_ms_compiler
> +build = false
> +reason = 'not supported building with Visual Studio Toolset'
> +subdir_done()
> +endif
> +
>  sources = files(
>  'rte_mldev_pmd.c',
>  'rte_mldev.c',
> diff --git a/lib/rcu/meson.build b/lib/rcu/meson.build
> index 09abc52..71143f5 100644
> --- a/lib/rcu/meson.build
> +++ b/lib/rcu/meson.build
> @@ -1,6 

[PATCH] mlx5: fix race at mlx5_dev_close

2024-04-10 Thread hepeng
From: "hepeng.0320" 

mlx5_dev_close currently will set priv->sh->port[priv->dev_port -
1].nl_ih_port_id to RTE_MAX_ETHPORTS to avoid mlx5_dev_interrupt_nl_cb
to use the port's dev_private, because later the rte_eth_dev_close
will free the dev_private and set the pointer to NULL.

However, since mlx5_dev_interrupt_nl_cb is running in another thread,
I think the race still exists. So perhaps an easy fix is to wait for
1ms to avoid this race.

Signed-off-by: hepeng.0320 
---
 drivers/net/mlx5/mlx5.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/mlx5/mlx5.c b/drivers/net/mlx5/mlx5.c
index d1a6382..283162f 100644
--- a/drivers/net/mlx5/mlx5.c
+++ b/drivers/net/mlx5/mlx5.c
@@ -2457,6 +2457,10 @@ mlx5_dev_close(struct rte_eth_dev *dev)
 * mlx5_os_mac_addr_flush() uses ibdev_path for retrieving
 * ifindex if Netlink fails.
 */
+
+   /* Avoid race condition if mlx5_dev_interrupt_nl_cb is running. */
+   rte_delay_us_sleep(1000);
+
mlx5_free_shared_dev_ctx(priv->sh);
if (priv->domain_id != RTE_ETH_DEV_SWITCH_DOMAIN_ID_INVALID) {
unsigned int c = 0;
-- 
2.11.0



RE: [PATCH] ethdev: fix strict aliasing lead to link cannot be up

2024-04-10 Thread Morten Brørup
> From: Chengwen Feng [mailto:fengcheng...@huawei.com]
> Sent: Thursday, 11 April 2024 05.08
> 
> Fix a problem introduced by a compiler upgrade (from gcc10 to gcc12.3),
> which will lead the hns3 NIC can't link up. The root cause is strict
> aliasing violation in rte_eth_linkstatus_set() with hns3 driver, see
> [1] for more details.
> 
> This commit use union to avoid such aliasing violation.
> 
> [1] Strict aliasing problem with rte_eth_linkstatus_set()
> https://marc.info/?l=dpdk-dev&m=171274148514777&w=3
> 
> Cc: sta...@dpdk.org
> 
> Signed-off-by: Chengwen Feng 
> Signed-off-by: Dengdui Huang 
> ---

The patch mixes atomic and non-atomic access.
This is not new for DPDK, which used to rely on compiler built-in atomics.

I'm not sure if it needs to be changed, but my suggestion is inline below.

>  lib/ethdev/ethdev_driver.h | 23 +++
>  lib/ethdev/rte_ethdev.h| 16 ++--
>  2 files changed, 17 insertions(+), 22 deletions(-)
> 
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index 0dbf2dd6a2..9d831d5c84 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -1674,18 +1674,13 @@ static inline int
>  rte_eth_linkstatus_set(struct rte_eth_dev *dev,
>  const struct rte_eth_link *new_link)
>  {
> - RTE_ATOMIC(uint64_t) *dev_link = (uint64_t __rte_atomic *)&(dev-
> >data->dev_link);
> - union {
> - uint64_t val64;
> - struct rte_eth_link link;
> - } orig;
> -
> - RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
> + struct rte_eth_link old_link;
> 
> - orig.val64 = rte_atomic_exchange_explicit(dev_link, *(const
> uint64_t *)new_link,
> - rte_memory_order_seq_cst);
> + old_link.val64 = rte_atomic_exchange_explicit(&dev->data-
> >dev_link.val64,

old_link.val64 should be written using:
rte_atomic_store_explicit(&old_link.val64, 
rte_atomic_exchange_explicit(dev_link, ...), rte_memory_order_seq_cst)

> +   new_link->val64,

new_link->val64 should be read using:
rte_atomic_load_explicit(&new_link->val64, rte_memory_order_seq_cst)

> +   rte_memory_order_seq_cst);

> 
> - return (orig.link.link_status == new_link->link_status) ? -1 : 0;
> + return (old_link.link_status == new_link->link_status) ? -1 : 0;
>  }
> 
>  /**
> @@ -1701,12 +1696,8 @@ static inline void
>  rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
>  struct rte_eth_link *link)
>  {
> - RTE_ATOMIC(uint64_t) *src = (uint64_t __rte_atomic *)&(dev->data-
> >dev_link);
> - uint64_t *dst = (uint64_t *)link;
> -
> - RTE_BUILD_BUG_ON(sizeof(*link) != sizeof(uint64_t));
> -
> - *dst = rte_atomic_load_explicit(src, rte_memory_order_seq_cst);
> + link->val64 = rte_atomic_load_explicit(&dev->data->dev_link.val64,

link->val64 should be written using:
rte_atomic_store_explicit(&link->val64, 
rte_atomic_load_explicit(&dev->data->dev_link.val64, ...), 
rte_memory_order_seq_cst)


> +rte_memory_order_seq_cst);
>  }
> 
>  /**
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index 147257d6a2..0b5d3d2318 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -332,12 +332,16 @@ struct rte_eth_stats {
>  /**
>   * A structure used to retrieve link-level information of an Ethernet
> port.
>   */
> -__extension__
> -struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64
> read/write */
> - uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_ */
> - uint16_t link_duplex  : 1;  /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX
> */
> - uint16_t link_autoneg : 1;  /**< RTE_ETH_LINK_[AUTONEG/FIXED] */
> - uint16_t link_status  : 1;  /**< RTE_ETH_LINK_[DOWN/UP] */
> +struct rte_eth_link {
> + union {
> + uint64_t val64; /**< used for atomic64 read/write */
> + struct {
> + uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_
> */
> + uint16_t link_duplex  : 1;  /**<
> RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
> + uint16_t link_autoneg : 1;  /**<
> RTE_ETH_LINK_[AUTONEG/FIXED] */
> + uint16_t link_status  : 1;  /**<
> RTE_ETH_LINK_[DOWN/UP] */
> + };
> + };
>  };
> 
>  /**@{@name Link negotiation
> --
> 2.17.1



Recall: [PATCH] ethdev: fix strict aliasing lead to link cannot be up

2024-04-10 Thread Morten Brørup
Morten Brørup would like to recall the message, "[PATCH] ethdev: fix strict 
aliasing lead to link cannot be up".


RE: [PATCH] ethdev: fix strict aliasing lead to link cannot be up

2024-04-10 Thread Morten Brørup
> From: Chengwen Feng [mailto:fengcheng...@huawei.com]
> Sent: Thursday, 11 April 2024 05.08
> 
> Fix a problem introduced by a compiler upgrade (from gcc10 to gcc12.3),
> which will lead the hns3 NIC can't link up. The root cause is strict
> aliasing violation in rte_eth_linkstatus_set() with hns3 driver, see
> [1] for more details.
> 
> This commit use union to avoid such aliasing violation.
> 
> [1] Strict aliasing problem with rte_eth_linkstatus_set()
> https://marc.info/?l=dpdk-dev&m=171274148514777&w=3
> 
> Cc: sta...@dpdk.org
> 
> Signed-off-by: Chengwen Feng 
> Signed-off-by: Dengdui Huang 
> ---

The patch mixes atomic and non-atomic access.
This is not new for DPDK, which used to rely on compiler built-in atomics.

I'm not sure it needs to be changed, but my suggestion is inline below.
I don't think it makes any practical different for 64 bit arch, but it might 
for 32 bit arch.

>  lib/ethdev/ethdev_driver.h | 23 +++
>  lib/ethdev/rte_ethdev.h| 16 ++--
>  2 files changed, 17 insertions(+), 22 deletions(-)
> 
> diff --git a/lib/ethdev/ethdev_driver.h b/lib/ethdev/ethdev_driver.h
> index 0dbf2dd6a2..9d831d5c84 100644
> --- a/lib/ethdev/ethdev_driver.h
> +++ b/lib/ethdev/ethdev_driver.h
> @@ -1674,18 +1674,13 @@ static inline int
>  rte_eth_linkstatus_set(struct rte_eth_dev *dev,
>  const struct rte_eth_link *new_link)
>  {
> - RTE_ATOMIC(uint64_t) *dev_link = (uint64_t __rte_atomic *)&(dev-
> >data->dev_link);
> - union {
> - uint64_t val64;
> - struct rte_eth_link link;
> - } orig;
> -
> - RTE_BUILD_BUG_ON(sizeof(*new_link) != sizeof(uint64_t));
> + struct rte_eth_link old_link;
> 
> - orig.val64 = rte_atomic_exchange_explicit(dev_link, *(const
> uint64_t *)new_link,
> - rte_memory_order_seq_cst);
> + old_link.val64 = rte_atomic_exchange_explicit(&dev->data-
> >dev_link.val64,

old_link.val64 should be written using:
rte_atomic_store_explicit(&old_link.val64, ..., rte_memory_order_seq_cst)

> +   new_link->val64,

new_link->val64 should be read using:
rte_atomic_load_explicit(&new_link->val64, rte_memory_order_seq_cst)

> +   rte_memory_order_seq_cst);

> 
> - return (orig.link.link_status == new_link->link_status) ? -1 : 0;
> + return (old_link.link_status == new_link->link_status) ? -1 : 0;
>  }
> 
>  /**
> @@ -1701,12 +1696,8 @@ static inline void
>  rte_eth_linkstatus_get(const struct rte_eth_dev *dev,
>  struct rte_eth_link *link)
>  {
> - RTE_ATOMIC(uint64_t) *src = (uint64_t __rte_atomic *)&(dev->data-
> >dev_link);
> - uint64_t *dst = (uint64_t *)link;
> -
> - RTE_BUILD_BUG_ON(sizeof(*link) != sizeof(uint64_t));
> -
> - *dst = rte_atomic_load_explicit(src, rte_memory_order_seq_cst);
> + link->val64 = rte_atomic_load_explicit(&dev->data->dev_link.val64,

link->val64 should be written using:
rte_atomic_store_explicit(&link->val64, ..., rte_memory_order_seq_cst)

> +rte_memory_order_seq_cst);
>  }
> 
>  /**
> diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
> index 147257d6a2..0b5d3d2318 100644
> --- a/lib/ethdev/rte_ethdev.h
> +++ b/lib/ethdev/rte_ethdev.h
> @@ -332,12 +332,16 @@ struct rte_eth_stats {
>  /**
>   * A structure used to retrieve link-level information of an Ethernet
> port.
>   */
> -__extension__
> -struct __rte_aligned(8) rte_eth_link { /**< aligned for atomic64
> read/write */
> - uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_ */
> - uint16_t link_duplex  : 1;  /**< RTE_ETH_LINK_[HALF/FULL]_DUPLEX
> */
> - uint16_t link_autoneg : 1;  /**< RTE_ETH_LINK_[AUTONEG/FIXED] */
> - uint16_t link_status  : 1;  /**< RTE_ETH_LINK_[DOWN/UP] */
> +struct rte_eth_link {
> + union {
> + uint64_t val64; /**< used for atomic64 read/write */

The type of val64 should be:
RTE_ATOMIC(uint64_t)

> + struct {
> + uint32_t link_speed;/**< RTE_ETH_SPEED_NUM_
> */
> + uint16_t link_duplex  : 1;  /**<
> RTE_ETH_LINK_[HALF/FULL]_DUPLEX */
> + uint16_t link_autoneg : 1;  /**<
> RTE_ETH_LINK_[AUTONEG/FIXED] */
> + uint16_t link_status  : 1;  /**<
> RTE_ETH_LINK_[DOWN/UP] */
> + };
> + };
>  };
> 
>  /**@{@name Link negotiation
> --
> 2.17.1