RE: [EXT] Re: [PATCH 1/2] lib: add helper to read strings from sysfs files
>-Original Message- >From: Tyler Retzlaff >Sent: Wednesday, January 25, 2023 5:16 PM >To: Thomas Monjalon >Cc: Tomasz Duszynski ; dev@dpdk.org; Jerin Jacob >Kollanukkaran >; step...@networkplumber.org; chenbo@intel.com; >david.march...@redhat.com; >bruce.richard...@intel.com >Subject: [EXT] Re: [PATCH 1/2] lib: add helper to read strings from sysfs files > >External Email > >-- >On Wed, Jan 25, 2023 at 11:39:30AM +0100, Thomas Monjalon wrote: >> 25/01/2023 11:33, Tomasz Duszynski: >> > Reading strings from sysfs files is a re-occurring pattern hence add >> > helper for doing that. >> >> In general it would be to nice to clean sysfs parsing in libs and >> drivers, so they all use some functions from EAL. > >maybe there should be a general utility library for dealing with sysfs >separate from the core EAL >that drivers / platform specific libs can share? reading/writing of sysfs files is scattered around the codebase and this has been piling up with each and and every new pmd/lib that requires it. So generally a few simple utility functions in one place may be a good idea. Would following make sense? rte_sysfs_write_int() rte_sysfs_write_string() rte_sysfs_read_int() rte_sysfs_read_string() Also seems that pattern where file gets opened once and keeps being written to until closed is reoccurring as well. So there might be some utils for that as well. Thoughts?
RE: [EXT] Re: [PATCH 1/2] lib: add helper to read strings from sysfs files
>-Original Message- >From: Thomas Monjalon >Sent: Wednesday, January 25, 2023 11:40 AM >To: Tomasz Duszynski >Cc: dev@dpdk.org; Jerin Jacob Kollanukkaran ; >step...@networkplumber.org; >chenbo@intel.com; david.march...@redhat.com; bruce.richard...@intel.com >Subject: [EXT] Re: [PATCH 1/2] lib: add helper to read strings from sysfs files > >External Email > >-- >25/01/2023 11:33, Tomasz Duszynski: >> Reading strings from sysfs files is a re-occurring pattern hence add >> helper for doing that. > >In general it would be to nice to clean sysfs parsing in libs and drivers, so >they all use some >functions from EAL. > That's generally true. Here I wanted to avoid tree-wide changes caused by unrelated work i.e a new bus and do a cleanup, i.e use this read string util where applicable, later on.
RE: [EXT] Re: [PATCH v6 1/4] lib: add generic support for reading PMU events
>-Original Message- >From: Tyler Retzlaff >Sent: Friday, January 20, 2023 7:30 PM >To: Tomasz Duszynski >Cc: dev@dpdk.org; Thomas Monjalon ; Jerin Jacob >Kollanukkaran >; m...@smartsharesystems.com; ruifeng.w...@arm.com; >mattias.ronnb...@ericsson.com; zhou...@loongson.cn; bruce.richard...@intel.com >Subject: [EXT] Re: [PATCH v6 1/4] lib: add generic support for reading PMU >events > >External Email > >-- >On Fri, Jan 20, 2023 at 12:39:12AM +0100, Tomasz Duszynski wrote: >> Add support for programming PMU counters and reading their values in >> runtime bypassing kernel completely. >> >> This is especially useful in cases where CPU cores are isolated >> (nohz_full) i.e run dedicated tasks. In such cases one cannot use >> standard perf utility without sacrificing latency and performance. >> >> Signed-off-by: Tomasz Duszynski >> --- >> MAINTAINERS| 5 + >> app/test/meson.build | 4 + >> app/test/test_pmu.c| 42 +++ >> doc/api/doxy-api-index.md | 3 +- >> doc/api/doxy-api.conf.in | 1 + >> doc/guides/prog_guide/profile_app.rst | 8 + >> doc/guides/rel_notes/release_23_03.rst | 7 + >> lib/meson.build| 1 + >> lib/pmu/meson.build| 13 + >> lib/pmu/pmu_private.h | 29 ++ >> lib/pmu/rte_pmu.c | 436 + >> lib/pmu/rte_pmu.h | 206 >> lib/pmu/version.map| 19 ++ >> 13 files changed, 773 insertions(+), 1 deletion(-) create mode >> 100644 app/test/test_pmu.c create mode 100644 lib/pmu/meson.build >> create mode 100644 lib/pmu/pmu_private.h create mode 100644 >> lib/pmu/rte_pmu.c create mode 100644 lib/pmu/rte_pmu.h create mode >> 100644 lib/pmu/version.map >> >> diff --git a/MAINTAINERS b/MAINTAINERS index 9a0f416d2e..9f13eafd95 >> 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -1697,6 +1697,11 @@ M: Nithin Dabilpuram >> M: Pavan Nikhilesh >> F: lib/node/ >> >> +PMU - EXPERIMENTAL >> +M: Tomasz Duszynski >> +F: lib/pmu/ >> +F: app/test/test_pmu* >> + >> >> Test Applications >> - >> diff --git a/app/test/meson.build b/app/test/meson.build index >> f34d19e3c3..b2c2a618b1 100644 >> --- a/app/test/meson.build >> +++ b/app/test/meson.build >> @@ -360,6 +360,10 @@ if dpdk_conf.has('RTE_LIB_METRICS') >> test_sources += ['test_metrics.c'] >> fast_tests += [['metrics_autotest', true, true]] endif >> +if is_linux >> +test_sources += ['test_pmu.c'] >> +fast_tests += [['pmu_autotest', true, true]] endif > >traditionally we don't conditionally include tests at the meson.build level, >instead we run all >tests and have them skip when executed for unsupported exec environments. > >you can take a look at test_eventdev.c as an example for a test that is >skipped on windows, i'm >sure it could be adapted to skip on freebsd if you aren't supporting it. Right, this looks better. Thanks for pointing this out.
Re: [PATCH] net/nfp: fix teardown of flows sharing a mask ID
On 1/24/2023 7:16 AM, Chaoyong He wrote: > The same data in mask section of different flow add/delete control > messages will share the same mask ID of mask table. The first flow > add control message and the last flow delete control message for a > specific mask ID should have the NFP_FL_META_FLAG_MANAGE_MASK flag set, > this will indicate to the flower firmware to allocate/deallocate the > mask table entry. > > The original logic wrongly process the flow delete control message, > and caused the first flow delete control message to have the > NFP_FL_META_FLAG_MANAGE_MASK flagset, thus the flower firmware > deallocate the mask table entry on the first delete. This in turn > prevented all the other flows sharing the same mask ID from offloading. > > Fixes: ac09376096d8 ("net/nfp: add structures and functions for flow offload") > Cc: sta...@dpdk.org > > Signed-off-by: Chaoyong He > Reviewed-by: Niklas Söderlund Applied to dpdk-next-net/main, thanks.
Re: [PATCH V4 00/11] pipeline: add IPsec support
12/01/2023 19:53, Cristian Dumitrescu: > This patch set introduces a companion block for the SWX pipeline for > IPsec support. Please can you make sure there is no error in CI? I see this problem on CentOS 7.9: examples/pipeline/cli.c:298:9: error: missing braces around initializer
Re: [PATCH v3] test/service: fix spurious failures by extending timeout
Hello Harry, On Thu, Oct 6, 2022 at 9:33 PM David Marchand wrote: > > On Thu, Oct 6, 2022 at 3:27 PM Morten Brørup > wrote: > > > This commit extends the timeout for service_may_be_active() > > > from 100ms to 1000ms. Local testing on a idle and loaded system > > > (compiling DPDK with all cores) always completes after 1 ms. > > > > > > The wait time for a service-lcore to finish is also extended > > > from 100ms to 1000ms. > > > > > > The same timeout waiting code was duplicated in two tests, and > > > is now refactored to a standalone function avoiding duplication. > > > > > > Reported-by: David Marchand > > > Suggested-by: Mattias Ronnblom > > > Signed-off-by: Harry van Haaren > > Acked-by: Morten Brørup > Reviewed-by: Mattias Rönnblom > > Ok, let's see if the situation gets better with this. > Applied, thanks. I took a look at the january month failures at UNH. Downloads/dpdk_31608e4db568_2023-01-03_06-58-00_NA/out/testlog.txt:EAL: Test assert service_lcore_attr_get line 422 failed: Service lcore not stopped after waiting. Extending the timeout just made it less likely. On a similar note, other parts are failing every once in a while: Downloads/dpdk_2a211079a92e_25064_2023-01-24_15-08-50_NA/out/testlog.txt:EAL: Test assert service_attr_get line 319 failed: attr_get() failed to get cycles (expected > zero) Downloads/dpdk_2a211079a92e_25074_2023-01-25_05-40-46_NA/out/testlog.txt:EAL: Test assert service_lcore_start_stop line 900 failed: Service core expected to poll service but it didn't Downloads/dpdk_2a211079a92e_25075_2023-01-25_09-15-58_NA/out/testlog.txt:EAL: Test assert service_lcore_start_stop line 900 failed: Service core expected to poll service but it didn't Downloads/dpdk_373f4c7de8ff_24866_2023-01-03_22-56-01_NA/out/testlog.txt:EAL: Test assert service_lcore_start_stop line 900 failed: Service core expected to poll service but it didn't Downloads/dpdk_83397b9f0739_25030_2023-01-18_18-30-19_NA/out/testlog.txt:EAL: Test assert service_lcore_start_stop line 901 failed: Service core expected to poll service but it didn't The timeout approach just does not have its place in a functional test. Either this test is rewritten, or it must go to the performance tests list so that we stop getting false positives. Can you work on this? Thanks. -- David Marchand
RE: [PATCH v6 1/4] lib: add generic support for reading PMU events
>-Original Message- >From: Morten Brørup >Sent: Friday, January 20, 2023 10:47 AM >To: Tomasz Duszynski ; dev@dpdk.org; Thomas Monjalon > >Cc: Jerin Jacob Kollanukkaran ; ruifeng.w...@arm.com; >mattias.ronnb...@ericsson.com; zhou...@loongson.cn; bruce.richard...@intel.com; >roret...@linux.microsoft.com >Subject: [EXT] RE: [PATCH v6 1/4] lib: add generic support for reading PMU >events > >External Email > >-- >> From: Tomasz Duszynski [mailto:tduszyn...@marvell.com] >> Sent: Friday, 20 January 2023 00.39 >> >> Add support for programming PMU counters and reading their values in >> runtime bypassing kernel completely. >> >> This is especially useful in cases where CPU cores are isolated >> (nohz_full) i.e run dedicated tasks. In such cases one cannot use >> standard perf utility without sacrificing latency and performance. >> >> Signed-off-by: Tomasz Duszynski >> --- > >If you insist on passing lcore_id around as a function parameter, the function >description must >mention that the lcore_id parameter must be set to rte_lcore_id() for the >functions where this is a >requirement, including all functions that use those functions. > Not sure why are you insisting so much on removing that rte_lcore_id(). Yes that macro evaluates to integer but if you don't think about internals this resembles a function call. Then natural pattern is to call it once and reuse results if possible. Passing lcore_id around implies that calls are per l-core, why would that confuse anyone reading that code? Besides, all functions taking it are internal stuff hence you cannot call it elsewhere. >Alternatively, follow my previous suggestion: Omit the lcore_id function >parameter, and use >rte_lcore_id() instead. >
Re: [PATCH 1/3] build: unblock the use of the MSVC compiler
On Wed, Jan 25, 2023 at 11:25:05AM -0800, Tyler Retzlaff wrote: > Detect when MSVC toolset is available and tweak toolchain arguments > where the meson build system offers no abstraction. > > Signed-off-by: Tyler Retzlaff > --- Acked-by: Bruce Richardson
Re: [PATCH 2/3] build: determine execution environment at config time
On Wed, Jan 25, 2023 at 11:25:06AM -0800, Tyler Retzlaff wrote: > Move execution environment determination and definitions to config. The > RTE_EXEC_ENV macros are actually used by libraries built before EAL. > > Currently it does not matter that this is determined in lib/eal since > the definitions are consumed before anything is built including libs > built before lib/eal. By moving this logic to config it allows kvargs > and telemetry to be built without EAL. > > No functional change intended. > > Signed-off-by: Tyler Retzlaff > --- Good change. This should have been done when the code was added originally. Acked-by: Bruce Richardson
Re: [PATCH v2 1/3] ethdev: add ICMPv6 ID and sequence
On 12/20/2022 7:44 AM, Leo Xu wrote: > This patch adds API support for ICMPv6 ID and sequence. > 1: Add two new pattern item types for ICMPv6 echo request and reply: > RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REQUEST > RTE_FLOW_ITEM_TYPE_ICMP6_ECHO_REPLY > > 2: Add new header file rte_icmp6.h for ICMPv6 packet definitions. > 3: Enhance testpmd flow pattern to support ICMPv6 identifier and sequence. > > Example of ICMPv6 echo pattern in testpmd command: > > pattern eth / ipv6 / icmp6_echo_request / end > pattern eth / ipv6 / icmp6_echo_reply / end > pattern eth / ipv6 / icmp6_echo_request ident is 20 seq is 30 / end > > Signed-off-by: Leo Xu > Signed-off-by: Bing Zhao > --- > app/test-pmd/cmdline_flow.c | 70 + > doc/guides/prog_guide/rte_flow.rst | 14 + > doc/guides/rel_notes/release_23_03.rst | 4 ++ > doc/guides/testpmd_app_ug/testpmd_funcs.rst | 10 +++ > lib/ethdev/rte_flow.c | 4 ++ > lib/ethdev/rte_flow.h | 25 > lib/net/meson.build | 1 + > lib/net/rte_icmp6.h | 48 ++ > 8 files changed, 176 insertions(+) > create mode 100644 lib/net/rte_icmp6.h Please update .mailmap with in this patch. > > diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c > index 88108498e0..7dc1528899 100644 > --- a/app/test-pmd/cmdline_flow.c > +++ b/app/test-pmd/cmdline_flow.c > @@ -360,6 +360,12 @@ enum index { > ITEM_ICMP6, > ITEM_ICMP6_TYPE, > ITEM_ICMP6_CODE, > + ITEM_ICMP6_ECHO_REQUEST, > + ITEM_ICMP6_ECHO_REQUEST_ID, > + ITEM_ICMP6_ECHO_REQUEST_SEQ, > + ITEM_ICMP6_ECHO_REPLY, > + ITEM_ICMP6_ECHO_REPLY_ID, > + ITEM_ICMP6_ECHO_REPLY_SEQ, > ITEM_ICMP6_ND_NS, > ITEM_ICMP6_ND_NS_TARGET_ADDR, > ITEM_ICMP6_ND_NA, > @@ -1327,6 +1333,8 @@ static const enum index next_item[] = { > ITEM_IPV6_EXT, > ITEM_IPV6_FRAG_EXT, > ITEM_ICMP6, > + ITEM_ICMP6_ECHO_REQUEST, > + ITEM_ICMP6_ECHO_REPLY, > ITEM_ICMP6_ND_NS, > ITEM_ICMP6_ND_NA, > ITEM_ICMP6_ND_OPT, > @@ -1575,6 +1583,20 @@ static const enum index item_icmp6[] = { > ZERO, > }; > > +static const enum index item_icmp6_echo_request[] = { > + ITEM_ICMP6_ECHO_REQUEST_ID, > + ITEM_ICMP6_ECHO_REQUEST_SEQ, > + ITEM_NEXT, > + ZERO, > +}; > + > +static const enum index item_icmp6_echo_reply[] = { > + ITEM_ICMP6_ECHO_REPLY_ID, > + ITEM_ICMP6_ECHO_REPLY_SEQ, > + ITEM_NEXT, > + ZERO, > +}; > + > static const enum index item_icmp6_nd_ns[] = { > ITEM_ICMP6_ND_NS_TARGET_ADDR, > ITEM_NEXT, > @@ -4323,6 +4345,54 @@ static const struct token token_list[] = { > .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6, >code)), > }, > + [ITEM_ICMP6_ECHO_REQUEST] = { > + .name = "icmp6_echo_request", > + .help = "match ICMPv6 echo request", > + .priv = PRIV_ITEM(ICMP6_ECHO_REQUEST, > + sizeof(struct rte_flow_item_icmp6_echo)), > + .next = NEXT(item_icmp6_echo_request), > + .call = parse_vc, > + }, > + [ITEM_ICMP6_ECHO_REQUEST_ID] = { > + .name = "ident", > + .help = "ICMPv6 echo request identifier", > + .next = NEXT(item_icmp6_echo_request, > NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, > + echo.identifier)), > + }, > + [ITEM_ICMP6_ECHO_REQUEST_SEQ] = { > + .name = "seq", > + .help = "ICMPv6 echo request sequence", > + .next = NEXT(item_icmp6_echo_request, > NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, > + echo.sequence)), > + }, > + [ITEM_ICMP6_ECHO_REPLY] = { > + .name = "icmp6_echo_reply", > + .help = "match ICMPv6 echo reply", > + .priv = PRIV_ITEM(ICMP6_ECHO_REPLY, > + sizeof(struct rte_flow_item_icmp6_echo)), > + .next = NEXT(item_icmp6_echo_reply), > + .call = parse_vc, > + }, > + [ITEM_ICMP6_ECHO_REPLY_ID] = { > + .name = "ident", > + .help = "ICMPv6 echo reply identifier", > + .next = NEXT(item_icmp6_echo_reply, NEXT_ENTRY(COMMON_UNSIGNED), > + item_param), > + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_icmp6_echo, > + echo.identifier)), > + }, > + [ITEM_ICMP6_ECHO_REPLY_SEQ] = { > + .name = "seq", > + .help = "ICMPv6 echo reply sequence", > + .next =
Re: [PATCH v2 0/3] support match icmpv6 ID and sequence
On 12/20/2022 7:44 AM, Leo Xu wrote: > Currently, rte_flow API does not support matching > ID and sequence fields of icmp6 echo packets. > > This patchset is used to support match icmpv6 ID and > sequence in rte_flow. It adds needed API in rte_flow, > and gives corresponding implementation for mlx5 pmd. > > Leo Xu (3): > ethdev: add ICMPv6 ID and sequence > net/mlx5: add ICMPv6 ID and sequence match support > net/mlx5/hws: add ICMPv6 ID and sequence match support > > --- > v2: > * rebase 23.03 > mlx patches are giving following warning: $ ./devtools/check-doc-vs-code.sh rte_flow doc out of sync for mlx5 item icmp6_echo_reply item icmp6_echo_request Also can you please make sure driver patches are acked by driver maintainers, so we can merge all set with ethdev and driver patches together.
Re: [EXT] Re: [PATCH v3 0/4] implementation of ML common code
25/01/2023 15:59, Srikanth Yalavarthi: > From: Thomas Monjalon > > 25/01/2023 14:25, Srikanth Yalavarthi: > > > From: Thomas Monjalon > > > > 20/12/2022 18:52, Srikanth Yalavarthi: > > > > > This patch series implements the common ML code that can be used > > > > > by ML drivers. Common code include functions to convert ML IO type > > > > > to string, IO format type to string, function get size of ML IO > > > > > type, and functions for converting data types from higher > > > > > precision to lower precision and vice-versa. > > > > > > > > I'm not sure about the path of this code. > > > > In general we implement drivers helper in the same directory as the > > > > driver and mark it as internal. > > > > Would it work here? > > > > > > We are planning to implement two different ML drivers, ml/cnxk driver > > (submitted for review) and a software only driver (part of ML roadmap and > > currently WIP). Both the drivers would be using these common functions for > > quantization and dequantization. Hence, placed the files in common/ml > > directory. > > > > > > Moreover, these functions are used to convert data from higher to lower > > precision or vice-versa and can also be used by future ML drivers for other > > platforms. > > > > I understand, and what you say does not contradict with having this code in > > lib/mldev/. > > So would you agree to move? > > These common functions do not have an rte_ml_dev_ prefix. As it is exported, it should have rte_ prefix. > Is it ok to have non-RTE code in lib/mldev. If yes, we can move to lib/mldev. Look at lib/ethdev/ethdev_driver.h, it should be similar.
Re: [EXT] Re: [PATCH v5 2/2] app/testpmd: add command to process Rx metadata negotiation
Please reply inline below instead of doing an incomplete copy of the replies on top. 25/01/2023 15:42, Nithin Kumar Dabilpuram: > > >Will it work to enable them all by default and add capability to disable > > >it in testpmd, which helps to run performance tests also to verify the > > > impact of the API? > > The spirit of the negotiating features/Rx/Tx offloads upfront is to have it > disabled by default and enable the feature only when needed. Having the > features enabled by default is probably against that spirit. > > We understand the concerns with drivers that didn't not implement that API. There is no such concern I think. > Why not disable it by default(like other offloads) and modify rte_flow action > creation in testpmd to check for if !ENOSUP and feature disabled and add > print to enable. So for the PMD's that won't support > rte_eth_rx_metadata_negotiate(), there won't be any difference and for very > few PMD's that support this API, they need to enable it before using RTE_FLOW > with MARK/FLAG. > Behavior change would be seen only with two PMD's(cnxk, sfc). I think you missed the whole point. Ferruh is proposing to have a command "port config ..." to configure the flags to negotiate. Are you OK with this approach? > > Note: I don't understand why we don't have > > RTE_FLOW_ACTION_TYPE_SET_TAG and RTE_FLOW_ACTION_TYPE_SET_META > > negotiated in this function. Probably something to add. > > The purpose of negotiate is to tell the PMD upfront so that PMD can prepare > HW appropriately. Having these new actions would be very late to inform PMD > and > I think won't solve the purpose. I am not talking about your problem here. I am just saying that TAG and META should be negotiated as well in rte_eth_rx_metadata_negotiate(). > From: Thomas Monjalon > > 25/01/2023 14:55, Ferruh Yigit: > > > On 1/25/2023 12:55 PM, Thomas Monjalon wrote: > > > > 25/01/2023 10:30, Hanumanth Reddy Pothula: > > > >> ++ Ivan Malov and Andrew Rybchenko > > > >> > > > >> From: Ferruh Yigit > > > >>> On 12/21/2022 2:07 AM, Hanumanth Pothula wrote: > > > Presently, Rx metadata is sent to PMD by default, leading to a > > > performance drop as processing for the same in Rx path takes extra > > > cycles. > > > > > > Hence, add new testpmd command, > > > 'enable port nic_to_pmd_rx_metadata' > > > > > > This command helps in sending Rx metadata to PMD and thereby Rx > > > metadata flow command requests are processed. > > > > > > Signed-off-by: Hanumanth Pothula > > > >>> > > > >>> Hi Hanumanth, > > > >>> > > > >>> I agree with Thomas for the patch. > > > >>> > > > >>> 'eth_rx_metadata_negotiate_mp()' requests all Rx metadata offloads to > > > >>> be > > > >>> enabled, but at this stage if there is no flow rule for Rx metadata > > > >>> why it is > > > >>> consuming extra cycles? > > > >>> > > > >>> Can you update driver code to process Rx metadata when it is enabled > > > >>> by > > > >>> application (via 'rte_eth_rx_metadata_negotiate()') AND there is at > > > >>> least > > > >>> one flow rule for it? > > > >> > > > >> #1 What is the purpose of rte_eth_rx_metadata_negotiate() API if it is > > > >> always called by > > testpmd. > > > >> We thought it was added so that when that metadata is not needed, > > > >> application need > > not call this > > > >> thereby saving cycles/bandwidth. > > > > > > > > testpmd is for testing all features. That's why all is negotiated. > > > > Cycles should be saved if you don't enable it until a flow rule > > > > requires it. > > > > > > > > > > Hi Thomas, > > > > > > Not just for saving cycles, but from testing perspective too, do you > > > think does it work if a way to disable these Rx metadata added by > > > keeping default behavior as it is? > > > > > > And new command can be in a consistent command syntax like: > > > "port config ..." > > > > Yes I agree it would be good to have a way to test different values. > > And it would allow to completely disable metadata I suppose. > > > > Note: I don't understand why we don't have > > RTE_FLOW_ACTION_TYPE_SET_TAG and RTE_FLOW_ACTION_TYPE_SET_META > > negotiated in this function. Probably something to add. > > > > > > > >> #2 We use this API similar to Rx/Tx offload flags so that we can set > > > >> things up before > > device is > > > >> configured. We thought that is the purpose of having this negotiate > > > >> API and avoid > > depleting offload flags. > > > > > > > > It is just a configuration negotiation specific to metadata. > > > > > > > >> #3 Generally any new offloads added to DPDK would be in disabled state > > > >> in testpmd > > and we would have > > > >> an option to enable it. In this case, testpmd is by default calling > > > >> this negotiation. > > > > > > > > Negotiating is not enabling. > > > > > > > >> We can update the driver if the purpose of this API is clear. > > > > > > > > Please do. > > > > > > Is following understanding correc
Re: [PATCH 3/3] build: limit what is built when using MSVC compiler
On Wed, Jan 25, 2023 at 11:25:07AM -0800, Tyler Retzlaff wrote: > Build only kvargs and telemetry when is_ms_compiler. > > Signed-off-by: Tyler Retzlaff > --- > lib/meson.build | 7 +++ > meson.build | 13 + > 2 files changed, 16 insertions(+), 4 deletions(-) > > diff --git a/lib/meson.build b/lib/meson.build > index 82e4666..8e99e21 100644 > --- a/meson.build > +++ b/meson.build > @@ -76,11 +76,16 @@ subdir('config') > > # build libs and drivers > subdir('lib') > -subdir('drivers') > > -# build binaries and installable tools > -subdir('usertools') > -subdir('app') > +if is_ms_compiler > +enabled_apps = [] > +else > +subdir('drivers') > + > +# build binaries and installable tools > +subdir('usertools') > +subdir('app') > +endif > My own preference here would be to put the checks inside the subdirectories, and try and keep the top-level meson.build file clean. Would that work ok? > # build docs > subdir('doc') > -- > 1.8.3.1 >
Re: [dpdk-dev] [PATCH v1 00/12] mldev: introduce machine learning device library
25/01/2023 20:01, Jerin Jacob: > On Wed, Jan 25, 2023 at 7:50 PM Thomas Monjalon wrote: > > 14/11/2022 13:02, jer...@marvell.com: > > > ML Model: An ML model is an algorithm trained over a dataset. A model > > > consists of > > > procedure/algorithm and data/pattern required to make predictions on live > > > data. > > > Once the model is created and trained outside of the DPDK scope, the > > > model can be loaded > > > via rte_ml_model_load() and then start it using rte_ml_model_start() API. > > > The rte_ml_model_params_update() can be used to update the model > > > parameters such as weight > > > and bias without unloading the model using rte_ml_model_unload(). > > > > The fact that the model is prepared outside means the model format is free > > and probably different per mldev driver. > > I think it is OK but it requires a lot of documentation effort to explain > > how to bind the model and its parameters with the DPDK API. > > Also we may need to pass some metadata from the model builder > > to the inference engine in order to enable optimizations prepared in the > > model. > > And the other way, we may need inference capabilities in order to generate > > an optimized model which can run in the inference engine. > > The base API specification kept absolute minimum. Currently, weight and biases > parameters updated through rte_ml_model_params_update(). It can be extended > when there are drivers supports it or if you have any specific > parameter you would like to add > it in rte_ml_model_params_update(). This function is int rte_ml_model_params_update(int16_t dev_id, int16_t model_id, void *buffer); How are we supposed to provide separate parameters in this void* ? > Other metadata data like batch, shapes, formats queried using > rte_ml_io_info(). Copying: +/** Input and output data information structure + * + * Specifies the type and shape of input and output data. + */ +struct rte_ml_io_info { + char name[RTE_ML_STR_MAX]; + /**< Name of data */ + struct rte_ml_io_shape shape; + /**< Shape of data */ + enum rte_ml_io_type qtype; + /**< Type of quantized data */ + enum rte_ml_io_type dtype; + /**< Type of de-quantized data */ +}; Is it the right place to notify the app that some model optimizations are supported? (example: merge some operations in the graph) > > [...] > > > Typical application utilisation of the ML API will follow the following > > > programming flow. > > > > > > - rte_ml_dev_configure() > > > - rte_ml_dev_queue_pair_setup() > > > - rte_ml_model_load() > > > - rte_ml_model_start() > > > - rte_ml_model_info() > > > - rte_ml_dev_start() > > > - rte_ml_enqueue_burst() > > > - rte_ml_dequeue_burst() > > > - rte_ml_model_stop() > > > - rte_ml_model_unload() > > > - rte_ml_dev_stop() > > > - rte_ml_dev_close() > > > > Where is parameters update in this flow? > > Added the mandatory APIs in the top level flow doc. > rte_ml_model_params_update() used to update the parameters. The question is "where" should it be done? Before/after start? > > Should we update all parameters at once or can it be done more fine-grain? > > Currently, rte_ml_model_params_update() can be used to update weight > and bias via buffer when device is > in stop state and without unloading the model. The question is "can we update a single parameter"? And how? > > Question about the memory used by mldev: > > Can we manage where the memory is allocated (host, device, mix, etc)? > > Just passing buffer pointers now like other subsystem. > Other EAL infra service can take care of the locality of memory as it > is not specific to ML dev. I was thinking about memory allocation required by the inference engine. How to specify where to allocate? Is it just hardcoded in the driver?
Minutes of Technical Board Meeting, 2023-01-25
NOTE: The technical board meetings are on every second Wednesday at https://meet.jit.si/DPDK at 3 pm UTC. Meetings are public, and DPDK community members are welcome to attend. NOTE: Next meeting will be on Wednesday 2023-02-08 @3pm UTC, and will be chaired by Hemant. Agenda Items New Library Acceptance --- - TB agreed the need for a documented process for accepting new libraries into DPDK - Doing a proper RFC and then full patchsets is significant work and getting early approval-in-principle that a library is suitable for DPDK will help avoid wasted effort if it is not suitable - As part of the process, our guidelines should document what needs to be covered in the initial library RFC submission - any licensing constraints - justification for adding to DPDK - any other implementations of the same functionality in other libs/products and how this version differs. - Jerin has already made an initial proposal on the mailing list - Action: Jerin to propose an official process/policy by way of documentation patch for DPDK contributing guide. - to be discussed on-list - voted on by Tech-Board at next meeting Review of Proposed Libraries for DPDK 23.03 PDCP Library - library is solving a single problem - library offers complete support for full or partial protocol offload - designed in the same way as existing IPSec library in DPDK - Library approved in principle for inclusion in DPDK MLDev Library - library for inference functionality only - model creation is out of scope for library - for use cases of offloading raw packets, or lightly processed packets to inference engine - Library approved in principle for inclusion in DPDK Memarea Library - Jerin provided best-effort explanation of library purpose and functionality - library for giving blocks of memory for general DPDK use - memory may be of different types and not necessarily pinned or dma-capable - can request memory from certain specific registered ranges - Stephen H. to investigate similar functionality which is believed available in some malloc libraries, to see if we can learn from those whether this may fit in our existing malloc code. - felt that merging would reduce duplication, and avoid confusion about the number of memory allocation/free functions DPDK supports - concern expressed about perf of rte_malloc - library was felt to be providing a fast-path variable-size allocator for DPDK: - DPDK mempools provide existing fast-path allocator but for fixed-size blocks only - DPDK rte_malloc provides variable allocations, but is not for fast-path use - Decided to invite author in to a future techboard meeting to discuss further PMU Library - library to expose HW performance counters from various architectures - plans to link this in with DPDK trace functionality - TB ask to try and keep functionality in new library, rather than in EAL - concern about variance in both counters and methods of counting across architectures - felt this just needed to be covered in documentation - Library approved in principle for inclusion in DPDK Splitting EAL -- - Bruce reminded TB about patchset to extract logging functionality from EAL into separate library - also covered other (unsuccessful) attempts to extract other parts cleanly - Morten suggested looking to extract out per-architecture parts, or per-OS parts of EAL - Thomas suggested alternative approach of extracting the EAL init - higher level parts - of EAL rather than looking to extract out the low-level bits first. - More discussion to follow - few people actually looking into problem, so help needed. Conference --- - Question asked about planning for a conference or meetup for DPDK this year. - Thomas informed TB that there was a small marketing team looking at this, but nothing likely to be organised in early part of the year.
Re: [PATCH v6 1/5] eal: add lcore info in telemetry
On Thu, Jan 19, 2023 at 4:08 PM Robin Jarry wrote: > > Report the same information than rte_lcore_dump() in the telemetry > API into /eal/lcore/list and /eal/lcore/info,ID. > > Example: > > --> /eal/lcore/info,3 > { > "/eal/lcore/info": { > "lcore_id": 3, > "socket": 0, > "role": "RTE", > "cpuset": [ > 3 > ] > } > } > > Signed-off-by: Robin Jarry > Acked-by: Morten Brørup > --- > > Notes: > v5 -> v6: No change > > lib/eal/common/eal_common_lcore.c | 96 +++ > 1 file changed, 96 insertions(+) > > diff --git a/lib/eal/common/eal_common_lcore.c > b/lib/eal/common/eal_common_lcore.c > index 06c594b0224f..16548977dce8 100644 > --- a/lib/eal/common/eal_common_lcore.c > +++ b/lib/eal/common/eal_common_lcore.c > @@ -10,6 +10,9 @@ > #include > #include > #include > +#ifndef RTE_EXEC_ENV_WINDOWS > +#include > +#endif > > #include "eal_private.h" > #include "eal_thread.h" > @@ -456,3 +459,96 @@ rte_lcore_dump(FILE *f) > { > rte_lcore_iterate(lcore_dump_cb, f); > } > + > +#ifndef RTE_EXEC_ENV_WINDOWS > +static int > +lcore_telemetry_id_cb(unsigned int lcore_id, void *arg) > +{ > + struct rte_tel_data *d = arg; > + return rte_tel_data_add_array_int(d, lcore_id); > +} > + > +static int > +handle_lcore_list(const char *cmd __rte_unused, > + const char *params __rte_unused, > + struct rte_tel_data *d) Indent should be single tab. > +{ > + int ret = rte_tel_data_start_array(d, RTE_TEL_INT_VAL); > + if (ret) > + return ret; > + return rte_lcore_iterate(lcore_telemetry_id_cb, d); > +} > + > +struct lcore_telemetry_info { > + unsigned int lcore_id; > + struct rte_tel_data *d; > +}; > + > +static int > +lcore_telemetry_info_cb(unsigned int lcore_id, void *arg) > +{ > + struct lcore_telemetry_info *info = arg; > + struct rte_config *cfg = rte_eal_get_configuration(); > + struct rte_tel_data *cpuset; > + const char *role; > + unsigned int cpu; When possible, reverse xmas tree please. > + > + if (info->lcore_id != lcore_id) > + return 0; > + > + switch (cfg->lcore_role[lcore_id]) { > + case ROLE_RTE: > + role = "RTE"; > + break; > + case ROLE_SERVICE: > + role = "SERVICE"; > + break; > + case ROLE_NON_EAL: > + role = "NON_EAL"; > + break; > + default: > + role = "UNKNOWN"; > + break; > + } Please put this translation block in a helper to avoid duplicating with lcore_dump_cb. > + rte_tel_data_start_dict(info->d); > + rte_tel_data_add_dict_int(info->d, "lcore_id", lcore_id); > + rte_tel_data_add_dict_int(info->d, "socket", > rte_lcore_to_socket_id(lcore_id)); > + rte_tel_data_add_dict_string(info->d, "role", role); > + cpuset = rte_tel_data_alloc(); > + if (!cpuset) > + return -ENOMEM; > + rte_tel_data_start_array(cpuset, RTE_TEL_INT_VAL); > + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) > + if (CPU_ISSET(cpu, &lcore_config[lcore_id].cpuset)) > + rte_tel_data_add_array_int(cpuset, cpu); > + rte_tel_data_add_dict_container(info->d, "cpuset", cpuset, 0); > + > + return 0; > +} > + > +static int > +handle_lcore_info(const char *cmd __rte_unused, const char *params, struct > rte_tel_data *d) > +{ > + struct lcore_telemetry_info info = { .d = d }; > + char *endptr = NULL; Missing a newline. > + if (params == NULL || strlen(params) == 0) > + return -EINVAL; > + errno = 0; > + info.lcore_id = strtoul(params, &endptr, 10); > + if (errno) > + return -errno; > + if (endptr == params) > + return -EINVAL; > + return rte_lcore_iterate(lcore_telemetry_info_cb, &info); > +} > + > +RTE_INIT(lcore_telemetry) > +{ > + rte_telemetry_register_cmd( > + "/eal/lcore/list", handle_lcore_list, > + "List of lcore ids. Takes no parameters"); Please fix indent. > + rte_telemetry_register_cmd( > + "/eal/lcore/info", handle_lcore_info, > + "Returns lcore info. Parameters: int lcore_id"); > +} > +#endif /* !RTE_EXEC_ENV_WINDOWS */ > -- > 2.39.0 > -- David Marchand
Re: [PATCH v6 2/5] eal: allow applications to report their cpu usage
On Thu, Jan 19, 2023 at 4:08 PM Robin Jarry wrote: > > Allow applications to register a callback that will be invoked in > rte_lcore_dump() and when requesting lcore info in the telemetry API. > > The callback is expected to return the number of TSC cycles that have > passed since application start and the number of these cycles that were > spent doing busy work. > > Signed-off-by: Robin Jarry > Acked-by: Morten Brørup > --- > > Notes: > v5 -> v6: Added/rephrased some inline comments. > > lib/eal/common/eal_common_lcore.c | 45 --- > lib/eal/include/rte_lcore.h | 35 > lib/eal/version.map | 1 + > 3 files changed, 78 insertions(+), 3 deletions(-) > > diff --git a/lib/eal/common/eal_common_lcore.c > b/lib/eal/common/eal_common_lcore.c > index 16548977dce8..80513cfe3725 100644 > --- a/lib/eal/common/eal_common_lcore.c > +++ b/lib/eal/common/eal_common_lcore.c > @@ -2,6 +2,7 @@ > * Copyright(c) 2010-2014 Intel Corporation > */ > > +#include > #include > #include > > @@ -422,11 +423,21 @@ rte_lcore_iterate(rte_lcore_iterate_cb cb, void *arg) > return ret; > } > > +static rte_lcore_usage_cb lcore_usage_cb; > + > +void > +rte_lcore_register_usage_cb(rte_lcore_usage_cb cb) > +{ > + lcore_usage_cb = cb; > +} > + > static int > lcore_dump_cb(unsigned int lcore_id, void *arg) > { > struct rte_config *cfg = rte_eal_get_configuration(); > - char cpuset[RTE_CPU_AFFINITY_STR_LEN]; > + char cpuset[RTE_CPU_AFFINITY_STR_LEN], usage_str[256]; This is a debug/non performance sensitive helper. Please remove this "big enough for now" buffer and use a dynamic allocation. > + struct rte_lcore_usage usage; > + rte_lcore_usage_cb usage_cb; > const char *role; > FILE *f = arg; > int ret; > @@ -446,11 +457,25 @@ lcore_dump_cb(unsigned int lcore_id, void *arg) > break; > } > > + /* The callback may not set all the fields in the structure, so clear > it here. */ > + memset(&usage, 0, sizeof(usage)); > + usage_str[0] = '\0'; > + /* > +* Guard against concurrent modification of lcore_usage_cb. > +* rte_lcore_register_usage_cb() should only be called once at > application init > +* but nothing prevents and application to reset the callback to NULL. > +*/ > + usage_cb = lcore_usage_cb; > + if (usage_cb != NULL && usage_cb(lcore_id, &usage) == 0) { > + snprintf(usage_str, sizeof(usage_str), ", busy cycles > %"PRIu64"/%"PRIu64, > + usage.busy_cycles, usage.total_cycles); > + } > ret = eal_thread_dump_affinity(&lcore_config[lcore_id].cpuset, cpuset, > sizeof(cpuset)); > - fprintf(f, "lcore %u, socket %u, role %s, cpuset %s%s\n", lcore_id, > + fprintf(f, "lcore %u, socket %u, role %s, cpuset %s%s%s\n", lcore_id, > rte_lcore_to_socket_id(lcore_id), role, cpuset, > - ret == 0 ? "" : "..."); > + ret == 0 ? "" : "...", usage_str); > + > return 0; > } > > @@ -489,7 +514,9 @@ lcore_telemetry_info_cb(unsigned int lcore_id, void *arg) > { > struct lcore_telemetry_info *info = arg; > struct rte_config *cfg = rte_eal_get_configuration(); > + struct rte_lcore_usage usage; > struct rte_tel_data *cpuset; > + rte_lcore_usage_cb usage_cb; > const char *role; > unsigned int cpu; Reverse xmas tree please. > > @@ -522,6 +549,18 @@ lcore_telemetry_info_cb(unsigned int lcore_id, void *arg) > if (CPU_ISSET(cpu, &lcore_config[lcore_id].cpuset)) > rte_tel_data_add_array_int(cpuset, cpu); > rte_tel_data_add_dict_container(info->d, "cpuset", cpuset, 0); > + /* The callback may not set all the fields in the structure, so clear > it here. */ > + memset(&usage, 0, sizeof(usage)); > + /* > +* Guard against concurrent modification of lcore_usage_cb. > +* rte_lcore_register_usage_cb() should only be called once at > application init > +* but nothing prevents and application to reset the callback to NULL. > +*/ > + usage_cb = lcore_usage_cb; > + if (usage_cb != NULL && usage_cb(lcore_id, &usage) == 0) { > + rte_tel_data_add_dict_u64(info->d, "total_cycles", > usage.total_cycles); > + rte_tel_data_add_dict_u64(info->d, "busy_cycles", > usage.busy_cycles); > + } > > return 0; > } > diff --git a/lib/eal/include/rte_lcore.h b/lib/eal/include/rte_lcore.h > index 6938c3fd7b81..52468e7120dd 100644 > --- a/lib/eal/include/rte_lcore.h > +++ b/lib/eal/include/rte_lcore.h > @@ -328,6 +328,41 @@ typedef int (*rte_lcore_iterate_cb)(unsigned int > lcore_id, void *arg); > int > rte_lcore_iterate(rte_lcore_iterate_cb cb, void *arg); > > +/** > + * CPU usage statistics. Let's be consistent a
Re: [PATCH v6 3/5] testpmd: add dump_lcores command
On Thu, Jan 19, 2023 at 4:08 PM Robin Jarry wrote: > > Add a simple command that calls rte_lcore_dump(). > > Signed-off-by: Robin Jarry > Acked-by: Morten Brørup > Acked-by: Konstantin Ananyev We maintain consistent prefixes for commit titles in git. Historically, testpmd patches titles are prefixed with app/testpmd. All dump commands are described in testpmd documentation. Please update it. -- David Marchand
Re: [PATCH v4 1/9] eal: annotate spinlock, rwlock and seqlock
On Thu, Jan 19, 2023 at 10:50 PM Tyler Retzlaff wrote: > > > we briefly touched on abstracting annotations in another thread. it > > > would be favorable if annotations were stashed behind macros that could > > > be expanded for more than just clang/internal/under doxygen to make > > > available opportunities to use other annotation dialects that may be > > > compatible. > > > > I am open to abstractions. > > Do you have pointers for an equivalent functionnality in other > > compilers/tooling? > > aye, reference documentation for SALv2 is here. > https://learn.microsoft.com/en-us/cpp/code-quality/using-sal-annotations-to-reduce-c-cpp-code-defects?view=msvc-170 > > locking annotations are here. > https://learn.microsoft.com/en-us/cpp/code-quality/annotating-locking-behavior?view=msvc-170 I had a brief look at it and it seems close to what clang proposes. I think there would be no issue with my current proposal since SAL uses function attributes-like syntax for locking. Do you see anything blocking? Thanks Tyler. -- David Marchand
RE: [PATCH 2/2] app/testpmd: add disable-flow-flush parameter
Hi, > -Original Message- > From: Ferruh Yigit > Sent: Wednesday, 25 January 2023 20:38 > > On 12/15/2022 1:41 AM, Chengwen Feng wrote: > > This patch adds "--disable-flow-flush" parameter, which could used to > > disable port flow flush when stop port. It allows testing keep flow > > rules or shared flow objects across restart. > > > > Signed-off-by: Chengwen Feng > > +cc Ori > > I am for proceeding with this patch unless there is objection from Aman > & Ori. > > > --- > > app/test-pmd/parameters.c | 4 > > app/test-pmd/testpmd.c| 7 ++- > > app/test-pmd/testpmd.h| 1 + > > doc/guides/testpmd_app_ug/run_app.rst | 5 + > > 4 files changed, 16 insertions(+), 1 deletion(-) > > > > diff --git a/app/test-pmd/parameters.c b/app/test-pmd/parameters.c > > index d597c209ba..e734ad9a02 100644 > > --- a/app/test-pmd/parameters.c > > +++ b/app/test-pmd/parameters.c > > @@ -175,6 +175,7 @@ usage(char* progname) > >"disable print of designated event or all of them.\n"); > > printf(" --flow-isolate-all: " > >"requests flow API isolated mode on all ports at initialization > time.\n"); > > + printf(" --disable-flow-flush: disable port flow flush when stop > port.\n"); > > printf(" --tx-offloads=0x: hexadecimal bitmask of TX > queue offloads\n"); > > printf(" --rx-offloads=0x: hexadecimal bitmask of RX > queue offloads\n"); > > printf(" --hot-plug: enable hot plug for device.\n"); > > @@ -667,6 +668,7 @@ launch_args_parse(int argc, char** argv) > > { "rxfreet",1, 0, 0 }, > > { "no-flush-rx",0, 0, 0 }, > > { "flow-isolate-all", 0, 0, 0 }, > > + { "disable-flow-flush", 0, 0, 0 }, > > { "rxoffs", 1, 0, 0 }, > > { "rxpkts", 1, 0, 0 }, > > { "rxhdrs", 1, 0, 0 }, > > @@ -1330,6 +1332,8 @@ launch_args_parse(int argc, char** argv) > > rmv_interrupt = 0; > > if (!strcmp(lgopts[opt_idx].name, "flow-isolate-all")) > > flow_isolate_all = 1; > > + if (!strcmp(lgopts[opt_idx].name, "disable-flow- > flush")) > > + no_flow_flush = 1; > > if (!strcmp(lgopts[opt_idx].name, "tx-offloads")) { > > char *end = NULL; > > n = strtoull(optarg, &end, 16); > > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c > > index 134d79a555..ea78f8982d 100644 > > --- a/app/test-pmd/testpmd.c > > +++ b/app/test-pmd/testpmd.c > > @@ -383,6 +383,11 @@ uint8_t no_flush_rx = 0; /* flush by default */ > > */ > > uint8_t flow_isolate_all; > > > > +/* > > + * Disable port flow flush when stop port. > > + */ > > +uint8_t no_flow_flush = 0; /* do flow flush by default */ > > + > > /* > > * Avoids to check link status when starting/stopping a port. > > */ > > @@ -3246,7 +3251,7 @@ stop_port(portid_t pid) > > } > > } > > > > - if (port->flow_list) > > + if (port->flow_list && !no_flow_flush) > > port_flow_flush(pi); > > > > ret = eth_dev_stop_mp(pi); > > diff --git a/app/test-pmd/testpmd.h b/app/test-pmd/testpmd.h > > index 7d24d25970..ab4733522d 100644 > > --- a/app/test-pmd/testpmd.h > > +++ b/app/test-pmd/testpmd.h > > @@ -476,6 +476,7 @@ extern uint8_t numa_support; /**< set by "-- > numa" parameter */ > > extern uint16_t port_topology; /**< set by "--port-topology" parameter > */ > > extern uint8_t no_flush_rx; /** > extern uint8_t flow_isolate_all; /**< set by "--flow-isolate-all */ > > +extern uint8_t no_flow_flush; /**< set by "--disable-flow-flush" > parameter */ > > extern uint8_t mp_alloc_type; > > /**< set by "--mp-anon" or "--mp-alloc" parameter */ > > extern uint32_t eth_link_speed; > > diff --git a/doc/guides/testpmd_app_ug/run_app.rst > b/doc/guides/testpmd_app_ug/run_app.rst > > index 074f910fc9..3ec3d4f5e6 100644 > > --- a/doc/guides/testpmd_app_ug/run_app.rst > > +++ b/doc/guides/testpmd_app_ug/run_app.rst > > @@ -436,6 +436,11 @@ The command line options are: > > > > Ports that do not support this mode are automatically discarded. > > > > +* ``--disable-flow-flush`` > > + > > +Disable port flow flush when stop port. This allows testing keep flow > rules > > +or shared flow objects across restart. > > + > > * ``--tx-offloads=0x`` > > > > Set the hexadecimal bitmask of TX queue offloads. Acked-by: Ori Kam Best, Ori
RE: [PATCH v6 1/4] lib: add generic support for reading PMU events
> From: Tomasz Duszynski [mailto:tduszyn...@marvell.com] > Sent: Thursday, 26 January 2023 10.40 > > >From: Morten Brørup > >Sent: Friday, January 20, 2023 10:47 AM > > > >> From: Tomasz Duszynski [mailto:tduszyn...@marvell.com] > >> Sent: Friday, 20 January 2023 00.39 > >> > >> Add support for programming PMU counters and reading their values in > >> runtime bypassing kernel completely. > >> > >> This is especially useful in cases where CPU cores are isolated > >> (nohz_full) i.e run dedicated tasks. In such cases one cannot use > >> standard perf utility without sacrificing latency and performance. > >> > >> Signed-off-by: Tomasz Duszynski > >> --- > > > >If you insist on passing lcore_id around as a function parameter, the > function description must > >mention that the lcore_id parameter must be set to rte_lcore_id() for > the functions where this is a > >requirement, including all functions that use those functions. Perhaps I'm stating this wrong, so let me try to rephrase: As I understand it, some of the setup functions must be called from the EAL thread that executes that function - due to some syscall (SYS_perf_event_open) needing to be called from the thread itself. Those functions should not take an lcore_id parameter. Otherwise, I would expect to be able to call those functions from e.g. the main thread and pass the lcore_id of any EAL thread as a parameter, which you at the bottom of this email [1] explained is not possible. [1]: http://inbox.dpdk.org/dev/dm4pr18mb4368461ec42603f77a7dc1bcd2...@dm4pr18mb4368.namprd18.prod.outlook.com/ > > > > Not sure why are you insisting so much on removing that rte_lcore_id(). > Yes that macro evaluates > to integer but if you don't think about internals this resembles a > function call. I agree with this argument. And for that reason, passing lcore_id around could be relevant. I only wanted to bring your attention to the low cost of fetching it inside the functions, as an alternative to passing it as an argument. > > Then natural pattern is to call it once and reuse results if possible. Yes, and I would usually agree to using this pattern. > Passing lcore_id around > implies that calls are per l-core, why would that confuse anyone > reading that code? This is where I disagree: Passing lcore_id as a parameter to a function does NOT imply that the function is running on that lcore! E.g rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id) [2] takes lcore_id as a parameter, and does not assume that lcore_id==rte_lcore_id(). [2]: https://elixir.bootlin.com/dpdk/latest/source/lib/mempool/rte_mempool.h#L1315 > > Besides, all functions taking it are internal stuff hence you cannot > call it elsewhere. OK. I agree that this reduces the risk of incorrect use. Generally, I think that internal functions should be documented too. Not to the full extent, like public functions, but some documentation is nice. And if there are special requirements to a function parameter, it should be documented with that function. Requiring that the lcore_id parameter must be == rte_lcore_id() is certainly a special requirement. It might just be me worrying too much, so... If nobody else complains about this, I can live with it as is. Assuming that none of the public functions have this special requirement (either directly or indirectly, by calling functions with the special requirement). > > >Alternatively, follow my previous suggestion: Omit the lcore_id > function parameter, and use > >rte_lcore_id() instead. > > >
RE: [PATCH] net/mlx5/hws: fix memory leak on general pool db init
From: Alex Vesker > On elemend db init we allocated the element_manager which was unused > and not freed. > > Fixes: b4dd7bcb0dcbe ("net/mlx5/hws: add pool and buddy") > Signed-off-by: Alex Vesker > Reviewed-by: Erez Shitrit Acked-by: Matan Azrad
Re: [PATCH v6 1/4] lib: add generic support for reading PMU events
On Thu, Jan 26, 2023 at 01:29:36PM +0100, Morten Brørup wrote: > > From: Tomasz Duszynski [mailto:tduszyn...@marvell.com] > > Sent: Thursday, 26 January 2023 10.40 > > > > >From: Morten Brørup > > >Sent: Friday, January 20, 2023 10:47 AM > > > > > >> From: Tomasz Duszynski [mailto:tduszyn...@marvell.com] > > >> Sent: Friday, 20 January 2023 00.39 > > >> > > >> Add support for programming PMU counters and reading their values in > > >> runtime bypassing kernel completely. > > >> > > >> This is especially useful in cases where CPU cores are isolated > > >> (nohz_full) i.e run dedicated tasks. In such cases one cannot use > > >> standard perf utility without sacrificing latency and performance. > > >> > > >> Signed-off-by: Tomasz Duszynski > > >> --- > > > > > >If you insist on passing lcore_id around as a function parameter, the > > function description must > > >mention that the lcore_id parameter must be set to rte_lcore_id() for > > the functions where this is a > > >requirement, including all functions that use those functions. > > Perhaps I'm stating this wrong, so let me try to rephrase: > > As I understand it, some of the setup functions must be called from the EAL > thread that executes that function - due to some syscall > (SYS_perf_event_open) needing to be called from the thread itself. > > Those functions should not take an lcore_id parameter. Otherwise, I would > expect to be able to call those functions from e.g. the main thread and pass > the lcore_id of any EAL thread as a parameter, which you at the bottom of > this email [1] explained is not possible. > > [1]: > http://inbox.dpdk.org/dev/dm4pr18mb4368461ec42603f77a7dc1bcd2...@dm4pr18mb4368.namprd18.prod.outlook.com/ > > > > > > > > Not sure why are you insisting so much on removing that rte_lcore_id(). > > Yes that macro evaluates > > to integer but if you don't think about internals this resembles a > > function call. > > I agree with this argument. And for that reason, passing lcore_id around > could be relevant. > > I only wanted to bring your attention to the low cost of fetching it inside > the functions, as an alternative to passing it as an argument. > > > > > Then natural pattern is to call it once and reuse results if possible. > > Yes, and I would usually agree to using this pattern. > > > Passing lcore_id around > > implies that calls are per l-core, why would that confuse anyone > > reading that code? > > This is where I disagree: Passing lcore_id as a parameter to a function does > NOT imply that the function is running on that lcore! > > E.g rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id) [2] > takes lcore_id as a parameter, and does not assume that > lcore_id==rte_lcore_id(). > > [2]: > https://elixir.bootlin.com/dpdk/latest/source/lib/mempool/rte_mempool.h#L1315 > > > > > Besides, all functions taking it are internal stuff hence you cannot > > call it elsewhere. > > OK. I agree that this reduces the risk of incorrect use. > > Generally, I think that internal functions should be documented too. Not to > the full extent, like public functions, but some documentation is nice. > > And if there are special requirements to a function parameter, it should be > documented with that function. Requiring that the lcore_id parameter must be > == rte_lcore_id() is certainly a special requirement. > > It might just be me worrying too much, so... If nobody else complains about > this, I can live with it as is. Assuming that none of the public functions > have this special requirement (either directly or indirectly, by calling > functions with the special requirement). > I would tend to agree with you Morten. If the lcore_id parameter to the function must be rte_lcore_id(), then I think it's error prone to have that as an explicit parameter, and that the function should always get the core id itself. Other possible complication is - how does this work with threads that are not pinned to a particular physical core? Do things work as expected in that case? /Bruce
RE: [PATCH V4 00/11] pipeline: add IPsec support
> -Original Message- > From: Thomas Monjalon > Sent: Thursday, January 26, 2023 9:17 AM > To: Dumitrescu, Cristian > Cc: dev@dpdk.org > Subject: Re: [PATCH V4 00/11] pipeline: add IPsec support > > 12/01/2023 19:53, Cristian Dumitrescu: > > This patch set introduces a companion block for the SWX pipeline for > > IPsec support. > > Please can you make sure there is no error in CI? > > I see this problem on CentOS 7.9: > examples/pipeline/cli.c:298:9: error: missing braces around initializer > Yes, will send V5 in a few minutes. This is valid C syntax, but it looks like the old (i.e. from 2015) gcc 4.8.5 that comes with CentOS 7.9 complains about it. Thanks, Cristian
[PATCH v4 0/8] start cleanup of rte_flow_item_*
There was a plan to have structures from lib/net/ at the beginning of corresponding flow item structures. Unfortunately this plan has not been followed up so far. This series is a step to make the most used items, compliant with the inheritance design explained above. The old API is kept in anonymous union for compatibility, but the code in drivers and apps is updated to use the new API. v4: * Fix build error for RHEL7 (gcc 4.8.5) caused by nested struct initialization. v3: * Updated Higig2 protocol flow item assignment taking into account endianness annotations. v2: (by Ferruh) * Rebased on latest next-net for v23.03 * 'struct rte_gre_hdr' endianness annotation added to protocol field * more driver code updated for rte_flow_item_eth & rte_flow_item_vlan * 'struct rte_gre_hdr' updated to have a combined "rte_be16_t c_rsvd0_ver" field and updated drivers accordingly * more driver code updated for rte_flow_item_gre * more driver code updated for rte_flow_item_gtp Cc: David Marchand Thomas Monjalon (8): ethdev: use Ethernet protocol struct for flow matching net: add smaller fields for VXLAN ethdev: use VXLAN protocol struct for flow matching ethdev: use GRE protocol struct for flow matching ethdev: use GTP protocol struct for flow matching ethdev: use ARP protocol struct for flow matching doc: fix description of L2TPV2 flow item net: mark all big endian types app/test-flow-perf/actions_gen.c | 2 +- app/test-flow-perf/items_gen.c | 24 +-- app/test-pmd/cmdline_flow.c | 180 +++--- doc/guides/prog_guide/rte_flow.rst | 57 ++- doc/guides/rel_notes/deprecation.rst | 6 +- drivers/net/bnxt/bnxt_flow.c | 54 +++ drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 112 +++--- drivers/net/bonding/rte_eth_bond_pmd.c | 12 +- drivers/net/cxgbe/cxgbe_flow.c | 44 +++--- drivers/net/dpaa2/dpaa2_flow.c | 60 drivers/net/dpaa2/dpaa2_mux.c| 2 +- drivers/net/e1000/igb_flow.c | 14 +- drivers/net/enic/enic_flow.c | 24 +-- drivers/net/enic/enic_fm_flow.c | 16 +- drivers/net/hinic/hinic_pmd_flow.c | 14 +- drivers/net/hns3/hns3_flow.c | 40 ++--- drivers/net/i40e/i40e_fdir.c | 14 +- drivers/net/i40e/i40e_flow.c | 124 +++ drivers/net/i40e/i40e_hash.c | 4 +- drivers/net/iavf/iavf_fdir.c | 18 +-- drivers/net/iavf/iavf_fsub.c | 10 +- drivers/net/iavf/iavf_ipsec_crypto.c | 4 +- drivers/net/ice/ice_acl_filter.c | 20 +-- drivers/net/ice/ice_fdir_filter.c| 24 +-- drivers/net/ice/ice_switch_filter.c | 64 drivers/net/igc/igc_flow.c | 8 +- drivers/net/ipn3ke/ipn3ke_flow.c | 12 +- drivers/net/ixgbe/ixgbe_flow.c | 58 +++ drivers/net/mlx4/mlx4_flow.c | 38 ++--- drivers/net/mlx5/hws/mlx5dr_definer.c| 48 +++--- drivers/net/mlx5/mlx5_flow.c | 62 drivers/net/mlx5/mlx5_flow_dv.c | 184 --- drivers/net/mlx5/mlx5_flow_hw.c | 80 +- drivers/net/mlx5/mlx5_flow_verbs.c | 46 +++--- drivers/net/mlx5/mlx5_trigger.c | 28 ++-- drivers/net/mvpp2/mrvl_flow.c| 28 ++-- drivers/net/nfp/nfp_flow.c | 21 +-- drivers/net/sfc/sfc_flow.c | 52 +++ drivers/net/sfc/sfc_mae.c| 46 +++--- drivers/net/tap/tap_flow.c | 58 +++ drivers/net/txgbe/txgbe_flow.c | 28 ++-- lib/ethdev/rte_flow.h| 121 ++- lib/net/rte_arp.h| 28 ++-- lib/net/rte_gre.h| 7 +- lib/net/rte_higig.h | 6 +- lib/net/rte_mpls.h | 2 +- lib/net/rte_vxlan.h | 35 - 47 files changed, 987 insertions(+), 952 deletions(-) -- 2.25.1
[PATCH v4 1/8] ethdev: use Ethernet protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. The Ethernet headers (including VLAN) structures are used instead of the redundant fields in the flow items. The remaining protocols to clean up are listed for future work in the deprecation list. Some protocols are not even defined in the directory net yet. Signed-off-by: Thomas Monjalon --- app/test-flow-perf/items_gen.c | 4 +- app/test-pmd/cmdline_flow.c | 140 +++ doc/guides/prog_guide/rte_flow.rst | 7 +- doc/guides/rel_notes/deprecation.rst | 2 + drivers/net/bnxt/bnxt_flow.c | 42 +++ drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 58 +- drivers/net/bonding/rte_eth_bond_pmd.c | 12 +- drivers/net/cxgbe/cxgbe_flow.c | 44 +++ drivers/net/dpaa2/dpaa2_flow.c | 48 drivers/net/dpaa2/dpaa2_mux.c| 2 +- drivers/net/e1000/igb_flow.c | 14 +-- drivers/net/enic/enic_flow.c | 24 ++-- drivers/net/enic/enic_fm_flow.c | 16 +-- drivers/net/hinic/hinic_pmd_flow.c | 14 +-- drivers/net/hns3/hns3_flow.c | 28 ++--- drivers/net/i40e/i40e_flow.c | 100 drivers/net/i40e/i40e_hash.c | 4 +- drivers/net/iavf/iavf_fdir.c | 10 +- drivers/net/iavf/iavf_fsub.c | 10 +- drivers/net/iavf/iavf_ipsec_crypto.c | 4 +- drivers/net/ice/ice_acl_filter.c | 20 ++-- drivers/net/ice/ice_fdir_filter.c| 14 +-- drivers/net/ice/ice_switch_filter.c | 34 +++--- drivers/net/igc/igc_flow.c | 8 +- drivers/net/ipn3ke/ipn3ke_flow.c | 8 +- drivers/net/ixgbe/ixgbe_flow.c | 40 +++ drivers/net/mlx4/mlx4_flow.c | 38 +++--- drivers/net/mlx5/hws/mlx5dr_definer.c| 26 ++--- drivers/net/mlx5/mlx5_flow.c | 24 ++-- drivers/net/mlx5/mlx5_flow_dv.c | 94 +++ drivers/net/mlx5/mlx5_flow_hw.c | 80 ++--- drivers/net/mlx5/mlx5_flow_verbs.c | 30 ++--- drivers/net/mlx5/mlx5_trigger.c | 28 ++--- drivers/net/mvpp2/mrvl_flow.c| 28 ++--- drivers/net/nfp/nfp_flow.c | 12 +- drivers/net/sfc/sfc_flow.c | 46 drivers/net/sfc/sfc_mae.c| 38 +++--- drivers/net/tap/tap_flow.c | 58 +- drivers/net/txgbe/txgbe_flow.c | 28 ++--- 39 files changed, 618 insertions(+), 619 deletions(-) diff --git a/app/test-flow-perf/items_gen.c b/app/test-flow-perf/items_gen.c index a73de9031f54..b7f51030a119 100644 --- a/app/test-flow-perf/items_gen.c +++ b/app/test-flow-perf/items_gen.c @@ -37,10 +37,10 @@ add_vlan(struct rte_flow_item *items, __rte_unused struct additional_para para) { static struct rte_flow_item_vlan vlan_spec = { - .tci = RTE_BE16(VLAN_VALUE), + .hdr.vlan_tci = RTE_BE16(VLAN_VALUE), }; static struct rte_flow_item_vlan vlan_mask = { - .tci = RTE_BE16(0x), + .hdr.vlan_tci = RTE_BE16(0x), }; items[items_counter].type = RTE_FLOW_ITEM_TYPE_VLAN; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 88108498e0c3..694a7eb647c5 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -3633,19 +3633,19 @@ static const struct token token_list[] = { .name = "dst", .help = "destination MAC", .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, dst)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), }, [ITEM_ETH_SRC] = { .name = "src", .help = "source MAC", .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, src)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), }, [ITEM_ETH_TYPE] = { .name = "type", .help = "EtherType", .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), }, [ITEM_ETH_HAS_VLAN] = { .name = "has_vlan", @@ -3666,7 +3666,7 @@ static const struct token token_list[] = { .help = "tag control information", .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)), +
[PATCH v4 2/8] net: add smaller fields for VXLAN
From: Thomas Monjalon The VXLAN and VXLAN-GPE headers were including reserved fields with other fields in big uint32_t struct members. Some more precise definitions are added as union of the old ones. The new struct members are smaller in size and in names. Signed-off-by: Thomas Monjalon --- lib/net/rte_vxlan.h | 35 +-- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/net/rte_vxlan.h b/lib/net/rte_vxlan.h index 929fa7a1dd01..997fc784fc84 100644 --- a/lib/net/rte_vxlan.h +++ b/lib/net/rte_vxlan.h @@ -30,9 +30,20 @@ extern "C" { * Contains the 8-bit flag, 24-bit VXLAN Network Identifier and * Reserved fields (24 bits and 8 bits) */ +__extension__ /* no named member in struct */ struct rte_vxlan_hdr { - rte_be32_t vx_flags; /**< flag (8) + Reserved (24). */ - rte_be32_t vx_vni; /**< VNI (24) + Reserved (8). */ + union { + struct { + rte_be32_t vx_flags; /**< flags (8) + Reserved (24). */ + rte_be32_t vx_vni; /**< VNI (24) + Reserved (8). */ + }; + struct { + uint8_tflags;/**< Should be 8 (I flag). */ + uint8_trsvd0[3]; /**< Reserved. */ + uint8_tvni[3]; /**< VXLAN identifier. */ + uint8_trsvd1;/**< Reserved. */ + }; + }; } __rte_packed; /** VXLAN tunnel header length. */ @@ -45,11 +56,23 @@ struct rte_vxlan_hdr { * Contains the 8-bit flag, 8-bit next-protocol, 24-bit VXLAN Network * Identifier and Reserved fields (16 bits and 8 bits). */ +__extension__ /* no named member in struct */ struct rte_vxlan_gpe_hdr { - uint8_t vx_flags;/**< flag (8). */ - uint8_t reserved[2]; /**< Reserved (16). */ - uint8_t proto; /**< next-protocol (8). */ - rte_be32_t vx_vni; /**< VNI (24) + Reserved (8). */ + union { + struct { + uint8_t vx_flags;/**< flag (8). */ + uint8_t reserved[2]; /**< Reserved (16). */ + uint8_t protocol;/**< next-protocol (8). */ + rte_be32_t vx_vni; /**< VNI (24) + Reserved (8). */ + }; + struct { + uint8_t flags;/**< Flags. */ + uint8_t rsvd0[2]; /**< Reserved. */ + uint8_t proto;/**< Next protocol. */ + uint8_t vni[3]; /**< VXLAN identifier. */ + uint8_t rsvd1;/**< Reserved. */ + }; + }; } __rte_packed; /** VXLAN-GPE tunnel header length. */ -- 2.25.1
[PATCH v4 3/8] ethdev: use VXLAN protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. In the case of VXLAN-GPE, the protocol struct is added in an unnamed union, keeping old field names. The VXLAN headers (including VXLAN-GPE) are used in apps and drivers instead of the redundant fields in the flow items. Signed-off-by: Thomas Monjalon --- app/test-flow-perf/actions_gen.c | 2 +- app/test-flow-perf/items_gen.c | 12 +++ app/test-pmd/cmdline_flow.c | 10 +++--- doc/guides/prog_guide/rte_flow.rst | 11 ++- doc/guides/rel_notes/deprecation.rst | 1 - drivers/net/bnxt/bnxt_flow.c | 12 --- drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 42 drivers/net/hns3/hns3_flow.c | 12 +++ drivers/net/i40e/i40e_flow.c | 4 +-- drivers/net/ice/ice_switch_filter.c | 18 +- drivers/net/ipn3ke/ipn3ke_flow.c | 4 +-- drivers/net/ixgbe/ixgbe_flow.c | 18 +- drivers/net/mlx5/mlx5_flow.c | 16 - drivers/net/mlx5/mlx5_flow_dv.c | 40 +++--- drivers/net/mlx5/mlx5_flow_verbs.c | 8 ++--- drivers/net/sfc/sfc_flow.c | 6 ++-- drivers/net/sfc/sfc_mae.c| 8 ++--- lib/ethdev/rte_flow.h| 24 ++ 18 files changed, 126 insertions(+), 122 deletions(-) diff --git a/app/test-flow-perf/actions_gen.c b/app/test-flow-perf/actions_gen.c index 63f05d87fa86..f1d59313256d 100644 --- a/app/test-flow-perf/actions_gen.c +++ b/app/test-flow-perf/actions_gen.c @@ -874,7 +874,7 @@ add_vxlan_encap(struct rte_flow_action *actions, items[2].type = RTE_FLOW_ITEM_TYPE_UDP; - item_vxlan.vni[2] = 1; + item_vxlan.hdr.vni[2] = 1; items[3].spec = &item_vxlan; items[3].mask = &item_vxlan; items[3].type = RTE_FLOW_ITEM_TYPE_VXLAN; diff --git a/app/test-flow-perf/items_gen.c b/app/test-flow-perf/items_gen.c index b7f51030a119..a58245239ba1 100644 --- a/app/test-flow-perf/items_gen.c +++ b/app/test-flow-perf/items_gen.c @@ -128,12 +128,12 @@ add_vxlan(struct rte_flow_item *items, /* Set standard vxlan vni */ for (i = 0; i < 3; i++) { - vxlan_specs[ti].vni[2 - i] = vni_value >> (i * 8); - vxlan_masks[ti].vni[2 - i] = 0xff; + vxlan_specs[ti].hdr.vni[2 - i] = vni_value >> (i * 8); + vxlan_masks[ti].hdr.vni[2 - i] = 0xff; } /* Standard vxlan flags */ - vxlan_specs[ti].flags = 0x8; + vxlan_specs[ti].hdr.flags = 0x8; items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN; items[items_counter].spec = &vxlan_specs[ti]; @@ -155,12 +155,12 @@ add_vxlan_gpe(struct rte_flow_item *items, /* Set vxlan-gpe vni */ for (i = 0; i < 3; i++) { - vxlan_gpe_specs[ti].vni[2 - i] = vni_value >> (i * 8); - vxlan_gpe_masks[ti].vni[2 - i] = 0xff; + vxlan_gpe_specs[ti].hdr.vni[2 - i] = vni_value >> (i * 8); + vxlan_gpe_masks[ti].hdr.vni[2 - i] = 0xff; } /* vxlan-gpe flags */ - vxlan_gpe_specs[ti].flags = 0x0c; + vxlan_gpe_specs[ti].hdr.flags = 0x0c; items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE; items[items_counter].spec = &vxlan_gpe_specs[ti]; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 694a7eb647c5..b904f8c3d45c 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -3984,7 +3984,7 @@ static const struct token token_list[] = { .help = "VXLAN identifier", .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), }, [ITEM_VXLAN_LAST_RSVD] = { .name = "last_rsvd", @@ -3992,7 +3992,7 @@ static const struct token token_list[] = { .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, -rsvd1)), +hdr.rsvd1)), }, [ITEM_E_TAG] = { .name = "e_tag", @@ -4210,7 +4210,7 @@ static const struct token token_list[] = { .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, -vni)), +hdr.vni)), }, [ITEM_ARP_ETH_IPV4] = { .name = "arp_eth_ipv4", @@ -7500,7 +75
[PATCH v4 4/8] ethdev: use GRE protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. The protocol struct is added in an unnamed union, keeping old field names. The GRE header struct members are used in apps and drivers instead of the redundant fields in the flow items. Signed-off-by: Thomas Monjalon --- app/test-flow-perf/items_gen.c | 4 ++-- app/test-pmd/cmdline_flow.c | 14 +-- doc/guides/prog_guide/rte_flow.rst | 6 + doc/guides/rel_notes/deprecation.rst | 1 - drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 12 +- drivers/net/dpaa2/dpaa2_flow.c | 12 +- drivers/net/mlx5/hws/mlx5dr_definer.c| 8 +++ drivers/net/mlx5/mlx5_flow.c | 22 - drivers/net/mlx5/mlx5_flow_dv.c | 30 +--- drivers/net/mlx5/mlx5_flow_verbs.c | 8 +++ drivers/net/nfp/nfp_flow.c | 9 +++ lib/ethdev/rte_flow.h| 24 +-- lib/net/rte_gre.h| 5 13 files changed, 83 insertions(+), 72 deletions(-) diff --git a/app/test-flow-perf/items_gen.c b/app/test-flow-perf/items_gen.c index a58245239ba1..0f19e5e53648 100644 --- a/app/test-flow-perf/items_gen.c +++ b/app/test-flow-perf/items_gen.c @@ -173,10 +173,10 @@ add_gre(struct rte_flow_item *items, __rte_unused struct additional_para para) { static struct rte_flow_item_gre gre_spec = { - .protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), + .hdr.proto = RTE_BE16(RTE_ETHER_TYPE_TEB), }; static struct rte_flow_item_gre gre_mask = { - .protocol = RTE_BE16(0x), + .hdr.proto = RTE_BE16(0x), }; items[items_counter].type = RTE_FLOW_ITEM_TYPE_GRE; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index b904f8c3d45c..0e115956514c 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -4071,7 +4071,7 @@ static const struct token token_list[] = { .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, -protocol)), +hdr.proto)), }, [ITEM_GRE_C_RSVD0_VER] = { .name = "c_rsvd0_ver", @@ -4082,7 +4082,7 @@ static const struct token token_list[] = { .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, -c_rsvd0_ver)), +hdr.c_rsvd0_ver)), }, [ITEM_GRE_C_BIT] = { .name = "c_bit", @@ -4090,7 +4090,7 @@ static const struct token token_list[] = { .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, - c_rsvd0_ver, + hdr.c_rsvd0_ver, "\x80\x00\x00\x00")), }, [ITEM_GRE_S_BIT] = { @@ -4098,7 +4098,7 @@ static const struct token token_list[] = { .help = "sequence number bit (S)", .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, - c_rsvd0_ver, + hdr.c_rsvd0_ver, "\x10\x00\x00\x00")), }, [ITEM_GRE_K_BIT] = { @@ -4106,7 +4106,7 @@ static const struct token token_list[] = { .help = "key bit (K)", .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, - c_rsvd0_ver, + hdr.c_rsvd0_ver, "\x20\x00\x00\x00")), }, [ITEM_FUZZY] = { @@ -7837,7 +7837,7 @@ parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, }, }; struct rte_flow_item_gre gre = { - .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), + .hdr.proto = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), }; struct rte_flow_item_mpls mpls = { .ttl = 0, @@ -7935,7 +7935,7 @@ parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, }, };
[PATCH v4 5/8] ethdev: use GTP protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. The protocol struct is added in an unnamed union, keeping old field names. The GTP header struct members are used in apps and drivers instead of the redundant fields in the flow items. Signed-off-by: Thomas Monjalon --- app/test-flow-perf/items_gen.c| 4 ++-- app/test-pmd/cmdline_flow.c | 8 +++ doc/guides/prog_guide/rte_flow.rst| 10 ++--- doc/guides/rel_notes/deprecation.rst | 1 - drivers/net/i40e/i40e_fdir.c | 14 ++-- drivers/net/i40e/i40e_flow.c | 20 - drivers/net/iavf/iavf_fdir.c | 8 +++ drivers/net/ice/ice_fdir_filter.c | 10 - drivers/net/ice/ice_switch_filter.c | 12 +- drivers/net/mlx5/hws/mlx5dr_definer.c | 14 ++-- drivers/net/mlx5/mlx5_flow_dv.c | 20 - lib/ethdev/rte_flow.h | 32 ++- 12 files changed, 78 insertions(+), 75 deletions(-) diff --git a/app/test-flow-perf/items_gen.c b/app/test-flow-perf/items_gen.c index 0f19e5e53648..55eb6f5cf009 100644 --- a/app/test-flow-perf/items_gen.c +++ b/app/test-flow-perf/items_gen.c @@ -213,10 +213,10 @@ add_gtp(struct rte_flow_item *items, __rte_unused struct additional_para para) { static struct rte_flow_item_gtp gtp_spec = { - .teid = RTE_BE32(TEID_VALUE), + .hdr.teid = RTE_BE32(TEID_VALUE), }; static struct rte_flow_item_gtp gtp_mask = { - .teid = RTE_BE32(0x), + .hdr.teid = RTE_BE32(0x), }; items[items_counter].type = RTE_FLOW_ITEM_TYPE_GTP; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 0e115956514c..dd6da9d98d9b 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -4137,19 +4137,19 @@ static const struct token token_list[] = { .help = "GTP flags", .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, - v_pt_rsv_flags)), + hdr.gtp_hdr_info)), }, [ITEM_GTP_MSG_TYPE] = { .name = "msg_type", .help = "GTP message type", .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, msg_type)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), }, [ITEM_GTP_TEID] = { .name = "teid", .help = "tunnel endpoint identifier", .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, teid)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), }, [ITEM_GTPC] = { .name = "gtpc", @@ -11224,7 +11224,7 @@ cmd_set_raw_parsed(const struct buffer *in) goto error; } gtp = item->spec; - if ((gtp->v_pt_rsv_flags & 0x07) != 0x04) { + if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { /* Only E flag should be set. */ fprintf(stderr, "Error - GTP unsupported flags\n"); diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 603e1b866be3..ec2e335fac3d 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1064,12 +1064,7 @@ Note: GTP, GTPC and GTPU use the same structure. GTPC and GTPU item are defined for a user-friendly API when creating GTP-C and GTP-U flow rules. -- ``v_pt_rsv_flags``: version (3b), protocol type (1b), reserved (1b), - extension header flag (1b), sequence number flag (1b), N-PDU number - flag (1b). -- ``msg_type``: message type. -- ``msg_len``: message length. -- ``teid``: tunnel endpoint identifier. +- ``hdr``: header definition (``rte_gtp.h``). - Default ``mask`` matches teid only. Item: ``ESP`` @@ -1235,8 +1230,7 @@ Item: ``GTP_PSC`` Matches a GTP PDU extension header with type 0x85. -- ``pdu_type``: PDU type. -- ``qfi``: QoS flow identifier. +- ``hdr``: header definition (``rte_gtp.h``). - Default ``mask`` matches QFI only. Item: ``PPPOES``, ``PPPOED`` diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index 80bf7209065a..b89450b239ef 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -68,7 +68,6 @@ Deprecation Notices - ``rte_flow_item_e_tag`` - ``rte_flow_item_geneve`` - ``rte_flow_i
[PATCH v4 6/8] ethdev: use ARP protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. The protocol struct is added in an unnamed union, keeping old field names. The ARP header struct members are used in testpmd instead of the redundant fields in the flow items. Signed-off-by: Thomas Monjalon --- app/test-pmd/cmdline_flow.c | 8 +++--- doc/guides/prog_guide/rte_flow.rst | 10 +--- doc/guides/rel_notes/deprecation.rst | 1 - lib/ethdev/rte_flow.h| 37 ++-- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index dd6da9d98d9b..1d337a96199d 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -4226,7 +4226,7 @@ static const struct token token_list[] = { .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, -sha)), +hdr.arp_data.arp_sha)), }, [ITEM_ARP_ETH_IPV4_SPA] = { .name = "spa", @@ -4234,7 +4234,7 @@ static const struct token token_list[] = { .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, -spa)), +hdr.arp_data.arp_sip)), }, [ITEM_ARP_ETH_IPV4_THA] = { .name = "tha", @@ -4242,7 +4242,7 @@ static const struct token token_list[] = { .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, -tha)), +hdr.arp_data.arp_tha)), }, [ITEM_ARP_ETH_IPV4_TPA] = { .name = "tpa", @@ -4250,7 +4250,7 @@ static const struct token token_list[] = { .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, -tpa)), +hdr.arp_data.arp_tip)), }, [ITEM_IPV6_EXT] = { .name = "ipv6_ext", diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index ec2e335fac3d..8bf85df2f611 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1100,15 +1100,7 @@ Item: ``ARP_ETH_IPV4`` Matches an ARP header for Ethernet/IPv4. -- ``hdr``: hardware type, normally 1. -- ``pro``: protocol type, normally 0x0800. -- ``hln``: hardware address length, normally 6. -- ``pln``: protocol address length, normally 4. -- ``op``: opcode (1 for request, 2 for reply). -- ``sha``: sender hardware address. -- ``spa``: sender IPv4 address. -- ``tha``: target hardware address. -- ``tpa``: target IPv4 address. +- ``hdr``: header definition (``rte_arp.h``). - Default ``mask`` matches SHA, SPA, THA and TPA. Item: ``IPV6_EXT`` diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index b89450b239ef..8e3683990117 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -64,7 +64,6 @@ Deprecation Notices These items are not compliant (not including struct from lib/net/): - ``rte_flow_item_ah`` - - ``rte_flow_item_arp_eth_ipv4`` - ``rte_flow_item_e_tag`` - ``rte_flow_item_geneve`` - ``rte_flow_item_geneve_opt`` diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index 85ca73d1dc04..a215daa83640 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1255,26 +1256,36 @@ static const struct rte_flow_item_vxlan_gpe rte_flow_item_vxlan_gpe_mask = { * * Matches an ARP header for Ethernet/IPv4. */ +RTE_STD_C11 struct rte_flow_item_arp_eth_ipv4 { - rte_be16_t hrd; /**< Hardware type, normally 1. */ - rte_be16_t pro; /**< Protocol type, normally 0x0800. */ - uint8_t hln; /**< Hardware address length, normally 6. */ - uint8_t pln; /**< Protocol address length, normally 4. */ - rte_be16_t op; /**< Opcode (1 for request, 2 for reply). */ - struct rte_ether_addr sha; /**< Sender hardware address. */ - rte_be32_t spa; /**< Sender IPv4 address. */ - struct rte_ether_addr tha; /**< Target hardware address. */ - rte_be32_t tpa; /**< Target IPv4 address. */ + union { +
[PATCH v4 7/8] doc: fix description of L2TPV2 flow item
From: Thomas Monjalon The flow item structure includes the protocol definition from the directory lib/net/, so it is reflected in the guide. Section title underlining is also fixed around. Fixes: 3a929df1f286 ("ethdev: support L2TPv2 and PPP procotol") Cc: sta...@dpdk.org Signed-off-by: Thomas Monjalon --- Cc: jie1x.w...@intel.com --- doc/guides/prog_guide/rte_flow.rst | 13 +++-- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 8bf85df2f611..c01b53aad8ed 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1485,22 +1485,15 @@ rte_flow_flex_item_create() routine. value and mask. Item: ``L2TPV2`` -^^^ + Matches a L2TPv2 header. -- ``flags_version``: flags(12b), version(4b). -- ``length``: total length of the message. -- ``tunnel_id``: identifier for the control connection. -- ``session_id``: identifier for a session within a tunnel. -- ``ns``: sequence number for this date or control message. -- ``nr``: sequence number expected in the next control message to be received. -- ``offset_size``: offset of payload data. -- ``offset_padding``: offset padding, variable length. +- ``hdr``: header definition (``rte_l2tpv2.h``). - Default ``mask`` matches flags_version only. Item: ``PPP`` -^^^ +^ Matches a PPP header. -- 2.25.1
[PATCH v4 8/8] net: mark all big endian types
From: Thomas Monjalon Some protocols (ARP, MPLS and HIGIG2) were using uint16_t and uint32_t types for their 16 and 32-bit fields. It was correct but not conveying the big endian nature of these fields. As for other protocols defined in this directory, all types are explicitly marked as big endian fields. Signed-off-by: Thomas Monjalon --- lib/ethdev/rte_flow.h | 4 ++-- lib/net/rte_arp.h | 28 ++-- lib/net/rte_gre.h | 2 +- lib/net/rte_higig.h | 6 +++--- lib/net/rte_mpls.h| 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index a215daa83640..99f8340f8274 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -642,8 +642,8 @@ struct rte_flow_item_higig2_hdr { static const struct rte_flow_item_higig2_hdr rte_flow_item_higig2_hdr_mask = { .hdr = { .ppt1 = { - .classification = 0x, - .vid = 0xfff, + .classification = RTE_BE16(0x), + .vid = RTE_BE16(0xfff), }, }, }; diff --git a/lib/net/rte_arp.h b/lib/net/rte_arp.h index 076c8ab314ee..151e6c641fc5 100644 --- a/lib/net/rte_arp.h +++ b/lib/net/rte_arp.h @@ -23,28 +23,28 @@ extern "C" { */ struct rte_arp_ipv4 { struct rte_ether_addr arp_sha; /**< sender hardware address */ - uint32_t arp_sip; /**< sender IP address */ + rte_be32_tarp_sip; /**< sender IP address */ struct rte_ether_addr arp_tha; /**< target hardware address */ - uint32_t arp_tip; /**< target IP address */ + rte_be32_tarp_tip; /**< target IP address */ } __rte_packed __rte_aligned(2); /** * ARP header. */ struct rte_arp_hdr { - uint16_t arp_hardware;/* format of hardware address */ -#define RTE_ARP_HRD_ETHER 1 /* ARP Ethernet address format */ + rte_be16_t arp_hardware; /** format of hardware address */ +#define RTE_ARP_HRD_ETHER 1 /** ARP Ethernet address format */ - uint16_t arp_protocol;/* format of protocol address */ - uint8_t arp_hlen;/* length of hardware address */ - uint8_t arp_plen;/* length of protocol address */ - uint16_t arp_opcode; /* ARP opcode (command) */ -#defineRTE_ARP_OP_REQUEST1 /* request to resolve address */ -#defineRTE_ARP_OP_REPLY 2 /* response to previous request */ -#defineRTE_ARP_OP_REVREQUEST 3 /* request proto addr given hardware */ -#defineRTE_ARP_OP_REVREPLY 4 /* response giving protocol address */ -#defineRTE_ARP_OP_INVREQUEST 8 /* request to identify peer */ -#defineRTE_ARP_OP_INVREPLY 9 /* response identifying peer */ + rte_be16_t arp_protocol; /** format of protocol address */ + uint8_tarp_hlen; /** length of hardware address */ + uint8_tarp_plen; /** length of protocol address */ + rte_be16_t arp_opcode; /** ARP opcode (command) */ +#defineRTE_ARP_OP_REQUEST1 /** request to resolve address */ +#defineRTE_ARP_OP_REPLY 2 /** response to previous request */ +#defineRTE_ARP_OP_REVREQUEST 3 /** request proto addr given hardware */ +#defineRTE_ARP_OP_REVREPLY 4 /** response giving protocol address */ +#defineRTE_ARP_OP_INVREQUEST 8 /** request to identify peer */ +#defineRTE_ARP_OP_INVREPLY 9 /** response identifying peer */ struct rte_arp_ipv4 arp_data; } __rte_packed __rte_aligned(2); diff --git a/lib/net/rte_gre.h b/lib/net/rte_gre.h index 210b81c99018..6b1169c8b0c1 100644 --- a/lib/net/rte_gre.h +++ b/lib/net/rte_gre.h @@ -50,7 +50,7 @@ struct rte_gre_hdr { }; rte_be16_t c_rsvd0_ver; }; - uint16_t proto; /**< Protocol Type */ + rte_be16_t proto; /**< Protocol Type */ } __rte_packed; /** diff --git a/lib/net/rte_higig.h b/lib/net/rte_higig.h index b55fb1a7db44..bba3898a883f 100644 --- a/lib/net/rte_higig.h +++ b/lib/net/rte_higig.h @@ -112,9 +112,9 @@ struct rte_higig2_ppt_type0 { */ __extension__ struct rte_higig2_ppt_type1 { - uint16_t classification; - uint16_t resv; - uint16_t vid; + rte_be16_t classification; + rte_be16_t resv; + rte_be16_t vid; #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN uint16_t opcode:3; uint16_t resv1:2; diff --git a/lib/net/rte_mpls.h b/lib/net/rte_mpls.h index 3e8cb90ec383..51523e7a1188 100644 --- a/lib/net/rte_mpls.h +++ b/lib/net/rte_mpls.h @@ -23,7 +23,7 @@ extern "C" { */ __extension__ struct rte_mpls_hdr { - uint16_t tag_msb; /**< Label(msb). */ + rte_be16_t tag_msb; /**< Label(msb). */ #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN uint8_t tag_lsb:4; /**< Label(lsb). */ uint8_t tc:3; /**< Traffic class. */ -- 2.25.1
[PATCH V5 00/11] pipeline: add IPsec support
This patch set introduces a companion block for the SWX pipeline for IPsec support. The IPsec block is external to the pipeline, hence it needs to be explicitly instantiated by the user and connected to a pipeline instance through the pipeline I/O ports. Main features: * IPsec inbound (encrypted input packets -> clear text output packets) and outbound (clear text input packets -> encrypted output packets) processing support for tunnel and transport modes. Interaction of the IPsec block with the pipeline: * Each IPsec block instance has its own set of Security Associations (SAs) used to process the input packets. Each SA is identified by its unique SA ID. The IPsec inbound and outbound SAs share the same ID space. * Each input packet is first mapped to one of the existing SAs by using the SA ID and then processed according to the identified SA. The SA ID is read from input packet. The SA ID field is typically written by the pipeline before sending the packet to the IPsec block. Change log: V5: Fixed build issue for gcc 4.8.5. V4: Fixed Doxygen issues. V3: Rebased on top of main latest. V2: Fixed minor style issues. Cristian Dumitrescu (11): pipeline: add IPsec support examples/pipeline: rework memory pool support examples/pipeline: streamline ring support examples/pipeline: streamline the Ethernet device support examples/pipeline: support crypto devices examples/pipeline: add CLI command for crypto device examples/pipeline: add IPsec CLI commands examples/pipeline: rework the thread configuration updates examples/pipeline: support blocks other than pipelines examples/pipeline: add block enable/disable CLI commands examples/pipeline: add IPsec example examples/pipeline/cli.c | 896 ++-- examples/pipeline/examples/fib.cli|4 +- examples/pipeline/examples/hash_func.cli |4 +- examples/pipeline/examples/ipsec.cli | 57 + examples/pipeline/examples/ipsec.io | 23 + examples/pipeline/examples/ipsec.spec | 138 ++ examples/pipeline/examples/ipsec_sa.txt | 216 ++ examples/pipeline/examples/l2fwd.cli |4 +- examples/pipeline/examples/l2fwd_macswp.cli |4 +- .../pipeline/examples/l2fwd_macswp_pcap.cli |4 +- examples/pipeline/examples/l2fwd_pcap.cli |4 +- examples/pipeline/examples/learner.cli|4 +- examples/pipeline/examples/meter.cli |4 +- examples/pipeline/examples/mirroring.cli |4 +- examples/pipeline/examples/recirculation.cli |4 +- examples/pipeline/examples/registers.cli |4 +- examples/pipeline/examples/selector.cli |4 +- examples/pipeline/examples/varbit.cli |4 +- examples/pipeline/examples/vxlan.cli |4 +- examples/pipeline/examples/vxlan_pcap.cli |4 +- examples/pipeline/main.c | 12 +- examples/pipeline/obj.c | 361 +--- examples/pipeline/obj.h | 100 +- examples/pipeline/thread.c| 655 +++--- examples/pipeline/thread.h| 24 +- lib/pipeline/meson.build |4 +- lib/pipeline/rte_swx_ipsec.c | 1821 + lib/pipeline/rte_swx_ipsec.h | 383 lib/pipeline/version.map |9 + 29 files changed, 3741 insertions(+), 1018 deletions(-) create mode 100644 examples/pipeline/examples/ipsec.cli create mode 100644 examples/pipeline/examples/ipsec.io create mode 100644 examples/pipeline/examples/ipsec.spec create mode 100644 examples/pipeline/examples/ipsec_sa.txt create mode 100644 lib/pipeline/rte_swx_ipsec.c create mode 100644 lib/pipeline/rte_swx_ipsec.h -- 2.34.1
[PATCH V5 01/11] pipeline: add IPsec support
This block is providing IPsec support to the SWX pipeline. The IPsec block is external to the pipeline, so it needs to be explicitly instantiated and connected to a pipeline through the I/O ports. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- lib/pipeline/meson.build |4 +- lib/pipeline/rte_swx_ipsec.c | 1821 ++ lib/pipeline/rte_swx_ipsec.h | 383 +++ lib/pipeline/version.map |9 + 4 files changed, 2216 insertions(+), 1 deletion(-) create mode 100644 lib/pipeline/rte_swx_ipsec.c create mode 100644 lib/pipeline/rte_swx_ipsec.h diff --git a/lib/pipeline/meson.build b/lib/pipeline/meson.build index 3ca98ed194..aa3fd0c2b8 100644 --- a/lib/pipeline/meson.build +++ b/lib/pipeline/meson.build @@ -11,6 +11,7 @@ sources = files( 'rte_pipeline.c', 'rte_port_in_action.c', 'rte_table_action.c', + 'rte_swx_ipsec.c', 'rte_swx_pipeline.c', 'rte_swx_pipeline_spec.c', 'rte_swx_ctl.c', @@ -19,8 +20,9 @@ headers = files( 'rte_pipeline.h', 'rte_port_in_action.h', 'rte_table_action.h', + 'rte_swx_ipsec.h', 'rte_swx_pipeline.h', 'rte_swx_extern.h', 'rte_swx_ctl.h', ) -deps += ['port', 'table', 'meter', 'sched', 'cryptodev'] +deps += ['port', 'table', 'meter', 'sched', 'cryptodev', 'ipsec'] diff --git a/lib/pipeline/rte_swx_ipsec.c b/lib/pipeline/rte_swx_ipsec.c new file mode 100644 index 00..b23056e23e --- /dev/null +++ b/lib/pipeline/rte_swx_ipsec.c @@ -0,0 +1,1821 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2022 Intel Corporation + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rte_swx_ipsec.h" + +#ifndef RTE_SWX_IPSEC_HUGE_PAGES_DISABLE + +#include + +static void * +env_calloc(size_t size, size_t alignment, int numa_node) +{ + return rte_zmalloc_socket(NULL, size, alignment, numa_node); +} + +static void +env_free(void *start, size_t size __rte_unused) +{ + rte_free(start); +} + +#else + +#include + +static void * +env_calloc(size_t size, size_t alignment __rte_unused, int numa_node) +{ + void *start; + + if (numa_available() == -1) + return NULL; + + start = numa_alloc_onnode(size, numa_node); + if (!start) + return NULL; + + memset(start, 0, size); + return start; +} + +static void +env_free(void *start, size_t size) +{ + if ((numa_available() == -1) || !start) + return; + + numa_free(start, size); +} + +#endif + +#ifndef RTE_SWX_IPSEC_POOL_CACHE_SIZE +#define RTE_SWX_IPSEC_POOL_CACHE_SIZE 256 +#endif + +/* The two crypto device mempools have their size set to the number of SAs. The mempool API requires + * the mempool size to be at least 1.5 times the size of the mempool cache. + */ +#define N_SA_MIN (RTE_SWX_IPSEC_POOL_CACHE_SIZE * 1.5) + +struct ipsec_sa { + struct rte_ipsec_session s; + int valid; +}; + +struct ipsec_pkts_in { + struct rte_mbuf *pkts[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct ipsec_sa *sa[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_ipsec_group groups[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_crypto_op *group_cops[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_crypto_op *cops[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + uint32_t n_cops; +}; + +struct ipsec_pkts_out { + struct rte_crypto_op *cops[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_mbuf *group_pkts[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_ipsec_group groups[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_mbuf *pkts[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + uint32_t n_pkts; +}; + +struct rte_swx_ipsec { + /* +* Parameters. +*/ + + /* IPsec instance name. */ + char name[RTE_SWX_IPSEC_NAME_SIZE]; + + /* Input packet queue. */ + struct rte_ring *ring_in; + + /* Output packet queue. */ + struct rte_ring *ring_out; + + /* Crypto device ID. */ + uint8_t dev_id; + + /* Crypto device queue pair ID. */ + uint16_t qp_id; + + /* Burst sizes. */ + struct rte_swx_ipsec_burst_size bsz; + + /* SA table size. */ + size_t n_sa_max; + + /* +* Internals. +*/ + /* Crypto device buffer pool for sessions. */ + struct rte_mempool *mp_session; + + /* Pre-crypto packets. */ + struct ipsec_pkts_in in; + + /* Post-crypto packets. */ + struct ipsec_pkts_out out; + + /* Crypto device enqueue threshold. */ + uint32_t crypto_wr_threshold; + + /* Packets currently under crypto device processing. */ + uint32_t n_pkts_crypto; + + /* List of free SADB positions. */ + uint32_t *sa_free_id; + + /* Number of elements in the SADB list of free positions. */ + size_t n_sa_free_id; + + /* Allo
[PATCH V5 02/11] examples/pipeline: rework memory pool support
Rework the memory pool CLI command to accommodate the MBUF private meta-data area size parameter. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 72 ++--- examples/pipeline/examples/fib.cli| 2 +- examples/pipeline/examples/hash_func.cli | 2 +- examples/pipeline/examples/l2fwd.cli | 2 +- examples/pipeline/examples/l2fwd_macswp.cli | 2 +- .../pipeline/examples/l2fwd_macswp_pcap.cli | 2 +- examples/pipeline/examples/l2fwd_pcap.cli | 2 +- examples/pipeline/examples/learner.cli| 2 +- examples/pipeline/examples/meter.cli | 2 +- examples/pipeline/examples/mirroring.cli | 2 +- examples/pipeline/examples/recirculation.cli | 2 +- examples/pipeline/examples/registers.cli | 2 +- examples/pipeline/examples/selector.cli | 2 +- examples/pipeline/examples/varbit.cli | 2 +- examples/pipeline/examples/vxlan.cli | 2 +- examples/pipeline/examples/vxlan_pcap.cli | 2 +- examples/pipeline/obj.c | 80 +-- examples/pipeline/obj.h | 27 --- 18 files changed, 63 insertions(+), 146 deletions(-) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index e1e7aaddc1..14f1cfa47e 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -192,72 +192,88 @@ parse_table_entry(struct rte_swx_ctl_pipeline *p, } static const char cmd_mempool_help[] = -"mempool \n" -" buffer \n" -" pool \n" -" cache \n" -" cpu \n"; +"mempool " +"meta " +"pkt " +"pool " +"cache " +"numa \n"; static void cmd_mempool(char **tokens, - uint32_t n_tokens, - char *out, - size_t out_size, - void *obj) + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj __rte_unused) { - struct mempool_params p; - char *name; - struct mempool *mempool; + struct rte_mempool *mp; + char *mempool_name; + uint32_t mbuf_private_size, pkt_buffer_size, pool_size, cache_size, numa_node; - if (n_tokens != 10) { + if (n_tokens != 12) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } - name = tokens[1]; + mempool_name = tokens[1]; + + if (strcmp(tokens[2], "meta")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meta"); + return; + } - if (strcmp(tokens[2], "buffer") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer"); + if (parser_read_uint32(&mbuf_private_size, tokens[3])) { + snprintf(out, out_size, MSG_ARG_INVALID, "mbuf_private_size"); return; } - if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size"); + if (strcmp(tokens[4], "pkt")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkt"); return; } - if (strcmp(tokens[4], "pool") != 0) { + if (parser_read_uint32(&pkt_buffer_size, tokens[5])) { + snprintf(out, out_size, MSG_ARG_INVALID, "pkt_buffer_size"); + return; + } + + if (strcmp(tokens[6], "pool")) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool"); return; } - if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) { + if (parser_read_uint32(&pool_size, tokens[7])) { snprintf(out, out_size, MSG_ARG_INVALID, "pool_size"); return; } - if (strcmp(tokens[6], "cache") != 0) { + if (strcmp(tokens[8], "cache")) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache"); return; } - if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) { + if (parser_read_uint32(&cache_size, tokens[9])) { snprintf(out, out_size, MSG_ARG_INVALID, "cache_size"); return; } - if (strcmp(tokens[8], "cpu") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu"); + if (strcmp(tokens[10], "numa")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa"); return; } - if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id"); + if (parser_read_uint32(&numa_node, tokens[11])) { + snprintf(out, out_size, MSG_ARG_INVALID, "numa_node"); return; } - mempool = mempool_create(obj, name, &p); - if (mempool == NULL) { + mp = rte_pktmbuf_pool_create(mempool_name, +pool_size, +cache_size, +mbuf_private_size, +
[PATCH V5 03/11] examples/pipeline: streamline ring support
Remove redundant ring related code. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 24 ++-- examples/pipeline/obj.c | 63 - examples/pipeline/obj.h | 21 -- 3 files changed, 15 insertions(+), 93 deletions(-) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 14f1cfa47e..517682f7c9 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -491,11 +492,11 @@ cmd_ring(char **tokens, uint32_t n_tokens, char *out, size_t out_size, - void *obj) + void *obj __rte_unused) { - struct ring_params p; + struct rte_ring *r; char *name; - struct ring *ring; + uint32_t size, numa_node; if (n_tokens != 6) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); @@ -504,28 +505,32 @@ cmd_ring(char **tokens, name = tokens[1]; - if (strcmp(tokens[2], "size") != 0) { + if (strcmp(tokens[2], "size")) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size"); return; } - if (parser_read_uint32(&p.size, tokens[3]) != 0) { + if (parser_read_uint32(&size, tokens[3])) { snprintf(out, out_size, MSG_ARG_INVALID, "size"); return; } - if (strcmp(tokens[4], "numa") != 0) { + if (strcmp(tokens[4], "numa")) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa"); return; } - if (parser_read_uint32(&p.numa_node, tokens[5]) != 0) { + if (parser_read_uint32(&numa_node, tokens[5])) { snprintf(out, out_size, MSG_ARG_INVALID, "numa_node"); return; } - ring = ring_create(obj, name, &p); - if (!ring) { + r = rte_ring_create( + name, + size, + (int)numa_node, + RING_F_SP_ENQ | RING_F_SC_DEQ); + if (!r) { snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); return; } @@ -2999,6 +3004,7 @@ cmd_help(char **tokens, "List of commands:\n" "\tmempool\n" "\tethdev\n" + "\tring\n" "\tpipeline codegen\n" "\tpipeline libbuild\n" "\tpipeline build\n" diff --git a/examples/pipeline/obj.c b/examples/pipeline/obj.c index 697d14a901..3614b99d28 100644 --- a/examples/pipeline/obj.c +++ b/examples/pipeline/obj.c @@ -24,17 +24,11 @@ */ TAILQ_HEAD(link_list, link); -/* - * ring - */ -TAILQ_HEAD(ring_list, ring); - /* * obj */ struct obj { struct link_list link_list; - struct ring_list ring_list; }; /* @@ -282,62 +276,6 @@ link_next(struct obj *obj, struct link *link) TAILQ_FIRST(&obj->link_list) : TAILQ_NEXT(link, node); } -/* - * ring - */ -struct ring * -ring_create(struct obj *obj, const char *name, struct ring_params *params) -{ - struct ring *ring; - struct rte_ring *r; - unsigned int flags = RING_F_SP_ENQ | RING_F_SC_DEQ; - - /* Check input params */ - if (!name || ring_find(obj, name) || !params || !params->size) - return NULL; - - /** -* Resource create -*/ - r = rte_ring_create( - name, - params->size, - params->numa_node, - flags); - if (!r) - return NULL; - - /* Node allocation */ - ring = calloc(1, sizeof(struct ring)); - if (!ring) { - rte_ring_free(r); - return NULL; - } - - /* Node fill in */ - strlcpy(ring->name, name, sizeof(ring->name)); - - /* Node add to list */ - TAILQ_INSERT_TAIL(&obj->ring_list, ring, node); - - return ring; -} - -struct ring * -ring_find(struct obj *obj, const char *name) -{ - struct ring *ring; - - if (!obj || !name) - return NULL; - - TAILQ_FOREACH(ring, &obj->ring_list, node) - if (strcmp(ring->name, name) == 0) - return ring; - - return NULL; -} - /* * obj */ @@ -351,7 +289,6 @@ obj_init(void) return NULL; TAILQ_INIT(&obj->link_list); - TAILQ_INIT(&obj->ring_list); return obj; } diff --git a/examples/pipeline/obj.h b/examples/pipeline/obj.h index 4ea610ceed..dbbc6d39a0 100644 --- a/examples/pipeline/obj.h +++ b/examples/pipeline/obj.h @@ -73,25 +73,4 @@ link_find(struct obj *obj, const char *name); struct link * link_next(struct obj *obj, struct link *link); -/* - * ring - */ -struct ring_params { - uint32_t size; - uint32_t numa_node; -}; - -struct ring { - TAILQ_ENTRY(ring) node; - char
[PATCH V5 04/11] examples/pipeline: streamline the Ethernet device support
Streamline the Ethernet device support code and remove redundant code. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 175 ++-- examples/pipeline/main.c | 12 +-- examples/pipeline/obj.c | 186 +-- examples/pipeline/obj.h | 51 ++- 4 files changed, 136 insertions(+), 288 deletions(-) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 517682f7c9..f4c8300ea7 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -292,16 +292,14 @@ cmd_ethdev(char **tokens, uint32_t n_tokens, char *out, size_t out_size, - void *obj) + void *obj __rte_unused) { - struct link_params p; - struct link_params_rss rss; - struct link *link; + struct ethdev_params p = {0}; + struct ethdev_params_rss rss = {0}; char *name; + int status; - memset(&p, 0, sizeof(p)); - - if ((n_tokens < 11) || (n_tokens > 12 + LINK_RXQ_RSS_MAX)) { + if (n_tokens < 11 || n_tokens > 12 + ETHDEV_RXQ_RSS_MAX) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -377,111 +375,98 @@ cmd_ethdev(char **tokens, } } - link = link_create(obj, name, &p); - if (link == NULL) { + status = ethdev_config(name, &p); + if (status) { snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); return; } } -/* Print the link stats and info */ static void -print_link_info(struct link *link, char *out, size_t out_size) +ethdev_show(uint16_t port_id, char **out, size_t *out_size) { - struct rte_eth_stats stats; - struct rte_ether_addr mac_addr; - struct rte_eth_link eth_link; - uint16_t mtu; - int ret; - - memset(&stats, 0, sizeof(stats)); - rte_eth_stats_get(link->port_id, &stats); - - ret = rte_eth_macaddr_get(link->port_id, &mac_addr); - if (ret != 0) { - snprintf(out, out_size, "\n%s: MAC address get failed: %s", -link->name, rte_strerror(-ret)); - return; - } - - ret = rte_eth_link_get(link->port_id, ð_link); - if (ret < 0) { - snprintf(out, out_size, "\n%s: link get failed: %s", -link->name, rte_strerror(-ret)); - return; - } - - rte_eth_dev_get_mtu(link->port_id, &mtu); - - snprintf(out, out_size, - "\n" - "%s: flags=<%s> mtu %u\n" - "\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n" - "\tport# %u speed %s\n" - "\tRX packets %" PRIu64" bytes %" PRIu64"\n" - "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n" - "\tTX packets %" PRIu64" bytes %" PRIu64"\n" - "\tTX errors %" PRIu64"\n", - link->name, - eth_link.link_status == 0 ? "DOWN" : "UP", - mtu, - RTE_ETHER_ADDR_BYTES(&mac_addr), - link->n_rxq, - link->n_txq, - link->port_id, - rte_eth_link_speed_to_str(eth_link.link_speed), - stats.ipackets, - stats.ibytes, - stats.ierrors, - stats.imissed, - stats.rx_nombuf, - stats.opackets, - stats.obytes, - stats.oerrors); + char name[RTE_ETH_NAME_MAX_LEN] = {0}; + struct rte_eth_dev_info info = {0}; + struct rte_eth_stats stats = {0}; + struct rte_ether_addr addr = {0}; + struct rte_eth_link link = {0}; + uint32_t length; + uint16_t mtu = 0; + + if (!rte_eth_dev_is_valid_port(port_id)) + return; + + rte_eth_dev_get_name_by_port(port_id, name); + rte_eth_dev_info_get(port_id, &info); + rte_eth_stats_get(port_id, &stats); + rte_eth_macaddr_get(port_id, &addr); + rte_eth_link_get(port_id, &link); + rte_eth_dev_get_mtu(port_id, &mtu); + + snprintf(*out, *out_size, +"%s: flags=<%s> mtu %u\n" +"\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n" +"\tport# %u speed %s\n" +"\tRX packets %" PRIu64" bytes %" PRIu64"\n" +"\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n" +"\tTX packets %" PRIu64" bytes %" PRIu64"\n" +"\tTX errors %" PRIu64"\n\n", +name, +link.link_status ? "UP" : "DOWN", +mtu, +RTE_ETHER_ADDR_BYTES(&addr), +info.nb_rx_queues, +info.nb_tx_queues, +port_id, +rte_eth_link_speed_to_str(link.link_speed), +stats.ipackets, +stats.ib
[PATCH V5 05/11] examples/pipeline: support crypto devices
Add support for crypto devices in the application. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/obj.c | 62 + examples/pipeline/obj.h | 11 2 files changed, 73 insertions(+) diff --git a/examples/pipeline/obj.c b/examples/pipeline/obj.c index 143b968472..d39034ec22 100644 --- a/examples/pipeline/obj.c +++ b/examples/pipeline/obj.c @@ -7,6 +7,7 @@ #include #include +#include #include "obj.h" @@ -190,3 +191,64 @@ ethdev_config(const char *name, struct ethdev_params *params) return 0; } + +/* + * cryptodev + */ +int +cryptodev_config(const char *name, struct cryptodev_params *params) +{ + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_config dev_conf; + struct rte_cryptodev_qp_conf queue_conf; + uint8_t dev_id; + uint32_t socket_id, i; + int status; + + /* Check input parameters. */ + if (!name || + !params->n_queue_pairs || + !params->queue_size) + return -EINVAL; + + /* Find the crypto device. */ + status = rte_cryptodev_get_dev_id(name); + if (status < 0) + return -EINVAL; + + dev_id = (uint8_t)status; + + rte_cryptodev_info_get(dev_id, &dev_info); + if (params->n_queue_pairs > dev_info.max_nb_queue_pairs) + return -EINVAL; + + socket_id = rte_cryptodev_socket_id(dev_id); + + /* Configure the crypto device. */ + memset(&dev_conf, 0, sizeof(dev_conf)); + dev_conf.socket_id = socket_id; + dev_conf.nb_queue_pairs = params->n_queue_pairs; + dev_conf.ff_disable = 0; + + status = rte_cryptodev_configure(dev_id, &dev_conf); + if (status) + return status; + + /* Configure the crypto device queue pairs. */ + memset(&queue_conf, 0, sizeof(queue_conf)); + queue_conf.nb_descriptors = params->queue_size; + queue_conf.mp_session = NULL; + + for (i = 0; i < params->n_queue_pairs; i++) { + status = rte_cryptodev_queue_pair_setup(dev_id, i, &queue_conf, socket_id); + if (status) + return status; + } + + /* Start the crypto device. */ + status = rte_cryptodev_start(dev_id); + if (status) + return status; + + return 0; +} diff --git a/examples/pipeline/obj.h b/examples/pipeline/obj.h index fb091f4ba7..0f103be6a7 100644 --- a/examples/pipeline/obj.h +++ b/examples/pipeline/obj.h @@ -38,4 +38,15 @@ struct ethdev_params { int ethdev_config(const char *name, struct ethdev_params *params); +/* + * cryptodev + */ +struct cryptodev_params { + uint32_t n_queue_pairs; + uint32_t queue_size; +}; + +int +cryptodev_config(const char *name, struct cryptodev_params *params); + #endif /* _INCLUDE_OBJ_H_ */ -- 2.34.1
[PATCH V5 06/11] examples/pipeline: add CLI command for crypto device
Add CLI command for the configuration of crypto devices. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 63 + 1 file changed, 63 insertions(+) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index f4c8300ea7..6b5d5a3370 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -521,6 +521,58 @@ cmd_ring(char **tokens, } } +static const char cmd_cryptodev_help[] = +"cryptodev queues qsize \n"; + +static void +cmd_cryptodev(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj __rte_unused) +{ + struct cryptodev_params params; + char *cryptodev_name; + int status; + + if (n_tokens != 6) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + if (strcmp(tokens[0], "cryptodev")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cryptodev"); + return; + } + + cryptodev_name = tokens[1]; + + if (strcmp(tokens[2], "queues")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "queues"); + return; + } + + if (parser_read_uint32(¶ms.n_queue_pairs, tokens[3])) { + snprintf(out, out_size, MSG_ARG_INVALID, "n_queue_pairs"); + return; + } + + if (strcmp(tokens[4], "qsize")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "qsize"); + return; + } + + + if (parser_read_uint32(¶ms.queue_size, tokens[5])) { + snprintf(out, out_size, MSG_ARG_INVALID, "queue_size"); + return; + } + + status = cryptodev_config(cryptodev_name, ¶ms); + if (status) + snprintf(out, out_size, "Crypto device configuration failed (%d).\n", status); +} + static const char cmd_pipeline_codegen_help[] = "pipeline codegen \n"; @@ -2991,6 +3043,7 @@ cmd_help(char **tokens, "\tethdev\n" "\tethdev show\n" "\tring\n" + "\tcryptodev\n" "\tpipeline codegen\n" "\tpipeline libbuild\n" "\tpipeline build\n" @@ -3042,6 +3095,11 @@ cmd_help(char **tokens, return; } + if (!strcmp(tokens[0], "cryptodev")) { + snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help); + return; + } + if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 2) && (strcmp(tokens[1], "codegen") == 0)) { snprintf(out, out_size, "\n%s\n", cmd_pipeline_codegen_help); @@ -3297,6 +3355,11 @@ cli_process(char *in, char *out, size_t out_size, void *obj) return; } + if (!strcmp(tokens[0], "cryptodev")) { + cmd_cryptodev(tokens, n_tokens, out, out_size, obj); + return; + } + if (strcmp(tokens[0], "pipeline") == 0) { if ((n_tokens >= 3) && (strcmp(tokens[1], "codegen") == 0)) { -- 2.34.1
[PATCH V5 07/11] examples/pipeline: add IPsec CLI commands
Add CLI commands for IPsec block configuration. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 298 1 file changed, 298 insertions(+) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 6b5d5a3370..92ec0fd8e3 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "cli.h" @@ -2910,6 +2911,263 @@ cmd_pipeline_mirror_session(char **tokens, } } +static const char cmd_ipsec_create_help[] = +"ipsec create " +"in out " +"cryptodev cryptoq " +"bsz " +"samax " +"numa \n"; + +static void +cmd_ipsec_create(char **tokens, +uint32_t n_tokens, +char *out, +size_t out_size, +void *obj __rte_unused) +{ + struct rte_swx_ipsec_params p; + struct rte_swx_ipsec *ipsec; + char *ipsec_instance_name; + uint32_t numa_node; + int status; + + if (n_tokens != 20) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + ipsec_instance_name = tokens[1]; + + if (strcmp(tokens[2], "create")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "create"); + return; + } + + if (strcmp(tokens[3], "in")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in"); + return; + } + + p.ring_in_name = tokens[4]; + + if (strcmp(tokens[5], "out")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out"); + return; + } + + p.ring_out_name = tokens[6]; + + if (strcmp(tokens[7], "cryptodev")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cryptodev"); + return; + } + + p.crypto_dev_name = tokens[8]; + + if (strcmp(tokens[9], "cryptoq")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cryptoq"); + return; + } + + if (parser_read_uint32(&p.crypto_dev_queue_pair_id, tokens[10])) { + snprintf(out, out_size, MSG_ARG_INVALID, "crypto_dev_queue_pair_id"); + return; + } + + if (strcmp(tokens[11], "bsz")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz"); + return; + } + + if (parser_read_uint32(&p.bsz.ring_rd, tokens[12])) { + snprintf(out, out_size, MSG_ARG_INVALID, "ring_rd_bsz"); + return; + } + + if (parser_read_uint32(&p.bsz.ring_wr, tokens[13])) { + snprintf(out, out_size, MSG_ARG_INVALID, "ring_wr_bsz"); + return; + } + + if (parser_read_uint32(&p.bsz.crypto_wr, tokens[14])) { + snprintf(out, out_size, MSG_ARG_INVALID, "crypto_wr_bsz"); + return; + } + + if (parser_read_uint32(&p.bsz.crypto_rd, tokens[15])) { + snprintf(out, out_size, MSG_ARG_INVALID, "crypto_rd_bsz"); + return; + } + + if (strcmp(tokens[16], "samax")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "samax"); + return; + } + + if (parser_read_uint32(&p.n_sa_max, tokens[17])) { + snprintf(out, out_size, MSG_ARG_INVALID, "n_sa_max"); + return; + } + + if (strcmp(tokens[18], "numa")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa"); + return; + } + + if (parser_read_uint32(&numa_node, tokens[19])) { + snprintf(out, out_size, MSG_ARG_INVALID, "numa_node"); + return; + } + + status = rte_swx_ipsec_create(&ipsec, + ipsec_instance_name, + &p, + (int)numa_node); + if (status) + snprintf(out, out_size, "IPsec instance creation failed (%d).\n", status); +} + +static const char cmd_ipsec_sa_add_help[] = +"ipsec sa add \n"; + +static void +cmd_ipsec_sa_add(char **tokens, +uint32_t n_tokens, +char *out, +size_t out_size, +void *obj __rte_unused) +{ + struct rte_swx_ipsec *ipsec; + char *ipsec_instance_name, *file_name, *line = NULL; + FILE *file = NULL; + uint32_t line_id = 0; + + if (n_tokens != 5) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + ipsec_instance_name = tokens[1]; + ipsec = rte_swx_ipsec_find(ipsec_instance_name); + if (!ipsec) { + snprintf(out, out_size, MSG_ARG_INVALID, "ipsec_instance_name"); + goto free; + } + + if (strcmp(tokens[2], "sa")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "sa"); + goto free; + } + + if (str
[PATCH V5 08/11] examples/pipeline: rework the thread configuration updates
Previously, the configuration updates for the data plane threads were performed through message queues. Now, this mechanism is replaced by the control thread updating the mirror copy of the data plane thread configuration followed by pointer swapping. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 154 ++--- examples/pipeline/examples/fib.cli| 2 +- examples/pipeline/examples/hash_func.cli | 2 +- examples/pipeline/examples/l2fwd.cli | 2 +- examples/pipeline/examples/l2fwd_macswp.cli | 2 +- .../pipeline/examples/l2fwd_macswp_pcap.cli | 2 +- examples/pipeline/examples/l2fwd_pcap.cli | 2 +- examples/pipeline/examples/learner.cli| 2 +- examples/pipeline/examples/meter.cli | 2 +- examples/pipeline/examples/mirroring.cli | 2 +- examples/pipeline/examples/recirculation.cli | 2 +- examples/pipeline/examples/registers.cli | 2 +- examples/pipeline/examples/selector.cli | 2 +- examples/pipeline/examples/varbit.cli | 2 +- examples/pipeline/examples/vxlan.cli | 2 +- examples/pipeline/examples/vxlan_pcap.cli | 2 +- examples/pipeline/thread.c| 586 -- examples/pipeline/thread.h| 17 +- 18 files changed, 217 insertions(+), 570 deletions(-) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 92ec0fd8e3..68bb93a46c 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -3168,119 +3168,86 @@ cmd_ipsec_sa_delete(char **tokens, rte_swx_ipsec_sa_delete(ipsec, sa_id); } -static const char cmd_thread_pipeline_enable_help[] = -"thread pipeline enable [ period ]\n"; - -#ifndef TIMER_PERIOD_MS_DEFAULT -#define TIMER_PERIOD_MS_DEFAULT 10 -#endif +static const char cmd_pipeline_enable_help[] = +"pipeline enable thread \n"; static void -cmd_thread_pipeline_enable(char **tokens, - uint32_t n_tokens, - char *out, - size_t out_size, - void *obj __rte_unused) +cmd_pipeline_enable(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj __rte_unused) { char *pipeline_name; struct rte_swx_pipeline *p; - uint32_t thread_id, timer_period_ms = TIMER_PERIOD_MS_DEFAULT; + uint32_t thread_id; int status; - if ((n_tokens != 5) && (n_tokens != 7)) { + if (n_tokens != 5) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } - if (parser_read_uint32(&thread_id, tokens[1]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); - return; - } - - if (strcmp(tokens[2], "pipeline") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline"); - return; - } - - pipeline_name = tokens[3]; + pipeline_name = tokens[1]; p = rte_swx_pipeline_find(pipeline_name); if (!p) { snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); return; } - if (strcmp(tokens[4], "enable") != 0) { + if (strcmp(tokens[2], "enable") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable"); return; } - if (n_tokens == 7) { - if (strcmp(tokens[5], "period") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period"); - return; - } + if (strcmp(tokens[3], "thread") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread"); + return; + } - if (parser_read_uint32(&timer_period_ms, tokens[6]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms"); - return; - } + if (parser_read_uint32(&thread_id, tokens[4]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); + return; } - status = thread_pipeline_enable(thread_id, p, timer_period_ms); + status = pipeline_enable(p, thread_id); if (status) { - snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable"); + snprintf(out, out_size, MSG_CMD_FAIL, "pipeline enable"); return; } } -static const char cmd_thread_pipeline_disable_help[] = -"thread pipeline disable\n"; +static const char cmd_pipeline_disable_help[] = +"pipeline disable\n"; static void -cmd_thread_pipeline_disable(char **tokens, - uint32_t n_tokens, - char *out, - size_t out_size, - void *obj __rte_unused) +cmd_pipeline_disable(char **tokens, +uint32_t n_tokens, +char *out, +size_t out_size, +
[PATCH V5 09/11] examples/pipeline: support blocks other than pipelines
Previously, the data plane threads only supported the execution of pipelines assigned to them through configuration updates. Now, the data plane threads also support running blocks such as IPsec. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/thread.c | 143 + examples/pipeline/thread.h | 9 +++ 2 files changed, 152 insertions(+) diff --git a/examples/pipeline/thread.c b/examples/pipeline/thread.c index 3001bc0858..dc3ea73fbf 100644 --- a/examples/pipeline/thread.c +++ b/examples/pipeline/thread.c @@ -16,6 +16,10 @@ #define THREAD_PIPELINES_MAX 256 #endif +#ifndef THREAD_BLOCKS_MAX +#define THREAD_BLOCKS_MAX 256 +#endif + /* Pipeline instruction quanta: Needs to be big enough to do some meaningful * work, but not too big to avoid starving any other pipelines mapped to the * same thread. For a pipeline that executes 10 instructions per packet, a @@ -38,9 +42,16 @@ * - Read-write by the CP thread; * - Read-only by the DP thread. */ +struct block { + block_run_f block_func; + void *block; +}; + struct thread { struct rte_swx_pipeline *pipelines[THREAD_PIPELINES_MAX]; + struct block *blocks[THREAD_BLOCKS_MAX]; volatile uint64_t n_pipelines; + volatile uint64_t n_blocks; int enabled; } __rte_cache_aligned; @@ -53,14 +64,43 @@ int thread_init(void) { uint32_t thread_id; + int status = 0; RTE_LCORE_FOREACH_WORKER(thread_id) { struct thread *t = &threads[thread_id]; + uint32_t i; t->enabled = 1; + + for (i = 0; i < THREAD_BLOCKS_MAX; i++) { + struct block *b; + + b = calloc(1, sizeof(struct block)); + if (!b) { + status = -ENOMEM; + goto error; + } + + t->blocks[i] = b; + } } return 0; + +error: + RTE_LCORE_FOREACH_WORKER(thread_id) { + struct thread *t = &threads[thread_id]; + uint32_t i; + + t->enabled = 0; + + for (i = 0; i < THREAD_BLOCKS_MAX; i++) { + free(t->blocks[i]); + t->blocks[i] = NULL; + } + } + + return status; } static uint32_t @@ -83,6 +123,26 @@ pipeline_find(struct rte_swx_pipeline *p) return thread_id; } +static uint32_t +block_find(void *b) +{ + uint32_t thread_id; + + for (thread_id = 0; thread_id < RTE_MAX_LCORE; thread_id++) { + struct thread *t = &threads[thread_id]; + uint32_t i; + + if (!t->enabled) + continue; + + for (i = 0; i < t->n_blocks; i++) + if (t->blocks[i]->block == b) + break; + } + + return thread_id; +} + /** * Enable a given pipeline to run on a specific DP thread. * @@ -201,9 +261,85 @@ pipeline_disable(struct rte_swx_pipeline *p) return; } +int +block_enable(block_run_f block_func, void *block, uint32_t thread_id) +{ + struct thread *t; + uint64_t n_blocks; + + /* Check input params */ + if (!block_func || !block || thread_id >= RTE_MAX_LCORE) + return -EINVAL; + + if (block_find(block) < RTE_MAX_LCORE) + return -EEXIST; + + t = &threads[thread_id]; + if (!t->enabled) + return -EINVAL; + + n_blocks = t->n_blocks; + + /* Check there is room for at least one more block. */ + if (n_blocks >= THREAD_BLOCKS_MAX) + return -ENOSPC; + + /* Install the new block. */ + t->blocks[n_blocks]->block_func = block_func; + t->blocks[n_blocks]->block = block; + + rte_wmb(); + t->n_blocks = n_blocks + 1; + + return 0; +} + +void +block_disable(void *block) +{ + struct thread *t; + uint64_t n_blocks; + uint32_t thread_id, i; + + /* Check input params */ + if (!block) + return; + + /* Find the thread that runs this block. */ + thread_id = block_find(block); + if (thread_id == RTE_MAX_LCORE) + return; + + t = &threads[thread_id]; + n_blocks = t->n_blocks; + + for (i = 0; i < n_blocks; i++) { + struct block *b = t->blocks[i]; + + if (block != b->block) + continue; + + if (i < n_blocks - 1) { + struct block *block_last = t->blocks[n_blocks - 1]; + + t->blocks[i] = block_last; + } + + rte_wmb(); + t->n_blocks = n_blocks - 1; + + rte_wmb(); + t->blocks[n_blocks - 1] = b; + +
[PATCH V5 10/11] examples/pipeline: add block enable/disable CLI commands
Add CLI commands to enable/disable block execution on data plane threads. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 154 1 file changed, 154 insertions(+) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 68bb93a46c..37250b7072 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -3250,6 +3250,134 @@ cmd_pipeline_disable(char **tokens, pipeline_disable(p); } +static const char cmd_block_enable_help[] = +"block type instance enable thread \n"; + +static void +cmd_block_enable(char **tokens, +uint32_t n_tokens, +char *out, +size_t out_size, +void *obj __rte_unused) +{ + char *block_type, *block_name; + block_run_f block_func = NULL; + void *block = NULL; + uint32_t thread_id; + int status; + + if (n_tokens != 8) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + if (strcmp(tokens[1], "type") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "type"); + return; + } + + block_type = tokens[2]; + + if (strcmp(tokens[3], "instance") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "instance"); + return; + } + + block_name = tokens[4]; + + if (strcmp(tokens[5], "enable") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable"); + return; + } + + if (strcmp(tokens[6], "thread") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread"); + return; + } + + if (parser_read_uint32(&thread_id, tokens[7]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); + return; + } + + if (!strcmp(block_type, "ipsec")) { + struct rte_swx_ipsec *ipsec; + + ipsec = rte_swx_ipsec_find(block_name); + if (!ipsec) { + snprintf(out, out_size, MSG_ARG_INVALID, "block_name"); + return; + } + + block_func = (block_run_f)rte_swx_ipsec_run; + block = (void *)ipsec; + } else { + snprintf(out, out_size, MSG_ARG_INVALID, "block_type"); + return; + } + + status = block_enable(block_func, block, thread_id); + if (status) { + snprintf(out, out_size, MSG_CMD_FAIL, "block enable"); + return; + } +} + +static const char cmd_block_disable_help[] = +"block type instance disable\n"; + +static void +cmd_block_disable(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj __rte_unused) +{ + char *block_type, *block_name; + void *block = NULL; + + if (n_tokens != 6) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + if (strcmp(tokens[1], "type") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "type"); + return; + } + + block_type = tokens[2]; + + if (strcmp(tokens[3], "instance") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "instance"); + return; + } + + block_name = tokens[4]; + + if (strcmp(tokens[5], "disable") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable"); + return; + } + + if (!strcmp(block_type, "ipsec")) { + struct rte_swx_ipsec *ipsec; + + ipsec = rte_swx_ipsec_find(block_name); + if (!ipsec) { + snprintf(out, out_size, MSG_ARG_INVALID, "block_name"); + return; + } + + block = (void *)ipsec; + } else { + snprintf(out, out_size, MSG_ARG_INVALID, "block_type"); + return; + } + + block_disable(block); +} + static void cmd_help(char **tokens, uint32_t n_tokens, @@ -3298,6 +3426,8 @@ cmd_help(char **tokens, "\tipsec create\n" "\tipsec sa add\n" "\tipsec sa delete\n" + "\tblock enable\n" + "\tblock disable\n" ); return; } @@ -3553,6 +3683,18 @@ cmd_help(char **tokens, return; } + if (!strcmp(tokens[0], "block") && + (n_tokens == 2) && !strcmp(tokens[1], "enable")) { + snprintf(out, out_size, "\n%s\n", cmd_block_enable_help); + return; + } + + if (!strcmp(tokens[0], "block") && + (n_tokens == 2) && !strcmp(tokens[1], "disable")) { +
[PATCH V5 11/11] examples/pipeline: add IPsec example
Add example files to illustrate the pipeline IPsec support. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/examples/ipsec.cli| 57 +++ examples/pipeline/examples/ipsec.io | 23 +++ examples/pipeline/examples/ipsec.spec | 138 +++ examples/pipeline/examples/ipsec_sa.txt | 216 4 files changed, 434 insertions(+) create mode 100644 examples/pipeline/examples/ipsec.cli create mode 100644 examples/pipeline/examples/ipsec.io create mode 100644 examples/pipeline/examples/ipsec.spec create mode 100644 examples/pipeline/examples/ipsec_sa.txt diff --git a/examples/pipeline/examples/ipsec.cli b/examples/pipeline/examples/ipsec.cli new file mode 100644 index 00..8cb5bf4239 --- /dev/null +++ b/examples/pipeline/examples/ipsec.cli @@ -0,0 +1,57 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright(c) 2022 Intel Corporation + +# Example command line: +# ./build/examples/dpdk-pipeline -l0-1 --vdev crypto_aesni_mb0 -- -s ./examples/pipeline/examples/ipsec.cli +# +# Once the application has started, the command to get the CLI prompt is: +# telnet 0.0.0.0 8086 + +; +; Pipeline code generation & shared object library build. +; +pipeline codegen ./examples/pipeline/examples/ipsec.spec /tmp/ipsec.c +pipeline libbuild /tmp/ipsec.c /tmp/ipsec.so + +; +; List of DPDK devices. +; +; Note: Customize the parameters below to match your setup. +; +mempool MEMPOOL0 meta 128 pkt 2176 pool 32K cache 256 numa 0 +ethdev :18:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on +ethdev :18:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on +ethdev :3b:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on +ethdev :3b:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on + +cryptodev crypto_aesni_mb0 queues 1 qsize 128 +ring RING0 size 1024 numa 0 +ring RING1 size 1024 numa 0 + +; +; List of pipelines. +; +pipeline PIPELINE0 build lib /tmp/ipsec.so io ./examples/pipeline/examples/ipsec.io numa 0 + +; +; List of IPsec devices. +; +ipsec IPSEC0 create in RING0 out RING1 cryptodev crypto_aesni_mb0 cryptoq 0 bsz 32 32 32 32 samax 512 numa 0 + +; +; Initial set of table entries. +; +; The table entries can later be updated at run-time through the CLI commands. +; +//pipeline PIPELINE0 table policy_table add ./examples/pipeline/examples/ipsec_policy_table.txt +//pipeline PIPELINE0 table routing_table add ./examples/pipeline/examples/ipsec_routing_table.txt +//pipeline PIPELINE0 table nexthop_table add ./examples/pipeline/examples/ipsec_nexthop_table.txt +//pipeline PIPELINE0 commit + +ipsec IPSEC0 sa add ./examples/pipeline/examples/ipsec_sa.txt + +; +; Pipelines and blocks mapping to CPU threads. +; +pipeline PIPELINE0 enable thread 1 +block type ipsec instance IPSEC0 enable thread 1 diff --git a/examples/pipeline/examples/ipsec.io b/examples/pipeline/examples/ipsec.io new file mode 100644 index 00..f5a3fcf961 --- /dev/null +++ b/examples/pipeline/examples/ipsec.io @@ -0,0 +1,23 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright(c) 2022 Intel Corporation + +; +; Pipeline packet mirroring. +; +mirroring slots 4 sessions 64 + +; +; Pipeline input ports. +; +; Note: Customize the parameters below to match your setup. +; +port in 0 ethdev :18:00.0 rxq 0 bsz 32 +port in 1 ring RING1 bsz 32 + +; +; Pipeline output ports. +; +; Note: Customize the parameters below to match your setup. +; +port out 0 ethdev :18:00.0 txq 0 bsz 32 +port out 1 ring RING0 bsz 32 diff --git a/examples/pipeline/examples/ipsec.spec b/examples/pipeline/examples/ipsec.spec new file mode 100644 index 00..09aa831881 --- /dev/null +++ b/examples/pipeline/examples/ipsec.spec @@ -0,0 +1,138 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright(c) 2020 Intel Corporation + +// +// Headers +// +struct ethernet_h { + bit<48> dst_addr + bit<48> src_addr + bit<16> ethertype +} + +struct ipv4_h { + bit<8> ver_ihl + bit<8> diffserv + bit<16> total_len + bit<16> identification + bit<16> flags_offset + bit<8> ttl + bit<8> protocol + bit<16> hdr_checksum + bit<32> src_addr + bit<32> dst_addr +} + +struct udp_h { + bit<16> src_port + bit<16> dst_port + bit<16> length + bit<16> checksum +} + +struct ipsec_internal_h { + bit<32> sa_id +} + +header ethernet instanceof ethernet_h +header ipv4 instanceof ipv4_h +header udp instanceof udp_h +header ipsec_internal instanceof ipsec_internal_h + +// +// Meta-data +// +struct metadata_t { + bit<32> port_in + bit<32> port_out + + bit<32> src_addr + bit<32> dst_addr + bit<8> protocol + bit<16> src_port + bit<16> dst_port +} + +metadata instanceof metadata_t + +// +// Actions +// +struct encrypt_args_t { + bit<32> sa_id +} + +action encrypt args instanceof encrypt_args_t { + //Set the IPsec internal header. + validate h.ipsec_internal
[PATCH V6 00/11] pipeline: add IPsec support
This patch set introduces a companion block for the SWX pipeline for IPsec support. The IPsec block is external to the pipeline, hence it needs to be explicitly instantiated by the user and connected to a pipeline instance through the pipeline I/O ports. Main features: * IPsec inbound (encrypted input packets -> clear text output packets) and outbound (clear text input packets -> encrypted output packets) processing support for tunnel and transport modes. Interaction of the IPsec block with the pipeline: * Each IPsec block instance has its own set of Security Associations (SAs) used to process the input packets. Each SA is identified by its unique SA ID. The IPsec inbound and outbound SAs share the same ID space. * Each input packet is first mapped to one of the existing SAs by using the SA ID and then processed according to the identified SA. The SA ID is read from input packet. The SA ID field is typically written by the pipeline before sending the packet to the IPsec block. Change log: V6: Fixed more build issues for gcc 4.8.5. V5: Fixed build issue for gcc 4.8.5. V4: Fixed Doxygen issues. V3: Rebased on top of main latest. V2: Fixed minor style issues. Cristian Dumitrescu (11): pipeline: add IPsec support examples/pipeline: rework memory pool support examples/pipeline: streamline ring support examples/pipeline: streamline the Ethernet device support examples/pipeline: support crypto devices examples/pipeline: add CLI command for crypto device examples/pipeline: add IPsec CLI commands examples/pipeline: rework the thread configuration updates examples/pipeline: support blocks other than pipelines examples/pipeline: add block enable/disable CLI commands examples/pipeline: add IPsec example examples/pipeline/cli.c | 893 ++-- examples/pipeline/examples/fib.cli|4 +- examples/pipeline/examples/hash_func.cli |4 +- examples/pipeline/examples/ipsec.cli | 57 + examples/pipeline/examples/ipsec.io | 23 + examples/pipeline/examples/ipsec.spec | 138 ++ examples/pipeline/examples/ipsec_sa.txt | 216 ++ examples/pipeline/examples/l2fwd.cli |4 +- examples/pipeline/examples/l2fwd_macswp.cli |4 +- .../pipeline/examples/l2fwd_macswp_pcap.cli |4 +- examples/pipeline/examples/l2fwd_pcap.cli |4 +- examples/pipeline/examples/learner.cli|4 +- examples/pipeline/examples/meter.cli |4 +- examples/pipeline/examples/mirroring.cli |4 +- examples/pipeline/examples/recirculation.cli |4 +- examples/pipeline/examples/registers.cli |4 +- examples/pipeline/examples/selector.cli |4 +- examples/pipeline/examples/varbit.cli |4 +- examples/pipeline/examples/vxlan.cli |4 +- examples/pipeline/examples/vxlan_pcap.cli |4 +- examples/pipeline/main.c | 12 +- examples/pipeline/obj.c | 361 +--- examples/pipeline/obj.h | 100 +- examples/pipeline/thread.c| 655 +++--- examples/pipeline/thread.h| 24 +- lib/pipeline/meson.build |4 +- lib/pipeline/rte_swx_ipsec.c | 1821 + lib/pipeline/rte_swx_ipsec.h | 383 lib/pipeline/version.map |9 + 29 files changed, 3741 insertions(+), 1015 deletions(-) create mode 100644 examples/pipeline/examples/ipsec.cli create mode 100644 examples/pipeline/examples/ipsec.io create mode 100644 examples/pipeline/examples/ipsec.spec create mode 100644 examples/pipeline/examples/ipsec_sa.txt create mode 100644 lib/pipeline/rte_swx_ipsec.c create mode 100644 lib/pipeline/rte_swx_ipsec.h -- 2.34.1
[PATCH V6 01/11] pipeline: add IPsec support
This block is providing IPsec support to the SWX pipeline. The IPsec block is external to the pipeline, so it needs to be explicitly instantiated and connected to a pipeline through the I/O ports. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- lib/pipeline/meson.build |4 +- lib/pipeline/rte_swx_ipsec.c | 1821 ++ lib/pipeline/rte_swx_ipsec.h | 383 +++ lib/pipeline/version.map |9 + 4 files changed, 2216 insertions(+), 1 deletion(-) create mode 100644 lib/pipeline/rte_swx_ipsec.c create mode 100644 lib/pipeline/rte_swx_ipsec.h diff --git a/lib/pipeline/meson.build b/lib/pipeline/meson.build index 3ca98ed194..aa3fd0c2b8 100644 --- a/lib/pipeline/meson.build +++ b/lib/pipeline/meson.build @@ -11,6 +11,7 @@ sources = files( 'rte_pipeline.c', 'rte_port_in_action.c', 'rte_table_action.c', + 'rte_swx_ipsec.c', 'rte_swx_pipeline.c', 'rte_swx_pipeline_spec.c', 'rte_swx_ctl.c', @@ -19,8 +20,9 @@ headers = files( 'rte_pipeline.h', 'rte_port_in_action.h', 'rte_table_action.h', + 'rte_swx_ipsec.h', 'rte_swx_pipeline.h', 'rte_swx_extern.h', 'rte_swx_ctl.h', ) -deps += ['port', 'table', 'meter', 'sched', 'cryptodev'] +deps += ['port', 'table', 'meter', 'sched', 'cryptodev', 'ipsec'] diff --git a/lib/pipeline/rte_swx_ipsec.c b/lib/pipeline/rte_swx_ipsec.c new file mode 100644 index 00..b23056e23e --- /dev/null +++ b/lib/pipeline/rte_swx_ipsec.c @@ -0,0 +1,1821 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2022 Intel Corporation + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rte_swx_ipsec.h" + +#ifndef RTE_SWX_IPSEC_HUGE_PAGES_DISABLE + +#include + +static void * +env_calloc(size_t size, size_t alignment, int numa_node) +{ + return rte_zmalloc_socket(NULL, size, alignment, numa_node); +} + +static void +env_free(void *start, size_t size __rte_unused) +{ + rte_free(start); +} + +#else + +#include + +static void * +env_calloc(size_t size, size_t alignment __rte_unused, int numa_node) +{ + void *start; + + if (numa_available() == -1) + return NULL; + + start = numa_alloc_onnode(size, numa_node); + if (!start) + return NULL; + + memset(start, 0, size); + return start; +} + +static void +env_free(void *start, size_t size) +{ + if ((numa_available() == -1) || !start) + return; + + numa_free(start, size); +} + +#endif + +#ifndef RTE_SWX_IPSEC_POOL_CACHE_SIZE +#define RTE_SWX_IPSEC_POOL_CACHE_SIZE 256 +#endif + +/* The two crypto device mempools have their size set to the number of SAs. The mempool API requires + * the mempool size to be at least 1.5 times the size of the mempool cache. + */ +#define N_SA_MIN (RTE_SWX_IPSEC_POOL_CACHE_SIZE * 1.5) + +struct ipsec_sa { + struct rte_ipsec_session s; + int valid; +}; + +struct ipsec_pkts_in { + struct rte_mbuf *pkts[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct ipsec_sa *sa[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_ipsec_group groups[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_crypto_op *group_cops[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_crypto_op *cops[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + uint32_t n_cops; +}; + +struct ipsec_pkts_out { + struct rte_crypto_op *cops[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_mbuf *group_pkts[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_ipsec_group groups[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + struct rte_mbuf *pkts[RTE_SWX_IPSEC_BURST_SIZE_MAX]; + uint32_t n_pkts; +}; + +struct rte_swx_ipsec { + /* +* Parameters. +*/ + + /* IPsec instance name. */ + char name[RTE_SWX_IPSEC_NAME_SIZE]; + + /* Input packet queue. */ + struct rte_ring *ring_in; + + /* Output packet queue. */ + struct rte_ring *ring_out; + + /* Crypto device ID. */ + uint8_t dev_id; + + /* Crypto device queue pair ID. */ + uint16_t qp_id; + + /* Burst sizes. */ + struct rte_swx_ipsec_burst_size bsz; + + /* SA table size. */ + size_t n_sa_max; + + /* +* Internals. +*/ + /* Crypto device buffer pool for sessions. */ + struct rte_mempool *mp_session; + + /* Pre-crypto packets. */ + struct ipsec_pkts_in in; + + /* Post-crypto packets. */ + struct ipsec_pkts_out out; + + /* Crypto device enqueue threshold. */ + uint32_t crypto_wr_threshold; + + /* Packets currently under crypto device processing. */ + uint32_t n_pkts_crypto; + + /* List of free SADB positions. */ + uint32_t *sa_free_id; + + /* Number of elements in the SADB list of free positions. */ + size_t n_sa_free_id; + + /* Allo
[PATCH V6 02/11] examples/pipeline: rework memory pool support
Rework the memory pool CLI command to accommodate the MBUF private meta-data area size parameter. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 72 ++--- examples/pipeline/examples/fib.cli| 2 +- examples/pipeline/examples/hash_func.cli | 2 +- examples/pipeline/examples/l2fwd.cli | 2 +- examples/pipeline/examples/l2fwd_macswp.cli | 2 +- .../pipeline/examples/l2fwd_macswp_pcap.cli | 2 +- examples/pipeline/examples/l2fwd_pcap.cli | 2 +- examples/pipeline/examples/learner.cli| 2 +- examples/pipeline/examples/meter.cli | 2 +- examples/pipeline/examples/mirroring.cli | 2 +- examples/pipeline/examples/recirculation.cli | 2 +- examples/pipeline/examples/registers.cli | 2 +- examples/pipeline/examples/selector.cli | 2 +- examples/pipeline/examples/varbit.cli | 2 +- examples/pipeline/examples/vxlan.cli | 2 +- examples/pipeline/examples/vxlan_pcap.cli | 2 +- examples/pipeline/obj.c | 80 +-- examples/pipeline/obj.h | 27 --- 18 files changed, 63 insertions(+), 146 deletions(-) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index e1e7aaddc1..14f1cfa47e 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -192,72 +192,88 @@ parse_table_entry(struct rte_swx_ctl_pipeline *p, } static const char cmd_mempool_help[] = -"mempool \n" -" buffer \n" -" pool \n" -" cache \n" -" cpu \n"; +"mempool " +"meta " +"pkt " +"pool " +"cache " +"numa \n"; static void cmd_mempool(char **tokens, - uint32_t n_tokens, - char *out, - size_t out_size, - void *obj) + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj __rte_unused) { - struct mempool_params p; - char *name; - struct mempool *mempool; + struct rte_mempool *mp; + char *mempool_name; + uint32_t mbuf_private_size, pkt_buffer_size, pool_size, cache_size, numa_node; - if (n_tokens != 10) { + if (n_tokens != 12) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } - name = tokens[1]; + mempool_name = tokens[1]; + + if (strcmp(tokens[2], "meta")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "meta"); + return; + } - if (strcmp(tokens[2], "buffer") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "buffer"); + if (parser_read_uint32(&mbuf_private_size, tokens[3])) { + snprintf(out, out_size, MSG_ARG_INVALID, "mbuf_private_size"); return; } - if (parser_read_uint32(&p.buffer_size, tokens[3]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "buffer_size"); + if (strcmp(tokens[4], "pkt")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pkt"); return; } - if (strcmp(tokens[4], "pool") != 0) { + if (parser_read_uint32(&pkt_buffer_size, tokens[5])) { + snprintf(out, out_size, MSG_ARG_INVALID, "pkt_buffer_size"); + return; + } + + if (strcmp(tokens[6], "pool")) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pool"); return; } - if (parser_read_uint32(&p.pool_size, tokens[5]) != 0) { + if (parser_read_uint32(&pool_size, tokens[7])) { snprintf(out, out_size, MSG_ARG_INVALID, "pool_size"); return; } - if (strcmp(tokens[6], "cache") != 0) { + if (strcmp(tokens[8], "cache")) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cache"); return; } - if (parser_read_uint32(&p.cache_size, tokens[7]) != 0) { + if (parser_read_uint32(&cache_size, tokens[9])) { snprintf(out, out_size, MSG_ARG_INVALID, "cache_size"); return; } - if (strcmp(tokens[8], "cpu") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cpu"); + if (strcmp(tokens[10], "numa")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa"); return; } - if (parser_read_uint32(&p.cpu_id, tokens[9]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "cpu_id"); + if (parser_read_uint32(&numa_node, tokens[11])) { + snprintf(out, out_size, MSG_ARG_INVALID, "numa_node"); return; } - mempool = mempool_create(obj, name, &p); - if (mempool == NULL) { + mp = rte_pktmbuf_pool_create(mempool_name, +pool_size, +cache_size, +mbuf_private_size, +
[PATCH V6 03/11] examples/pipeline: streamline ring support
Remove redundant ring related code. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 24 ++-- examples/pipeline/obj.c | 63 - examples/pipeline/obj.h | 21 -- 3 files changed, 15 insertions(+), 93 deletions(-) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 14f1cfa47e..517682f7c9 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -11,6 +11,7 @@ #include #include +#include #include #include #include @@ -491,11 +492,11 @@ cmd_ring(char **tokens, uint32_t n_tokens, char *out, size_t out_size, - void *obj) + void *obj __rte_unused) { - struct ring_params p; + struct rte_ring *r; char *name; - struct ring *ring; + uint32_t size, numa_node; if (n_tokens != 6) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); @@ -504,28 +505,32 @@ cmd_ring(char **tokens, name = tokens[1]; - if (strcmp(tokens[2], "size") != 0) { + if (strcmp(tokens[2], "size")) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "size"); return; } - if (parser_read_uint32(&p.size, tokens[3]) != 0) { + if (parser_read_uint32(&size, tokens[3])) { snprintf(out, out_size, MSG_ARG_INVALID, "size"); return; } - if (strcmp(tokens[4], "numa") != 0) { + if (strcmp(tokens[4], "numa")) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa"); return; } - if (parser_read_uint32(&p.numa_node, tokens[5]) != 0) { + if (parser_read_uint32(&numa_node, tokens[5])) { snprintf(out, out_size, MSG_ARG_INVALID, "numa_node"); return; } - ring = ring_create(obj, name, &p); - if (!ring) { + r = rte_ring_create( + name, + size, + (int)numa_node, + RING_F_SP_ENQ | RING_F_SC_DEQ); + if (!r) { snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); return; } @@ -2999,6 +3004,7 @@ cmd_help(char **tokens, "List of commands:\n" "\tmempool\n" "\tethdev\n" + "\tring\n" "\tpipeline codegen\n" "\tpipeline libbuild\n" "\tpipeline build\n" diff --git a/examples/pipeline/obj.c b/examples/pipeline/obj.c index 697d14a901..3614b99d28 100644 --- a/examples/pipeline/obj.c +++ b/examples/pipeline/obj.c @@ -24,17 +24,11 @@ */ TAILQ_HEAD(link_list, link); -/* - * ring - */ -TAILQ_HEAD(ring_list, ring); - /* * obj */ struct obj { struct link_list link_list; - struct ring_list ring_list; }; /* @@ -282,62 +276,6 @@ link_next(struct obj *obj, struct link *link) TAILQ_FIRST(&obj->link_list) : TAILQ_NEXT(link, node); } -/* - * ring - */ -struct ring * -ring_create(struct obj *obj, const char *name, struct ring_params *params) -{ - struct ring *ring; - struct rte_ring *r; - unsigned int flags = RING_F_SP_ENQ | RING_F_SC_DEQ; - - /* Check input params */ - if (!name || ring_find(obj, name) || !params || !params->size) - return NULL; - - /** -* Resource create -*/ - r = rte_ring_create( - name, - params->size, - params->numa_node, - flags); - if (!r) - return NULL; - - /* Node allocation */ - ring = calloc(1, sizeof(struct ring)); - if (!ring) { - rte_ring_free(r); - return NULL; - } - - /* Node fill in */ - strlcpy(ring->name, name, sizeof(ring->name)); - - /* Node add to list */ - TAILQ_INSERT_TAIL(&obj->ring_list, ring, node); - - return ring; -} - -struct ring * -ring_find(struct obj *obj, const char *name) -{ - struct ring *ring; - - if (!obj || !name) - return NULL; - - TAILQ_FOREACH(ring, &obj->ring_list, node) - if (strcmp(ring->name, name) == 0) - return ring; - - return NULL; -} - /* * obj */ @@ -351,7 +289,6 @@ obj_init(void) return NULL; TAILQ_INIT(&obj->link_list); - TAILQ_INIT(&obj->ring_list); return obj; } diff --git a/examples/pipeline/obj.h b/examples/pipeline/obj.h index 4ea610ceed..dbbc6d39a0 100644 --- a/examples/pipeline/obj.h +++ b/examples/pipeline/obj.h @@ -73,25 +73,4 @@ link_find(struct obj *obj, const char *name); struct link * link_next(struct obj *obj, struct link *link); -/* - * ring - */ -struct ring_params { - uint32_t size; - uint32_t numa_node; -}; - -struct ring { - TAILQ_ENTRY(ring) node; - char
[PATCH V6 04/11] examples/pipeline: streamline the Ethernet device support
Streamline the Ethernet device support code and remove redundant code. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 172 ++-- examples/pipeline/main.c | 12 +-- examples/pipeline/obj.c | 186 +-- examples/pipeline/obj.h | 51 ++- 4 files changed, 136 insertions(+), 285 deletions(-) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 517682f7c9..617af63d63 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -292,16 +292,17 @@ cmd_ethdev(char **tokens, uint32_t n_tokens, char *out, size_t out_size, - void *obj) + void *obj __rte_unused) { - struct link_params p; - struct link_params_rss rss; - struct link *link; + struct ethdev_params p; + struct ethdev_params_rss rss; char *name; + int status; memset(&p, 0, sizeof(p)); + memset(&rss, 0, sizeof(rss)); - if ((n_tokens < 11) || (n_tokens > 12 + LINK_RXQ_RSS_MAX)) { + if (n_tokens < 11 || n_tokens > 12 + ETHDEV_RXQ_RSS_MAX) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } @@ -377,111 +378,98 @@ cmd_ethdev(char **tokens, } } - link = link_create(obj, name, &p); - if (link == NULL) { + status = ethdev_config(name, &p); + if (status) { snprintf(out, out_size, MSG_CMD_FAIL, tokens[0]); return; } } -/* Print the link stats and info */ static void -print_link_info(struct link *link, char *out, size_t out_size) +ethdev_show(uint16_t port_id, char **out, size_t *out_size) { + char name[RTE_ETH_NAME_MAX_LEN]; + struct rte_eth_dev_info info; struct rte_eth_stats stats; - struct rte_ether_addr mac_addr; - struct rte_eth_link eth_link; - uint16_t mtu; - int ret; - - memset(&stats, 0, sizeof(stats)); - rte_eth_stats_get(link->port_id, &stats); - - ret = rte_eth_macaddr_get(link->port_id, &mac_addr); - if (ret != 0) { - snprintf(out, out_size, "\n%s: MAC address get failed: %s", -link->name, rte_strerror(-ret)); - return; - } - - ret = rte_eth_link_get(link->port_id, ð_link); - if (ret < 0) { - snprintf(out, out_size, "\n%s: link get failed: %s", -link->name, rte_strerror(-ret)); - return; - } - - rte_eth_dev_get_mtu(link->port_id, &mtu); - - snprintf(out, out_size, - "\n" - "%s: flags=<%s> mtu %u\n" - "\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n" - "\tport# %u speed %s\n" - "\tRX packets %" PRIu64" bytes %" PRIu64"\n" - "\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n" - "\tTX packets %" PRIu64" bytes %" PRIu64"\n" - "\tTX errors %" PRIu64"\n", - link->name, - eth_link.link_status == 0 ? "DOWN" : "UP", - mtu, - RTE_ETHER_ADDR_BYTES(&mac_addr), - link->n_rxq, - link->n_txq, - link->port_id, - rte_eth_link_speed_to_str(eth_link.link_speed), - stats.ipackets, - stats.ibytes, - stats.ierrors, - stats.imissed, - stats.rx_nombuf, - stats.opackets, - stats.obytes, - stats.oerrors); + struct rte_ether_addr addr; + struct rte_eth_link link; + uint32_t length; + uint16_t mtu = 0; + + if (!rte_eth_dev_is_valid_port(port_id)) + return; + + rte_eth_dev_get_name_by_port(port_id, name); + rte_eth_dev_info_get(port_id, &info); + rte_eth_stats_get(port_id, &stats); + rte_eth_macaddr_get(port_id, &addr); + rte_eth_link_get(port_id, &link); + rte_eth_dev_get_mtu(port_id, &mtu); + + snprintf(*out, *out_size, +"%s: flags=<%s> mtu %u\n" +"\tether " RTE_ETHER_ADDR_PRT_FMT " rxqueues %u txqueues %u\n" +"\tport# %u speed %s\n" +"\tRX packets %" PRIu64" bytes %" PRIu64"\n" +"\tRX errors %" PRIu64" missed %" PRIu64" no-mbuf %" PRIu64"\n" +"\tTX packets %" PRIu64" bytes %" PRIu64"\n" +"\tTX errors %" PRIu64"\n\n", +name, +link.link_status ? "UP" : "DOWN", +mtu, +RTE_ETHER_ADDR_BYTES(&addr), +info.nb_rx_queues, +info.nb_tx_queues, +port_id, +rte_eth_link_speed_to_str(link.link_speed), +stats.ipackets, +stats.ibytes, +stats.ierrors, +
[PATCH V6 05/11] examples/pipeline: support crypto devices
Add support for crypto devices in the application. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/obj.c | 62 + examples/pipeline/obj.h | 11 2 files changed, 73 insertions(+) diff --git a/examples/pipeline/obj.c b/examples/pipeline/obj.c index 143b968472..d39034ec22 100644 --- a/examples/pipeline/obj.c +++ b/examples/pipeline/obj.c @@ -7,6 +7,7 @@ #include #include +#include #include "obj.h" @@ -190,3 +191,64 @@ ethdev_config(const char *name, struct ethdev_params *params) return 0; } + +/* + * cryptodev + */ +int +cryptodev_config(const char *name, struct cryptodev_params *params) +{ + struct rte_cryptodev_info dev_info; + struct rte_cryptodev_config dev_conf; + struct rte_cryptodev_qp_conf queue_conf; + uint8_t dev_id; + uint32_t socket_id, i; + int status; + + /* Check input parameters. */ + if (!name || + !params->n_queue_pairs || + !params->queue_size) + return -EINVAL; + + /* Find the crypto device. */ + status = rte_cryptodev_get_dev_id(name); + if (status < 0) + return -EINVAL; + + dev_id = (uint8_t)status; + + rte_cryptodev_info_get(dev_id, &dev_info); + if (params->n_queue_pairs > dev_info.max_nb_queue_pairs) + return -EINVAL; + + socket_id = rte_cryptodev_socket_id(dev_id); + + /* Configure the crypto device. */ + memset(&dev_conf, 0, sizeof(dev_conf)); + dev_conf.socket_id = socket_id; + dev_conf.nb_queue_pairs = params->n_queue_pairs; + dev_conf.ff_disable = 0; + + status = rte_cryptodev_configure(dev_id, &dev_conf); + if (status) + return status; + + /* Configure the crypto device queue pairs. */ + memset(&queue_conf, 0, sizeof(queue_conf)); + queue_conf.nb_descriptors = params->queue_size; + queue_conf.mp_session = NULL; + + for (i = 0; i < params->n_queue_pairs; i++) { + status = rte_cryptodev_queue_pair_setup(dev_id, i, &queue_conf, socket_id); + if (status) + return status; + } + + /* Start the crypto device. */ + status = rte_cryptodev_start(dev_id); + if (status) + return status; + + return 0; +} diff --git a/examples/pipeline/obj.h b/examples/pipeline/obj.h index fb091f4ba7..0f103be6a7 100644 --- a/examples/pipeline/obj.h +++ b/examples/pipeline/obj.h @@ -38,4 +38,15 @@ struct ethdev_params { int ethdev_config(const char *name, struct ethdev_params *params); +/* + * cryptodev + */ +struct cryptodev_params { + uint32_t n_queue_pairs; + uint32_t queue_size; +}; + +int +cryptodev_config(const char *name, struct cryptodev_params *params); + #endif /* _INCLUDE_OBJ_H_ */ -- 2.34.1
[PATCH V6 06/11] examples/pipeline: add CLI command for crypto device
Add CLI command for the configuration of crypto devices. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 63 + 1 file changed, 63 insertions(+) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index 617af63d63..dbaf436620 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -524,6 +524,58 @@ cmd_ring(char **tokens, } } +static const char cmd_cryptodev_help[] = +"cryptodev queues qsize \n"; + +static void +cmd_cryptodev(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj __rte_unused) +{ + struct cryptodev_params params; + char *cryptodev_name; + int status; + + if (n_tokens != 6) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + if (strcmp(tokens[0], "cryptodev")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cryptodev"); + return; + } + + cryptodev_name = tokens[1]; + + if (strcmp(tokens[2], "queues")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "queues"); + return; + } + + if (parser_read_uint32(¶ms.n_queue_pairs, tokens[3])) { + snprintf(out, out_size, MSG_ARG_INVALID, "n_queue_pairs"); + return; + } + + if (strcmp(tokens[4], "qsize")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "qsize"); + return; + } + + + if (parser_read_uint32(¶ms.queue_size, tokens[5])) { + snprintf(out, out_size, MSG_ARG_INVALID, "queue_size"); + return; + } + + status = cryptodev_config(cryptodev_name, ¶ms); + if (status) + snprintf(out, out_size, "Crypto device configuration failed (%d).\n", status); +} + static const char cmd_pipeline_codegen_help[] = "pipeline codegen \n"; @@ -2994,6 +3046,7 @@ cmd_help(char **tokens, "\tethdev\n" "\tethdev show\n" "\tring\n" + "\tcryptodev\n" "\tpipeline codegen\n" "\tpipeline libbuild\n" "\tpipeline build\n" @@ -3045,6 +3098,11 @@ cmd_help(char **tokens, return; } + if (!strcmp(tokens[0], "cryptodev")) { + snprintf(out, out_size, "\n%s\n", cmd_cryptodev_help); + return; + } + if ((strcmp(tokens[0], "pipeline") == 0) && (n_tokens == 2) && (strcmp(tokens[1], "codegen") == 0)) { snprintf(out, out_size, "\n%s\n", cmd_pipeline_codegen_help); @@ -3300,6 +3358,11 @@ cli_process(char *in, char *out, size_t out_size, void *obj) return; } + if (!strcmp(tokens[0], "cryptodev")) { + cmd_cryptodev(tokens, n_tokens, out, out_size, obj); + return; + } + if (strcmp(tokens[0], "pipeline") == 0) { if ((n_tokens >= 3) && (strcmp(tokens[1], "codegen") == 0)) { -- 2.34.1
[PATCH V6 07/11] examples/pipeline: add IPsec CLI commands
Add CLI commands for IPsec block configuration. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 298 1 file changed, 298 insertions(+) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index dbaf436620..bcb3e54fb0 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "cli.h" @@ -2913,6 +2914,263 @@ cmd_pipeline_mirror_session(char **tokens, } } +static const char cmd_ipsec_create_help[] = +"ipsec create " +"in out " +"cryptodev cryptoq " +"bsz " +"samax " +"numa \n"; + +static void +cmd_ipsec_create(char **tokens, +uint32_t n_tokens, +char *out, +size_t out_size, +void *obj __rte_unused) +{ + struct rte_swx_ipsec_params p; + struct rte_swx_ipsec *ipsec; + char *ipsec_instance_name; + uint32_t numa_node; + int status; + + if (n_tokens != 20) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + ipsec_instance_name = tokens[1]; + + if (strcmp(tokens[2], "create")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "create"); + return; + } + + if (strcmp(tokens[3], "in")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "in"); + return; + } + + p.ring_in_name = tokens[4]; + + if (strcmp(tokens[5], "out")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "out"); + return; + } + + p.ring_out_name = tokens[6]; + + if (strcmp(tokens[7], "cryptodev")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cryptodev"); + return; + } + + p.crypto_dev_name = tokens[8]; + + if (strcmp(tokens[9], "cryptoq")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "cryptoq"); + return; + } + + if (parser_read_uint32(&p.crypto_dev_queue_pair_id, tokens[10])) { + snprintf(out, out_size, MSG_ARG_INVALID, "crypto_dev_queue_pair_id"); + return; + } + + if (strcmp(tokens[11], "bsz")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "bsz"); + return; + } + + if (parser_read_uint32(&p.bsz.ring_rd, tokens[12])) { + snprintf(out, out_size, MSG_ARG_INVALID, "ring_rd_bsz"); + return; + } + + if (parser_read_uint32(&p.bsz.ring_wr, tokens[13])) { + snprintf(out, out_size, MSG_ARG_INVALID, "ring_wr_bsz"); + return; + } + + if (parser_read_uint32(&p.bsz.crypto_wr, tokens[14])) { + snprintf(out, out_size, MSG_ARG_INVALID, "crypto_wr_bsz"); + return; + } + + if (parser_read_uint32(&p.bsz.crypto_rd, tokens[15])) { + snprintf(out, out_size, MSG_ARG_INVALID, "crypto_rd_bsz"); + return; + } + + if (strcmp(tokens[16], "samax")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "samax"); + return; + } + + if (parser_read_uint32(&p.n_sa_max, tokens[17])) { + snprintf(out, out_size, MSG_ARG_INVALID, "n_sa_max"); + return; + } + + if (strcmp(tokens[18], "numa")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "numa"); + return; + } + + if (parser_read_uint32(&numa_node, tokens[19])) { + snprintf(out, out_size, MSG_ARG_INVALID, "numa_node"); + return; + } + + status = rte_swx_ipsec_create(&ipsec, + ipsec_instance_name, + &p, + (int)numa_node); + if (status) + snprintf(out, out_size, "IPsec instance creation failed (%d).\n", status); +} + +static const char cmd_ipsec_sa_add_help[] = +"ipsec sa add \n"; + +static void +cmd_ipsec_sa_add(char **tokens, +uint32_t n_tokens, +char *out, +size_t out_size, +void *obj __rte_unused) +{ + struct rte_swx_ipsec *ipsec; + char *ipsec_instance_name, *file_name, *line = NULL; + FILE *file = NULL; + uint32_t line_id = 0; + + if (n_tokens != 5) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + ipsec_instance_name = tokens[1]; + ipsec = rte_swx_ipsec_find(ipsec_instance_name); + if (!ipsec) { + snprintf(out, out_size, MSG_ARG_INVALID, "ipsec_instance_name"); + goto free; + } + + if (strcmp(tokens[2], "sa")) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "sa"); + goto free; + } + + if (str
[PATCH V6 08/11] examples/pipeline: rework the thread configuration updates
Previously, the configuration updates for the data plane threads were performed through message queues. Now, this mechanism is replaced by the control thread updating the mirror copy of the data plane thread configuration followed by pointer swapping. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 154 ++--- examples/pipeline/examples/fib.cli| 2 +- examples/pipeline/examples/hash_func.cli | 2 +- examples/pipeline/examples/l2fwd.cli | 2 +- examples/pipeline/examples/l2fwd_macswp.cli | 2 +- .../pipeline/examples/l2fwd_macswp_pcap.cli | 2 +- examples/pipeline/examples/l2fwd_pcap.cli | 2 +- examples/pipeline/examples/learner.cli| 2 +- examples/pipeline/examples/meter.cli | 2 +- examples/pipeline/examples/mirroring.cli | 2 +- examples/pipeline/examples/recirculation.cli | 2 +- examples/pipeline/examples/registers.cli | 2 +- examples/pipeline/examples/selector.cli | 2 +- examples/pipeline/examples/varbit.cli | 2 +- examples/pipeline/examples/vxlan.cli | 2 +- examples/pipeline/examples/vxlan_pcap.cli | 2 +- examples/pipeline/thread.c| 586 -- examples/pipeline/thread.h| 17 +- 18 files changed, 217 insertions(+), 570 deletions(-) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index bcb3e54fb0..d9c325c89c 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -3171,119 +3171,86 @@ cmd_ipsec_sa_delete(char **tokens, rte_swx_ipsec_sa_delete(ipsec, sa_id); } -static const char cmd_thread_pipeline_enable_help[] = -"thread pipeline enable [ period ]\n"; - -#ifndef TIMER_PERIOD_MS_DEFAULT -#define TIMER_PERIOD_MS_DEFAULT 10 -#endif +static const char cmd_pipeline_enable_help[] = +"pipeline enable thread \n"; static void -cmd_thread_pipeline_enable(char **tokens, - uint32_t n_tokens, - char *out, - size_t out_size, - void *obj __rte_unused) +cmd_pipeline_enable(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj __rte_unused) { char *pipeline_name; struct rte_swx_pipeline *p; - uint32_t thread_id, timer_period_ms = TIMER_PERIOD_MS_DEFAULT; + uint32_t thread_id; int status; - if ((n_tokens != 5) && (n_tokens != 7)) { + if (n_tokens != 5) { snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); return; } - if (parser_read_uint32(&thread_id, tokens[1]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); - return; - } - - if (strcmp(tokens[2], "pipeline") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "pipeline"); - return; - } - - pipeline_name = tokens[3]; + pipeline_name = tokens[1]; p = rte_swx_pipeline_find(pipeline_name); if (!p) { snprintf(out, out_size, MSG_ARG_INVALID, "pipeline_name"); return; } - if (strcmp(tokens[4], "enable") != 0) { + if (strcmp(tokens[2], "enable") != 0) { snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable"); return; } - if (n_tokens == 7) { - if (strcmp(tokens[5], "period") != 0) { - snprintf(out, out_size, MSG_ARG_NOT_FOUND, "period"); - return; - } + if (strcmp(tokens[3], "thread") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread"); + return; + } - if (parser_read_uint32(&timer_period_ms, tokens[6]) != 0) { - snprintf(out, out_size, MSG_ARG_INVALID, "timer_period_ms"); - return; - } + if (parser_read_uint32(&thread_id, tokens[4]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); + return; } - status = thread_pipeline_enable(thread_id, p, timer_period_ms); + status = pipeline_enable(p, thread_id); if (status) { - snprintf(out, out_size, MSG_CMD_FAIL, "thread pipeline enable"); + snprintf(out, out_size, MSG_CMD_FAIL, "pipeline enable"); return; } } -static const char cmd_thread_pipeline_disable_help[] = -"thread pipeline disable\n"; +static const char cmd_pipeline_disable_help[] = +"pipeline disable\n"; static void -cmd_thread_pipeline_disable(char **tokens, - uint32_t n_tokens, - char *out, - size_t out_size, - void *obj __rte_unused) +cmd_pipeline_disable(char **tokens, +uint32_t n_tokens, +char *out, +size_t out_size, +
[PATCH V6 09/11] examples/pipeline: support blocks other than pipelines
Previously, the data plane threads only supported the execution of pipelines assigned to them through configuration updates. Now, the data plane threads also support running blocks such as IPsec. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/thread.c | 143 + examples/pipeline/thread.h | 9 +++ 2 files changed, 152 insertions(+) diff --git a/examples/pipeline/thread.c b/examples/pipeline/thread.c index 3001bc0858..dc3ea73fbf 100644 --- a/examples/pipeline/thread.c +++ b/examples/pipeline/thread.c @@ -16,6 +16,10 @@ #define THREAD_PIPELINES_MAX 256 #endif +#ifndef THREAD_BLOCKS_MAX +#define THREAD_BLOCKS_MAX 256 +#endif + /* Pipeline instruction quanta: Needs to be big enough to do some meaningful * work, but not too big to avoid starving any other pipelines mapped to the * same thread. For a pipeline that executes 10 instructions per packet, a @@ -38,9 +42,16 @@ * - Read-write by the CP thread; * - Read-only by the DP thread. */ +struct block { + block_run_f block_func; + void *block; +}; + struct thread { struct rte_swx_pipeline *pipelines[THREAD_PIPELINES_MAX]; + struct block *blocks[THREAD_BLOCKS_MAX]; volatile uint64_t n_pipelines; + volatile uint64_t n_blocks; int enabled; } __rte_cache_aligned; @@ -53,14 +64,43 @@ int thread_init(void) { uint32_t thread_id; + int status = 0; RTE_LCORE_FOREACH_WORKER(thread_id) { struct thread *t = &threads[thread_id]; + uint32_t i; t->enabled = 1; + + for (i = 0; i < THREAD_BLOCKS_MAX; i++) { + struct block *b; + + b = calloc(1, sizeof(struct block)); + if (!b) { + status = -ENOMEM; + goto error; + } + + t->blocks[i] = b; + } } return 0; + +error: + RTE_LCORE_FOREACH_WORKER(thread_id) { + struct thread *t = &threads[thread_id]; + uint32_t i; + + t->enabled = 0; + + for (i = 0; i < THREAD_BLOCKS_MAX; i++) { + free(t->blocks[i]); + t->blocks[i] = NULL; + } + } + + return status; } static uint32_t @@ -83,6 +123,26 @@ pipeline_find(struct rte_swx_pipeline *p) return thread_id; } +static uint32_t +block_find(void *b) +{ + uint32_t thread_id; + + for (thread_id = 0; thread_id < RTE_MAX_LCORE; thread_id++) { + struct thread *t = &threads[thread_id]; + uint32_t i; + + if (!t->enabled) + continue; + + for (i = 0; i < t->n_blocks; i++) + if (t->blocks[i]->block == b) + break; + } + + return thread_id; +} + /** * Enable a given pipeline to run on a specific DP thread. * @@ -201,9 +261,85 @@ pipeline_disable(struct rte_swx_pipeline *p) return; } +int +block_enable(block_run_f block_func, void *block, uint32_t thread_id) +{ + struct thread *t; + uint64_t n_blocks; + + /* Check input params */ + if (!block_func || !block || thread_id >= RTE_MAX_LCORE) + return -EINVAL; + + if (block_find(block) < RTE_MAX_LCORE) + return -EEXIST; + + t = &threads[thread_id]; + if (!t->enabled) + return -EINVAL; + + n_blocks = t->n_blocks; + + /* Check there is room for at least one more block. */ + if (n_blocks >= THREAD_BLOCKS_MAX) + return -ENOSPC; + + /* Install the new block. */ + t->blocks[n_blocks]->block_func = block_func; + t->blocks[n_blocks]->block = block; + + rte_wmb(); + t->n_blocks = n_blocks + 1; + + return 0; +} + +void +block_disable(void *block) +{ + struct thread *t; + uint64_t n_blocks; + uint32_t thread_id, i; + + /* Check input params */ + if (!block) + return; + + /* Find the thread that runs this block. */ + thread_id = block_find(block); + if (thread_id == RTE_MAX_LCORE) + return; + + t = &threads[thread_id]; + n_blocks = t->n_blocks; + + for (i = 0; i < n_blocks; i++) { + struct block *b = t->blocks[i]; + + if (block != b->block) + continue; + + if (i < n_blocks - 1) { + struct block *block_last = t->blocks[n_blocks - 1]; + + t->blocks[i] = block_last; + } + + rte_wmb(); + t->n_blocks = n_blocks - 1; + + rte_wmb(); + t->blocks[n_blocks - 1] = b; + +
[PATCH V6 11/11] examples/pipeline: add IPsec example
Add example files to illustrate the pipeline IPsec support. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/examples/ipsec.cli| 57 +++ examples/pipeline/examples/ipsec.io | 23 +++ examples/pipeline/examples/ipsec.spec | 138 +++ examples/pipeline/examples/ipsec_sa.txt | 216 4 files changed, 434 insertions(+) create mode 100644 examples/pipeline/examples/ipsec.cli create mode 100644 examples/pipeline/examples/ipsec.io create mode 100644 examples/pipeline/examples/ipsec.spec create mode 100644 examples/pipeline/examples/ipsec_sa.txt diff --git a/examples/pipeline/examples/ipsec.cli b/examples/pipeline/examples/ipsec.cli new file mode 100644 index 00..8cb5bf4239 --- /dev/null +++ b/examples/pipeline/examples/ipsec.cli @@ -0,0 +1,57 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright(c) 2022 Intel Corporation + +# Example command line: +# ./build/examples/dpdk-pipeline -l0-1 --vdev crypto_aesni_mb0 -- -s ./examples/pipeline/examples/ipsec.cli +# +# Once the application has started, the command to get the CLI prompt is: +# telnet 0.0.0.0 8086 + +; +; Pipeline code generation & shared object library build. +; +pipeline codegen ./examples/pipeline/examples/ipsec.spec /tmp/ipsec.c +pipeline libbuild /tmp/ipsec.c /tmp/ipsec.so + +; +; List of DPDK devices. +; +; Note: Customize the parameters below to match your setup. +; +mempool MEMPOOL0 meta 128 pkt 2176 pool 32K cache 256 numa 0 +ethdev :18:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on +ethdev :18:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on +ethdev :3b:00.0 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on +ethdev :3b:00.1 rxq 1 128 MEMPOOL0 txq 1 512 promiscuous on + +cryptodev crypto_aesni_mb0 queues 1 qsize 128 +ring RING0 size 1024 numa 0 +ring RING1 size 1024 numa 0 + +; +; List of pipelines. +; +pipeline PIPELINE0 build lib /tmp/ipsec.so io ./examples/pipeline/examples/ipsec.io numa 0 + +; +; List of IPsec devices. +; +ipsec IPSEC0 create in RING0 out RING1 cryptodev crypto_aesni_mb0 cryptoq 0 bsz 32 32 32 32 samax 512 numa 0 + +; +; Initial set of table entries. +; +; The table entries can later be updated at run-time through the CLI commands. +; +//pipeline PIPELINE0 table policy_table add ./examples/pipeline/examples/ipsec_policy_table.txt +//pipeline PIPELINE0 table routing_table add ./examples/pipeline/examples/ipsec_routing_table.txt +//pipeline PIPELINE0 table nexthop_table add ./examples/pipeline/examples/ipsec_nexthop_table.txt +//pipeline PIPELINE0 commit + +ipsec IPSEC0 sa add ./examples/pipeline/examples/ipsec_sa.txt + +; +; Pipelines and blocks mapping to CPU threads. +; +pipeline PIPELINE0 enable thread 1 +block type ipsec instance IPSEC0 enable thread 1 diff --git a/examples/pipeline/examples/ipsec.io b/examples/pipeline/examples/ipsec.io new file mode 100644 index 00..f5a3fcf961 --- /dev/null +++ b/examples/pipeline/examples/ipsec.io @@ -0,0 +1,23 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright(c) 2022 Intel Corporation + +; +; Pipeline packet mirroring. +; +mirroring slots 4 sessions 64 + +; +; Pipeline input ports. +; +; Note: Customize the parameters below to match your setup. +; +port in 0 ethdev :18:00.0 rxq 0 bsz 32 +port in 1 ring RING1 bsz 32 + +; +; Pipeline output ports. +; +; Note: Customize the parameters below to match your setup. +; +port out 0 ethdev :18:00.0 txq 0 bsz 32 +port out 1 ring RING0 bsz 32 diff --git a/examples/pipeline/examples/ipsec.spec b/examples/pipeline/examples/ipsec.spec new file mode 100644 index 00..09aa831881 --- /dev/null +++ b/examples/pipeline/examples/ipsec.spec @@ -0,0 +1,138 @@ +; SPDX-License-Identifier: BSD-3-Clause +; Copyright(c) 2020 Intel Corporation + +// +// Headers +// +struct ethernet_h { + bit<48> dst_addr + bit<48> src_addr + bit<16> ethertype +} + +struct ipv4_h { + bit<8> ver_ihl + bit<8> diffserv + bit<16> total_len + bit<16> identification + bit<16> flags_offset + bit<8> ttl + bit<8> protocol + bit<16> hdr_checksum + bit<32> src_addr + bit<32> dst_addr +} + +struct udp_h { + bit<16> src_port + bit<16> dst_port + bit<16> length + bit<16> checksum +} + +struct ipsec_internal_h { + bit<32> sa_id +} + +header ethernet instanceof ethernet_h +header ipv4 instanceof ipv4_h +header udp instanceof udp_h +header ipsec_internal instanceof ipsec_internal_h + +// +// Meta-data +// +struct metadata_t { + bit<32> port_in + bit<32> port_out + + bit<32> src_addr + bit<32> dst_addr + bit<8> protocol + bit<16> src_port + bit<16> dst_port +} + +metadata instanceof metadata_t + +// +// Actions +// +struct encrypt_args_t { + bit<32> sa_id +} + +action encrypt args instanceof encrypt_args_t { + //Set the IPsec internal header. + validate h.ipsec_internal
[PATCH V6 10/11] examples/pipeline: add block enable/disable CLI commands
Add CLI commands to enable/disable block execution on data plane threads. Signed-off-by: Cristian Dumitrescu Signed-off-by: Kamalakannan R --- examples/pipeline/cli.c | 154 1 file changed, 154 insertions(+) diff --git a/examples/pipeline/cli.c b/examples/pipeline/cli.c index d9c325c89c..87f9c0370d 100644 --- a/examples/pipeline/cli.c +++ b/examples/pipeline/cli.c @@ -3253,6 +3253,134 @@ cmd_pipeline_disable(char **tokens, pipeline_disable(p); } +static const char cmd_block_enable_help[] = +"block type instance enable thread \n"; + +static void +cmd_block_enable(char **tokens, +uint32_t n_tokens, +char *out, +size_t out_size, +void *obj __rte_unused) +{ + char *block_type, *block_name; + block_run_f block_func = NULL; + void *block = NULL; + uint32_t thread_id; + int status; + + if (n_tokens != 8) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + if (strcmp(tokens[1], "type") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "type"); + return; + } + + block_type = tokens[2]; + + if (strcmp(tokens[3], "instance") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "instance"); + return; + } + + block_name = tokens[4]; + + if (strcmp(tokens[5], "enable") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "enable"); + return; + } + + if (strcmp(tokens[6], "thread") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "thread"); + return; + } + + if (parser_read_uint32(&thread_id, tokens[7]) != 0) { + snprintf(out, out_size, MSG_ARG_INVALID, "thread_id"); + return; + } + + if (!strcmp(block_type, "ipsec")) { + struct rte_swx_ipsec *ipsec; + + ipsec = rte_swx_ipsec_find(block_name); + if (!ipsec) { + snprintf(out, out_size, MSG_ARG_INVALID, "block_name"); + return; + } + + block_func = (block_run_f)rte_swx_ipsec_run; + block = (void *)ipsec; + } else { + snprintf(out, out_size, MSG_ARG_INVALID, "block_type"); + return; + } + + status = block_enable(block_func, block, thread_id); + if (status) { + snprintf(out, out_size, MSG_CMD_FAIL, "block enable"); + return; + } +} + +static const char cmd_block_disable_help[] = +"block type instance disable\n"; + +static void +cmd_block_disable(char **tokens, + uint32_t n_tokens, + char *out, + size_t out_size, + void *obj __rte_unused) +{ + char *block_type, *block_name; + void *block = NULL; + + if (n_tokens != 6) { + snprintf(out, out_size, MSG_ARG_MISMATCH, tokens[0]); + return; + } + + if (strcmp(tokens[1], "type") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "type"); + return; + } + + block_type = tokens[2]; + + if (strcmp(tokens[3], "instance") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "instance"); + return; + } + + block_name = tokens[4]; + + if (strcmp(tokens[5], "disable") != 0) { + snprintf(out, out_size, MSG_ARG_NOT_FOUND, "disable"); + return; + } + + if (!strcmp(block_type, "ipsec")) { + struct rte_swx_ipsec *ipsec; + + ipsec = rte_swx_ipsec_find(block_name); + if (!ipsec) { + snprintf(out, out_size, MSG_ARG_INVALID, "block_name"); + return; + } + + block = (void *)ipsec; + } else { + snprintf(out, out_size, MSG_ARG_INVALID, "block_type"); + return; + } + + block_disable(block); +} + static void cmd_help(char **tokens, uint32_t n_tokens, @@ -3301,6 +3429,8 @@ cmd_help(char **tokens, "\tipsec create\n" "\tipsec sa add\n" "\tipsec sa delete\n" + "\tblock enable\n" + "\tblock disable\n" ); return; } @@ -3556,6 +3686,18 @@ cmd_help(char **tokens, return; } + if (!strcmp(tokens[0], "block") && + (n_tokens == 2) && !strcmp(tokens[1], "enable")) { + snprintf(out, out_size, "\n%s\n", cmd_block_enable_help); + return; + } + + if (!strcmp(tokens[0], "block") && + (n_tokens == 2) && !strcmp(tokens[1], "disable")) { +
RE: [PATCH 1/3] lib: dpdk spec to skip red for ingress policer
> -Original Message- > From: Rakesh Kudurumalla > Sent: Wednesday, 18 January 2023 10:10 > > > > -Original Message- > > From: Rakesh Kudurumalla > > Sent: Tuesday, January 10, 2023 12:12 PM > > To: Ori Kam ; Jerin Jacob ; > > Stephen Hemminger > > Cc: NBU-Contact-Thomas Monjalon (EXTERNAL) ; > > Ferruh Yigit ; Andrew Rybchenko > > ; dev@dpdk.org; NBU-Contact-Adrien > > Mazarguil (EXTERNAL) > > Subject: RE: [PATCH 1/3] lib: dpdk spec to skip red for ingress policer > > > > > > > > > -Original Message- > > > From: Ori Kam > > > Sent: Monday, December 26, 2022 10:30 PM > > > To: Jerin Jacob ; Stephen Hemminger > > > > > > Cc: Rakesh Kudurumalla ; NBU-Contact- > > Thomas > > > Monjalon (EXTERNAL) ; Ferruh Yigit > > > ; Andrew Rybchenko > > > ; dev@dpdk.org; NBU-Contact- > Adrien > > > Mazarguil (EXTERNAL) > > > Subject: [EXT] RE: [PATCH 1/3] lib: dpdk spec to skip red for ingress > > > policer > > > > > > External Email > > > > > > -- > > > Hi All, > > > > > > > -Original Message- > > > > From: Jerin Jacob > > > > Sent: Thursday, 22 December 2022 7:27 > > > > > > > > On Thu, Dec 22, 2022 at 8:32 AM Stephen Hemminger > > > > wrote: > > > > > > > > > > On Thu, 22 Dec 2022 07:09:02 +0530 Rakesh Kudurumalla > > > > > wrote: > > > > > > > > > > > Dropping of packets based on RED can be skipped with meter > > > > > > action, when RED is configured using > > > > > > rte_eth_cman_config_set() > > > > > > > > > > > > Signed-off-by: Rakesh Kudurumalla > > > > > > > > > > Should this be more general and apply to all congestion management > > > > > options. Assuming the hardware can do something better than RED. > > > > > > > > Yes. We can use "enum rte_cman_mode mode" in the descriptor to > > > > future- proof. > > > > > > I'm missing the idea of this new action, I understand that is related > > > to Jerin congestion patches. > > > But I fail to see why we need it? Is it to mark some metadata that > > > will have some effect on the congestion result? (I assume the system > > > is implemented in the HW) > > > > Yes. It is implemented in HW. Congestion management is applied on > ethdev > > Rx queue using rte_eth_cman_config() API. Once it is configured, it applies > to > > all the packets that steer towards that particular ethdev Rx queue. This > > feature help to skip the congestion management processing based on the > > packet color identified by the rte_flow meter object. For example, If one > Rx > > queue configured as RED congestion and application wants to bypass the > > RED congestion processing for all GREEN color packet can be expressed > > though this API proposal. > > Hi Ori Kam, > > Let me know if above information would give clear idea on skip RED action I think so, to put it in my own words, when setting this the selected packet is treated as green packet? If so, can we use the meter_color field? If you want the packet to be green just set the field to green? Best, Ori
RE: [RFC] ethdev: sharing indirect actions between ports
> -Original Message- > From: Andrew Rybchenko > Sent: Friday, 20 January 2023 14:23 > > On 1/18/23 19:37, Slava Ovsiienko wrote: > > > > > >> -Original Message- > >> From: Thomas Monjalon > >> Sent: Wednesday, January 18, 2023 6:22 PM > >> To: Slava Ovsiienko ; Ori Kam > >> > >> Cc: dev@dpdk.org; Matan Azrad ; Raslan > Darawsheh > >> ; andrew.rybche...@oktetlabs.ru; > >> ivan.ma...@oktetlabs.ru; ferruh.yi...@amd.com > >> Subject: Re: [RFC] ethdev: sharing indirect actions between ports > >> > >> 18/01/2023 16:17, Ori Kam: > >>> From: Thomas Monjalon > 28/12/2022 17:54, Viacheslav Ovsiienko: > > The RTE Flow API implements the concept of shared objects, known > > as indirect actions (RTE_FLOW_ACTION_TYPE_INDIRECT). > > An application can create the indirect action of desired type and > > configuration with rte_flow_action_handle_create call and then > > specify the obtained action handle in multiple flows. > > > > The initial concept supposes the action handle has strict > > attachment to the port it was created on and to be used > > exclusively in the flows being installed on the port. > > > > Nowadays the multipath network topologies are quite common, > > packets belonging to the same connection might arrive and be sent > > over multiple ports, and there is the raising demand to handle > > these "spread" connections. To fulfil this demand it is proposed > > to extend indirect action sharing across the multiple ports. This > > kind of sharing would be extremely useful for the meters and > > counters, allowing to manage the single connection over the > > multiple ports. > > > > This cross-port object sharing is hard to implement in generic way > > merely with software on the upper layers, but can be provided by > > the driver over the single hardware instance, where multiple > > ports reside on the same physical NIC and share the same hardware > > context. > > > > To allow this action sharing application should specify the "host > > port" during flow configuring to claim the intention to share the > > indirect actions. All indirect actions reside within "host port" > > context and can be shared in flows being installed > > I don't like the word "host" because it may refer to the host CPU. > Also if I understand well, the application must choose one port > between all ports of the NIC and keep using the same. > I guess we don't want to create a NIC id. > So I would suggest to rename to nic_ref_port or something like that. > > >>> > >>> I think that host is the correct word since this port hosts all > >>> resources for other ports. (this is also why the host is used in case > >>> of CPU 😊) > >>> I don't think it is correct to use bad wording due to the fact that > >>> some one else also uses this word. > >>> in rte_flow we never talk about host CPU so I don't think this is > confusing. > >> > >> The confusion is that we can think of a port on the host. > > > > In my humble opinion, "_port_id" suffix explicitly specifies what field is > > and > does not leave > > too much space for confusion. > > > > "root_port_id"? "base_port_id"? "container_port_id" ? "mgmnt_port_id" > ? > > Looks worse as for me and does not reflect the exact meaning. > > As Ori mentioned this is DPDK port ID that embraces all the shared actions. > > It plays a host role for them. > > Maybe 'owner_port_id' or 'rsrc_port_id' ? > Rsrc? Owner_port looks O.K but I'm not sure what is the issue with the original suggestion. Best, Ori
RE: [PATCH v6 1/4] lib: add generic support for reading PMU events
>-Original Message- >From: Morten Brørup >Sent: Thursday, January 26, 2023 1:30 PM >To: Tomasz Duszynski ; dev@dpdk.org; Thomas Monjalon > >Cc: Jerin Jacob Kollanukkaran ; ruifeng.w...@arm.com; >mattias.ronnb...@ericsson.com; zhou...@loongson.cn; bruce.richard...@intel.com; >roret...@linux.microsoft.com >Subject: [EXT] RE: [PATCH v6 1/4] lib: add generic support for reading PMU >events > >External Email > >-- >> From: Tomasz Duszynski [mailto:tduszyn...@marvell.com] >> Sent: Thursday, 26 January 2023 10.40 >> >> >From: Morten Brørup >> >Sent: Friday, January 20, 2023 10:47 AM >> > >> >> From: Tomasz Duszynski [mailto:tduszyn...@marvell.com] >> >> Sent: Friday, 20 January 2023 00.39 >> >> >> >> Add support for programming PMU counters and reading their values >> >> in runtime bypassing kernel completely. >> >> >> >> This is especially useful in cases where CPU cores are isolated >> >> (nohz_full) i.e run dedicated tasks. In such cases one cannot use >> >> standard perf utility without sacrificing latency and performance. >> >> >> >> Signed-off-by: Tomasz Duszynski >> >> --- >> > >> >If you insist on passing lcore_id around as a function parameter, the >> function description must >> >mention that the lcore_id parameter must be set to rte_lcore_id() for >> the functions where this is a >> >requirement, including all functions that use those functions. > >Perhaps I'm stating this wrong, so let me try to rephrase: > >As I understand it, some of the setup functions must be called from the EAL >thread that executes >that function - due to some syscall (SYS_perf_event_open) needing to be called >from the thread >itself. > >Those functions should not take an lcore_id parameter. Otherwise, I would >expect to be able to call >those functions from e.g. the main thread and pass the lcore_id of any EAL >thread as a parameter, >which you at the bottom of this email [1] explained is not possible. > >[1]: https://urldefense.proofpoint.com/v2/url?u=http- >3A__inbox.dpdk.org_dev_DM4PR18MB4368461EC42603F77A7DC1BCD2E09- >40DM4PR18MB4368.namprd18.prod.outlook.com_&d=DwIFAw&c=nKjWec2b6R0mOyPaz7xtfQ&r=PZNXgrbjdlXxVEEGYkxI >xRndyEUwWU_ad5ce22YI6Is&m=QkMcmM2epUOCdRd6xI5o3d2nQaqruy0GvOQUgbn75cLlzobEVMwLBUiGXADiuvVz&s=5K9oM8 >e7u52C_0_5xtWIKl31aXRHhJDKoQTDQp5EHWY&e= > >> > >> >> Not sure why are you insisting so much on removing that rte_lcore_id(). >> Yes that macro evaluates >> to integer but if you don't think about internals this resembles a >> function call. > >I agree with this argument. And for that reason, passing lcore_id around could >be relevant. > >I only wanted to bring your attention to the low cost of fetching it inside >the functions, as an >alternative to passing it as an argument. > >> >> Then natural pattern is to call it once and reuse results if possible. > >Yes, and I would usually agree to using this pattern. > >> Passing lcore_id around >> implies that calls are per l-core, why would that confuse anyone >> reading that code? > >This is where I disagree: Passing lcore_id as a parameter to a function does >NOT imply that the >function is running on that lcore! > >E.g rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id) [2] >takes lcore_id as a >parameter, and does not assume that lcore_id==rte_lcore_id(). > Oh, now I got your point! Okay then, if this is going to cause confusion because of misleading self-documenting code I'll change that. >[2]: https://urldefense.proofpoint.com/v2/url?u=https- >3A__elixir.bootlin.com_dpdk_latest_source_lib_mempool_rte-5Fmempool.h- >23L1315&d=DwIFAw&c=nKjWec2b6R0mOyPaz7xtfQ&r=PZNXgrbjdlXxVEEGYkxIxRndyEUwWU_ad5ce22YI6Is&m=QkMcmM2ep >UOCdRd6xI5o3d2nQaqruy0GvOQUgbn75cLlzobEVMwLBUiGXADiuvVz&s=4pnL_TZcVhj476u19ybcn2Rbad6OTb3k2U- >nhFvhZ0k&e= > >> >> Besides, all functions taking it are internal stuff hence you cannot >> call it elsewhere. > >OK. I agree that this reduces the risk of incorrect use. > >Generally, I think that internal functions should be documented too. Not to >the full extent, like >public functions, but some documentation is nice. > >And if there are special requirements to a function parameter, it should be >documented with that >function. Requiring that the lcore_id parameter must be == rte_lcore_id() is >certainly a special >requirement. > >It might just be me worrying too much, so... If nobody else complains about >this, I can live with >it as is. Assuming that none of the public functions have this special >requirement (either directly >or indirectly, by calling functions with the special requirement). > >> >> >Alternatively, follow my previous suggestion: Omit the lcore_id >> function parameter, and use >> >rte_lcore_id() instead. >> > >>
[PATCH v7 2/5] eal: report applications lcore usage
Allow applications to register a callback that will be invoked in rte_lcore_dump() and when requesting lcore info in the telemetry API. The callback is expected to return the number of TSC cycles that have passed since application start and the number of these cycles that were spent doing busy work. Signed-off-by: Robin Jarry Acked-by: Morten Brørup Reviewed-by: Kevin Laatz --- Notes: v6 -> v7: * Use asprintf to format busy/total cycles in lcore_dump_cb * Style fixes * Moved rte_lcore_register_usage_cb in a 23.03 block of eal/version.map * Added release notes entry doc/guides/rel_notes/release_23_03.rst | 7 lib/eal/common/eal_common_lcore.c | 48 -- lib/eal/include/rte_lcore.h| 35 +++ lib/eal/version.map| 3 ++ 4 files changed, 91 insertions(+), 2 deletions(-) diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst index c15f6fbb9f19..4c84d16a5f7e 100644 --- a/doc/guides/rel_notes/release_23_03.rst +++ b/doc/guides/rel_notes/release_23_03.rst @@ -69,6 +69,13 @@ New Features ``rte_event_dev_config::nb_single_link_event_port_queues`` parameter required for eth_rx, eth_tx, crypto and timer eventdev adapters. +* **Added support for reporting lcore usage in applications.** + + * The ``/eal/lcore/list`` and ``/eal/lcore/info`` telemetry endpoints have +been added to provide information similar to ``rte_lcore_dump()``. + * Applications can register a callback at startup via +``rte_lcore_register_usage_cb()`` to provide lcore usage information. + Removed Items - diff --git a/lib/eal/common/eal_common_lcore.c b/lib/eal/common/eal_common_lcore.c index 2d0c98a529cd..4cc29ea6272f 100644 --- a/lib/eal/common/eal_common_lcore.c +++ b/lib/eal/common/eal_common_lcore.c @@ -2,6 +2,7 @@ * Copyright(c) 2010-2014 Intel Corporation */ +#include #include #include @@ -437,20 +438,49 @@ lcore_role_str(enum rte_lcore_role_t role) } } +static rte_lcore_usage_cb lcore_usage_cb; + +void +rte_lcore_register_usage_cb(rte_lcore_usage_cb cb) +{ + lcore_usage_cb = cb; +} + static int lcore_dump_cb(unsigned int lcore_id, void *arg) { struct rte_config *cfg = rte_eal_get_configuration(); char cpuset[RTE_CPU_AFFINITY_STR_LEN]; + struct rte_lcore_usage usage; + rte_lcore_usage_cb usage_cb; + char *usage_str = NULL; FILE *f = arg; int ret; + /* The callback may not set all the fields in the structure, so clear it here. */ + memset(&usage, 0, sizeof(usage)); + /* +* Guard against concurrent modification of lcore_usage_cb. +* rte_lcore_register_usage_cb() should only be called once at application init +* but nothing prevents and application to reset the callback to NULL. +*/ + usage_cb = lcore_usage_cb; + if (usage_cb != NULL && usage_cb(lcore_id, &usage) == 0) { + if (asprintf(&usage_str, ", busy cycles %"PRIu64"/%"PRIu64, + usage.busy_cycles, usage.total_cycles) < 0) { + return -ENOMEM; + } + } ret = eal_thread_dump_affinity(&lcore_config[lcore_id].cpuset, cpuset, sizeof(cpuset)); - fprintf(f, "lcore %u, socket %u, role %s, cpuset %s%s\n", lcore_id, + fprintf(f, "lcore %u, socket %u, role %s, cpuset %s%s%s\n", lcore_id, rte_lcore_to_socket_id(lcore_id), lcore_role_str(cfg->lcore_role[lcore_id]), - cpuset, ret == 0 ? "" : "..."); + cpuset, ret == 0 ? "" : "...", + usage_str ? usage_str : ""); + + free(usage_str); + return 0; } @@ -489,7 +519,9 @@ lcore_telemetry_info_cb(unsigned int lcore_id, void *arg) { struct rte_config *cfg = rte_eal_get_configuration(); struct lcore_telemetry_info *info = arg; + struct rte_lcore_usage usage; struct rte_tel_data *cpuset; + rte_lcore_usage_cb usage_cb; unsigned int cpu; if (info->lcore_id != lcore_id) @@ -508,6 +540,18 @@ lcore_telemetry_info_cb(unsigned int lcore_id, void *arg) rte_tel_data_add_array_int(cpuset, cpu); } rte_tel_data_add_dict_container(info->d, "cpuset", cpuset, 0); + /* The callback may not set all the fields in the structure, so clear it here. */ + memset(&usage, 0, sizeof(usage)); + /* +* Guard against concurrent modification of lcore_usage_cb. +* rte_lcore_register_usage_cb() should only be called once at application init +* but nothing prevents and application to reset the callback to NULL. +*/ + usage_cb = lcore_usage_cb; + if (usage_cb != NULL && usage_cb(lcore_id, &usage) == 0) { + rte_tel_data_add_dict_u64(info->d, "total_cycles", usage.total_cycles); +
[PATCH v7 0/5] lcore telemetry improvements
This is a follow up on previous work by Kevin Laatz: http://patches.dpdk.org/project/dpdk/list/?series=24658&state=* This series is aimed at allowing DPDK applications to expose their CPU usage stats in the DPDK telemetry under /eal/lcore/info. This is a much more basic and naive approach which leaves the cpu cycles accounting completely up to the application. For reference, I have implemented a draft patch in OvS to use rte_lcore_register_usage_cb() and report the already available busy cycles information. https://github.com/rjarry/ovs/commit/643e672fe388e348ea7ccbbda6f5a87a066fd919 Changes since v6: - Added release notes entry - Moved lcore role enum to name conversion in a function for reuse - Moved rte_lcore_register_usage_cb in a 23.03 block of eal/version.map - Style & indentation fixes - Use asprintf to format busy/total cycles in lcore_dump_cb Changes since v5: - Added/rephrased some inline comments to address reviews. - Added a new commit that adds the /eal/lcore/usage endpoint as suggested by Kevin and Morten. Robin Jarry (5): eal: add lcore info in telemetry eal: report applications lcore usage app/testpmd: add dump command for lcores app/testpmd: report lcore usage eal: add lcore usage telemetry endpoint app/test-pmd/5tswap.c | 5 +- app/test-pmd/cmdline.c | 3 + app/test-pmd/csumonly.c | 6 +- app/test-pmd/flowgen.c | 2 +- app/test-pmd/icmpecho.c | 6 +- app/test-pmd/iofwd.c| 5 +- app/test-pmd/macfwd.c | 5 +- app/test-pmd/macswap.c | 5 +- app/test-pmd/noisy_vnf.c| 4 + app/test-pmd/rxonly.c | 5 +- app/test-pmd/shared_rxq_fwd.c | 5 +- app/test-pmd/testpmd.c | 40 +++- app/test-pmd/testpmd.h | 14 +- app/test-pmd/txonly.c | 7 +- doc/guides/rel_notes/release_23_03.rst | 8 + doc/guides/testpmd_app_ug/testpmd_funcs.rst | 7 + lib/eal/common/eal_common_lcore.c | 227 ++-- lib/eal/include/rte_lcore.h | 35 +++ lib/eal/version.map | 3 + 19 files changed, 347 insertions(+), 45 deletions(-) -- 2.39.1
[PATCH v7 1/5] eal: add lcore info in telemetry
Report the same information than rte_lcore_dump() in the telemetry API into /eal/lcore/list and /eal/lcore/info,ID. Example: --> /eal/lcore/info,3 { "/eal/lcore/info": { "lcore_id": 3, "socket": 0, "role": "RTE", "cpuset": [ 3 ] } } Signed-off-by: Robin Jarry Acked-by: Morten Brørup Reviewed-by: Kevin Laatz --- Notes: v6 -> v7: * Moved lcore role enum to name conversion in a function for reuse * Style fixes lib/eal/common/eal_common_lcore.c | 119 +- 1 file changed, 101 insertions(+), 18 deletions(-) diff --git a/lib/eal/common/eal_common_lcore.c b/lib/eal/common/eal_common_lcore.c index 06c594b0224f..2d0c98a529cd 100644 --- a/lib/eal/common/eal_common_lcore.c +++ b/lib/eal/common/eal_common_lcore.c @@ -10,6 +10,9 @@ #include #include #include +#ifndef RTE_EXEC_ENV_WINDOWS +#include +#endif #include "eal_private.h" #include "eal_thread.h" @@ -419,35 +422,35 @@ rte_lcore_iterate(rte_lcore_iterate_cb cb, void *arg) return ret; } +static const char * +lcore_role_str(enum rte_lcore_role_t role) +{ + switch (role) { + case ROLE_RTE: + return "RTE"; + case ROLE_SERVICE: + return "SERVICE"; + case ROLE_NON_EAL: + return "NON_EAL"; + default: + return "UNKNOWN"; + } +} + static int lcore_dump_cb(unsigned int lcore_id, void *arg) { struct rte_config *cfg = rte_eal_get_configuration(); char cpuset[RTE_CPU_AFFINITY_STR_LEN]; - const char *role; FILE *f = arg; int ret; - switch (cfg->lcore_role[lcore_id]) { - case ROLE_RTE: - role = "RTE"; - break; - case ROLE_SERVICE: - role = "SERVICE"; - break; - case ROLE_NON_EAL: - role = "NON_EAL"; - break; - default: - role = "UNKNOWN"; - break; - } - ret = eal_thread_dump_affinity(&lcore_config[lcore_id].cpuset, cpuset, sizeof(cpuset)); fprintf(f, "lcore %u, socket %u, role %s, cpuset %s%s\n", lcore_id, - rte_lcore_to_socket_id(lcore_id), role, cpuset, - ret == 0 ? "" : "..."); + rte_lcore_to_socket_id(lcore_id), + lcore_role_str(cfg->lcore_role[lcore_id]), + cpuset, ret == 0 ? "" : "..."); return 0; } @@ -456,3 +459,83 @@ rte_lcore_dump(FILE *f) { rte_lcore_iterate(lcore_dump_cb, f); } + +#ifndef RTE_EXEC_ENV_WINDOWS +static int +lcore_telemetry_id_cb(unsigned int lcore_id, void *arg) +{ + struct rte_tel_data *d = arg; + return rte_tel_data_add_array_int(d, lcore_id); +} + +static int +handle_lcore_list(const char *cmd __rte_unused, + const char *params __rte_unused, + struct rte_tel_data *d) +{ + int ret = rte_tel_data_start_array(d, RTE_TEL_INT_VAL); + if (ret) + return ret; + return rte_lcore_iterate(lcore_telemetry_id_cb, d); +} + +struct lcore_telemetry_info { + unsigned int lcore_id; + struct rte_tel_data *d; +}; + +static int +lcore_telemetry_info_cb(unsigned int lcore_id, void *arg) +{ + struct rte_config *cfg = rte_eal_get_configuration(); + struct lcore_telemetry_info *info = arg; + struct rte_tel_data *cpuset; + unsigned int cpu; + + if (info->lcore_id != lcore_id) + return 0; + + rte_tel_data_start_dict(info->d); + rte_tel_data_add_dict_int(info->d, "lcore_id", lcore_id); + rte_tel_data_add_dict_int(info->d, "socket", rte_lcore_to_socket_id(lcore_id)); + rte_tel_data_add_dict_string(info->d, "role", lcore_role_str(cfg->lcore_role[lcore_id])); + cpuset = rte_tel_data_alloc(); + if (cpuset == NULL) + return -ENOMEM; + rte_tel_data_start_array(cpuset, RTE_TEL_INT_VAL); + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { + if (CPU_ISSET(cpu, &lcore_config[lcore_id].cpuset)) + rte_tel_data_add_array_int(cpuset, cpu); + } + rte_tel_data_add_dict_container(info->d, "cpuset", cpuset, 0); + + return 0; +} + +static int +handle_lcore_info(const char *cmd __rte_unused, const char *params, struct rte_tel_data *d) +{ + struct lcore_telemetry_info info = { .d = d }; + char *endptr = NULL; + + if (params == NULL || strlen(params) == 0) + return -EINVAL; + errno = 0; + info.lcore_id = strtoul(params, &endptr, 10); + if (errno) + return -errno; + if (endptr == params) + return -EINVAL; + return rte_lcore_iterate(lcore_telemetry_info_cb, &info); +} + +RTE_INIT(lcore_telemetry) +{ + rte_telemetry_register_cmd( + "/eal/lcore/list", handle_lcore_list, + "List of lcore ids. Takes no parameters"); + rte_telemetry_r
[PATCH v7 3/5] app/testpmd: add dump command for lcores
Add a simple command that calls rte_lcore_dump(). Signed-off-by: Robin Jarry Acked-by: Morten Brørup Acked-by: Konstantin Ananyev Reviewed-by: Kevin Laatz --- Notes: v6 -> v7: Added doc entry app/test-pmd/cmdline.c | 3 +++ doc/guides/testpmd_app_ug/testpmd_funcs.rst | 7 +++ 2 files changed, 10 insertions(+) diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c index b32dc8bfd445..96474d2ae458 100644 --- a/app/test-pmd/cmdline.c +++ b/app/test-pmd/cmdline.c @@ -8345,6 +8345,8 @@ static void cmd_dump_parsed(void *parsed_result, rte_mempool_list_dump(stdout); else if (!strcmp(res->dump, "dump_devargs")) rte_devargs_dump(stdout); + else if (!strcmp(res->dump, "dump_lcores")) + rte_lcore_dump(stdout); else if (!strcmp(res->dump, "dump_log_types")) rte_log_dump(stdout); } @@ -8358,6 +8360,7 @@ static cmdline_parse_token_string_t cmd_dump_dump = "dump_ring#" "dump_mempool#" "dump_devargs#" + "dump_lcores#" "dump_log_types"); static cmdline_parse_inst_t cmd_dump = { diff --git a/doc/guides/testpmd_app_ug/testpmd_funcs.rst b/doc/guides/testpmd_app_ug/testpmd_funcs.rst index 0037506a792c..33ceb138d11d 100644 --- a/doc/guides/testpmd_app_ug/testpmd_funcs.rst +++ b/doc/guides/testpmd_app_ug/testpmd_funcs.rst @@ -591,6 +591,13 @@ Dumps the user device list:: testpmd> dump_devargs +dump lcores +~~~ + +Dumps the logical cores list:: + + testpmd> dump_lcores + dump log types ~~ -- 2.39.1
[PATCH v7 5/5] eal: add lcore usage telemetry endpoint
Allow fetching CPU cycles usage for all lcores with a single request. This endpoint is intended for repeated and frequent invocations by external monitoring systems and therefore returns condensed data. It consists of a single dictionary with three keys: "lcore_ids", "total_cycles" and "busy_cycles" that are mapped to three arrays of integer values. Each array has the same number of values, one per lcore, in the same order. Example: --> /eal/lcore/usage { "/eal/lcore/usage": { "lcore_ids": [ 4, 5 ], "total_cycles": [ 23846845590, 23900558914 ], "busy_cycles": [ 21043446682, 21448837316 ] } } Cc: Morten Brørup Signed-off-by: Robin Jarry Reviewed-by: Kevin Laatz --- Notes: v7: * Indentation fix * Added release notes entry doc/guides/rel_notes/release_23_03.rst | 5 +- lib/eal/common/eal_common_lcore.c | 64 ++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/doc/guides/rel_notes/release_23_03.rst b/doc/guides/rel_notes/release_23_03.rst index 4c84d16a5f7e..3da483cf65f3 100644 --- a/doc/guides/rel_notes/release_23_03.rst +++ b/doc/guides/rel_notes/release_23_03.rst @@ -71,8 +71,9 @@ New Features * **Added support for reporting lcore usage in applications.** - * The ``/eal/lcore/list`` and ``/eal/lcore/info`` telemetry endpoints have -been added to provide information similar to ``rte_lcore_dump()``. + * The ``/eal/lcore/list``, ``/eal/lcore/usage`` and ``/eal/lcore/info`` +telemetry endpoints have been added to provide information similar to +``rte_lcore_dump()``. * Applications can register a callback at startup via ``rte_lcore_register_usage_cb()`` to provide lcore usage information. diff --git a/lib/eal/common/eal_common_lcore.c b/lib/eal/common/eal_common_lcore.c index 4cc29ea6272f..d84852a23d68 100644 --- a/lib/eal/common/eal_common_lcore.c +++ b/lib/eal/common/eal_common_lcore.c @@ -573,6 +573,67 @@ handle_lcore_info(const char *cmd __rte_unused, const char *params, struct rte_t return rte_lcore_iterate(lcore_telemetry_info_cb, &info); } +struct lcore_telemetry_usage { + struct rte_tel_data *lcore_ids; + struct rte_tel_data *total_cycles; + struct rte_tel_data *busy_cycles; +}; + +static int +lcore_telemetry_usage_cb(unsigned int lcore_id, void *arg) +{ + struct lcore_telemetry_usage *u = arg; + struct rte_lcore_usage usage; + rte_lcore_usage_cb usage_cb; + + /* The callback may not set all the fields in the structure, so clear it here. */ + memset(&usage, 0, sizeof(usage)); + /* +* Guard against concurrent modification of lcore_usage_cb. +* rte_lcore_register_usage_cb() should only be called once at application init +* but nothing prevents and application to reset the callback to NULL. +*/ + usage_cb = lcore_usage_cb; + if (usage_cb != NULL && usage_cb(lcore_id, &usage) == 0) { + rte_tel_data_add_array_int(u->lcore_ids, lcore_id); + rte_tel_data_add_array_u64(u->total_cycles, usage.total_cycles); + rte_tel_data_add_array_u64(u->busy_cycles, usage.busy_cycles); + } + + return 0; +} + +static int +handle_lcore_usage(const char *cmd __rte_unused, + const char *params __rte_unused, + struct rte_tel_data *d) +{ + struct lcore_telemetry_usage usage; + struct rte_tel_data *lcore_ids = rte_tel_data_alloc(); + struct rte_tel_data *total_cycles = rte_tel_data_alloc(); + struct rte_tel_data *busy_cycles = rte_tel_data_alloc(); + + if (!lcore_ids || !total_cycles || !busy_cycles) { + rte_tel_data_free(lcore_ids); + rte_tel_data_free(total_cycles); + rte_tel_data_free(busy_cycles); + return -ENOMEM; + } + + rte_tel_data_start_dict(d); + rte_tel_data_start_array(lcore_ids, RTE_TEL_INT_VAL); + rte_tel_data_start_array(total_cycles, RTE_TEL_U64_VAL); + rte_tel_data_start_array(busy_cycles, RTE_TEL_U64_VAL); + rte_tel_data_add_dict_container(d, "lcore_ids", lcore_ids, 0); + rte_tel_data_add_dict_container(d, "total_cycles", total_cycles, 0); + rte_tel_data_add_dict_container(d, "busy_cycles", busy_cycles, 0); + usage.lcore_ids = lcore_ids; + usage.total_cycles = total_cycles; + usage.busy_cycles = busy_cycles; + + return rte_lcore_iterate(lcore_telemetry_usage_cb, &usage); +} + RTE_INIT(lcore_telemetry) { rte_telemetry_register_cmd( @@ -581,5 +642,8 @@ RTE_INIT(lcore_telemetry) rte_telemetry_register_cmd( "/eal/lcore/info", handle_lcore_info, "Returns lcore info. Parameters: int lcore_id"); + rte_telemetry_register_cmd( + "/eal/lcore/usage", handle_lcore_usage, + "Returns lcore cycles usage. Takes no parameters
[PATCH v7 4/5] app/testpmd: report lcore usage
Reuse the --record-core-cycles option to account for busy cycles. One turn of packet_fwd_t is considered "busy" if there was at least one received or transmitted packet. Add a new busy_cycles field in struct fwd_stream. Update get_end_cycles to accept an additional argument for the number of processed packets. Update fwd_stream.busy_cycles when the number of packets is greater than zero. When --record-core-cycles is specified, register a callback with rte_lcore_register_usage_cb(). In the callback, use the new lcore_id field in struct fwd_lcore to identify the correct index in fwd_lcores and return the sum of busy/total cycles of all fwd_streams. This makes the cycles counters available in rte_lcore_dump() and the lcore telemetry API: testpmd> dump_lcores lcore 3, socket 0, role RTE, cpuset 3 lcore 4, socket 0, role RTE, cpuset 4, busy cycles 1228584096/9239923140 lcore 5, socket 0, role RTE, cpuset 5, busy cycles 1255661768/9218141538 --> /eal/lcore/info,4 { "/eal/lcore/info": { "lcore_id": 4, "socket": 0, "role": "RTE", "cpuset": [ 4 ], "busy_cycles": 10623340318, "total_cycles": 55331167354 } } Signed-off-by: Robin Jarry Acked-by: Morten Brørup Acked-by: Konstantin Ananyev Reviewed-by: Kevin Laatz --- Notes: v6 -> v7: minor style change app/test-pmd/5tswap.c | 5 +++-- app/test-pmd/csumonly.c | 6 +++--- app/test-pmd/flowgen.c| 2 +- app/test-pmd/icmpecho.c | 6 +++--- app/test-pmd/iofwd.c | 5 +++-- app/test-pmd/macfwd.c | 5 +++-- app/test-pmd/macswap.c| 5 +++-- app/test-pmd/noisy_vnf.c | 4 app/test-pmd/rxonly.c | 5 +++-- app/test-pmd/shared_rxq_fwd.c | 5 +++-- app/test-pmd/testpmd.c| 40 ++- app/test-pmd/testpmd.h| 14 app/test-pmd/txonly.c | 7 +++--- 13 files changed, 82 insertions(+), 27 deletions(-) diff --git a/app/test-pmd/5tswap.c b/app/test-pmd/5tswap.c index f041a5e1d530..03225075716c 100644 --- a/app/test-pmd/5tswap.c +++ b/app/test-pmd/5tswap.c @@ -116,7 +116,7 @@ pkt_burst_5tuple_swap(struct fwd_stream *fs) nb_pkt_per_burst); inc_rx_burst_stats(fs, nb_rx); if (unlikely(nb_rx == 0)) - return; + goto end; fs->rx_packets += nb_rx; txp = &ports[fs->tx_port]; @@ -182,7 +182,8 @@ pkt_burst_5tuple_swap(struct fwd_stream *fs) rte_pktmbuf_free(pkts_burst[nb_tx]); } while (++nb_tx < nb_rx); } - get_end_cycles(fs, start_tsc); +end: + get_end_cycles(fs, start_tsc, nb_rx); } static void diff --git a/app/test-pmd/csumonly.c b/app/test-pmd/csumonly.c index 1c2459851522..03e141221a56 100644 --- a/app/test-pmd/csumonly.c +++ b/app/test-pmd/csumonly.c @@ -868,7 +868,7 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) nb_pkt_per_burst); inc_rx_burst_stats(fs, nb_rx); if (unlikely(nb_rx == 0)) - return; + goto end; fs->rx_packets += nb_rx; rx_bad_ip_csum = 0; @@ -1200,8 +1200,8 @@ pkt_burst_checksum_forward(struct fwd_stream *fs) rte_pktmbuf_free(tx_pkts_burst[nb_tx]); } while (++nb_tx < nb_rx); } - - get_end_cycles(fs, start_tsc); +end: + get_end_cycles(fs, start_tsc, nb_rx); } static void diff --git a/app/test-pmd/flowgen.c b/app/test-pmd/flowgen.c index fd6abc0f4124..7b2f0ffdf0f5 100644 --- a/app/test-pmd/flowgen.c +++ b/app/test-pmd/flowgen.c @@ -196,7 +196,7 @@ pkt_burst_flow_gen(struct fwd_stream *fs) RTE_PER_LCORE(_next_flow) = next_flow; - get_end_cycles(fs, start_tsc); + get_end_cycles(fs, start_tsc, nb_tx); } static int diff --git a/app/test-pmd/icmpecho.c b/app/test-pmd/icmpecho.c index 066f2a3ab79b..2fc9f96dc95f 100644 --- a/app/test-pmd/icmpecho.c +++ b/app/test-pmd/icmpecho.c @@ -303,7 +303,7 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) nb_pkt_per_burst); inc_rx_burst_stats(fs, nb_rx); if (unlikely(nb_rx == 0)) - return; + goto end; fs->rx_packets += nb_rx; nb_replies = 0; @@ -508,8 +508,8 @@ reply_to_icmp_echo_rqsts(struct fwd_stream *fs) } while (++nb_tx < nb_replies); } } - - get_end_cycles(fs, start_tsc); +end: + get_end_cycles(fs, start_tsc, nb_rx); } static void diff --git a/app/test-pmd/iofwd.c b/app/test-pmd/iofwd.c index 8fafdec548ad..e5a2dbe20c69 100644 --- a/app/test-pmd/iofwd.c +++ b/app/test-pmd/iofwd.c @@ -59,7 +59,7 @@ pkt_burst_io_forward(struct fwd_stream *fs) pkts_burst, nb_pkt_per_burst); inc_rx_burst_stats(fs, nb_rx); if (unlikely(nb_rx == 0)) - return; + goto end; fs->rx_
RE: [EXT] Re: [PATCH v6 1/4] lib: add generic support for reading PMU events
>-Original Message- >From: Bruce Richardson >Sent: Thursday, January 26, 2023 1:59 PM >To: Morten Brørup >Cc: Tomasz Duszynski ; dev@dpdk.org; Thomas Monjalon >; >Jerin Jacob Kollanukkaran ; ruifeng.w...@arm.com; >mattias.ronnb...@ericsson.com; zhou...@loongson.cn; >roret...@linux.microsoft.com >Subject: [EXT] Re: [PATCH v6 1/4] lib: add generic support for reading PMU >events > >External Email > >-- >On Thu, Jan 26, 2023 at 01:29:36PM +0100, Morten Brørup wrote: >> > From: Tomasz Duszynski [mailto:tduszyn...@marvell.com] >> > Sent: Thursday, 26 January 2023 10.40 >> > >> > >From: Morten Brørup >> > >Sent: Friday, January 20, 2023 10:47 AM >> > > >> > >> From: Tomasz Duszynski [mailto:tduszyn...@marvell.com] >> > >> Sent: Friday, 20 January 2023 00.39 >> > >> >> > >> Add support for programming PMU counters and reading their values >> > >> in runtime bypassing kernel completely. >> > >> >> > >> This is especially useful in cases where CPU cores are isolated >> > >> (nohz_full) i.e run dedicated tasks. In such cases one cannot use >> > >> standard perf utility without sacrificing latency and performance. >> > >> >> > >> Signed-off-by: Tomasz Duszynski >> > >> --- >> > > >> > >If you insist on passing lcore_id around as a function parameter, >> > >the >> > function description must >> > >mention that the lcore_id parameter must be set to rte_lcore_id() >> > >for >> > the functions where this is a >> > >requirement, including all functions that use those functions. >> >> Perhaps I'm stating this wrong, so let me try to rephrase: >> >> As I understand it, some of the setup functions must be called from the EAL >> thread that executes >that function - due to some syscall (SYS_perf_event_open) needing to be called >from the thread >itself. >> >> Those functions should not take an lcore_id parameter. Otherwise, I would >> expect to be able to >call those functions from e.g. the main thread and pass the lcore_id of any >EAL thread as a >parameter, which you at the bottom of this email [1] explained is not possible. >> >> [1]: >> https://urldefense.proofpoint.com/v2/url?u=http-3A__inbox.dpdk.org_dev >> _DM4PR18MB4368461EC42603F77A7DC1BCD2E09-40DM4PR18MB4368.namprd18.prod. >> outlook.com_&d=DwIDAw&c=nKjWec2b6R0mOyPaz7xtfQ&r=PZNXgrbjdlXxVEEGYkxIx >> RndyEUwWU_ad5ce22YI6Is&m=wEvFmuH_S_EhAgRZQTC7z3pQ1Sr_cEsbFAXxgE2Fi2ESd >> 4sMgg-tgVOVDepp-JYO&s=wU4g1LLV4EHyRYpj2inWOK8MDcUKq7txrZ7RXZhUM2I&e= >> >> > > >> > >> > Not sure why are you insisting so much on removing that rte_lcore_id(). >> > Yes that macro evaluates >> > to integer but if you don't think about internals this resembles a >> > function call. >> >> I agree with this argument. And for that reason, passing lcore_id around >> could be relevant. >> >> I only wanted to bring your attention to the low cost of fetching it inside >> the functions, as an >alternative to passing it as an argument. >> >> > >> > Then natural pattern is to call it once and reuse results if possible. >> >> Yes, and I would usually agree to using this pattern. >> >> > Passing lcore_id around >> > implies that calls are per l-core, why would that confuse anyone >> > reading that code? >> >> This is where I disagree: Passing lcore_id as a parameter to a function does >> NOT imply that the >function is running on that lcore! >> >> E.g rte_mempool_default_cache(struct rte_mempool *mp, unsigned lcore_id) [2] >> takes lcore_id as a >parameter, and does not assume that lcore_id==rte_lcore_id(). >> >> [2]: >> https://urldefense.proofpoint.com/v2/url?u=https-3A__elixir.bootlin.co >> m_dpdk_latest_source_lib_mempool_rte-5Fmempool.h-23L1315&d=DwIDAw&c=nK >> jWec2b6R0mOyPaz7xtfQ&r=PZNXgrbjdlXxVEEGYkxIxRndyEUwWU_ad5ce22YI6Is&m=w >> EvFmuH_S_EhAgRZQTC7z3pQ1Sr_cEsbFAXxgE2Fi2ESd4sMgg-tgVOVDepp-JYO&s=Ayyj >> pEtATWUHfWnGMn5j2XDLMjgxxJTh5gQV0m77z5Q&e= >> >> > >> > Besides, all functions taking it are internal stuff hence you cannot >> > call it elsewhere. >> >> OK. I agree that this reduces the risk of incorrect use. >> >> Generally, I think that internal functions should be documented too. Not to >> the full extent, like >public functions, but some documentation is nice. >> >> And if there are special requirements to a function parameter, it should be >> documented with that >function. Requiring that the lcore_id parameter must be == rte_lcore_id() is >certainly a special >requirement. >> >> It might just be me worrying too much, so... If nobody else complains about >> this, I can live with >it as is. Assuming that none of the public functions have this special >requirement (either directly >or indirectly, by calling functions with the special requirement). >> >I would tend to agree with you Morten. If the lcore_id parameter to the >function must be >rte_lcore_id(), then I think it's error prone to have that as an explicit >parameter, and that the >function should always get the core id itself. > >Other possi
Re: [PATCH 0/2] lib/reorder: fix drain/free issues
Hi Reshma, On Sat, Jan 7, 2023 at 4:20 PM Volodymyr Fialko wrote: > > This patch address issues with reorder drain/free, > discovered with enabled `RTE_LIBRTE_MEMPOOL_DEBUG`. > > Volodymyr Fialko (2): > reorder: invalidate buf from ready queue in drain > test/reorder: fix double free of drained buffers > > app/test/test_reorder.c | 2 ++ > lib/reorder/rte_reorder.c | 1 + > 2 files changed, 3 insertions(+) Please review, thanks. -- David Marchand
Re: [PATCH 0/3] reorder: introduce new APIs
On Fri, Jan 20, 2023 at 11:22 AM Volodymyr Fialko wrote: > > This patch series provides new APIs for reorder library and test cases for > them. > > Volodymyr Fialko (3): > reorder: add new drain up to seq number API > reorder: add ability to set min sequence number > test/reorder: add cases to cover new API > > app/test/test_reorder.c | 160 ++ > lib/reorder/rte_reorder.c | 108 + > lib/reorder/rte_reorder.h | 43 ++ > lib/reorder/version.map | 2 + > 4 files changed, 313 insertions(+) > Volodymyr, don't forget to Cc: the maintainer. Reshma, can you review this series? Thanks. -- David Marchand
Re: [PATCH 2/2] test/reorder: fix double free of drained buffers
On Sat, Jan 7, 2023 at 4:20 PM Volodymyr Fialko wrote: > > Set to zero array of drained buffers after free, to prevent freeing them > one more time. > Discovered with enabled `RTE_LIBRTE_MEMPOOL_DEBUG`. Good catch, having those debug options enabled in the CI could be interesting. Cc: CI people, for info. -- David Marchand
[PATCH 1/5] net/mlx5/hws: fix alias_rtc_0 print location in debug dump
Fix alias_rtc_0 print location in debug dump, move it to the end of matcher dumped info instead of the middle, to keep the dump compatibility. Fixes: dd2845361a58 ("net/mlx5/hws: add debug details for cross gvmi") Signed-off-by: Hamdan Igbaria --- drivers/net/mlx5/hws/mlx5dr_debug.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 0815327b18..4bbdb767ee 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -208,13 +208,11 @@ static int mlx5dr_debug_dump_matcher(FILE *f, struct mlx5dr_matcher *matcher) ste_1 = NULL; } - ret = fprintf(f, ",%d,%d,%d,%d,%d", + ret = fprintf(f, ",%d,%d,%d,%d", matcher->match_ste.rtc_0 ? matcher->match_ste.rtc_0->id : 0, ste_0 ? (int)ste_0->id : -1, matcher->match_ste.rtc_1 ? matcher->match_ste.rtc_1->id : 0, - ste_1 ? (int)ste_1->id : -1, - is_shared && !is_root ? - matcher->match_ste.aliased_rtc_0->id : 0); + ste_1 ? (int)ste_1->id : -1); if (ret < 0) goto out_err; @@ -229,11 +227,13 @@ static int mlx5dr_debug_dump_matcher(FILE *f, struct mlx5dr_matcher *matcher) ste_1 = NULL; } - ret = fprintf(f, ",%d,%d,%d,%d\n", + ret = fprintf(f, ",%d,%d,%d,%d,%d\n", matcher->action_ste.rtc_0 ? matcher->action_ste.rtc_0->id : 0, ste_0 ? (int)ste_0->id : -1, matcher->action_ste.rtc_1 ? matcher->action_ste.rtc_1->id : 0, - ste_1 ? (int)ste_1->id : -1); + ste_1 ? (int)ste_1->id : -1, + is_shared && !is_root ? + matcher->match_ste.aliased_rtc_0->id : 0); if (ret < 0) goto out_err; -- 2.31.1
[PATCH 2/5] net/mlx5/hws: change STC array size to 32K
Change STC array size from 16K to 32K. This change allows supporting more actions using HWS. Signed-off-by: Hamdan Igbaria --- drivers/net/mlx5/hws/mlx5dr_pool.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/net/mlx5/hws/mlx5dr_pool.h b/drivers/net/mlx5/hws/mlx5dr_pool.h index cd12c3ab9a..4edc4b8c79 100644 --- a/drivers/net/mlx5/hws/mlx5dr_pool.h +++ b/drivers/net/mlx5/hws/mlx5dr_pool.h @@ -10,7 +10,7 @@ enum mlx5dr_pool_type { MLX5DR_POOL_TYPE_STC, }; -#define MLX5DR_POOL_STC_LOG_SZ 14 +#define MLX5DR_POOL_STC_LOG_SZ 15 #define MLX5DR_POOL_RESOURCE_ARR_SZ 100 -- 2.31.1
[PATCH 3/5] net/mlx5/hws: support STC info dump
Dump the STC info in debug dump. Signed-off-by: Hamdan Igbaria --- drivers/net/mlx5/hws/mlx5dr_debug.c | 55 + drivers/net/mlx5/hws/mlx5dr_debug.h | 1 + 2 files changed, 56 insertions(+) diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.c b/drivers/net/mlx5/hws/mlx5dr_debug.c index 4bbdb767ee..6a2644693b 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.c +++ b/drivers/net/mlx5/hws/mlx5dr_debug.c @@ -435,6 +435,57 @@ static int mlx5dr_debug_dump_context_info(FILE *f, struct mlx5dr_context *ctx) return 0; } +static int +mlx5dr_debug_dump_context_stc_resource(FILE *f, + struct mlx5dr_context *ctx, + uint32_t tbl_type, + struct mlx5dr_pool_resource *resource) +{ + int ret; + + ret = fprintf(f, "%d,0x%" PRIx64 ",%u,%u\n", + MLX5DR_DEBUG_RES_TYPE_CONTEXT_STC, + (uint64_t)(uintptr_t)ctx, + tbl_type, + resource->base_id); + if (ret < 0) { + rte_errno = EINVAL; + return rte_errno; + } + + return 0; +} + +static int mlx5dr_debug_dump_context_stc(FILE *f, struct mlx5dr_context *ctx) +{ + struct mlx5dr_pool *stc_pool; + int ret; + int i; + + for (i = 0; i < MLX5DR_TABLE_TYPE_MAX; i++) { + stc_pool = ctx->stc_pool[i]; + + if (!stc_pool) + continue; + + if (stc_pool->resource[0] != NULL) { + ret = mlx5dr_debug_dump_context_stc_resource(f, ctx, i, + stc_pool->resource[0]); + if (ret) + return ret; + } + + if (i == MLX5DR_TABLE_TYPE_FDB && stc_pool->mirror_resource[0] != NULL) { + ret = mlx5dr_debug_dump_context_stc_resource(f, ctx, i, + stc_pool->mirror_resource[0]); + if (ret) + return ret; + } + } + + return 0; +} + static int mlx5dr_debug_dump_context(FILE *f, struct mlx5dr_context *ctx) { struct mlx5dr_table *tbl; @@ -448,6 +499,10 @@ static int mlx5dr_debug_dump_context(FILE *f, struct mlx5dr_context *ctx) if (ret) return ret; + ret = mlx5dr_debug_dump_context_stc(f, ctx); + if (ret) + return ret; + LIST_FOREACH(tbl, &ctx->head, next) { ret = mlx5dr_debug_dump_table(f, tbl); if (ret) diff --git a/drivers/net/mlx5/hws/mlx5dr_debug.h b/drivers/net/mlx5/hws/mlx5dr_debug.h index cf00170f7d..4702ed0ea5 100644 --- a/drivers/net/mlx5/hws/mlx5dr_debug.h +++ b/drivers/net/mlx5/hws/mlx5dr_debug.h @@ -13,6 +13,7 @@ enum mlx5dr_debug_res_type { MLX5DR_DEBUG_RES_TYPE_CONTEXT_CAPS = 4002, MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_ENGINE = 4003, MLX5DR_DEBUG_RES_TYPE_CONTEXT_SEND_RING = 4004, + MLX5DR_DEBUG_RES_TYPE_CONTEXT_STC = 4005, MLX5DR_DEBUG_RES_TYPE_TABLE = 4100, -- 2.31.1
[PATCH 5/5] net/mlx5: support HW steering debug dump
Add the ability for the DPDK apps to call HW steering relevant debug data dump function. Signed-off-by: Hamdan Igbaria --- drivers/net/mlx5/mlx5_flow.c | 19 +-- 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/net/mlx5/mlx5_flow.c b/drivers/net/mlx5/mlx5_flow.c index f5e2831480..8e3da63299 100644 --- a/drivers/net/mlx5/mlx5_flow.c +++ b/drivers/net/mlx5/mlx5_flow.c @@ -9857,10 +9857,13 @@ mlx5_flow_dev_dump(struct rte_eth_dev *dev, struct rte_flow *flow_idx, #ifdef HAVE_IBV_FLOW_DV_SUPPORT if (mlx5_flow_dev_dump_sh_all(dev, file, error)) return -EINVAL; + + if (sh->config.dv_flow_en == 2) + return mlx5dr_debug_dump(priv->dr_ctx, file); #endif return mlx5_devx_cmd_flow_dump(sh->fdb_domain, - sh->rx_domain, - sh->tx_domain, file); + sh->rx_domain, + sh->tx_domain, file); } /* dump one */ flow = mlx5_ipool_get(priv->flows[MLX5_FLOW_TYPE_GEN], @@ -9878,10 +9881,14 @@ mlx5_flow_dev_dump(struct rte_eth_dev *dev, struct rte_flow *flow_idx, if (!dh) return -ENOENT; if (dh->drv_flow) { - ret = mlx5_devx_cmd_flow_single_dump(dh->drv_flow, - file); - if (ret) - return -ENOENT; + if (sh->config.dv_flow_en == 2) { + return -ENOTSUP; + } else { + ret = mlx5_devx_cmd_flow_single_dump(dh->drv_flow, +file); + if (ret) + return -ENOENT; + } } handle_idx = dh->next.next; } -- 2.31.1
[PATCH 4/5] net/mlx5/hws: support IP version matching for non relaxed
Enable matching on IP version explicitly for non relaxed mode. This will add support for the user cases where he needs to match on ip version explicitly, for such case to have outer ipv6 and inner ipv4 packets, etc. Signed-off-by: Hamdan Igbaria --- drivers/net/mlx5/hws/mlx5dr_definer.c | 16 1 file changed, 16 insertions(+) diff --git a/drivers/net/mlx5/hws/mlx5dr_definer.c b/drivers/net/mlx5/hws/mlx5dr_definer.c index 6b98eb8c96..79f4f2667f 100644 --- a/drivers/net/mlx5/hws/mlx5dr_definer.c +++ b/drivers/net/mlx5/hws/mlx5dr_definer.c @@ -539,6 +539,14 @@ mlx5dr_definer_conv_item_ipv4(struct mlx5dr_definer_conv_data *cd, return rte_errno; } + if (m->version) { + fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_ipv4_version_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + DR_CALC_SET(fc, eth_l2, l3_type, inner); + } + if (m->fragment_offset) { fc = &cd->fc[DR_CALC_FNAME(IP_FRAG, inner)]; fc->item_idx = item_idx; @@ -628,6 +636,14 @@ mlx5dr_definer_conv_item_ipv6(struct mlx5dr_definer_conv_data *cd, DR_CALC_SET(fc, eth_l4, ip_fragmented, inner); } + if (DR_GET(header_ipv6_vtc, &m->hdr.vtc_flow, version)) { + fc = &cd->fc[DR_CALC_FNAME(IP_VERSION, inner)]; + fc->item_idx = item_idx; + fc->tag_set = &mlx5dr_definer_ipv6_version_set; + fc->tag_mask_set = &mlx5dr_definer_ones_set; + DR_CALC_SET(fc, eth_l2, l3_type, inner); + } + if (DR_GET(header_ipv6_vtc, &m->hdr.vtc_flow, tos)) { fc = &cd->fc[DR_CALC_FNAME(IP_TOS, inner)]; fc->item_idx = item_idx; -- 2.31.1
[PATCH v5 0/8] start cleanup of rte_flow_item_*
There was a plan to have structures from lib/net/ at the beginning of corresponding flow item structures. Unfortunately this plan has not been followed up so far. This series is a step to make the most used items, compliant with the inheritance design explained above. The old API is kept in anonymous union for compatibility, but the code in drivers and apps is updated to use the new API. v5: * Fix more RHEL7 build error v4: * Fix build error for RHEL7 (gcc 4.8.5) caused by nested struct initialization. v3: * Updated Higig2 protocol flow item assignment taking into account endianness annotations. v2: (by Ferruh) * Rebased on latest next-net for v23.03 * 'struct rte_gre_hdr' endianness annotation added to protocol field * more driver code updated for rte_flow_item_eth & rte_flow_item_vlan * 'struct rte_gre_hdr' updated to have a combined "rte_be16_t c_rsvd0_ver" field and updated drivers accordingly * more driver code updated for rte_flow_item_gre * more driver code updated for rte_flow_item_gtp Cc: David Marchand Thomas Monjalon (8): ethdev: use Ethernet protocol struct for flow matching net: add smaller fields for VXLAN ethdev: use VXLAN protocol struct for flow matching ethdev: use GRE protocol struct for flow matching ethdev: use GTP protocol struct for flow matching ethdev: use ARP protocol struct for flow matching doc: fix description of L2TPV2 flow item net: mark all big endian types app/test-flow-perf/actions_gen.c | 2 +- app/test-flow-perf/items_gen.c | 24 +-- app/test-pmd/cmdline_flow.c | 180 +++--- doc/guides/prog_guide/rte_flow.rst | 57 ++- doc/guides/rel_notes/deprecation.rst | 6 +- drivers/net/bnxt/bnxt_flow.c | 54 +++ drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 112 +++--- drivers/net/bonding/rte_eth_bond_pmd.c | 12 +- drivers/net/cxgbe/cxgbe_flow.c | 44 +++--- drivers/net/dpaa2/dpaa2_flow.c | 60 drivers/net/dpaa2/dpaa2_mux.c| 2 +- drivers/net/e1000/igb_flow.c | 14 +- drivers/net/enic/enic_flow.c | 24 +-- drivers/net/enic/enic_fm_flow.c | 16 +- drivers/net/hinic/hinic_pmd_flow.c | 14 +- drivers/net/hns3/hns3_flow.c | 40 ++--- drivers/net/i40e/i40e_fdir.c | 14 +- drivers/net/i40e/i40e_flow.c | 124 +++ drivers/net/i40e/i40e_hash.c | 4 +- drivers/net/iavf/iavf_fdir.c | 18 +-- drivers/net/iavf/iavf_fsub.c | 10 +- drivers/net/iavf/iavf_ipsec_crypto.c | 4 +- drivers/net/ice/ice_acl_filter.c | 20 +-- drivers/net/ice/ice_fdir_filter.c| 24 +-- drivers/net/ice/ice_switch_filter.c | 64 drivers/net/igc/igc_flow.c | 8 +- drivers/net/ipn3ke/ipn3ke_flow.c | 12 +- drivers/net/ixgbe/ixgbe_flow.c | 58 +++ drivers/net/mlx4/mlx4_flow.c | 38 ++--- drivers/net/mlx5/hws/mlx5dr_definer.c| 48 +++--- drivers/net/mlx5/mlx5_flow.c | 62 drivers/net/mlx5/mlx5_flow_dv.c | 184 --- drivers/net/mlx5/mlx5_flow_hw.c | 80 +- drivers/net/mlx5/mlx5_flow_verbs.c | 48 +++--- drivers/net/mlx5/mlx5_trigger.c | 28 ++-- drivers/net/mvpp2/mrvl_flow.c| 28 ++-- drivers/net/nfp/nfp_flow.c | 21 +-- drivers/net/sfc/sfc_flow.c | 52 +++ drivers/net/sfc/sfc_mae.c| 46 +++--- drivers/net/tap/tap_flow.c | 58 +++ drivers/net/txgbe/txgbe_flow.c | 28 ++-- lib/ethdev/rte_flow.h| 121 ++- lib/net/rte_arp.h| 28 ++-- lib/net/rte_gre.h| 7 +- lib/net/rte_higig.h | 6 +- lib/net/rte_mpls.h | 2 +- lib/net/rte_vxlan.h | 35 - 47 files changed, 988 insertions(+), 953 deletions(-) -- 2.25.1
[PATCH v5 2/8] net: add smaller fields for VXLAN
From: Thomas Monjalon The VXLAN and VXLAN-GPE headers were including reserved fields with other fields in big uint32_t struct members. Some more precise definitions are added as union of the old ones. The new struct members are smaller in size and in names. Signed-off-by: Thomas Monjalon --- lib/net/rte_vxlan.h | 35 +-- 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/lib/net/rte_vxlan.h b/lib/net/rte_vxlan.h index 929fa7a1dd01..997fc784fc84 100644 --- a/lib/net/rte_vxlan.h +++ b/lib/net/rte_vxlan.h @@ -30,9 +30,20 @@ extern "C" { * Contains the 8-bit flag, 24-bit VXLAN Network Identifier and * Reserved fields (24 bits and 8 bits) */ +__extension__ /* no named member in struct */ struct rte_vxlan_hdr { - rte_be32_t vx_flags; /**< flag (8) + Reserved (24). */ - rte_be32_t vx_vni; /**< VNI (24) + Reserved (8). */ + union { + struct { + rte_be32_t vx_flags; /**< flags (8) + Reserved (24). */ + rte_be32_t vx_vni; /**< VNI (24) + Reserved (8). */ + }; + struct { + uint8_tflags;/**< Should be 8 (I flag). */ + uint8_trsvd0[3]; /**< Reserved. */ + uint8_tvni[3]; /**< VXLAN identifier. */ + uint8_trsvd1;/**< Reserved. */ + }; + }; } __rte_packed; /** VXLAN tunnel header length. */ @@ -45,11 +56,23 @@ struct rte_vxlan_hdr { * Contains the 8-bit flag, 8-bit next-protocol, 24-bit VXLAN Network * Identifier and Reserved fields (16 bits and 8 bits). */ +__extension__ /* no named member in struct */ struct rte_vxlan_gpe_hdr { - uint8_t vx_flags;/**< flag (8). */ - uint8_t reserved[2]; /**< Reserved (16). */ - uint8_t proto; /**< next-protocol (8). */ - rte_be32_t vx_vni; /**< VNI (24) + Reserved (8). */ + union { + struct { + uint8_t vx_flags;/**< flag (8). */ + uint8_t reserved[2]; /**< Reserved (16). */ + uint8_t protocol;/**< next-protocol (8). */ + rte_be32_t vx_vni; /**< VNI (24) + Reserved (8). */ + }; + struct { + uint8_t flags;/**< Flags. */ + uint8_t rsvd0[2]; /**< Reserved. */ + uint8_t proto;/**< Next protocol. */ + uint8_t vni[3]; /**< VXLAN identifier. */ + uint8_t rsvd1;/**< Reserved. */ + }; + }; } __rte_packed; /** VXLAN-GPE tunnel header length. */ -- 2.25.1
[PATCH v5 1/8] ethdev: use Ethernet protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. The Ethernet headers (including VLAN) structures are used instead of the redundant fields in the flow items. The remaining protocols to clean up are listed for future work in the deprecation list. Some protocols are not even defined in the directory net yet. Signed-off-by: Thomas Monjalon --- app/test-flow-perf/items_gen.c | 4 +- app/test-pmd/cmdline_flow.c | 140 +++ doc/guides/prog_guide/rte_flow.rst | 7 +- doc/guides/rel_notes/deprecation.rst | 2 + drivers/net/bnxt/bnxt_flow.c | 42 +++ drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 58 +- drivers/net/bonding/rte_eth_bond_pmd.c | 12 +- drivers/net/cxgbe/cxgbe_flow.c | 44 +++ drivers/net/dpaa2/dpaa2_flow.c | 48 drivers/net/dpaa2/dpaa2_mux.c| 2 +- drivers/net/e1000/igb_flow.c | 14 +-- drivers/net/enic/enic_flow.c | 24 ++-- drivers/net/enic/enic_fm_flow.c | 16 +-- drivers/net/hinic/hinic_pmd_flow.c | 14 +-- drivers/net/hns3/hns3_flow.c | 28 ++--- drivers/net/i40e/i40e_flow.c | 100 drivers/net/i40e/i40e_hash.c | 4 +- drivers/net/iavf/iavf_fdir.c | 10 +- drivers/net/iavf/iavf_fsub.c | 10 +- drivers/net/iavf/iavf_ipsec_crypto.c | 4 +- drivers/net/ice/ice_acl_filter.c | 20 ++-- drivers/net/ice/ice_fdir_filter.c| 14 +-- drivers/net/ice/ice_switch_filter.c | 34 +++--- drivers/net/igc/igc_flow.c | 8 +- drivers/net/ipn3ke/ipn3ke_flow.c | 8 +- drivers/net/ixgbe/ixgbe_flow.c | 40 +++ drivers/net/mlx4/mlx4_flow.c | 38 +++--- drivers/net/mlx5/hws/mlx5dr_definer.c| 26 ++--- drivers/net/mlx5/mlx5_flow.c | 24 ++-- drivers/net/mlx5/mlx5_flow_dv.c | 94 +++ drivers/net/mlx5/mlx5_flow_hw.c | 80 ++--- drivers/net/mlx5/mlx5_flow_verbs.c | 30 ++--- drivers/net/mlx5/mlx5_trigger.c | 28 ++--- drivers/net/mvpp2/mrvl_flow.c| 28 ++--- drivers/net/nfp/nfp_flow.c | 12 +- drivers/net/sfc/sfc_flow.c | 46 drivers/net/sfc/sfc_mae.c| 38 +++--- drivers/net/tap/tap_flow.c | 58 +- drivers/net/txgbe/txgbe_flow.c | 28 ++--- 39 files changed, 618 insertions(+), 619 deletions(-) diff --git a/app/test-flow-perf/items_gen.c b/app/test-flow-perf/items_gen.c index a73de9031f54..b7f51030a119 100644 --- a/app/test-flow-perf/items_gen.c +++ b/app/test-flow-perf/items_gen.c @@ -37,10 +37,10 @@ add_vlan(struct rte_flow_item *items, __rte_unused struct additional_para para) { static struct rte_flow_item_vlan vlan_spec = { - .tci = RTE_BE16(VLAN_VALUE), + .hdr.vlan_tci = RTE_BE16(VLAN_VALUE), }; static struct rte_flow_item_vlan vlan_mask = { - .tci = RTE_BE16(0x), + .hdr.vlan_tci = RTE_BE16(0x), }; items[items_counter].type = RTE_FLOW_ITEM_TYPE_VLAN; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 88108498e0c3..694a7eb647c5 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -3633,19 +3633,19 @@ static const struct token token_list[] = { .name = "dst", .help = "destination MAC", .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, dst)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.dst_addr)), }, [ITEM_ETH_SRC] = { .name = "src", .help = "source MAC", .next = NEXT(item_eth, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, src)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.src_addr)), }, [ITEM_ETH_TYPE] = { .name = "type", .help = "EtherType", .next = NEXT(item_eth, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, type)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_eth, hdr.ether_type)), }, [ITEM_ETH_HAS_VLAN] = { .name = "has_vlan", @@ -3666,7 +3666,7 @@ static const struct token token_list[] = { .help = "tag control information", .next = NEXT(item_vlan, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vlan, tci)), +
[PATCH v5 3/8] ethdev: use VXLAN protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. In the case of VXLAN-GPE, the protocol struct is added in an unnamed union, keeping old field names. The VXLAN headers (including VXLAN-GPE) are used in apps and drivers instead of the redundant fields in the flow items. Signed-off-by: Thomas Monjalon --- app/test-flow-perf/actions_gen.c | 2 +- app/test-flow-perf/items_gen.c | 12 +++ app/test-pmd/cmdline_flow.c | 10 +++--- doc/guides/prog_guide/rte_flow.rst | 11 ++- doc/guides/rel_notes/deprecation.rst | 1 - drivers/net/bnxt/bnxt_flow.c | 12 --- drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 42 drivers/net/hns3/hns3_flow.c | 12 +++ drivers/net/i40e/i40e_flow.c | 4 +-- drivers/net/ice/ice_switch_filter.c | 18 +- drivers/net/ipn3ke/ipn3ke_flow.c | 4 +-- drivers/net/ixgbe/ixgbe_flow.c | 18 +- drivers/net/mlx5/mlx5_flow.c | 16 - drivers/net/mlx5/mlx5_flow_dv.c | 40 +++--- drivers/net/mlx5/mlx5_flow_verbs.c | 8 ++--- drivers/net/sfc/sfc_flow.c | 6 ++-- drivers/net/sfc/sfc_mae.c| 8 ++--- lib/ethdev/rte_flow.h| 24 ++ 18 files changed, 126 insertions(+), 122 deletions(-) diff --git a/app/test-flow-perf/actions_gen.c b/app/test-flow-perf/actions_gen.c index 63f05d87fa86..f1d59313256d 100644 --- a/app/test-flow-perf/actions_gen.c +++ b/app/test-flow-perf/actions_gen.c @@ -874,7 +874,7 @@ add_vxlan_encap(struct rte_flow_action *actions, items[2].type = RTE_FLOW_ITEM_TYPE_UDP; - item_vxlan.vni[2] = 1; + item_vxlan.hdr.vni[2] = 1; items[3].spec = &item_vxlan; items[3].mask = &item_vxlan; items[3].type = RTE_FLOW_ITEM_TYPE_VXLAN; diff --git a/app/test-flow-perf/items_gen.c b/app/test-flow-perf/items_gen.c index b7f51030a119..a58245239ba1 100644 --- a/app/test-flow-perf/items_gen.c +++ b/app/test-flow-perf/items_gen.c @@ -128,12 +128,12 @@ add_vxlan(struct rte_flow_item *items, /* Set standard vxlan vni */ for (i = 0; i < 3; i++) { - vxlan_specs[ti].vni[2 - i] = vni_value >> (i * 8); - vxlan_masks[ti].vni[2 - i] = 0xff; + vxlan_specs[ti].hdr.vni[2 - i] = vni_value >> (i * 8); + vxlan_masks[ti].hdr.vni[2 - i] = 0xff; } /* Standard vxlan flags */ - vxlan_specs[ti].flags = 0x8; + vxlan_specs[ti].hdr.flags = 0x8; items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN; items[items_counter].spec = &vxlan_specs[ti]; @@ -155,12 +155,12 @@ add_vxlan_gpe(struct rte_flow_item *items, /* Set vxlan-gpe vni */ for (i = 0; i < 3; i++) { - vxlan_gpe_specs[ti].vni[2 - i] = vni_value >> (i * 8); - vxlan_gpe_masks[ti].vni[2 - i] = 0xff; + vxlan_gpe_specs[ti].hdr.vni[2 - i] = vni_value >> (i * 8); + vxlan_gpe_masks[ti].hdr.vni[2 - i] = 0xff; } /* vxlan-gpe flags */ - vxlan_gpe_specs[ti].flags = 0x0c; + vxlan_gpe_specs[ti].hdr.flags = 0x0c; items[items_counter].type = RTE_FLOW_ITEM_TYPE_VXLAN_GPE; items[items_counter].spec = &vxlan_gpe_specs[ti]; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 694a7eb647c5..b904f8c3d45c 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -3984,7 +3984,7 @@ static const struct token token_list[] = { .help = "VXLAN identifier", .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, vni)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, hdr.vni)), }, [ITEM_VXLAN_LAST_RSVD] = { .name = "last_rsvd", @@ -3992,7 +3992,7 @@ static const struct token token_list[] = { .next = NEXT(item_vxlan, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan, -rsvd1)), +hdr.rsvd1)), }, [ITEM_E_TAG] = { .name = "e_tag", @@ -4210,7 +4210,7 @@ static const struct token token_list[] = { .next = NEXT(item_vxlan_gpe, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_vxlan_gpe, -vni)), +hdr.vni)), }, [ITEM_ARP_ETH_IPV4] = { .name = "arp_eth_ipv4", @@ -7500,7 +75
[PATCH v5 4/8] ethdev: use GRE protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. The protocol struct is added in an unnamed union, keeping old field names. The GRE header struct members are used in apps and drivers instead of the redundant fields in the flow items. Signed-off-by: Thomas Monjalon --- app/test-flow-perf/items_gen.c | 4 ++-- app/test-pmd/cmdline_flow.c | 14 +-- doc/guides/prog_guide/rte_flow.rst | 6 + doc/guides/rel_notes/deprecation.rst | 1 - drivers/net/bnxt/tf_ulp/ulp_rte_parser.c | 12 +- drivers/net/dpaa2/dpaa2_flow.c | 12 +- drivers/net/mlx5/hws/mlx5dr_definer.c| 8 +++ drivers/net/mlx5/mlx5_flow.c | 22 - drivers/net/mlx5/mlx5_flow_dv.c | 30 +--- drivers/net/mlx5/mlx5_flow_verbs.c | 10 drivers/net/nfp/nfp_flow.c | 9 +++ lib/ethdev/rte_flow.h| 24 +-- lib/net/rte_gre.h| 5 13 files changed, 84 insertions(+), 73 deletions(-) diff --git a/app/test-flow-perf/items_gen.c b/app/test-flow-perf/items_gen.c index a58245239ba1..0f19e5e53648 100644 --- a/app/test-flow-perf/items_gen.c +++ b/app/test-flow-perf/items_gen.c @@ -173,10 +173,10 @@ add_gre(struct rte_flow_item *items, __rte_unused struct additional_para para) { static struct rte_flow_item_gre gre_spec = { - .protocol = RTE_BE16(RTE_ETHER_TYPE_TEB), + .hdr.proto = RTE_BE16(RTE_ETHER_TYPE_TEB), }; static struct rte_flow_item_gre gre_mask = { - .protocol = RTE_BE16(0x), + .hdr.proto = RTE_BE16(0x), }; items[items_counter].type = RTE_FLOW_ITEM_TYPE_GRE; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index b904f8c3d45c..0e115956514c 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -4071,7 +4071,7 @@ static const struct token token_list[] = { .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, -protocol)), +hdr.proto)), }, [ITEM_GRE_C_RSVD0_VER] = { .name = "c_rsvd0_ver", @@ -4082,7 +4082,7 @@ static const struct token token_list[] = { .next = NEXT(item_gre, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gre, -c_rsvd0_ver)), +hdr.c_rsvd0_ver)), }, [ITEM_GRE_C_BIT] = { .name = "c_bit", @@ -4090,7 +4090,7 @@ static const struct token token_list[] = { .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, - c_rsvd0_ver, + hdr.c_rsvd0_ver, "\x80\x00\x00\x00")), }, [ITEM_GRE_S_BIT] = { @@ -4098,7 +4098,7 @@ static const struct token token_list[] = { .help = "sequence number bit (S)", .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, - c_rsvd0_ver, + hdr.c_rsvd0_ver, "\x10\x00\x00\x00")), }, [ITEM_GRE_K_BIT] = { @@ -4106,7 +4106,7 @@ static const struct token token_list[] = { .help = "key bit (K)", .next = NEXT(item_gre, NEXT_ENTRY(COMMON_BOOLEAN), item_param), .args = ARGS(ARGS_ENTRY_MASK_HTON(struct rte_flow_item_gre, - c_rsvd0_ver, + hdr.c_rsvd0_ver, "\x20\x00\x00\x00")), }, [ITEM_FUZZY] = { @@ -7837,7 +7837,7 @@ parse_vc_action_mplsogre_encap(struct context *ctx, const struct token *token, }, }; struct rte_flow_item_gre gre = { - .protocol = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), + .hdr.proto = rte_cpu_to_be_16(ETHER_TYPE_MPLS_UNICAST), }; struct rte_flow_item_mpls mpls = { .ttl = 0, @@ -7935,7 +7935,7 @@ parse_vc_action_mplsogre_decap(struct context *ctx, const struct token *token, }, };
[PATCH v5 5/8] ethdev: use GTP protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. The protocol struct is added in an unnamed union, keeping old field names. The GTP header struct members are used in apps and drivers instead of the redundant fields in the flow items. Signed-off-by: Thomas Monjalon --- app/test-flow-perf/items_gen.c| 4 ++-- app/test-pmd/cmdline_flow.c | 8 +++ doc/guides/prog_guide/rte_flow.rst| 10 ++--- doc/guides/rel_notes/deprecation.rst | 1 - drivers/net/i40e/i40e_fdir.c | 14 ++-- drivers/net/i40e/i40e_flow.c | 20 - drivers/net/iavf/iavf_fdir.c | 8 +++ drivers/net/ice/ice_fdir_filter.c | 10 - drivers/net/ice/ice_switch_filter.c | 12 +- drivers/net/mlx5/hws/mlx5dr_definer.c | 14 ++-- drivers/net/mlx5/mlx5_flow_dv.c | 20 - lib/ethdev/rte_flow.h | 32 ++- 12 files changed, 78 insertions(+), 75 deletions(-) diff --git a/app/test-flow-perf/items_gen.c b/app/test-flow-perf/items_gen.c index 0f19e5e53648..55eb6f5cf009 100644 --- a/app/test-flow-perf/items_gen.c +++ b/app/test-flow-perf/items_gen.c @@ -213,10 +213,10 @@ add_gtp(struct rte_flow_item *items, __rte_unused struct additional_para para) { static struct rte_flow_item_gtp gtp_spec = { - .teid = RTE_BE32(TEID_VALUE), + .hdr.teid = RTE_BE32(TEID_VALUE), }; static struct rte_flow_item_gtp gtp_mask = { - .teid = RTE_BE32(0x), + .hdr.teid = RTE_BE32(0x), }; items[items_counter].type = RTE_FLOW_ITEM_TYPE_GTP; diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index 0e115956514c..dd6da9d98d9b 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -4137,19 +4137,19 @@ static const struct token token_list[] = { .help = "GTP flags", .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, - v_pt_rsv_flags)), + hdr.gtp_hdr_info)), }, [ITEM_GTP_MSG_TYPE] = { .name = "msg_type", .help = "GTP message type", .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, msg_type)), + .args = ARGS(ARGS_ENTRY(struct rte_flow_item_gtp, hdr.msg_type)), }, [ITEM_GTP_TEID] = { .name = "teid", .help = "tunnel endpoint identifier", .next = NEXT(item_gtp, NEXT_ENTRY(COMMON_UNSIGNED), item_param), - .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, teid)), + .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_gtp, hdr.teid)), }, [ITEM_GTPC] = { .name = "gtpc", @@ -11224,7 +11224,7 @@ cmd_set_raw_parsed(const struct buffer *in) goto error; } gtp = item->spec; - if ((gtp->v_pt_rsv_flags & 0x07) != 0x04) { + if (gtp->hdr.s == 1 || gtp->hdr.pn == 1) { /* Only E flag should be set. */ fprintf(stderr, "Error - GTP unsupported flags\n"); diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 603e1b866be3..ec2e335fac3d 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1064,12 +1064,7 @@ Note: GTP, GTPC and GTPU use the same structure. GTPC and GTPU item are defined for a user-friendly API when creating GTP-C and GTP-U flow rules. -- ``v_pt_rsv_flags``: version (3b), protocol type (1b), reserved (1b), - extension header flag (1b), sequence number flag (1b), N-PDU number - flag (1b). -- ``msg_type``: message type. -- ``msg_len``: message length. -- ``teid``: tunnel endpoint identifier. +- ``hdr``: header definition (``rte_gtp.h``). - Default ``mask`` matches teid only. Item: ``ESP`` @@ -1235,8 +1230,7 @@ Item: ``GTP_PSC`` Matches a GTP PDU extension header with type 0x85. -- ``pdu_type``: PDU type. -- ``qfi``: QoS flow identifier. +- ``hdr``: header definition (``rte_gtp.h``). - Default ``mask`` matches QFI only. Item: ``PPPOES``, ``PPPOED`` diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index 80bf7209065a..b89450b239ef 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -68,7 +68,6 @@ Deprecation Notices - ``rte_flow_item_e_tag`` - ``rte_flow_item_geneve`` - ``rte_flow_i
[PATCH v5 6/8] ethdev: use ARP protocol struct for flow matching
From: Thomas Monjalon As announced in the deprecation notice, flow item structures should re-use the protocol header definitions from the directory lib/net/. The protocol struct is added in an unnamed union, keeping old field names. The ARP header struct members are used in testpmd instead of the redundant fields in the flow items. Signed-off-by: Thomas Monjalon --- app/test-pmd/cmdline_flow.c | 8 +++--- doc/guides/prog_guide/rte_flow.rst | 10 +--- doc/guides/rel_notes/deprecation.rst | 1 - lib/ethdev/rte_flow.h| 37 ++-- 4 files changed, 29 insertions(+), 27 deletions(-) diff --git a/app/test-pmd/cmdline_flow.c b/app/test-pmd/cmdline_flow.c index dd6da9d98d9b..1d337a96199d 100644 --- a/app/test-pmd/cmdline_flow.c +++ b/app/test-pmd/cmdline_flow.c @@ -4226,7 +4226,7 @@ static const struct token token_list[] = { .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, -sha)), +hdr.arp_data.arp_sha)), }, [ITEM_ARP_ETH_IPV4_SPA] = { .name = "spa", @@ -4234,7 +4234,7 @@ static const struct token token_list[] = { .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, -spa)), +hdr.arp_data.arp_sip)), }, [ITEM_ARP_ETH_IPV4_THA] = { .name = "tha", @@ -4242,7 +4242,7 @@ static const struct token token_list[] = { .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_MAC_ADDR), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, -tha)), +hdr.arp_data.arp_tha)), }, [ITEM_ARP_ETH_IPV4_TPA] = { .name = "tpa", @@ -4250,7 +4250,7 @@ static const struct token token_list[] = { .next = NEXT(item_arp_eth_ipv4, NEXT_ENTRY(COMMON_IPV4_ADDR), item_param), .args = ARGS(ARGS_ENTRY_HTON(struct rte_flow_item_arp_eth_ipv4, -tpa)), +hdr.arp_data.arp_tip)), }, [ITEM_IPV6_EXT] = { .name = "ipv6_ext", diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index ec2e335fac3d..8bf85df2f611 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1100,15 +1100,7 @@ Item: ``ARP_ETH_IPV4`` Matches an ARP header for Ethernet/IPv4. -- ``hdr``: hardware type, normally 1. -- ``pro``: protocol type, normally 0x0800. -- ``hln``: hardware address length, normally 6. -- ``pln``: protocol address length, normally 4. -- ``op``: opcode (1 for request, 2 for reply). -- ``sha``: sender hardware address. -- ``spa``: sender IPv4 address. -- ``tha``: target hardware address. -- ``tpa``: target IPv4 address. +- ``hdr``: header definition (``rte_arp.h``). - Default ``mask`` matches SHA, SPA, THA and TPA. Item: ``IPV6_EXT`` diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst index b89450b239ef..8e3683990117 100644 --- a/doc/guides/rel_notes/deprecation.rst +++ b/doc/guides/rel_notes/deprecation.rst @@ -64,7 +64,6 @@ Deprecation Notices These items are not compliant (not including struct from lib/net/): - ``rte_flow_item_ah`` - - ``rte_flow_item_arp_eth_ipv4`` - ``rte_flow_item_e_tag`` - ``rte_flow_item_geneve`` - ``rte_flow_item_geneve_opt`` diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index 85ca73d1dc04..a215daa83640 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1255,26 +1256,36 @@ static const struct rte_flow_item_vxlan_gpe rte_flow_item_vxlan_gpe_mask = { * * Matches an ARP header for Ethernet/IPv4. */ +RTE_STD_C11 struct rte_flow_item_arp_eth_ipv4 { - rte_be16_t hrd; /**< Hardware type, normally 1. */ - rte_be16_t pro; /**< Protocol type, normally 0x0800. */ - uint8_t hln; /**< Hardware address length, normally 6. */ - uint8_t pln; /**< Protocol address length, normally 4. */ - rte_be16_t op; /**< Opcode (1 for request, 2 for reply). */ - struct rte_ether_addr sha; /**< Sender hardware address. */ - rte_be32_t spa; /**< Sender IPv4 address. */ - struct rte_ether_addr tha; /**< Target hardware address. */ - rte_be32_t tpa; /**< Target IPv4 address. */ + union { +
[PATCH v5 7/8] doc: fix description of L2TPV2 flow item
From: Thomas Monjalon The flow item structure includes the protocol definition from the directory lib/net/, so it is reflected in the guide. Section title underlining is also fixed around. Fixes: 3a929df1f286 ("ethdev: support L2TPv2 and PPP procotol") Cc: sta...@dpdk.org Signed-off-by: Thomas Monjalon --- Cc: jie1x.w...@intel.com --- doc/guides/prog_guide/rte_flow.rst | 13 +++-- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/doc/guides/prog_guide/rte_flow.rst b/doc/guides/prog_guide/rte_flow.rst index 8bf85df2f611..c01b53aad8ed 100644 --- a/doc/guides/prog_guide/rte_flow.rst +++ b/doc/guides/prog_guide/rte_flow.rst @@ -1485,22 +1485,15 @@ rte_flow_flex_item_create() routine. value and mask. Item: ``L2TPV2`` -^^^ + Matches a L2TPv2 header. -- ``flags_version``: flags(12b), version(4b). -- ``length``: total length of the message. -- ``tunnel_id``: identifier for the control connection. -- ``session_id``: identifier for a session within a tunnel. -- ``ns``: sequence number for this date or control message. -- ``nr``: sequence number expected in the next control message to be received. -- ``offset_size``: offset of payload data. -- ``offset_padding``: offset padding, variable length. +- ``hdr``: header definition (``rte_l2tpv2.h``). - Default ``mask`` matches flags_version only. Item: ``PPP`` -^^^ +^ Matches a PPP header. -- 2.25.1
[PATCH v5 8/8] net: mark all big endian types
From: Thomas Monjalon Some protocols (ARP, MPLS and HIGIG2) were using uint16_t and uint32_t types for their 16 and 32-bit fields. It was correct but not conveying the big endian nature of these fields. As for other protocols defined in this directory, all types are explicitly marked as big endian fields. Signed-off-by: Thomas Monjalon --- lib/ethdev/rte_flow.h | 4 ++-- lib/net/rte_arp.h | 28 ++-- lib/net/rte_gre.h | 2 +- lib/net/rte_higig.h | 6 +++--- lib/net/rte_mpls.h| 2 +- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/lib/ethdev/rte_flow.h b/lib/ethdev/rte_flow.h index a215daa83640..99f8340f8274 100644 --- a/lib/ethdev/rte_flow.h +++ b/lib/ethdev/rte_flow.h @@ -642,8 +642,8 @@ struct rte_flow_item_higig2_hdr { static const struct rte_flow_item_higig2_hdr rte_flow_item_higig2_hdr_mask = { .hdr = { .ppt1 = { - .classification = 0x, - .vid = 0xfff, + .classification = RTE_BE16(0x), + .vid = RTE_BE16(0xfff), }, }, }; diff --git a/lib/net/rte_arp.h b/lib/net/rte_arp.h index 076c8ab314ee..151e6c641fc5 100644 --- a/lib/net/rte_arp.h +++ b/lib/net/rte_arp.h @@ -23,28 +23,28 @@ extern "C" { */ struct rte_arp_ipv4 { struct rte_ether_addr arp_sha; /**< sender hardware address */ - uint32_t arp_sip; /**< sender IP address */ + rte_be32_tarp_sip; /**< sender IP address */ struct rte_ether_addr arp_tha; /**< target hardware address */ - uint32_t arp_tip; /**< target IP address */ + rte_be32_tarp_tip; /**< target IP address */ } __rte_packed __rte_aligned(2); /** * ARP header. */ struct rte_arp_hdr { - uint16_t arp_hardware;/* format of hardware address */ -#define RTE_ARP_HRD_ETHER 1 /* ARP Ethernet address format */ + rte_be16_t arp_hardware; /** format of hardware address */ +#define RTE_ARP_HRD_ETHER 1 /** ARP Ethernet address format */ - uint16_t arp_protocol;/* format of protocol address */ - uint8_t arp_hlen;/* length of hardware address */ - uint8_t arp_plen;/* length of protocol address */ - uint16_t arp_opcode; /* ARP opcode (command) */ -#defineRTE_ARP_OP_REQUEST1 /* request to resolve address */ -#defineRTE_ARP_OP_REPLY 2 /* response to previous request */ -#defineRTE_ARP_OP_REVREQUEST 3 /* request proto addr given hardware */ -#defineRTE_ARP_OP_REVREPLY 4 /* response giving protocol address */ -#defineRTE_ARP_OP_INVREQUEST 8 /* request to identify peer */ -#defineRTE_ARP_OP_INVREPLY 9 /* response identifying peer */ + rte_be16_t arp_protocol; /** format of protocol address */ + uint8_tarp_hlen; /** length of hardware address */ + uint8_tarp_plen; /** length of protocol address */ + rte_be16_t arp_opcode; /** ARP opcode (command) */ +#defineRTE_ARP_OP_REQUEST1 /** request to resolve address */ +#defineRTE_ARP_OP_REPLY 2 /** response to previous request */ +#defineRTE_ARP_OP_REVREQUEST 3 /** request proto addr given hardware */ +#defineRTE_ARP_OP_REVREPLY 4 /** response giving protocol address */ +#defineRTE_ARP_OP_INVREQUEST 8 /** request to identify peer */ +#defineRTE_ARP_OP_INVREPLY 9 /** response identifying peer */ struct rte_arp_ipv4 arp_data; } __rte_packed __rte_aligned(2); diff --git a/lib/net/rte_gre.h b/lib/net/rte_gre.h index 210b81c99018..6b1169c8b0c1 100644 --- a/lib/net/rte_gre.h +++ b/lib/net/rte_gre.h @@ -50,7 +50,7 @@ struct rte_gre_hdr { }; rte_be16_t c_rsvd0_ver; }; - uint16_t proto; /**< Protocol Type */ + rte_be16_t proto; /**< Protocol Type */ } __rte_packed; /** diff --git a/lib/net/rte_higig.h b/lib/net/rte_higig.h index b55fb1a7db44..bba3898a883f 100644 --- a/lib/net/rte_higig.h +++ b/lib/net/rte_higig.h @@ -112,9 +112,9 @@ struct rte_higig2_ppt_type0 { */ __extension__ struct rte_higig2_ppt_type1 { - uint16_t classification; - uint16_t resv; - uint16_t vid; + rte_be16_t classification; + rte_be16_t resv; + rte_be16_t vid; #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN uint16_t opcode:3; uint16_t resv1:2; diff --git a/lib/net/rte_mpls.h b/lib/net/rte_mpls.h index 3e8cb90ec383..51523e7a1188 100644 --- a/lib/net/rte_mpls.h +++ b/lib/net/rte_mpls.h @@ -23,7 +23,7 @@ extern "C" { */ __extension__ struct rte_mpls_hdr { - uint16_t tag_msb; /**< Label(msb). */ + rte_be16_t tag_msb; /**< Label(msb). */ #if RTE_BYTE_ORDER == RTE_BIG_ENDIAN uint8_t tag_lsb:4; /**< Label(lsb). */ uint8_t tc:3; /**< Traffic class. */ -- 2.25.1
Re: [EXT] Re: [PATCH 1/2] lib: add helper to read strings from sysfs files
On Thu, Jan 26, 2023 at 08:30:01AM +, Tomasz Duszynski wrote: > > >-Original Message- > >From: Tyler Retzlaff > >Sent: Wednesday, January 25, 2023 5:16 PM > >To: Thomas Monjalon > >Cc: Tomasz Duszynski ; dev@dpdk.org; Jerin Jacob > >Kollanukkaran > >; step...@networkplumber.org; chenbo@intel.com; > >david.march...@redhat.com; > >bruce.richard...@intel.com > >Subject: [EXT] Re: [PATCH 1/2] lib: add helper to read strings from sysfs > >files > > > >External Email > > > >-- > >On Wed, Jan 25, 2023 at 11:39:30AM +0100, Thomas Monjalon wrote: > >> 25/01/2023 11:33, Tomasz Duszynski: > >> > Reading strings from sysfs files is a re-occurring pattern hence add > >> > helper for doing that. > >> > >> In general it would be to nice to clean sysfs parsing in libs and > >> drivers, so they all use some functions from EAL. > > > >maybe there should be a general utility library for dealing with sysfs > >separate from the core EAL > >that drivers / platform specific libs can share? > > reading/writing of sysfs files is scattered around the codebase and this has > been piling up > with each and and every new pmd/lib that requires it. So generally a few > simple utility functions > in one place may be a good idea. i'm an advocate of smaller libraries that tackle a subject area and do so well. even better if they can be unit tested without dragging in a lot of dependencies or bootstrapping other unrelated subsystems. it is also in alignment with trying to de-bloat eal which i think there is increasing interest in. > > Would following make sense? > > rte_sysfs_write_int() > rte_sysfs_write_string() > rte_sysfs_read_int() > rte_sysfs_read_string() > > Also seems that pattern where file gets opened once and keeps being written > to until closed is > reoccurring as well. So there might be some utils for that as well. Thoughts? i guess the answer here is whatever makes a simple intuitive api for sysfs access, i don't contribute much on the linux side to dpdk so can't speak to what makes a good api here, but i imagine others can in review. thanks
Re: [PATCH 3/3] build: limit what is built when using MSVC compiler
On Thu, Jan 26, 2023 at 11:10:26AM +, Bruce Richardson wrote: > On Wed, Jan 25, 2023 at 11:25:07AM -0800, Tyler Retzlaff wrote: > > Build only kvargs and telemetry when is_ms_compiler. > > > > Signed-off-by: Tyler Retzlaff > > --- > > lib/meson.build | 7 +++ > > meson.build | 13 + > > 2 files changed, 16 insertions(+), 4 deletions(-) > > > > diff --git a/lib/meson.build b/lib/meson.build > > index 82e4666..8e99e21 100644 > > > --- a/meson.build > > +++ b/meson.build > > @@ -76,11 +76,16 @@ subdir('config') > > > > # build libs and drivers > > subdir('lib') > > -subdir('drivers') > > > > -# build binaries and installable tools > > -subdir('usertools') > > -subdir('app') > > +if is_ms_compiler > > +enabled_apps = [] > > +else > > +subdir('drivers') > > + > > +# build binaries and installable tools > > +subdir('usertools') > > +subdir('app') > > +endif > > > > My own preference here would be to put the checks inside the > subdirectories, and try and keep the top-level meson.build file clean. > Would that work ok? no objection. one clarification request though. do you mean just for drivers, usertools and app or do you mean for every lib/ as well? i'll send up a v2 once i get confirmation. > > > # build docs > > subdir('doc') > > -- > > 1.8.3.1 > >
Re: [PATCH 3/3] build: limit what is built when using MSVC compiler
On Thu, Jan 26, 2023 at 09:28:58AM -0800, Tyler Retzlaff wrote: > On Thu, Jan 26, 2023 at 11:10:26AM +, Bruce Richardson wrote: > > On Wed, Jan 25, 2023 at 11:25:07AM -0800, Tyler Retzlaff wrote: > > > Build only kvargs and telemetry when is_ms_compiler. > > > > > > Signed-off-by: Tyler Retzlaff > > > --- > > > lib/meson.build | 7 +++ > > > meson.build | 13 + > > > 2 files changed, 16 insertions(+), 4 deletions(-) > > > > > > diff --git a/lib/meson.build b/lib/meson.build > > > index 82e4666..8e99e21 100644 > > > > > --- a/meson.build > > > +++ b/meson.build > > > @@ -76,11 +76,16 @@ subdir('config') > > > > > > # build libs and drivers > > > subdir('lib') > > > -subdir('drivers') > > > > > > -# build binaries and installable tools > > > -subdir('usertools') > > > -subdir('app') > > > +if is_ms_compiler > > > +enabled_apps = [] > > > +else > > > +subdir('drivers') > > > + > > > +# build binaries and installable tools > > > +subdir('usertools') > > > +subdir('app') > > > +endif > > > > > > > My own preference here would be to put the checks inside the > > subdirectories, and try and keep the top-level meson.build file clean. > > Would that work ok? > > no objection. one clarification request though. > > do you mean just for drivers, usertools and app or do you mean for every > lib/ as well? > No, not for every lib, there are far too many of them. What you have done there makes most sense. But for drivers/apps/usertools, putting the check in the subfolder help keep the top-level file cleaner.
Re: [PATCH 3/3] build: limit what is built when using MSVC compiler
On Thu, Jan 26, 2023 at 05:34:50PM +, Bruce Richardson wrote: > On Thu, Jan 26, 2023 at 09:28:58AM -0800, Tyler Retzlaff wrote: > > On Thu, Jan 26, 2023 at 11:10:26AM +, Bruce Richardson wrote: > > > On Wed, Jan 25, 2023 at 11:25:07AM -0800, Tyler Retzlaff wrote: > > > > Build only kvargs and telemetry when is_ms_compiler. > > > > > > > > Signed-off-by: Tyler Retzlaff > > > > --- > > > > lib/meson.build | 7 +++ > > > > meson.build | 13 + > > > > 2 files changed, 16 insertions(+), 4 deletions(-) > > > > > > > > diff --git a/lib/meson.build b/lib/meson.build > > > > index 82e4666..8e99e21 100644 > > > > > > > --- a/meson.build > > > > +++ b/meson.build > > > > @@ -76,11 +76,16 @@ subdir('config') > > > > > > > > # build libs and drivers > > > > subdir('lib') > > > > -subdir('drivers') > > > > > > > > -# build binaries and installable tools > > > > -subdir('usertools') > > > > -subdir('app') > > > > +if is_ms_compiler > > > > +enabled_apps = [] > > > > +else > > > > +subdir('drivers') > > > > + > > > > +# build binaries and installable tools > > > > +subdir('usertools') > > > > +subdir('app') > > > > +endif > > > > > > > > > > My own preference here would be to put the checks inside the > > > subdirectories, and try and keep the top-level meson.build file clean. > > > Would that work ok? > > > > no objection. one clarification request though. > > > > do you mean just for drivers, usertools and app or do you mean for every > > lib/ as well? > > > > No, not for every lib, there are far too many of them. What you have done > there makes most sense. But for drivers/apps/usertools, putting the check > in the subfolder help keep the top-level file cleaner. thanks, i'll fire up v2 sometime today.
[PATCH v2 0/3] unblock the use of the MSVC compiler
Introduce minimum changes to the build system to allow use of the MSVC compiler. This change is intended to enable a phased approach to allowing DPDK to built with MSVC. Building with MSVC removes barriers to enterprise customers use of DPDK who have constraints around security policy, compliance and functional requirements. Tyler Retzlaff (3): build: unblock the use of the MSVC compiler build: determine execution environment at config time build: limit what is built when using MSVC compiler app/meson.build| 5 + buildtools/meson.build | 10 +++--- config/meson.build | 29 ++--- config/x86/meson.build | 8 +--- drivers/meson.build| 4 lib/eal/meson.build| 8 lib/meson.build| 20 +--- usertools/meson.build | 4 8 files changed, 64 insertions(+), 24 deletions(-) -- 1.8.3.1
[PATCH v2 2/3] build: determine execution environment at config time
Move execution environment determination and definitions to config. The RTE_EXEC_ENV macros are actually used by libraries built before EAL. Currently it does not matter that this is determined in lib/eal since the definitions are consumed before anything is built including libs built before lib/eal. By moving this logic to config it allows kvargs and telemetry to be built without EAL. No functional change intended. Signed-off-by: Tyler Retzlaff Acked-by: Bruce Richardson --- config/meson.build | 8 lib/eal/meson.build | 8 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/config/meson.build b/config/meson.build index 898b743..e0b9e4e 100644 --- a/config/meson.build +++ b/config/meson.build @@ -14,6 +14,14 @@ foreach env:supported_exec_envs set_variable('is_' + env, exec_env == env) endforeach +exec_envs = {'freebsd': 0, 'linux': 1, 'windows': 2} +foreach env, id:exec_envs +dpdk_conf.set('RTE_ENV_' + env.to_upper(), id) +dpdk_conf.set10('RTE_EXEC_ENV_IS_' + env.to_upper(), (exec_env == env)) +endforeach +dpdk_conf.set('RTE_EXEC_ENV', exec_envs[exec_env]) +dpdk_conf.set('RTE_EXEC_ENV_' + exec_env.to_upper(), 1) + # MS linker requires special treatment. # TODO: use cc.get_linker_id() with Meson >= 0.54 is_ms_compiler = is_windows and (cc.get_id() == 'msvc') diff --git a/lib/eal/meson.build b/lib/eal/meson.build index 056beb9..26c638f 100644 --- a/lib/eal/meson.build +++ b/lib/eal/meson.build @@ -10,14 +10,6 @@ if not is_windows subdir('unix') endif -exec_envs = {'freebsd': 0, 'linux': 1, 'windows': 2} -foreach env, id:exec_envs -dpdk_conf.set('RTE_ENV_' + env.to_upper(), id) -dpdk_conf.set10('RTE_EXEC_ENV_IS_' + env.to_upper(), (exec_env == env)) -endforeach -dpdk_conf.set('RTE_EXEC_ENV', exec_envs[exec_env]) - -dpdk_conf.set('RTE_EXEC_ENV_' + exec_env.to_upper(), 1) subdir(exec_env) subdir(arch_subdir) -- 1.8.3.1
[PATCH v2 3/3] build: limit what is built when using MSVC compiler
Build only kvargs and telemetry when is_ms_compiler. Signed-off-by: Tyler Retzlaff --- app/meson.build | 5 + drivers/meson.build | 4 lib/meson.build | 7 +++ usertools/meson.build | 4 4 files changed, 20 insertions(+) diff --git a/app/meson.build b/app/meson.build index e32ea4b..a606510 100644 --- a/app/meson.build +++ b/app/meson.build @@ -1,6 +1,11 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017-2019 Intel Corporation +if is_ms_compiler +enabled_apps = [] +subdir_done() +endif + disable_apps = ',' + get_option('disable_apps') disable_apps = run_command(list_dir_globs, disable_apps, check: true).stdout().split() diff --git a/drivers/meson.build b/drivers/meson.build index c6d6192..8ed1213 100644 --- a/drivers/meson.build +++ b/drivers/meson.build @@ -1,6 +1,10 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017-2019 Intel Corporation +if is_ms_compiler +subdir_done() +endif + fs = import('fs') # Defines the order of dependencies evaluation diff --git a/lib/meson.build b/lib/meson.build index 82e4666..8e99e21 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -65,6 +65,13 @@ libraries = [ 'node', ] +if is_ms_compiler +libraries = [ +'kvargs', +'telemetry', +] +endif + optional_libs = [ 'bitratestats', 'cfgfile', diff --git a/usertools/meson.build b/usertools/meson.build index b6271a2..1a56248 100644 --- a/usertools/meson.build +++ b/usertools/meson.build @@ -1,6 +1,10 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation +if is_ms_compiler +subdir_done() +endif + install_data([ 'dpdk-devbind.py', 'dpdk-pmdinfo.py', -- 1.8.3.1
[PATCH v2 1/3] build: unblock the use of the MSVC compiler
Detect when MSVC toolset is available and tweak toolchain arguments where the meson build system offers no abstraction. Signed-off-by: Tyler Retzlaff Acked-by: Bruce Richardson --- buildtools/meson.build | 10 +++--- config/meson.build | 21 ++--- config/x86/meson.build | 8 +--- lib/meson.build| 13 ++--- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/buildtools/meson.build b/buildtools/meson.build index e1c600e..838c39f 100644 --- a/buildtools/meson.build +++ b/buildtools/meson.build @@ -4,7 +4,9 @@ pkgconf = find_program('pkg-config', 'pkgconf', required: false) check_symbols = find_program('check-symbols.sh') ldflags_ibverbs_static = find_program('options-ibverbs-static.sh') -objdump = find_program('objdump', 'llvm-objdump') +if cc.get_id() != 'msvc' +objdump = find_program('objdump', 'llvm-objdump') +endif python3 = import('python').find_installation(required: false) if python3.found() @@ -18,8 +20,10 @@ map_to_win_cmd = py3 + files('map_to_win.py') sphinx_wrapper = py3 + files('call-sphinx-build.py') get_cpu_count_cmd = py3 + files('get-cpu-count.py') get_numa_count_cmd = py3 + files('get-numa-count.py') -binutils_avx512_check = (py3 + files('binutils-avx512-check.py') + -[objdump] + cc.cmd_array()) +if cc.get_id() != 'msvc' +binutils_avx512_check = (py3 + files('binutils-avx512-check.py') + +[objdump] + cc.cmd_array()) +endif # select library and object file format pmdinfo = py3 + files('gen-pmdinfo-cfile.py') + [meson.current_build_dir()] diff --git a/config/meson.build b/config/meson.build index 6d9ffd4..898b743 100644 --- a/config/meson.build +++ b/config/meson.build @@ -16,7 +16,8 @@ endforeach # MS linker requires special treatment. # TODO: use cc.get_linker_id() with Meson >= 0.54 -is_ms_linker = is_windows and (cc.get_id() == 'clang') +is_ms_compiler = is_windows and (cc.get_id() == 'msvc') +is_ms_linker = is_windows and (cc.get_id() == 'clang' or is_ms_compiler) # set the major version, which might be used by drivers and libraries # depending on the configuration options @@ -130,11 +131,13 @@ dpdk_conf.set('RTE_MACHINE', cpu_instruction_set) machine_args = [] # ppc64 does not support -march= at all, use -mcpu and -mtune for that -if host_machine.cpu_family().startswith('ppc') -machine_args += '-mcpu=' + cpu_instruction_set -machine_args += '-mtune=' + cpu_instruction_set -else -machine_args += '-march=' + cpu_instruction_set +if not is_ms_compiler +if host_machine.cpu_family().startswith('ppc') +machine_args += '-mcpu=' + cpu_instruction_set +machine_args += '-mtune=' + cpu_instruction_set +else +machine_args += '-march=' + cpu_instruction_set +endif endif toolchain = cc.get_id() @@ -252,7 +255,11 @@ if cc.get_id() == 'clang' and dpdk_conf.get('RTE_ARCH_64') == false endif # add -include rte_config to cflags -add_project_arguments('-include', 'rte_config.h', language: 'c') +if is_ms_compiler +add_project_arguments('/FI', 'rte_config.h', language: 'c') +else +add_project_arguments('-include', 'rte_config.h', language: 'c') +endif # enable extra warnings and disable any unwanted warnings # -Wall is added by default at warning level 1, and -Wextra diff --git a/config/x86/meson.build b/config/x86/meson.build index 54345c4..11f0bcc 100644 --- a/config/x86/meson.build +++ b/config/x86/meson.build @@ -25,9 +25,11 @@ if cc.has_argument('-mavx512f') endif # we require SSE4.2 for DPDK -if cc.get_define('__SSE4_2__', args: machine_args) == '' -message('SSE 4.2 not enabled by default, explicitly enabling') -machine_args += '-msse4' +if not is_ms_compiler +if cc.get_define('__SSE4_2__', args: machine_args) == '' +message('SSE 4.2 not enabled by default, explicitly enabling') +machine_args += '-msse4' +endif endif base_flags = ['SSE', 'SSE2', 'SSE3','SSSE3', 'SSE4_1', 'SSE4_2'] diff --git a/lib/meson.build b/lib/meson.build index a90fee3..82e4666 100644 --- a/lib/meson.build +++ b/lib/meson.build @@ -235,9 +235,16 @@ foreach l:libraries output: '@0@_exports.def'.format(libname)) lk_deps += [def_file] -lk_args = ['-Wl,/def:' + def_file.full_path()] -if meson.version().version_compare('<0.54.0') -lk_args += ['-Wl,/implib:lib\\librte_' + l + '.dll.a'] +if is_ms_compiler +lk_args = ['/def:' + def_file.full_path()] +if meson.version().version_compare('<0.54.0') +lk_args += ['/implib:lib\\librte_' + l + '.dll.a'] +endif +else +lk_args = ['-Wl,/def:' + def_file.full_path()] +if meson.version().version_compare('<0.54.0') +lk_args += ['-Wl,/implib:lib\\librte_' + l + '.dll.a'] +endif endif else if is_windows -- 1.8.3.1
Re: [PATCH v2 0/3] unblock the use of the MSVC compiler
On Thu, Jan 26, 2023 at 10:03:21AM -0800, Tyler Retzlaff wrote: > Introduce minimum changes to the build system to allow use of the MSVC > compiler. > > This change is intended to enable a phased approach to allowing DPDK to > built with MSVC. Building with MSVC removes barriers to enterprise > customers use of DPDK who have constraints around security policy, > compliance and functional requirements. oops, failed to update the cover letter. v2: * moved checks to skip drivers, apps, usertools directories in to /meson.build file and removed conditional check from root meson.build (patch 3/3). > > Tyler Retzlaff (3): > build: unblock the use of the MSVC compiler > build: determine execution environment at config time > build: limit what is built when using MSVC compiler > > app/meson.build| 5 + > buildtools/meson.build | 10 +++--- > config/meson.build | 29 ++--- > config/x86/meson.build | 8 +--- > drivers/meson.build| 4 > lib/eal/meson.build| 8 > lib/meson.build| 20 +--- > usertools/meson.build | 4 > 8 files changed, 64 insertions(+), 24 deletions(-) > > -- > 1.8.3.1
Re: [PATCH v2 3/3] build: limit what is built when using MSVC compiler
On Thu, Jan 26, 2023 at 10:03:24AM -0800, Tyler Retzlaff wrote: > Build only kvargs and telemetry when is_ms_compiler. > > Signed-off-by: Tyler Retzlaff > --- Thanks for v2 Acked-by: Bruce Richardson
[PATCH 0/3] dumpcap: small enhancements
Cover a few more options and statistics mode to be add more compatiablity with wireshark dumpcap. Stephen Hemminger (3): dumpcap: add --interface to help dumpcap: support temp-dir option dumpcap: add support statistics mode app/dumpcap/main.c | 67 -- 1 file changed, 59 insertions(+), 8 deletions(-) -- 2.39.0
[PATCH 1/3] dumpcap: add --interface to help
Make the help more complete, add all supported options. Signed-off-by: Stephen Hemminger --- app/dumpcap/main.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/dumpcap/main.c b/app/dumpcap/main.c index 2eb8414efaa5..297b6378aaf2 100644 --- a/app/dumpcap/main.c +++ b/app/dumpcap/main.c @@ -102,7 +102,8 @@ static void usage(void) { printf("Usage: %s [options] ...\n\n", progname); printf("Capture Interface:\n" - " -iname or port index of interface\n" + " -i , --interface \n" + " name or port index of interface\n" " -f packet filter in libpcap filter syntax\n"); printf(" -s , --snapshot-length \n" " packet snapshot length (def: %u)\n", -- 2.39.0
[PATCH 2/3] dumpcap: support temp-dir option
Option for putting output files in different directory. Same syntax as wireshark. Signed-off-by: Stephen Hemminger --- app/dumpcap/main.c | 9 - 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/dumpcap/main.c b/app/dumpcap/main.c index 297b6378aaf2..02bb8b2b2b4f 100644 --- a/app/dumpcap/main.c +++ b/app/dumpcap/main.c @@ -58,6 +58,7 @@ static bool quiet; static bool promiscuous_mode = true; static bool use_pcapng = true; static char *output_name; +static const char *tmp_dir = "/tmp"; static const char *filter_str; static unsigned int ring_size = 2048; static const char *capture_comment; @@ -126,6 +127,8 @@ static void usage(void) " -P use libpcap format instead of pcapng\n" " --capture-comment \n" " add a capture comment to the output file\n" + " --temp-dirwrite temporary files to this directory\n" + " (default: /tmp)\n" "\n" "Miscellaneous:\n" " --file-prefix= prefix to use for multi-process\n" @@ -327,6 +330,7 @@ static void parse_opts(int argc, char **argv) { "output-file", required_argument, NULL, 'w' }, { "ring-buffer", required_argument, NULL, 'b' }, { "snapshot-length", required_argument, NULL, 's' }, + { "temp-dir",required_argument, NULL, 0 }, { "version", no_argument, NULL, 'v' }, { NULL }, }; @@ -346,6 +350,9 @@ static void parse_opts(int argc, char **argv) } else if (!strcmp(long_options[option_index].name, "file-prefix")) { file_prefix = optarg; + } else if (!strcmp(long_options[option_index].name, + "temp-dir")) { + tmp_dir = optarg; } else { usage(); exit(1); @@ -642,7 +649,7 @@ static dumpcap_out_t create_output(void) strftime(ts, sizeof(ts), "%Y%m%d%H%M%S", tm); snprintf(tmp_path, sizeof(tmp_path), -"/tmp/%s_%u_%s_%s.%s", +"%s/%s_%u_%s_%s.%s", tmp_dir, progname, intf->port, intf->name, ts, use_pcapng ? "pcapng" : "pcap"); output_name = tmp_path; -- 2.39.0
[PATCH 3/3] dumpcap: add support statistics mode
This add new -S option which does the same thing as wireshark's dumpcap -S option. It loops over all interfaces and prints the number of received and dropped packets. In this mode, actual packet capture is not done. Signed-off-by: Stephen Hemminger --- app/dumpcap/main.c | 55 +- 1 file changed, 49 insertions(+), 6 deletions(-) diff --git a/app/dumpcap/main.c b/app/dumpcap/main.c index 02bb8b2b2b4f..d1c70f769be5 100644 --- a/app/dumpcap/main.c +++ b/app/dumpcap/main.c @@ -66,6 +66,7 @@ static const char *file_prefix; static uint32_t snaplen = RTE_MBUF_DEFAULT_BUF_SIZE; static bool dump_bpf; static bool show_interfaces; +static bool print_stats; static bool select_interfaces; const char *interface_arg; @@ -113,6 +114,7 @@ static void usage(void) " don't capture in promiscuous mode\n" " -D, --list-interfacesprint list of interfaces and exit\n" " -d print generated BPF code for capture filter\n" + " -S print statistics for each interface once per second\n" "\n" "Stop conditions:\n" " -c stop after n packets (def: infinite)\n" @@ -337,7 +339,7 @@ static void parse_opts(int argc, char **argv) int option_index, c; for (;;) { - c = getopt_long(argc, argv, "a:b:c:dDf:ghi:nN:pPqs:vw:", + c = getopt_long(argc, argv, "a:b:c:dDf:ghi:nN:pPqSs:vw:", long_options, &option_index); if (c == -1) break; @@ -406,6 +408,9 @@ static void parse_opts(int argc, char **argv) case 's': snaplen = get_uint(optarg, "snap_len", 0); break; + case 'S': + print_stats = true; + break; case 'w': output_name = optarg; break; @@ -427,6 +432,39 @@ signal_handler(int sig_num __rte_unused) __atomic_store_n(&quit_signal, true, __ATOMIC_RELAXED); } + +/* Instead of capturing, it tracks interface statistics */ +static void statistics_loop(void) +{ + struct rte_eth_stats stats; + char name[RTE_ETH_NAME_MAX_LEN]; + uint16_t p; + int r; + + printf("%-15s %10s %10s\n", + "Interface", "Received", "Dropped"); + + while (!__atomic_load_n(&quit_signal, __ATOMIC_RELAXED)) { + RTE_ETH_FOREACH_DEV(p) { + if (rte_eth_dev_get_name_by_port(p, name) < 0) + continue; + + r = rte_eth_stats_get(p, &stats); + if (r < 0) { + fprintf(stderr, + "stats_get for port %u failed: %d (%s)\n", + p, r, strerror(r)); + return; + } + + printf("%-15s %10"PRIu64" %10"PRIu64"\n", + name, stats.ipackets, + stats.imissed + stats.ierrors + stats.rx_nombuf); + } + sleep(1); + } +} + /* Return the time since 1/1/1970 in nanoseconds */ static uint64_t create_timestamp(void) { @@ -834,6 +872,16 @@ int main(int argc, char **argv) if (TAILQ_EMPTY(&interfaces)) set_default_interface(); + signal(SIGINT, signal_handler); + signal(SIGPIPE, SIG_IGN); + + enable_primary_monitor(); + + if (print_stats) { + statistics_loop(); + exit(0); + } + r = create_ring(); mp = create_mempool(); out = create_output(); @@ -841,11 +889,6 @@ int main(int argc, char **argv) start_time = create_timestamp(); enable_pdump(r, mp); - signal(SIGINT, signal_handler); - signal(SIGPIPE, SIG_IGN); - - enable_primary_monitor(); - if (!quiet) { fprintf(stderr, "Packets captured: "); show_count(0); -- 2.39.0
DPDK Release Status Meeting 2023-01-26
Release status meeting minutes 2023-01-26 = Agenda: * Release Dates * Subtrees * Roadmaps * LTS * Defects * Opens Participants: * AMD * Intel * Nvidia * Red Hat Release Dates - The following are the proposed current dates for 23.03: * V1: 25 December 2022 * RC1: 8 February 2023 * RC2: 1 March2023 * RC3: 8 March2023 * Release: 20 March2023 Subtrees * next-net * Needs more reviews/support. * Focus is on ethdev reviews. * rte_flow has a lot of cleanup changes in this release and needs reviews * Some reviews ongoing but we are missing reviewer support on this tree. * next-net-intel * No update. * next-net-mlx * Some patches integrated and waiting to be pulled. * More in the backlog. * next-net-mvl * No update * next-eventdev * No update * next-baseband * No update * next-virtio * No update * next-crypto * No update * main * Thread API from Tyler under review * Waiting for ack on deprecation * Telemetry patches from Robin under review. * Two series on annotations. * Spurious failures in service-cores tests * testpmd fixes/additions need closer reviews Proposed Schedule for 2023 -- See also http://core.dpdk.org/roadmap/#dates 23.03 * Proposal deadline (RFC/v1 patches): 25 December 2022 * API freeze (-rc1): 8 February 2023 * PMD features freeze (-rc2): 1 March 2023 * Builtin applications features freeze (-rc3): 8 March 2023 * Release: 20 March 2023 23.07 * Proposal deadline (RFC/v1 patches): 15 April 2023 * API freeze (-rc1): 31 May 2023 * PMD features freeze (-rc2): 21 June 2023 * Builtin applications features freeze (-rc3): 28 June 2023 * Release: 12 July 2023 23.11 * Proposal deadline (RFC/v1 patches): 12 August 2023 * API freeze (-rc1): 29 September 2023 * PMD features freeze (-rc2): 20 October 2023 * Builtin applications features freeze (-rc3): 27 October 2023 * Release: 15 November 2023 Other - * TBA LTS --- Next releases will be: * 22.11.1 * 21.11.4 * 20.11.8 * 19.11.15? * CVE and critical fixes only. * Distros * v20.11 in Debian 11 * Ubuntu 22.04 contains 21.11 Defects --- * Bugzilla links, 'Bugs', added for hosted projects * https://www.dpdk.org/hosted-projects/ Opens - * None DPDK Release Status Meetings The DPDK Release Status Meeting is intended for DPDK Committers to discuss the status of the master tree and sub-trees, and for project managers to track progress or milestone dates. The meeting occurs on every Thursday at 9:30 UTC over Jitsi on https://meet.jit.si/DPDK You don't need an invite to join the meeting but if you want a calendar reminder just send an email to "John McNamara john.mcnam...@intel.com" for the invite.