[PATCH 3/6] dts: add testpmd shell params
Luca Vizzarro
Luca.Vizzarro at arm.com
Wed Apr 10 12:49:29 CEST 2024
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 <luca.vizzarro at arm.com> wrote:
>>
>> Implement all the testpmd shell parameters into a data structure.
>>
>> Signed-off-by: Luca Vizzarro <luca.vizzarro at arm.com>
>> Reviewed-by: Jack Bond-Preston <jack.bond-preston at arm.com>
>> Reviewed-by: Honnappa Nagarahalli <honnappa.nagarahalli at arm.com>
>> ---
>> 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
>
> <snip>
>
>> + at 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
>> +
>> +
>
> <snip>
>
>> + at 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."""
>> +
>> +
>> + at 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."""
>> +
>> +
>> + at 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: (
>> + Literal[
>> + TestPmdForwardingModes.io,
>> + TestPmdForwardingModes.mac,
>> + TestPmdForwardingModes.macswap,
>> + TestPmdForwardingModes.fivetswap,
>> + ]
>> + | None
>
> Is there a difference between using union (TestPmdForwardingModes.io |
> TestPmdForwardingModes.mac etc.) and Literal?
TestPmdForwardingModes.io etc are literals and mypy complains:
error: Invalid type: try using Literal[TestPmdForwardingModes.io]
instead? [misc]
Therefore they need to be wrapped in Literal[..]
Literal[A, B] is the equivalent of Union[Literal[A], Literal[B]]
So this ultimately renders as Union[Lit[io], Lit[mac], Lit[macswap],
Lit[fivetswap], None]. So it's really a matter of conciseness, by using
Literal[A, ..], vs intuitiveness, by using Literal[A] | Literal[..] | ..
Which one would we prefer?
>> + at dataclass
>> +class TestPmdDisableRSS(Params):
>> + """Disable RSS (Receive Side Scaling)."""
>
> Let's put the explanation/reminder of what RSS stands for to either
> all three classes or none of them.
>
Ack.
>> + rss: TestPmdDisableRSS | TestPmdSetRSSIPOnly | TestPmdSetRSSUDP | None = None
>> + """RSS option setting.
>> +
>> + The value can be one of:
>> + * :class:`TestPmdDisableRSS`, to disable RSS
>> + * :class:`TestPmdSetRSSIPOnly`, to set RSS for IPv4/IPv6 only
>> + * :class:`TestPmdSetRSSUDP`, to set RSS for IPv4/IPv6 and UDP
>> + """
>
> Have you thought about making an Enum where values would be these
> classes? That could simplify things a bit for users if it works.
It would be lovely to have classes as enum values, and I thought of it
thinking of other languages like Rust. Not sure this is possible in
Python. Are you suggesting to pass a class type as a value? In the hope
that doing:
TestPmdRSS.Disable()
could work? As this wouldn't. What works instead is:
TestPmdRSS.Disable.value()
Which is somewhat ugly. Maybe I could modify the behaviour of the enum
to return the underlying value instead of a reference to the field.
Do you have any better ideas?
>> +
>> + forward_mode: (
>> + Literal[
>> + TestPmdForwardingModes.io,
>> + TestPmdForwardingModes.mac,
>> + TestPmdForwardingModes.macswap,
>> + TestPmdForwardingModes.rxonly,
>> + TestPmdForwardingModes.csum,
>> + TestPmdForwardingModes.icmpecho,
>> + TestPmdForwardingModes.ieee1588,
>> + TestPmdForwardingModes.fivetswap,
>> + TestPmdForwardingModes.shared_rxq,
>> + TestPmdForwardingModes.recycle_mbufs,
>> + ]
>
> This could result in just TestPmdForwardingModes | the rest if we
> remove the compound fw modes from TestPmdForwardingModes. Maybe we
> could rename TestPmdForwardingModes to TestPmdSimpleForwardingModes or
> something at that point.
Yes, good idea.
>> + | TestPmdFlowGenForwardingMode
>> + | TestPmdTXOnlyForwardingMode
>> + | TestPmdNoisyForwardingMode
>> + | None
>> + ) = TestPmdForwardingModes.io
>> + """Set the forwarding mode.
>
> <snip>
>
>> + mempool_allocation_mode: (
>> + Literal[
>> + TestPmdMempoolAllocationMode.native,
>> + TestPmdMempoolAllocationMode.xmem,
>> + TestPmdMempoolAllocationMode.xmemhuge,
>> + ]
>> + | TestPmdAnonMempoolAllocationMode
>> + | None
>
> This looks similar to fw modes, maybe the same applies here as well.
Ack.
>> + ) = field(default=None, metadata=long("mp-alloc"))
>> + """Select mempool allocation mode.
>> +
>> + The value can be one of:
>> + * :attr:`TestPmdMempoolAllocationMode.native`
>> + * :class:`TestPmdAnonMempoolAllocationMode`
>> + * :attr:`TestPmdMempoolAllocationMode.xmem`
>> + * :attr:`TestPmdMempoolAllocationMode.xmemhuge`
>> + """
More information about the dev
mailing list