[PATCH] examples/l3fwd: fix Tx performance deteriorate

2024-11-22 Thread Jie Hai
The application send packets only when the buffer is full, or the
buffer is empty and the number of packets to be sent extends half
of the buffer.

The change of MAX_PKT_BURST increases TX buffer size, while the
default size of local cache on each lcore is 256, which not greater
than the limit of transmitting. That would make the mbuf not on the
local cache be frequently used and the performance deteriorates.

This problem can be solved by making the TX threshold smaller than
the local cache size. For example, use the '--mbcache' parameter to
make the local cache greater. This patch optimizes the default
performance by lowering TX threshold.

Fixes: d5c4897ecfb2 ("examples/l3fwd: add option to set Rx burst size")

Signed-off-by: Jie Hai 
---
 examples/l3fwd/l3fwd.h| 8 +---
 examples/l3fwd/l3fwd_common.h | 6 +++---
 2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
index 0cce3406ee7d..a01fecd51261 100644
--- a/examples/l3fwd/l3fwd.h
+++ b/examples/l3fwd/l3fwd.h
@@ -35,7 +35,7 @@
 /*
  * Try to avoid TX buffering if we have at least MAX_TX_BURST packets to send.
  */
-#defineMAX_TX_BURST  (MAX_PKT_BURST / 2)
+#defineMAX_TX_BURST DEFAULT_PKT_BURST
 
 #define NB_SOCKETS8
 
@@ -57,6 +57,8 @@
 #define L3FWD_HASH_ENTRIES (1024*1024*1)
 #endif
 
+static_assert(MAX_TX_BURST <= MAX_PKT_BURST, "MAX_TX_BURST should be at most 
MAX_PKT_BURST");
+
 struct parm_cfg {
const char *rule_ipv4_name;
const char *rule_ipv6_name;
@@ -152,8 +154,8 @@ send_single_packet(struct lcore_conf *qconf,
len++;
 
/* enough pkts to be sent */
-   if (unlikely(len == MAX_PKT_BURST)) {
-   send_burst(qconf, MAX_PKT_BURST, port);
+   if (unlikely(len == MAX_TX_BURST)) {
+   send_burst(qconf, MAX_TX_BURST, port);
len = 0;
}
 
diff --git a/examples/l3fwd/l3fwd_common.h b/examples/l3fwd/l3fwd_common.h
index d94e5f135791..3f504dc0a552 100644
--- a/examples/l3fwd/l3fwd_common.h
+++ b/examples/l3fwd/l3fwd_common.h
@@ -71,7 +71,7 @@ send_packetsx4(struct lcore_conf *qconf, uint16_t port, 
struct rte_mbuf *m[],
 * If TX buffer for that queue is empty, and we have enough packets,
 * then send them straightway.
 */
-   if (num >= MAX_TX_BURST && len == 0) {
+   if (num >= MAX_TX_BURST / 2 && len == 0) {
n = rte_eth_tx_burst(port, qconf->tx_queue_id[port], m, num);
if (unlikely(n < num)) {
do {
@@ -112,9 +112,9 @@ send_packetsx4(struct lcore_conf *qconf, uint16_t port, 
struct rte_mbuf *m[],
len += n;
 
/* enough pkts to be sent */
-   if (unlikely(len == MAX_PKT_BURST)) {
+   if (unlikely(len > MAX_TX_BURST)) {
 
-   send_burst(qconf, MAX_PKT_BURST, port);
+   send_burst(qconf, len, port);
 
/* copy rest of the packets into the TX buffer. */
len = num - n;
-- 
2.22.0



RE: [PATCH] examples/l3fwd: fix Tx performance deteriorate

2024-11-22 Thread Konstantin Ananyev



> The application send packets only when the buffer is full, or the
> buffer is empty and the number of packets to be sent extends half
> of the buffer.
> 
> The change of MAX_PKT_BURST increases TX buffer size, while the
> default size of local cache on each lcore is 256, which not greater
> than the limit of transmitting. That would make the mbuf not on the
> local cache be frequently used and the performance deteriorates.
> 
> This problem can be solved by making the TX threshold smaller than
> the local cache size. For example, use the '--mbcache' parameter to
> make the local cache greater. This patch optimizes the default
> performance by lowering TX threshold.

In  commit:
examples/l3fwd: add option to set Rx burst size
you introduced new global 
uint32_t nb_pkt_per_burst;
Why not to use it for both (rx and tx) paths?
Or if necessary introduce another one for tx, so we'll have:
uint32_t nb_rx_pkt_per_burst, nb_tx_pkt_per_burst,;
To me that is much better then create some hardcoded
and implicit thresholds.  

> Fixes: d5c4897ecfb2 ("examples/l3fwd: add option to set Rx burst size")
> 
> Signed-off-by: Jie Hai 
> ---
>  examples/l3fwd/l3fwd.h| 8 +---
>  examples/l3fwd/l3fwd_common.h | 6 +++---
>  2 files changed, 8 insertions(+), 6 deletions(-)
> 
> diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
> index 0cce3406ee7d..a01fecd51261 100644
> --- a/examples/l3fwd/l3fwd.h
> +++ b/examples/l3fwd/l3fwd.h
> @@ -35,7 +35,7 @@
>  /*
>   * Try to avoid TX buffering if we have at least MAX_TX_BURST packets to 
> send.
>   */
> -#define  MAX_TX_BURST  (MAX_PKT_BURST / 2)
> +#define  MAX_TX_BURST DEFAULT_PKT_BURST
> 
>  #define NB_SOCKETS8
> 
> @@ -57,6 +57,8 @@
>  #define L3FWD_HASH_ENTRIES   (1024*1024*1)
>  #endif
> 
> +static_assert(MAX_TX_BURST <= MAX_PKT_BURST, "MAX_TX_BURST should be at most 
> MAX_PKT_BURST");
> +
>  struct parm_cfg {
>   const char *rule_ipv4_name;
>   const char *rule_ipv6_name;
> @@ -152,8 +154,8 @@ send_single_packet(struct lcore_conf *qconf,
>   len++;
> 
>   /* enough pkts to be sent */
> - if (unlikely(len == MAX_PKT_BURST)) {
> - send_burst(qconf, MAX_PKT_BURST, port);
> + if (unlikely(len == MAX_TX_BURST)) {
> + send_burst(qconf, MAX_TX_BURST, port);
>   len = 0;
>   }
> 
> diff --git a/examples/l3fwd/l3fwd_common.h b/examples/l3fwd/l3fwd_common.h
> index d94e5f135791..3f504dc0a552 100644
> --- a/examples/l3fwd/l3fwd_common.h
> +++ b/examples/l3fwd/l3fwd_common.h
> @@ -71,7 +71,7 @@ send_packetsx4(struct lcore_conf *qconf, uint16_t port, 
> struct rte_mbuf *m[],
>* If TX buffer for that queue is empty, and we have enough packets,
>* then send them straightway.
>*/
> - if (num >= MAX_TX_BURST && len == 0) {
> + if (num >= MAX_TX_BURST / 2 && len == 0) {
>   n = rte_eth_tx_burst(port, qconf->tx_queue_id[port], m, num);
>   if (unlikely(n < num)) {
>   do {
> @@ -112,9 +112,9 @@ send_packetsx4(struct lcore_conf *qconf, uint16_t port, 
> struct rte_mbuf *m[],
>   len += n;
> 
>   /* enough pkts to be sent */
> - if (unlikely(len == MAX_PKT_BURST)) {
> + if (unlikely(len > MAX_TX_BURST)) {
> 
> - send_burst(qconf, MAX_PKT_BURST, port);
> + send_burst(qconf, len, port);
> 
>   /* copy rest of the packets into the TX buffer. */
>   len = num - n;
> --
> 2.22.0



Re: [PATCH] examples/l3fwd: fix Tx performance deteriorate

2024-11-22 Thread lihuisong (C)

LGTM, good job.
Acked-by: Huisong Li 

在 2024/11/22 15:13, Jie Hai 写道:

The application send packets only when the buffer is full, or the
buffer is empty and the number of packets to be sent extends half
of the buffer.

The change of MAX_PKT_BURST increases TX buffer size, while the
default size of local cache on each lcore is 256, which not greater
than the limit of transmitting. That would make the mbuf not on the
local cache be frequently used and the performance deteriorates.

This problem can be solved by making the TX threshold smaller than
the local cache size. For example, use the '--mbcache' parameter to
make the local cache greater. This patch optimizes the default
performance by lowering TX threshold.

Fixes: d5c4897ecfb2 ("examples/l3fwd: add option to set Rx burst size")

Signed-off-by: Jie Hai 
---
  examples/l3fwd/l3fwd.h| 8 +---
  examples/l3fwd/l3fwd_common.h | 6 +++---
  2 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/examples/l3fwd/l3fwd.h b/examples/l3fwd/l3fwd.h
index 0cce3406ee7d..a01fecd51261 100644
--- a/examples/l3fwd/l3fwd.h
+++ b/examples/l3fwd/l3fwd.h
@@ -35,7 +35,7 @@
  /*
   * Try to avoid TX buffering if we have at least MAX_TX_BURST packets to send.
   */
-#defineMAX_TX_BURST  (MAX_PKT_BURST / 2)
+#defineMAX_TX_BURST DEFAULT_PKT_BURST
  
  #define NB_SOCKETS8
  
@@ -57,6 +57,8 @@

  #define L3FWD_HASH_ENTRIES(1024*1024*1)
  #endif
  
+static_assert(MAX_TX_BURST <= MAX_PKT_BURST, "MAX_TX_BURST should be at most MAX_PKT_BURST");

+
  struct parm_cfg {
const char *rule_ipv4_name;
const char *rule_ipv6_name;
@@ -152,8 +154,8 @@ send_single_packet(struct lcore_conf *qconf,
len++;
  
  	/* enough pkts to be sent */

-   if (unlikely(len == MAX_PKT_BURST)) {
-   send_burst(qconf, MAX_PKT_BURST, port);
+   if (unlikely(len == MAX_TX_BURST)) {
+   send_burst(qconf, MAX_TX_BURST, port);
len = 0;
}
  
diff --git a/examples/l3fwd/l3fwd_common.h b/examples/l3fwd/l3fwd_common.h

index d94e5f135791..3f504dc0a552 100644
--- a/examples/l3fwd/l3fwd_common.h
+++ b/examples/l3fwd/l3fwd_common.h
@@ -71,7 +71,7 @@ send_packetsx4(struct lcore_conf *qconf, uint16_t port, 
struct rte_mbuf *m[],
 * If TX buffer for that queue is empty, and we have enough packets,
 * then send them straightway.
 */
-   if (num >= MAX_TX_BURST && len == 0) {
+   if (num >= MAX_TX_BURST / 2 && len == 0) {
n = rte_eth_tx_burst(port, qconf->tx_queue_id[port], m, num);
if (unlikely(n < num)) {
do {
@@ -112,9 +112,9 @@ send_packetsx4(struct lcore_conf *qconf, uint16_t port, 
struct rte_mbuf *m[],
len += n;
  
  	/* enough pkts to be sent */

-   if (unlikely(len == MAX_PKT_BURST)) {
+   if (unlikely(len > MAX_TX_BURST)) {
  
-		send_burst(qconf, MAX_PKT_BURST, port);

+   send_burst(qconf, len, port);
  
  		/* copy rest of the packets into the TX buffer. */

len = num - n;


RE: [EXTERNAL] [PATCH v4 5/9] app/test: fix TLS zero length record

2024-11-22 Thread Anoob Joseph
> The code was duplicating the same condition three times?
> Reading the commit message, the intention was:
>
>Add unit tests to verify the zero len TLS records. Zero len packets are
>allowed when content type is app data while zero packet length with
>other content type (such as handshake) would result in an error.
>
> Link: 
> https://urldefense.proofpoint.com/v2/url?u=https-3A__pvs-2Dstudio.com_en_blog_posts_cpp_1179_&d=DwIDAg&c=nKjWec2b6R0mOyPaz7xtfQ&r=jPfB8rwwviRSxyLWs2n6B-
> WYLn1v9SyTMrT5EQqh2TU&m=XameIFsYmmvHMhJycVwGxFucfJNVntjVlTBXIykV7kmsF4i5OLtyrXHT9KSTJnkm&s=JaPpRUXDxqq1KFX_JG2CQI0viz-YZG33I8zoO25Fr6k&e=
>
> Fixes: 79a58624369a ("test/security: verify zero length TLS records")
> Cc: mailto:vvelum...@marvell.com
> Cc: mailto:sta...@dpdk.org
>
> Signed-off-by: Stephen Hemminger 

Good catch. Looks like remnants after a rename exercise. Originally it was 
intended as separate for TLS 1.2, DTLS 1.2 & TLS 1.3. 
Acked-by: Anoob Joseph 




Re: [PATCH v4 2/9] app/test: fix typo in address compare

2024-11-22 Thread Bruce Richardson
On Thu, Nov 21, 2024 at 10:23:23AM -0800, Stephen Hemminger wrote:
> The first argument of 'memcmp' function was equal to the second argument.
> Therefore ASSERT would always be true.
> 
> Link: https://pvs-studio.com/en/blog/posts/cpp/1179/
> 
> Fixes: 92073ef961ee ("bond: unit tests")
> Cc: declan.dohe...@intel.com
> Cc: sta...@dpdk.org
> 
> Signed-off-by: Stephen Hemminger 
> ---
>  app/test/test_link_bonding.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/app/test/test_link_bonding.c b/app/test/test_link_bonding.c
> index 805613d7dd..b752a5ecbf 100644
> --- a/app/test/test_link_bonding.c
> +++ b/app/test/test_link_bonding.c
> @@ -792,7 +792,7 @@ test_set_primary_member(void)
>   &read_mac_addr),
>   "Failed to get mac address (port %d)",
>   test_params->bonding_port_id);
> - TEST_ASSERT_SUCCESS(memcmp(&read_mac_addr, &read_mac_addr,
> + TEST_ASSERT_SUCCESS(memcmp(expected_mac_addr, &read_mac_addr,
>   sizeof(read_mac_addr)),
>   "bonding port mac address not set to that of 
> primary port\n");
>

Acked-by: Bruce Richardson   


Re: [RFC] Revert "vhost: use imported VDUSE uAPI header"

2024-11-22 Thread Maxime Coquelin




On 11/17/24 18:32, Stephen Hemminger wrote:

The file vduse.h does not have a license that is compatiable
with current DPDK license policy.

This reverts commit 9fec3f0569087de0129c7f2badaf5be2776e.

Signed-off-by: Stephen Hemminger 
---
  kernel/linux/uapi/linux/vduse.h | 353 
  lib/vhost/meson.build   |   5 +-
  lib/vhost/vduse.c   |   2 +-
  lib/vhost/vduse.h   |  22 ++
  4 files changed, 27 insertions(+), 355 deletions(-)
  delete mode 100644 kernel/linux/uapi/linux/vduse.h



Acked-by: Maxime Coquelin 

Thanks,
Maxime



RE: [PATCH v5 01/16] eal: provide pack start macro for MSVC

2024-11-22 Thread Morten Brørup
> From: Andre Muezerie [mailto:andre...@linux.microsoft.com]
> Sent: Friday, 22 November 2024 01.12
> 
> On Thu, Nov 21, 2024 at 09:51:36PM +0100, Thomas Monjalon wrote:
> > 21/11/2024 20:39, Andre Muezerie:
> > > On Tue, Nov 19, 2024 at 09:32:07AM +0100, Morten Brørup wrote:
> > > > > From: Andre Muezerie [mailto:andre...@linux.microsoft.com]
> > > > > Sent: Tuesday, 19 November 2024 05.35
> > > > >
> > > > > From: Tyler Retzlaff 
> > > > >
> > > > > MSVC struct packing is not compatible with GCC. Provide a macro
> that
> > > > > can be used to push existing pack value and sets packing to 1-
> byte.
> > > > > The existing __rte_packed macro is then used to restore the
> pack value
> > > > > prior to the push.
> > > > >
> > > > > Instead of providing macros exclusively for MSVC and for GCC
> the
> > > > > existing macro is deliberately utilized to trigger a warning if
> no
> > > > > existing packing has been pushed allowing easy identification
> of
> > > > > locations where the __rte_msvc_pack is missing.
> > > > >
> > > > > Signed-off-by: Tyler Retzlaff 
> > > > > ---
> > > > >  lib/eal/include/rte_common.h | 4 +++-
> > > > >  1 file changed, 3 insertions(+), 1 deletion(-)
> > > > >
> > > > > diff --git a/lib/eal/include/rte_common.h
> > > > > b/lib/eal/include/rte_common.h
> > > > > index 4d299f2b36..409890863e 100644
> > > > > --- a/lib/eal/include/rte_common.h
> > > > > +++ b/lib/eal/include/rte_common.h
> > > > > @@ -103,8 +103,10 @@ typedef uint16_t unaligned_uint16_t;
> > > > >   * Force a structure to be packed
> > > > >   */
> > > > >  #ifdef RTE_TOOLCHAIN_MSVC
> > > > > -#define __rte_packed
> > > > > +#define __rte_msvc_pack __pragma(pack(push, 1))
> > > > > +#define __rte_packed __pragma(pack(pop))
> > > > >  #else
> > > > > +#define __rte_msvc_pack
> > > > >  #define __rte_packed __attribute__((__packed__))
> > > > >  #endif
> > > > >
> > > > > --
> > > > > 2.47.0.vfs.0.3
> > > >
> > > > Before proceeding with this, can we please discuss the
> alternative, proposed here:
> > > >
> https://inbox.dpdk.org/dev/CAJFAV8yStgiBbe+Nkt9mC30r0+ZP64_kGuRHOzqd90R
> d2hx...@mail.gmail.com/
> > > >
> > > > The definition of the packing macro in OVS, for reference:
> > > >
> https://github.com/openvswitch/ovs/blob/main/include/openvswitch/compil
> er.h#L209
> > > >
> > > > The current solution requires __rte_packed to be placed at the
> end of a structure, although __attribute__((packed)) is normally
> allowed at the beginning (between the "struct" tag and the name of the
> structure), which introduces a high risk of contributors placing it
> "incorrectly", thus causing errors.
> > > >
> > > > I have a strong preference for an __RTE_PACKED(decl) variant.
> > > >
> > > > Here's a third alternative:
> > > > #ifdef RTE_TOOLCHAIN_MSVC
> > > > #define __rte_msvc_pack_begin __pragma(pack(push, 1))
> > > > #define __rte_msvc_pack_end   __pragma(pack(pop))
> > > > #else
> > > > #define __rte_msvc_pack_begin
> > > > #define __rte_msvc_pack_end
> > > > #endif
> > > >
> > > > The third alternative is also problematic, e.g. if a contributor
> forgets the _end after the structure declaration, or adds another
> structure declaration before the _end.
> > > >
> > > > -Morten
> > >
> > > I looked at the suggestions made and I liked the one having a
> __RTE_PACKED macro
> > > the most.
> > >
> > > Advantages:
> > > - Can be placed in front of the struct, or even in the middle. Good
> for readability.
> > > - Does not require a different macro to be placed at the end of the
> structure as was
> > >   proposed in V5 series.
> > > - Works well in 99% of the cases.
> > >
> > > Problems can arise when compiler directives are present in the
> struct, as they
> > > become arguments for __RTE_PACKED macro. This is not portable.
> > > I've seen two situations in the DPDK code:
> > >
> > > 1) #defines mentioned in the struct. In this situation we can just
> move the
> > >#define out of the struct.

No problem.

> > >
> > > 2) #if/#ifdef/#elif mentioned in the struct.
> > > This is a somewhat common pattern in structs where fields change
> based on
> > > endianness.
> > > Example:
> > >
> > > /**
> > >  * IPv4 Header
> > >  */
> > > struct __rte_aligned(2) rte_ipv4_hdr {
> > >   __extension__
> > >   union {
> > >   uint8_t version_ihl;/**< version and header length */
> > >   struct {
> > > #if RTE_BYTE_ORDER == RTE_LITTLE_ENDIAN
> > >   uint8_t ihl:4; /**< header length */
> > >   uint8_t version:4; /**< version */
> > > #elif RTE_BYTE_ORDER == RTE_BIG_ENDIAN
> > >   uint8_t version:4; /**< version */
> > >   uint8_t ihl:4; /**< header length */
> > > #endif
> > >   };
> > >   };
> > >   uint8_t  type_of_service;   /**< type of service */
> > >   rte_be16_t total_length;/**< length of packet */
> > > ...
> > > } __rte_packed;
> > >
> > > One way to solve this is to move the #if to the outside. But that
> involves
> > > d

RE: [PATCH v12 04/21] ethdev: remove use of VLAs for Windows built code

2024-11-22 Thread Konstantin Ananyev


> -Original Message-
> From: Fengchengwen 
> Sent: Friday, November 22, 2024 1:33 AM
> To: Andre Muezerie ; dev@dpdk.org
> Cc: Konstantin Ananyev 
> Subject: Re: [PATCH v12 04/21] ethdev: remove use of VLAs for Windows built 
> code
> 
> On 2024/11/22 5:41, Andre Muezerie wrote:
> > From: Konstantin Ananyev 
> >
> > 1) ./lib/ethdev/rte_ethdev.c:3244:16
> > : warning: ISO C90 forbids variable length array ‘xstats_names’
> > 2) ./lib/ethdev/rte_ethdev.c:3345:17
> > : warning: ISO C90 forbids variable length array ‘ids_copy’
> > 3) ./lib/ethdev/rte_ethdev.c:3538:16
> > : warning: ISO C90 forbids variable length array ‘xstats’
> > 4) ./lib/ethdev/rte_ethdev.c:3554:17
> > : warning: ISO C90 forbids variable length array ‘ids_copy’
> >
> > For 1) and 3) - just replaced VLA with arrays allocated from heap.
> > As I understand xstats extraction belongs to control-path, so extra
> > calloc/free is hopefully acceptable.
> > Also ethdev xstats already doing that within
> > rte_eth_xstats_get_id_by_name().
> > For 2) and 4) changed the code to use fixed size array and call
> > appropriate devops function several times, if needed.
> 
> It will invoke PMD ops multi-times, I'm not sure whether all drivers
> impl correctly.

Hmm..., but then there is a bug in the driver that has to be fixed, no?

> And it also belong control-path, so suggest use the call/free as 1&3 case.
> 



[PATCH v6 00/25] replace strtok with strtok_r

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

This patchset replaces strtok with strtok_r in app, example, lib
and drivers. And adds check for use of strtok in checkpatches.sh.

--
v6:
1. adapt to the newest codes.
2. fix compile error.

v5:
1. remove CC stable for some patch.
2. replace strtok for all files.

v4:
1. fix mispellings.
2. add Acked-bys and Reviewd-bys.
3. remove some patch and add new. 
v3:
1. fix compile error.
2. use strtok_r instead.
v2:
1. fix commit log.
2. add check in checkpatches.sh.
3. replace strtok_r with strtok_s.
4. add Acked-by.
--

Jie Hai (25):
  app/bbdev: replace strtok with reentrant version
  app/compress-perf: replace strtok with reentrant version
  app/crypto-perf: replace strtok with reentrant version
  app/dma-perf: replace strtok with reentrant version
  app/flow-perf: replace strtok with reentrant version
  app/test-mldev: replace strtok with reentrant version
  app/test-fib: replace strtok with reentrant version
  dmadev: replace strtok with reentrant version
  eal: replace strtok with reentrant version
  ethdev: replace strtok with reentrant version
  eventdev: replace strtok with reentrant version
  security: replace strtok with reentrant version
  telemetry: replace strtok with reentrant version
  bus/fslmc: replace strtok with reentrant version
  common/cnxk: replace strtok with reentrant version
  event/cnxk: replace strtok with reentrant version
  net/ark: replace strtok with reentrant version
  raw/cnxk_gpio: replace strtok with reentrant version
  net/cnxk: replace strtok with reentrant version
  common/qat: replace strtok with reentrant version
  net/mlx5: replace strtok with reentrant version
  examples/l2fwd-crypto: replace strtok with reentrant version
  examples/vhost: replace strtok with reentrant version
  devtools: check for some reentrant function
  eal/linux: install rte_os_shim.h file

 app/test-bbdev/test_bbdev_vector.c| 42 +++
 .../comp_perf_options_parse.c | 17 
 app/test-crypto-perf/cperf_options_parsing.c  | 17 
 .../cperf_test_vector_parsing.c   | 11 +++--
 app/test-dma-perf/main.c  |  9 ++--
 app/test-fib/main.c   | 11 ++---
 app/test-flow-perf/main.c | 23 +-
 app/test-mldev/ml_options.c   | 19 +
 devtools/checkpatches.sh  |  8 
 drivers/bus/fslmc/fslmc_bus.c |  6 ++-
 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c  |  5 ++-
 drivers/common/cnxk/cnxk_telemetry_nix.c  | 13 +++---
 drivers/common/qat/qat_device.c   |  6 ++-
 drivers/event/cnxk/cnxk_eventdev.c| 12 --
 drivers/event/cnxk/cnxk_tim_evdev.c   | 12 +++---
 drivers/net/ark/ark_pktchkr.c | 11 ++---
 drivers/net/ark/ark_pktgen.c  | 11 ++---
 drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c  |  6 ++-
 drivers/net/mlx5/mlx5_testpmd.c   |  5 ++-
 drivers/raw/cnxk_gpio/cnxk_gpio.c |  7 ++--
 examples/l2fwd-crypto/main.c  |  7 ++--
 examples/vhost/main.c |  4 +-
 lib/dmadev/rte_dmadev.c   |  5 ++-
 lib/eal/common/eal_common_memory.c|  8 ++--
 lib/eal/linux/include/meson.build |  1 +
 lib/ethdev/rte_ethdev_telemetry.c | 10 +++--
 lib/eventdev/rte_event_eth_rx_adapter.c   | 39 -
 lib/eventdev/rte_eventdev.c   | 18 
 lib/security/rte_security.c   |  4 +-
 lib/telemetry/telemetry.c |  6 ++-
 30 files changed, 208 insertions(+), 145 deletions(-)

-- 
2.33.0



[PATCH v6 01/25] app/bbdev: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 0acdb9866756 ("test/bbdev: add FFT operations cases")
Fixes: f714a18885a6 ("app/testbbdev: add test application for bbdev")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
---
 app/test-bbdev/test_bbdev_vector.c | 42 +-
 1 file changed, 24 insertions(+), 18 deletions(-)

diff --git a/app/test-bbdev/test_bbdev_vector.c 
b/app/test-bbdev/test_bbdev_vector.c
index 8b32850982c3..fbbdde70bdfc 100644
--- a/app/test-bbdev/test_bbdev_vector.c
+++ b/app/test-bbdev/test_bbdev_vector.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "test_bbdev_vector.h"
 
@@ -63,8 +64,9 @@ parse_values(char *tokens, uint32_t **data, uint32_t 
*data_length)
 
uint32_t *values, *values_resized;
char *tok, *error = NULL;
+   char *sp = NULL;
 
-   tok = strtok(tokens, VALUE_DELIMITER);
+   tok = strtok_r(tokens, VALUE_DELIMITER, &sp);
if (tok == NULL)
return -1;
 
@@ -98,7 +100,7 @@ parse_values(char *tokens, uint32_t **data, uint32_t 
*data_length)
 
*data_length = *data_length + (strlen(tok) - strlen("0x"))/2;
 
-   tok = strtok(NULL, VALUE_DELIMITER);
+   tok = strtok_r(NULL, VALUE_DELIMITER, &sp);
if (tok == NULL)
break;
 
@@ -324,8 +326,9 @@ parse_turbo_flags(char *tokens, uint32_t *op_flags,
 {
char *tok = NULL;
uint32_t op_flag_value = 0;
+   char *sp = NULL;
 
-   tok = strtok(tokens, VALUE_DELIMITER);
+   tok = strtok_r(tokens, VALUE_DELIMITER, &sp);
if (tok == NULL)
return -1;
 
@@ -359,7 +362,7 @@ parse_turbo_flags(char *tokens, uint32_t *op_flags,
 
*op_flags = *op_flags | op_flag_value;
 
-   tok = strtok(NULL, VALUE_DELIMITER);
+   tok = strtok_r(NULL, VALUE_DELIMITER, &sp);
if (tok == NULL)
break;
}
@@ -399,9 +402,10 @@ static int
 parse_expected_status(char *tokens, int *status, enum rte_bbdev_op_type 
op_type)
 {
char *tok = NULL;
+   char *sp = NULL;
bool status_ok = false;
 
-   tok = strtok(tokens, VALUE_DELIMITER);
+   tok = strtok_r(tokens, VALUE_DELIMITER, &sp);
if (tok == NULL)
return -1;
 
@@ -432,7 +436,7 @@ parse_expected_status(char *tokens, int *status, enum 
rte_bbdev_op_type op_type)
return -1;
}
 
-   tok = strtok(NULL, VALUE_DELIMITER);
+   tok = strtok_r(NULL, VALUE_DELIMITER, &sp);
if (tok == NULL)
break;
}
@@ -932,6 +936,7 @@ parse_fft_params(const char *key_token, char *token,
int ret = 0, status = 0, i, shift;
uint32_t op_flags = 0;
char *tok, *err = NULL;
+   char *sp = NULL;
 
struct rte_bbdev_op_fft *fft = &vector->fft;
 
@@ -964,7 +969,7 @@ parse_fft_params(const char *key_token, char *token,
fft->output_leading_depadding = (uint32_t) strtoul(token, &err, 
0);
ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
} else if (!strcmp(key_token, "window_index")) {
-   tok = strtok(token, VALUE_DELIMITER);
+   tok = strtok_r(token, VALUE_DELIMITER, &sp);
if (tok == NULL)
return -1;
for (i = 0; i < FFT_WIN_SIZE; i++) {
@@ -972,7 +977,7 @@ parse_fft_params(const char *key_token, char *token,
fft->window_index[i / 2] |= (uint32_t) strtoul(tok, 
&err, 0)
<< shift;
if (i < (FFT_WIN_SIZE - 1)) {
-   tok = strtok(NULL, VALUE_DELIMITER);
+   tok = strtok_r(NULL, VALUE_DELIMITER, &sp);
if (tok == NULL)
return -1;
}
@@ -1016,53 +1021,53 @@ parse_fft_params(const char *key_token, char *token,
fft->output_depadded_size = (uint32_t) strtoul(token, &err, 0);
ret = ((err == NULL) || (*err != '\0')) ? -1 : 0;
} else if (!strcmp(key_token, "cs_theta_0")) {
-   tok = strtok(token, VALUE_DELIMITER);
+   tok = strtok_r(token, VALUE_DELIMITER, &sp);
if (tok == NULL)
return -1;
for (i = 0; i < FFT_WIN_SIZE; i++) {
fft->cs_theta_0[i] = (uint32_t) strtoul(tok, &err, 0);
if (i < (FFT_WIN_SIZE - 1)) {
-   tok = strtok(NULL, VALUE_DELIMITER

[PATCH v6 04/25] app/dma-perf: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 623dc9364dc6 ("app/dma-perf: introduce DMA performance test")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
---
 app/test-dma-perf/main.c | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/app/test-dma-perf/main.c b/app/test-dma-perf/main.c
index 0586b3e1d0dc..23c0981fc47b 100644
--- a/app/test-dma-perf/main.c
+++ b/app/test-dma-perf/main.c
@@ -18,6 +18,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "main.h"
 
@@ -183,6 +184,7 @@ parse_lcore(struct test_configure *test_case, const char 
*value)
uint16_t len;
char *input;
struct lcore_dma_map_t *lcore_dma_map;
+   char *sp = NULL;
 
if (test_case == NULL || value == NULL)
return -1;
@@ -191,7 +193,7 @@ parse_lcore(struct test_configure *test_case, const char 
*value)
input = (char *)malloc((len + 1) * sizeof(char));
strlcpy(input, value, len + 1);
 
-   char *token = strtok(input, ", ");
+   char *token = strtok_r(input, ", ", &sp);
while (token != NULL) {
lcore_dma_map = 
&(test_case->dma_config[test_case->num_worker++].lcore_dma_map);
memset(lcore_dma_map, 0, sizeof(struct lcore_dma_map_t));
@@ -203,7 +205,7 @@ parse_lcore(struct test_configure *test_case, const char 
*value)
uint16_t lcore_id = atoi(token);
lcore_dma_map->lcore = lcore_id;
 
-   token = strtok(NULL, ", ");
+   token = strtok_r(NULL, ", ", &sp);
}
 
free(input);
@@ -532,6 +534,7 @@ main(int argc, char *argv[])
char *rst_path_ptr = NULL;
char rst_path[PATH_MAX];
int new_argc;
+   char *sp = NULL;
 
memset(args, 0, sizeof(args));
 
@@ -550,7 +553,7 @@ main(int argc, char *argv[])
}
if (rst_path_ptr == NULL) {
strlcpy(rst_path, cfg_path_ptr, PATH_MAX);
-   char *token = strtok(basename(rst_path), ".");
+   char *token = strtok_r(basename(rst_path), ".", &sp);
if (token == NULL) {
printf("Config file error.\n");
return -1;
-- 
2.33.0



[PATCH v6 10/25] ethdev: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: f38f62650f7b ("ethdev: add Rx queue telemetry query")
Fixes: 9e7533aeb80a ("ethdev: add telemetry command for TM level capabilities")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Reviewed-by: Andrew Rybchenko 
Acked-by: Morten Brørup 
---
 lib/ethdev/rte_ethdev_telemetry.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/lib/ethdev/rte_ethdev_telemetry.c 
b/lib/ethdev/rte_ethdev_telemetry.c
index 5e6c4172d3be..e589032dd368 100644
--- a/lib/ethdev/rte_ethdev_telemetry.c
+++ b/lib/ethdev/rte_ethdev_telemetry.c
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 
 #include "rte_ethdev.h"
 #include "ethdev_driver.h"
@@ -477,6 +478,7 @@ ethdev_parse_queue_params(const char *params, bool is_rx,
const char *qid_param;
uint16_t nb_queues;
char *end_param;
+   char *sp = NULL;
uint64_t qid;
int ret;
 
@@ -489,7 +491,7 @@ ethdev_parse_queue_params(const char *params, bool is_rx,
if (nb_queues == 1 && *end_param == '\0')
qid = 0;
else {
-   qid_param = strtok(end_param, ",");
+   qid_param = strtok_r(end_param, ",", &sp);
if (!qid_param || strlen(qid_param) == 0 || 
!isdigit(*qid_param))
return -EINVAL;
 
@@ -1221,9 +1223,10 @@ static int
 eth_dev_parse_tm_params(char *params, uint32_t *result)
 {
const char *splited_param;
+   char *sp = NULL;
uint64_t ret;
 
-   splited_param = strtok(params, ",");
+   splited_param = strtok_r(params, ",", &sp);
if (!splited_param || strlen(splited_param) == 0 || 
!isdigit(*splited_param))
return -EINVAL;
 
@@ -1510,13 +1513,14 @@ eth_dev_handle_port_regs(const char *cmd __rte_unused,
 {
char *filter, *end_param;
uint16_t port_id;
+   char *sp = NULL;
int ret;
 
ret = eth_dev_parse_port_params(params, &port_id, &end_param, true);
if (ret != 0)
return ret;
 
-   filter = strtok(end_param, ",");
+   filter = strtok_r(end_param, ",", &sp);
if (filter != NULL && strlen(filter) == 0)
filter = NULL;
 
-- 
2.33.0



[PATCH v6 06/25] app/test-mldev: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: bbd272edcb14 ("app/mldev: add ordered inferences")
Fixes: 28a4a819c850 ("app/mldev: improve checks for invalid options")
Fixes: da6793390596 ("app/mldev: support inference validation")
Fixes: f6661e6d9a3a ("app/mldev: validate model operations")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
---
 app/test-mldev/ml_options.c | 19 ++-
 1 file changed, 10 insertions(+), 9 deletions(-)

diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index 320f6325ae67..1033444de0e1 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "ml_common.h"
 #include "ml_test.h"
@@ -76,12 +77,12 @@ ml_parse_models(struct ml_options *opt, const char *arg)
 {
const char *delim = ",";
char models[PATH_MAX];
-   char *token;
+   char *token, *sp = NULL;
int ret = 0;
 
strlcpy(models, arg, PATH_MAX);
 
-   token = strtok(models, delim);
+   token = strtok_r(models, delim, &sp);
while (token != NULL) {
if (opt->nb_filelist >= ML_TEST_MAX_MODELS) {
ml_err("Exceeded model count, max = %d\n", 
ML_TEST_MAX_MODELS);
@@ -92,7 +93,7 @@ ml_parse_models(struct ml_options *opt, const char *arg)
strlcpy(opt->filelist[opt->nb_filelist].model, token, PATH_MAX);
opt->nb_filelist++;
 
-   token = strtok(NULL, delim);
+   token = strtok_r(NULL, delim, &sp);
}
 
if (opt->nb_filelist == 0) {
@@ -108,7 +109,7 @@ ml_parse_filelist(struct ml_options *opt, const char *arg)
 {
const char *delim = ",";
char filelist[PATH_MAX];
-   char *token;
+   char *token, *sp = NULL;
 
if (opt->nb_filelist >= ML_TEST_MAX_MODELS) {
ml_err("Exceeded filelist count, max = %d\n", 
ML_TEST_MAX_MODELS);
@@ -118,7 +119,7 @@ ml_parse_filelist(struct ml_options *opt, const char *arg)
strlcpy(filelist, arg, PATH_MAX);
 
/* model */
-   token = strtok(filelist, delim);
+   token = strtok_r(filelist, delim, &sp);
if (token == NULL) {
ml_err("Invalid filelist, model not specified = %s\n", arg);
return -EINVAL;
@@ -126,7 +127,7 @@ ml_parse_filelist(struct ml_options *opt, const char *arg)
strlcpy(opt->filelist[opt->nb_filelist].model, token, PATH_MAX);
 
/* input */
-   token = strtok(NULL, delim);
+   token = strtok_r(NULL, delim, &sp);
if (token == NULL) {
ml_err("Invalid filelist, input not specified = %s\n", arg);
return -EINVAL;
@@ -134,7 +135,7 @@ ml_parse_filelist(struct ml_options *opt, const char *arg)
strlcpy(opt->filelist[opt->nb_filelist].input, token, PATH_MAX);
 
/* output */
-   token = strtok(NULL, delim);
+   token = strtok_r(NULL, delim, &sp);
if (token == NULL) {
ml_err("Invalid filelist, output not specified = %s\n", arg);
return -EINVAL;
@@ -142,14 +143,14 @@ ml_parse_filelist(struct ml_options *opt, const char *arg)
strlcpy(opt->filelist[opt->nb_filelist].output, token, PATH_MAX);
 
/* reference - optional */
-   token = strtok(NULL, delim);
+   token = strtok_r(NULL, delim, &sp);
if (token != NULL)
strlcpy(opt->filelist[opt->nb_filelist].reference, token, 
PATH_MAX);
else
memset(opt->filelist[opt->nb_filelist].reference, 0, PATH_MAX);
 
/* check for extra tokens */
-   token = strtok(NULL, delim);
+   token = strtok_r(NULL, delim, &sp);
if (token != NULL) {
ml_err("Invalid filelist. Entries > 4\n.");
return -EINVAL;
-- 
2.33.0



[PATCH v6 05/25] app/flow-perf: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 0c8f1f4ab90e ("app/flow-perf: support raw encap/decap actions")
Fixes: 7f37f0936a19 ("app/flow-perf: support meter policy API")
Fixes: 80a323319745 ("app/flow-perf: add destination ports parameter")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
---
 app/test-flow-perf/main.c | 23 +--
 1 file changed, 13 insertions(+), 10 deletions(-)

diff --git a/app/test-flow-perf/main.c b/app/test-flow-perf/main.c
index 07ddfe0e46df..7e68146c16d7 100644
--- a/app/test-flow-perf/main.c
+++ b/app/test-flow-perf/main.c
@@ -36,6 +36,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "config.h"
 #include "actions_gen.h"
@@ -602,6 +603,7 @@ read_meter_policy(char *prog, char *arg)
 {
char *token;
size_t i, j, k;
+   char *sp = NULL;
 
j = 0;
k = 0;
@@ -612,9 +614,9 @@ read_meter_policy(char *prog, char *arg)
token = strsep(&arg, ":\0");
}
j = 0;
-   token = strtok(actions_str[0], ",\0");
+   token = strtok_r(actions_str[0], ",\0", &sp);
while (token == NULL && j < RTE_COLORS - 1)
-   token = strtok(actions_str[++j], ",\0");
+   token = strtok_r(actions_str[++j], ",\0", &sp);
while (j < RTE_COLORS && token != NULL) {
for (i = 0; i < RTE_DIM(flow_options); i++) {
if (!strcmp(token, flow_options[i].str)) {
@@ -628,9 +630,9 @@ read_meter_policy(char *prog, char *arg)
usage(prog);
rte_exit(EXIT_SUCCESS, "Invalid colored actions\n");
}
-   token = strtok(NULL, ",\0");
+   token = strtok_r(NULL, ",\0", &sp);
while (!token && j < RTE_COLORS - 1) {
-   token = strtok(actions_str[++j], ",\0");
+   token = strtok_r(actions_str[++j], ",\0", &sp);
k = 0;
}
}
@@ -641,6 +643,7 @@ args_parse(int argc, char **argv)
 {
uint64_t pm, seed;
uint64_t hp_conf;
+   char *sp = NULL;
char **argvopt;
uint32_t prio;
char *token;
@@ -804,7 +807,7 @@ args_parse(int argc, char **argv)
RTE_FLOW_ACTION_TYPE_RAW_ENCAP
);
 
-   token = strtok(optarg, ",");
+   token = strtok_r(optarg, ",", &sp);
while (token != NULL) {
for (i = 0; i < RTE_DIM(flow_options); 
i++) {
if (strcmp(flow_options[i].str, 
token) == 0) {
@@ -817,7 +820,7 @@ args_parse(int argc, char **argv)
rte_exit(EXIT_FAILURE,
"Invalid encap 
item: %s\n", token);
}
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
}
printf(" / ");
}
@@ -828,7 +831,7 @@ args_parse(int argc, char **argv)
RTE_FLOW_ACTION_TYPE_RAW_DECAP
);
 
-   token = strtok(optarg, ",");
+   token = strtok_r(optarg, ",", &sp);
while (token != NULL) {
for (i = 0; i < RTE_DIM(flow_options); 
i++) {
if (strcmp(flow_options[i].str, 
token) == 0) {
@@ -841,7 +844,7 @@ args_parse(int argc, char **argv)
rte_exit(EXIT_FAILURE,
"Invalid decap 
item %s\n", token);
}
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
}
printf(" / ");
}
@@ -910,10 +913,10 @@ args_parse(int argc, char **argv)
uint16_t port_idx = 0;
char *token;
 
-   token = strtok(optarg, ",");
+   token = strtok_r(optarg, ",", &sp);
while (token != NULL) {
dst_port

[PATCH v6 02/25] app/compress-perf: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: e0b6287c035d ("app/compress-perf: add parser")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
---
 .../comp_perf_options_parse.c   | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/app/test-compress-perf/comp_perf_options_parse.c 
b/app/test-compress-perf/comp_perf_options_parse.c
index 6d8c370fc2ea..6f3f907162e6 100644
--- a/app/test-compress-perf/comp_perf_options_parse.c
+++ b/app/test-compress-perf/comp_perf_options_parse.c
@@ -12,6 +12,7 @@
 
 #include 
 #include 
+#include 
 
 #include "comp_perf_options.h"
 
@@ -177,6 +178,7 @@ parse_range(const char *arg, uint8_t *min, uint8_t *max, 
uint8_t *inc)
 {
char *token;
uint8_t number;
+   char *sp = NULL;
 
char *copy_arg = strdup(arg);
 
@@ -184,7 +186,7 @@ parse_range(const char *arg, uint8_t *min, uint8_t *max, 
uint8_t *inc)
return -1;
 
errno = 0;
-   token = strtok(copy_arg, ":");
+   token = strtok_r(copy_arg, ":", &sp);
 
/* Parse minimum value */
if (token != NULL) {
@@ -197,7 +199,7 @@ parse_range(const char *arg, uint8_t *min, uint8_t *max, 
uint8_t *inc)
} else
goto err_range;
 
-   token = strtok(NULL, ":");
+   token = strtok_r(NULL, ":", &sp);
 
/* Parse increment value */
if (token != NULL) {
@@ -211,7 +213,7 @@ parse_range(const char *arg, uint8_t *min, uint8_t *max, 
uint8_t *inc)
} else
goto err_range;
 
-   token = strtok(NULL, ":");
+   token = strtok_r(NULL, ":", &sp);
 
/* Parse maximum value */
if (token != NULL) {
@@ -225,7 +227,7 @@ parse_range(const char *arg, uint8_t *min, uint8_t *max, 
uint8_t *inc)
} else
goto err_range;
 
-   if (strtok(NULL, ":") != NULL)
+   if (strtok_r(NULL, ":", &sp) != NULL)
goto err_range;
 
free(copy_arg);
@@ -244,6 +246,7 @@ parse_list(const char *arg, uint8_t *list, uint8_t *min, 
uint8_t *max)
uint8_t count = 0;
uint32_t temp_min;
uint32_t temp_max;
+   char *sp = NULL;
 
char *copy_arg = strdup(arg);
 
@@ -251,7 +254,7 @@ parse_list(const char *arg, uint8_t *list, uint8_t *min, 
uint8_t *max)
return -1;
 
errno = 0;
-   token = strtok(copy_arg, ",");
+   token = strtok_r(copy_arg, ",", &sp);
 
/* Parse first value */
if (token != NULL) {
@@ -266,7 +269,7 @@ parse_list(const char *arg, uint8_t *list, uint8_t *min, 
uint8_t *max)
} else
goto err_list;
 
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
 
while (token != NULL) {
if (count == MAX_LIST) {
@@ -288,7 +291,7 @@ parse_list(const char *arg, uint8_t *list, uint8_t *min, 
uint8_t *max)
if (number > temp_max)
temp_max = number;
 
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
}
 
if (min)
-- 
2.33.0



[PATCH v6 07/25] app/test-fib: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 103809d032cd ("app/test-fib: add test application for FIB")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
---
 app/test-fib/main.c | 11 ++-
 1 file changed, 6 insertions(+), 5 deletions(-)

diff --git a/app/test-fib/main.c b/app/test-fib/main.c
index 6479f48cdf6c..11810a1a80a8 100644
--- a/app/test-fib/main.c
+++ b/app/test-fib/main.c
@@ -17,6 +17,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #definePRINT_USAGE_START   "%s [EAL options] --\n"
 
@@ -204,9 +205,9 @@ parse_distrib(uint8_t depth_lim, const uint32_t n)
uint32_t nrpd[128 + 1] = {0}; /* number of routes per depth */
uint32_t n_routes;
uint8_t depth, ratio, ratio_acc = 0;
-   char *in;
+   char *in, *sp = NULL;
 
-   in = strtok(distrib_string, ",");
+   in = strtok_r(distrib_string, ",", &sp);
 
/*parse configures routes percentage ratios*/
while (in != NULL) {
@@ -246,7 +247,7 @@ parse_distrib(uint8_t depth_lim, const uint32_t n)
}
 
/*number of configured depths in*/
-   in = strtok(NULL, ",");
+   in = strtok_r(NULL, ",", &sp);
}
 
if (ratio_acc > 100) {
@@ -522,10 +523,10 @@ parse_lookup(FILE *f, int af)
int ret, i = 0;
uint8_t *tbl = (uint8_t *)config.lookup_tbl;
int step = (af == AF_INET) ? 4 : 16;
-   char *s;
+   char *s, *sp = NULL;
 
while (fgets(line, sizeof(line), f) != NULL) {
-   s = strtok(line, " \t\n");
+   s = strtok_r(line, " \t\n", &sp);
if (s == NULL)
return -EINVAL;
ret = inet_pton(af, s, &tbl[i]);
-- 
2.33.0



[PATCH v6 08/25] dmadev: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 39b5ab60df30 ("dmadev: add telemetry")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Morten Brørup 
---
 lib/dmadev/rte_dmadev.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/lib/dmadev/rte_dmadev.c b/lib/dmadev/rte_dmadev.c
index 8bb7824aa129..eaf649e7d982 100644
--- a/lib/dmadev/rte_dmadev.c
+++ b/lib/dmadev/rte_dmadev.c
@@ -14,6 +14,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rte_dmadev.h"
 #include "rte_dmadev_pmd.h"
@@ -1016,7 +1017,7 @@ dmadev_handle_dev_stats(const char *cmd __rte_unused,
struct rte_dma_info dma_info;
struct rte_dma_stats dma_stats;
int dev_id, ret, vchan_id;
-   char *end_param;
+   char *end_param, *sp = NULL;
const char *vchan_param;
 
if (params == NULL || strlen(params) == 0 || !isdigit(*params))
@@ -1035,7 +1036,7 @@ dmadev_handle_dev_stats(const char *cmd __rte_unused,
if (dma_info.nb_vchans == 1 && *end_param == '\0')
vchan_id = 0;
else {
-   vchan_param = strtok(end_param, ",");
+   vchan_param = strtok_r(end_param, ",", &sp);
if (!vchan_param || strlen(vchan_param) == 0 || 
!isdigit(*vchan_param))
return -EINVAL;
 
-- 
2.33.0



[PATCH v6 16/25] event/cnxk: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 8a3d58c189fd ("event/cnxk: add option to control timer adapters")
Fixes: 8bdbae66b299 ("event/cnxk: add external clock support for timer")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Morten Brørup 
---
 drivers/event/cnxk/cnxk_eventdev.c  | 12 
 drivers/event/cnxk/cnxk_tim_evdev.c | 12 +++-
 2 files changed, 15 insertions(+), 9 deletions(-)

diff --git a/drivers/event/cnxk/cnxk_eventdev.c 
b/drivers/event/cnxk/cnxk_eventdev.c
index be6a487b590b..047b5250c7c0 100644
--- a/drivers/event/cnxk/cnxk_eventdev.c
+++ b/drivers/event/cnxk/cnxk_eventdev.c
@@ -2,6 +2,8 @@
  * Copyright(C) 2021 Marvell.
  */
 
+#include 
+
 #include "roc_api.h"
 
 #include "cnxk_eventdev.h"
@@ -482,7 +484,8 @@ parse_queue_param(char *value, void *opaque)
struct cnxk_sso_qos queue_qos = {0};
uint16_t *val = (uint16_t *)&queue_qos;
struct cnxk_sso_evdev *dev = opaque;
-   char *tok = strtok(value, "-");
+   char *sp = NULL;
+   char *tok = strtok_r(value, "-", &sp);
struct cnxk_sso_qos *old_ptr;
 
if (!strlen(value))
@@ -490,7 +493,7 @@ parse_queue_param(char *value, void *opaque)
 
while (tok != NULL) {
*val = atoi(tok);
-   tok = strtok(NULL, "-");
+   tok = strtok_r(NULL, "-", &sp);
val++;
}
 
@@ -518,7 +521,8 @@ parse_stash_param(char *value, void *opaque)
struct cnxk_sso_stash queue_stash = {0};
struct cnxk_sso_evdev *dev = opaque;
struct cnxk_sso_stash *old_ptr;
-   char *tok = strtok(value, "|");
+   char *sp = NULL;
+   char *tok = strtok_r(value, "|", &sp);
uint16_t *val;
 
if (!strlen(value))
@@ -527,7 +531,7 @@ parse_stash_param(char *value, void *opaque)
val = (uint16_t *)&queue_stash;
while (tok != NULL) {
*val = atoi(tok);
-   tok = strtok(NULL, "|");
+   tok = strtok_r(NULL, "|", &sp);
val++;
}
 
diff --git a/drivers/event/cnxk/cnxk_tim_evdev.c 
b/drivers/event/cnxk/cnxk_tim_evdev.c
index 994d1d1090e0..245d02a42eff 100644
--- a/drivers/event/cnxk/cnxk_tim_evdev.c
+++ b/drivers/event/cnxk/cnxk_tim_evdev.c
@@ -3,6 +3,7 @@
  */
 
 #include 
+#include 
 
 #include "roc_api.h"
 
@@ -455,7 +456,8 @@ cnxk_tim_parse_ring_param(char *value, void *opaque)
 {
struct cnxk_tim_evdev *dev = opaque;
struct cnxk_tim_ctl ring_ctl = {0};
-   char *tok = strtok(value, "-");
+   char *sp = NULL;
+   char *tok = strtok_r(value, "-", &sp);
struct cnxk_tim_ctl *old_ptr;
uint16_t *val;
 
@@ -466,7 +468,7 @@ cnxk_tim_parse_ring_param(char *value, void *opaque)
 
while (tok != NULL) {
*val = atoi(tok);
-   tok = strtok(NULL, "-");
+   tok = strtok_r(NULL, "-", &sp);
val++;
}
 
@@ -542,16 +544,16 @@ cnxk_tim_parse_clk_list(const char *value, void *opaque)
  ROC_TIM_CLK_SRC_INVALID};
struct cnxk_tim_evdev *dev = opaque;
char *str = strdup(value);
-   char *tok;
+   char *tok, *sp = NULL;
int i = 0;
 
if (str == NULL || !strlen(str))
goto free;
 
-   tok = strtok(str, "-");
+   tok = strtok_r(str, "-", &sp);
while (tok != NULL && src[i] != ROC_TIM_CLK_SRC_INVALID) {
dev->ext_clk_freq[src[i]] = strtoull(tok, NULL, 10);
-   tok = strtok(NULL, "-");
+   tok = strtok_r(NULL, "-", &sp);
i++;
}
 
-- 
2.33.0



[PATCH v6 11/25] eventdev: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Morten Brørup 
---
 lib/eventdev/rte_event_eth_rx_adapter.c | 39 +
 lib/eventdev/rte_eventdev.c | 18 ++--
 2 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/lib/eventdev/rte_event_eth_rx_adapter.c 
b/lib/eventdev/rte_event_eth_rx_adapter.c
index 39674c4604df..89e1b1836d59 100644
--- a/lib/eventdev/rte_event_eth_rx_adapter.c
+++ b/lib/eventdev/rte_event_eth_rx_adapter.c
@@ -23,6 +23,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rte_eventdev.h"
 #include "eventdev_pmd.h"
@@ -3651,7 +3652,7 @@ handle_rxa_get_queue_conf(const char *cmd __rte_unused,
uint8_t rx_adapter_id;
uint16_t rx_queue_id;
int eth_dev_id, ret = -1;
-   char *token, *l_params;
+   char *token, *l_params, *sp;
struct rte_event_eth_rx_adapter_queue_conf queue_conf;
 
if (params == NULL || strlen(params) == 0 || !isdigit(*params))
@@ -3661,19 +3662,19 @@ handle_rxa_get_queue_conf(const char *cmd __rte_unused,
l_params = strdup(params);
if (l_params == NULL)
return -ENOMEM;
-   token = strtok(l_params, ",");
+   token = strtok_r(l_params, ",", &sp);
RTE_EVENT_ETH_RX_ADAPTER_TOKEN_VALID_OR_GOTO_ERR_RET(token, -1);
rx_adapter_id = strtoul(token, NULL, 10);
RTE_EVENT_ETH_RX_ADAPTER_ID_VALID_OR_GOTO_ERR_RET(rx_adapter_id, 
-EINVAL);
 
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
RTE_EVENT_ETH_RX_ADAPTER_TOKEN_VALID_OR_GOTO_ERR_RET(token, -1);
 
/* Get device ID from parameter string */
eth_dev_id = strtoul(token, NULL, 10);
RTE_EVENT_ETH_RX_ADAPTER_PORTID_VALID_OR_GOTO_ERR_RET(eth_dev_id, 
-EINVAL);
 
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
RTE_EVENT_ETH_RX_ADAPTER_TOKEN_VALID_OR_GOTO_ERR_RET(token, -1);
 
/* Get Rx queue ID from parameter string */
@@ -3684,7 +3685,7 @@ handle_rxa_get_queue_conf(const char *cmd __rte_unused,
goto error;
}
 
-   token = strtok(NULL, "\0");
+   token = strtok_r(NULL, "\0", &sp);
if (token != NULL)
RTE_EDEV_LOG_ERR("Extra parameters passed to eventdev"
 " telemetry command, ignoring");
@@ -3723,7 +3724,7 @@ handle_rxa_get_queue_stats(const char *cmd __rte_unused,
uint8_t rx_adapter_id;
uint16_t rx_queue_id;
int eth_dev_id, ret = -1;
-   char *token, *l_params;
+   char *token, *l_params, *sp = NULL;
struct rte_event_eth_rx_adapter_queue_stats q_stats;
 
if (params == NULL || strlen(params) == 0 || !isdigit(*params))
@@ -3733,19 +3734,19 @@ handle_rxa_get_queue_stats(const char *cmd __rte_unused,
l_params = strdup(params);
if (l_params == NULL)
return -ENOMEM;
-   token = strtok(l_params, ",");
+   token = strtok_r(l_params, ",", &sp);
RTE_EVENT_ETH_RX_ADAPTER_TOKEN_VALID_OR_GOTO_ERR_RET(token, -1);
rx_adapter_id = strtoul(token, NULL, 10);
RTE_EVENT_ETH_RX_ADAPTER_ID_VALID_OR_GOTO_ERR_RET(rx_adapter_id, 
-EINVAL);
 
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
RTE_EVENT_ETH_RX_ADAPTER_TOKEN_VALID_OR_GOTO_ERR_RET(token, -1);
 
/* Get device ID from parameter string */
eth_dev_id = strtoul(token, NULL, 10);
RTE_EVENT_ETH_RX_ADAPTER_PORTID_VALID_OR_GOTO_ERR_RET(eth_dev_id, 
-EINVAL);
 
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
RTE_EVENT_ETH_RX_ADAPTER_TOKEN_VALID_OR_GOTO_ERR_RET(token, -1);
 
/* Get Rx queue ID from parameter string */
@@ -3756,7 +3757,7 @@ handle_rxa_get_queue_stats(const char *cmd __rte_unused,
goto error;
}
 
-   token = strtok(NULL, "\0");
+   token = strtok_r(NULL, "\0", &sp);
if (token != NULL)
RTE_EDEV_LOG_ERR("Extra parameters passed to eventdev"
 " telemetry command, ignoring");
@@ -3794,7 +3795,7 @@ handle_rxa_queue_stats_reset(const char *cmd __rte_unused,
uint8_t rx_adapter_id;
uint16_t rx_queue_id;
int eth_dev_id, ret = -1;
-   char *token, *l_params;
+   char *token, *l_params, *sp = NULL;
 
if (params == NULL || strlen(params) == 0 || !isdigit(*params))
return -1;
@@ -3803,19 +3804,19 @@ handle_rxa_queue_stats_reset(const char *cmd 
__rte_unused,
l_params = strdup(params);
if (l_params == NULL)
return -ENOMEM;
-   token = strtok

[PATCH v6 15/25] common/cnxk: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: af75aac78978 ("common/cnxk: support telemetry for NIX")
Cc: sta...@dpdk.org

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Morten Brørup 
Acked-by: Stephen Hemminger 
---
 drivers/common/cnxk/cnxk_telemetry_nix.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/common/cnxk/cnxk_telemetry_nix.c 
b/drivers/common/cnxk/cnxk_telemetry_nix.c
index abeefafe1e19..a0b587c97c63 100644
--- a/drivers/common/cnxk/cnxk_telemetry_nix.c
+++ b/drivers/common/cnxk/cnxk_telemetry_nix.c
@@ -3,6 +3,7 @@
  */
 
 #include 
+#include 
 #include "cnxk_telemetry.h"
 #include "roc_api.h"
 #include "roc_priv.h"
@@ -1015,7 +1016,7 @@ cnxk_nix_tel_handle_info_x(const char *cmd, const char 
*params,
   struct plt_tel_data *d)
 {
struct nix_tel_node *node;
-   char *name, *param;
+   char *name, *param, *sp = NULL;
char buf[1024];
int rc = -1;
 
@@ -1023,11 +1024,11 @@ cnxk_nix_tel_handle_info_x(const char *cmd, const char 
*params,
goto exit;
 
plt_strlcpy(buf, params, PCI_PRI_STR_SIZE + 1);
-   name = strtok(buf, ",");
+   name = strtok_r(buf, ",", &sp);
if (name == NULL)
goto exit;
 
-   param = strtok(NULL, "\0");
+   param = strtok_r(NULL, "\0", &sp);
 
node = nix_tel_node_get_by_pcidev_name(name);
if (!node)
@@ -1036,7 +1037,7 @@ cnxk_nix_tel_handle_info_x(const char *cmd, const char 
*params,
plt_tel_data_start_dict(d);
 
if (strstr(cmd, "rq")) {
-   char *tok = strtok(param, ",");
+   char *tok = strtok_r(param, ",", &sp);
int rq;
 
if (!tok)
@@ -1052,7 +1053,7 @@ cnxk_nix_tel_handle_info_x(const char *cmd, const char 
*params,
rc = cnxk_tel_nix_rq(node->rqs[rq], d);
 
} else if (strstr(cmd, "cq")) {
-   char *tok = strtok(param, ",");
+   char *tok = strtok_r(param, ",", &sp);
int cq;
 
if (!tok)
@@ -1068,7 +1069,7 @@ cnxk_nix_tel_handle_info_x(const char *cmd, const char 
*params,
rc = cnxk_tel_nix_cq(node->cqs[cq], d);
 
} else if (strstr(cmd, "sq")) {
-   char *tok = strtok(param, ",");
+   char *tok = strtok_r(param, ",", &sp);
int sq;
 
if (!tok)
-- 
2.33.0



[PATCH v6 14/25] bus/fslmc: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 9ccb76b24c1d ("bus/fslmc: enable portal interrupt handling")
Fixes: 828d51d8fc3e ("bus/fslmc: refactor scan and probe functions")
Cc: sta...@dpdk.org

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Sachin Saxena 
Acked-by: Morten Brørup 
---
 drivers/bus/fslmc/fslmc_bus.c| 6 --
 drivers/bus/fslmc/portal/dpaa2_hw_dpio.c | 5 +++--
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/bus/fslmc/fslmc_bus.c b/drivers/bus/fslmc/fslmc_bus.c
index 68ad2b801e95..89fcca2999ab 100644
--- a/drivers/bus/fslmc/fslmc_bus.c
+++ b/drivers/bus/fslmc/fslmc_bus.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "private.h"
 #include 
@@ -131,6 +132,7 @@ scan_one_fslmc_device(char *dev_name)
 {
char *dup_dev_name, *t_ptr;
struct rte_dpaa2_device *dev = NULL;
+   char *sp = NULL;
int ret = -1;
 
if (!dev_name)
@@ -168,7 +170,7 @@ scan_one_fslmc_device(char *dev_name)
}
 
/* Parse the device name and ID */
-   t_ptr = strtok(dup_dev_name, ".");
+   t_ptr = strtok_r(dup_dev_name, ".", &sp);
if (!t_ptr) {
DPAA2_BUS_ERR("Invalid device found: (%s)", dup_dev_name);
ret = -EINVAL;
@@ -199,7 +201,7 @@ scan_one_fslmc_device(char *dev_name)
else
dev->dev_type = DPAA2_UNKNOWN;
 
-   t_ptr = strtok(NULL, ".");
+   t_ptr = strtok_r(NULL, ".", &sp);
if (!t_ptr) {
DPAA2_BUS_ERR("Skipping invalid device (%s)", dup_dev_name);
ret = 0;
diff --git a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c 
b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
index 2dfcf7a49879..eba60c3c6d75 100644
--- a/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
+++ b/drivers/bus/fslmc/portal/dpaa2_hw_dpio.c
@@ -31,6 +31,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -141,7 +142,7 @@ dpaa2_affine_dpio_intr_to_respective_core(int32_t dpio_id, 
int cpu_id)
 #define AFFINITY_LEN   128
uint32_t cpu_mask = 1;
size_t len = 0;
-   char *temp = NULL, *token = NULL;
+   char *temp = NULL, *token = NULL, *sp = NULL;
char string[STRING_LEN];
char smp_affinity[AFFINITY_LEN];
FILE *file;
@@ -154,7 +155,7 @@ dpaa2_affine_dpio_intr_to_respective_core(int32_t dpio_id, 
int cpu_id)
}
while (getline(&temp, &len, file) != -1) {
if ((strstr(temp, string)) != NULL) {
-   token = strtok(temp, ":");
+   token = strtok_r(temp, ":", &sp);
break;
}
}
-- 
2.33.0



[PATCH v6 13/25] telemetry: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 6dd571fd07c3 ("telemetry: introduce new functionality")
Cc: sta...@dpdk.org

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Ciara Power 
Acked-by: Morten Brørup 
Acked-by: Stephen Hemminger 
---
 lib/telemetry/telemetry.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/telemetry/telemetry.c b/lib/telemetry/telemetry.c
index 31a2c91c0657..cd1eddc5609c 100644
--- a/lib/telemetry/telemetry.c
+++ b/lib/telemetry/telemetry.c
@@ -19,6 +19,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "rte_telemetry.h"
 #include "telemetry_json.h"
@@ -398,6 +399,7 @@ static void *
 client_handler(void *sock_id)
 {
int s = (int)(uintptr_t)sock_id;
+   char *sp = NULL;
char buffer[1024];
char info_str[1024];
snprintf(info_str, sizeof(info_str),
@@ -412,8 +414,8 @@ client_handler(void *sock_id)
int bytes = read(s, buffer, sizeof(buffer) - 1);
while (bytes > 0) {
buffer[bytes] = 0;
-   const char *cmd = strtok(buffer, ",");
-   const char *param = strtok(NULL, "\0");
+   const char *cmd = strtok_r(buffer, ",", &sp);
+   const char *param = strtok_r(NULL, "\0", &sp);
struct cmd_callback cb = {.fn = unknown_command};
int i;
 
-- 
2.33.0



[PATCH v6 09/25] eal: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 2054f31a1fcd ("mem: add memseg info in telemetry")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Amit Prakash Shukla 
Acked-by: Morten Brørup 
---
 lib/eal/common/eal_common_memory.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/lib/eal/common/eal_common_memory.c 
b/lib/eal/common/eal_common_memory.c
index a185e0b580c7..ace63313ea75 100644
--- a/lib/eal/common/eal_common_memory.c
+++ b/lib/eal/common/eal_common_memory.c
@@ -1275,22 +1275,22 @@ parse_params(const char *params, uint32_t *vals, size_t 
n_vals)
char dlim[2] = ",";
char *params_args;
size_t count = 0;
-   char *token;
+   char *token, *sp = NULL;
 
if (vals == NULL || params == NULL || strlen(params) == 0)
return -1;
 
-   /* strtok expects char * and param is const char *. Hence on using
+   /* strtok_r expects char * and param is const char *. Hence on using
 * params as "const char *" compiler throws warning.
 */
params_args = strdup(params);
if (params_args == NULL)
return -1;
 
-   token = strtok(params_args, dlim);
+   token = strtok_r(params_args, dlim, &sp);
while (token && isdigit(*token) && count < n_vals) {
vals[count++] = strtoul(token, NULL, 10);
-   token = strtok(NULL, dlim);
+   token = strtok_r(NULL, dlim, &sp);
}
 
free(params_args);
-- 
2.33.0



[PATCH v6 12/25] security: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 259ca6d1617f ("security: add telemetry endpoint for capabilities")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Morten Brørup 
---
 lib/security/rte_security.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/lib/security/rte_security.c b/lib/security/rte_security.c
index e5c862f5f570..669888ef0807 100644
--- a/lib/security/rte_security.c
+++ b/lib/security/rte_security.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "rte_security.h"
 #include "rte_security_driver.h"
 
@@ -497,13 +498,14 @@ security_handle_cryptodev_crypto_caps(const char *cmd 
__rte_unused, const char *
int dev_id, capa_id;
int crypto_caps_n;
char *end_param;
+   char *sp = NULL;
int rc;
 
if (!params || strlen(params) == 0 || !isdigit(*params))
return -EINVAL;
 
dev_id = strtoul(params, &end_param, 0);
-   capa_param = strtok(end_param, ",");
+   capa_param = strtok_r(end_param, ",", &sp);
if (!capa_param || strlen(capa_param) == 0 || !isdigit(*capa_param))
return -EINVAL;
 
-- 
2.33.0



[PATCH v6 23/25] examples/vhost: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 53d3f4778c1d ("vhost: integrate dmadev in asynchronous data-path")

Signed-off-by: Jie Hai 
---
 examples/vhost/main.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/examples/vhost/main.c b/examples/vhost/main.c
index 4391d88c3d15..0fbb11b1d4f4 100644
--- a/examples/vhost/main.c
+++ b/examples/vhost/main.c
@@ -29,6 +29,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "main.h"
 
@@ -259,6 +260,7 @@ open_dma(const char *value)
uint16_t i = 0;
char *dma_arg[RTE_MAX_VHOST_DEVICE];
int args_nr;
+   char *sp = NULL;
 
if (input == NULL)
return -1;
@@ -272,7 +274,7 @@ open_dma(const char *value)
 
/* process DMA devices within bracket. */
addrs++;
-   substr = strtok(addrs, ";]");
+   substr = strtok_r(addrs, ";]", &sp);
if (!substr) {
ret = -1;
goto out;
-- 
2.33.0



[PATCH v6 17/25] net/ark: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 9c7188a68d7b ("net/ark: provide API for hardware modules pktchkr and 
pktgen")
Cc: sta...@dpdk.org

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Morten Brørup 
---
 drivers/net/ark/ark_pktchkr.c | 11 ++-
 drivers/net/ark/ark_pktgen.c  | 11 ++-
 2 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ark/ark_pktchkr.c b/drivers/net/ark/ark_pktchkr.c
index e1f336c73c2a..2bb3dd7b5f36 100644
--- a/drivers/net/ark/ark_pktchkr.c
+++ b/drivers/net/ark/ark_pktchkr.c
@@ -7,6 +7,7 @@
 
 #include 
 #include 
+#include 
 
 #include "ark_pktchkr.h"
 #include "ark_logs.h"
@@ -359,14 +360,14 @@ set_arg(char *arg, char *val)
 void
 ark_pktchkr_parse(char *args)
 {
-   char *argv, *v;
+   char *argv, *v, *sp = NULL;
const char toks[] = "=\n\t\v\f \r";
-   argv = strtok(args, toks);
-   v = strtok(NULL, toks);
+   argv = strtok_r(args, toks, &sp);
+   v = strtok_r(NULL, toks, &sp);
while (argv && v) {
set_arg(argv, v);
-   argv = strtok(NULL, toks);
-   v = strtok(NULL, toks);
+   argv = strtok_r(NULL, toks, &sp);
+   v = strtok_r(NULL, toks, &sp);
}
 }
 
diff --git a/drivers/net/ark/ark_pktgen.c b/drivers/net/ark/ark_pktgen.c
index 69ff7072b2ab..4765b8f0992a 100644
--- a/drivers/net/ark/ark_pktgen.c
+++ b/drivers/net/ark/ark_pktgen.c
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "ark_pktgen.h"
 #include "ark_logs.h"
@@ -340,14 +341,14 @@ pmd_set_arg(char *arg, char *val)
 void
 ark_pktgen_parse(char *args)
 {
-   char *argv, *v;
+   char *argv, *v, *sp = NULL;
const char toks[] = " =\n\t\v\f \r";
-   argv = strtok(args, toks);
-   v = strtok(NULL, toks);
+   argv = strtok_r(args, toks, &sp);
+   v = strtok_r(NULL, toks, &sp);
while (argv && v) {
pmd_set_arg(argv, v);
-   argv = strtok(NULL, toks);
-   v = strtok(NULL, toks);
+   argv = strtok_r(NULL, toks, &sp);
+   v = strtok_r(NULL, toks, &sp);
}
 }
 
-- 
2.33.0



[PATCH v6 19/25] net/cnxk: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: c8f91985331c ("raw/cnxk_gpio: replace strtok with reentrant version")
Cc: sta...@dpdk.org

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
---
 drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c 
b/drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c
index 86c2453c0983..0b766be11a17 100644
--- a/drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c
+++ b/drivers/net/cnxk/cnxk_ethdev_sec_telemetry.c
@@ -5,6 +5,7 @@
 #include 
 
 #include 
+#include 
 
 #include 
 
@@ -214,6 +215,7 @@ parse_params(const char *params, uint32_t *vals, size_t 
n_vals)
char dlim[2] = ",";
char *params_args;
size_t count = 0;
+   char *sp = NULL;
char *token;
 
if (vals == NULL || params == NULL || strlen(params) == 0)
@@ -226,10 +228,10 @@ parse_params(const char *params, uint32_t *vals, size_t 
n_vals)
if (params_args == NULL)
return -1;
 
-   token = strtok(params_args, dlim);
+   token = strtok_r(params_args, dlim, &sp);
while (token && isdigit(*token) && count < n_vals) {
vals[count++] = strtoul(token, NULL, 10);
-   token = strtok(NULL, dlim);
+   token = strtok_r(NULL, dlim, &sp);
}
 
free(params_args);
-- 
2.33.0



[PATCH v6 18/25] raw/cnxk_gpio: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: ecc0dd455e9a ("raw/cnxk_gpio: add option to select subset of GPIOs")
Cc: sta...@dpdk.org

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Morten Brørup 
---
 drivers/raw/cnxk_gpio/cnxk_gpio.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/drivers/raw/cnxk_gpio/cnxk_gpio.c 
b/drivers/raw/cnxk_gpio/cnxk_gpio.c
index 329ac28a2736..e6408db824de 100644
--- a/drivers/raw/cnxk_gpio/cnxk_gpio.c
+++ b/drivers/raw/cnxk_gpio/cnxk_gpio.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 
@@ -192,7 +193,7 @@ static int
 cnxk_gpio_parse_allowlist(struct cnxk_gpiochip *gpiochip, char *allowlist)
 {
int i, ret, val, queue = 0;
-   char *token;
+   char *token, *sp = NULL;
int *list;
 
list = rte_calloc(NULL, gpiochip->num_gpios, sizeof(*list), 0);
@@ -210,7 +211,7 @@ cnxk_gpio_parse_allowlist(struct cnxk_gpiochip *gpiochip, 
char *allowlist)
allowlist[strlen(allowlist) - 1] = ' ';
 
/* quiesce -Wcast-qual */
-   token = strtok((char *)(uintptr_t)allowlist, ",");
+   token = strtok_r((char *)(uintptr_t)allowlist, ",", &sp);
do {
errno = 0;
val = strtol(token, NULL, 10);
@@ -236,7 +237,7 @@ cnxk_gpio_parse_allowlist(struct cnxk_gpiochip *gpiochip, 
char *allowlist)
}
if (i == queue)
list[queue++] = val;
-   } while ((token = strtok(NULL, ",")));
+   } while ((token = strtok_r(NULL, ",", &sp)));
 
free(allowlist);
gpiochip->allowlist = list;
-- 
2.33.0



[PATCH v6 20/25] common/qat: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 99ab2806687b ("common/qat: isolate parser arguments configuration")

Signed-off-by: Jie Hai 
---
 drivers/common/qat/qat_device.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/common/qat/qat_device.c b/drivers/common/qat/qat_device.c
index bca88fd9bded..99153775d883 100644
--- a/drivers/common/qat/qat_device.c
+++ b/drivers/common/qat/qat_device.c
@@ -4,6 +4,7 @@
 
 #include 
 #include 
+#include 
 #include 
 
 #include "qat_device.h"
@@ -222,6 +223,7 @@ qat_dev_parse_command_line(struct qat_pci_device *qat_dev,
 {
int len = 0;
char *token = NULL;
+   char *sp = NULL;
 
if (!devargs)
return 0;
@@ -236,14 +238,14 @@ qat_dev_parse_command_line(struct qat_pci_device *qat_dev,
return -1;
}
strcpy(qat_dev->command_line, devargs->drv_str);
-   token = strtok(qat_dev->command_line, ",");
+   token = strtok_r(qat_dev->command_line, ",", &sp);
while (token != NULL) {
if (!cmdline_validate(token)) {
QAT_LOG(ERR, "Incorrect command line argument: %s",
token);
return -1;
}
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
}
/* Copy once againe the entire string, strtok already altered the 
contents */
strcpy(qat_dev->command_line, devargs->drv_str);
-- 
2.33.0



[PATCH v6 24/25] devtools: check for some reentrant function

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

This patch adds check in checkpatches.sh for strtok, which is
non-reentrant.

Cc: sta...@dpdk.org

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Morten Brørup 
---
 devtools/checkpatches.sh | 8 
 1 file changed, 8 insertions(+)

diff --git a/devtools/checkpatches.sh b/devtools/checkpatches.sh
index 4a8591be225e..80fe41604427 100755
--- a/devtools/checkpatches.sh
+++ b/devtools/checkpatches.sh
@@ -145,6 +145,14 @@ check_forbidden_additions() { # 
-f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
"$1" || res=1
 
+   # refrain from using some non-reentrant functions
+   awk -v FOLDERS="lib drivers app examples" \
+   -v EXPRESSIONS="strtok\\\(" \
+   -v RET_ON_FAIL=1 \
+   -v MESSAGE='Using non-reentrant function strtok, prefer 
strtok_r' \
+   -f $(dirname $(readlink -f $0))/check-forbidden-tokens.awk \
+   "$1" || res=1
+
# refrain from using some pthread functions
awk -v FOLDERS="lib drivers app examples" \
-v 
EXPRESSIONS="pthread_(create|join|detach|set(_?name_np|affinity_np)|attr_set(inheritsched|schedpolicy))\\\("
 \
-- 
2.33.0



[PATCH v6 21/25] net/mlx5: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 0683c002f7f5 ("net/mlx5: add testpmd commands for GENEVE TLV parser")

Signed-off-by: Jie Hai 
---
 drivers/net/mlx5/mlx5_testpmd.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/mlx5/mlx5_testpmd.c b/drivers/net/mlx5/mlx5_testpmd.c
index 1bb5a89559fe..7bd220fafa46 100644
--- a/drivers/net/mlx5/mlx5_testpmd.c
+++ b/drivers/net/mlx5/mlx5_testpmd.c
@@ -353,6 +353,7 @@ mlx5_test_parse_geneve_option_data(const char *buff, 
uint8_t data_len,
   rte_be32_t **match_data_mask)
 {
rte_be32_t *data;
+   char *sp = NULL;
char *buff2;
char *token;
uint8_t i = 0;
@@ -377,7 +378,7 @@ mlx5_test_parse_geneve_option_data(const char *buff, 
uint8_t data_len,
return -ENOMEM;
}
 
-   token = strtok(buff2, SPACE_DELIMITER);
+   token = strtok_r(buff2, SPACE_DELIMITER, &sp);
while (token != NULL) {
if (i == data_len) {
TESTPMD_LOG(ERR,
@@ -393,7 +394,7 @@ mlx5_test_parse_geneve_option_data(const char *buff, 
uint8_t data_len,
else
data[i] = 0x0;
 
-   token = strtok(NULL, SPACE_DELIMITER);
+   token = strtok_r(NULL, SPACE_DELIMITER, &sp);
i++;
}
 
-- 
2.33.0



[PATCH v6 22/25] examples/l2fwd-crypto: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: 1df9c0109f4c ("examples/l2fwd-crypto: parse key parameters")

Signed-off-by: Jie Hai 
---
 examples/l2fwd-crypto/main.c | 7 ---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/examples/l2fwd-crypto/main.c b/examples/l2fwd-crypto/main.c
index a441312f5524..7128bd2e72cf 100644
--- a/examples/l2fwd-crypto/main.c
+++ b/examples/l2fwd-crypto/main.c
@@ -43,6 +43,7 @@
 #include 
 #include 
 #include 
+#include 
 #ifdef RTE_CRYPTO_SCHEDULER
 #include 
 #endif
@@ -1105,12 +1106,12 @@ static int
 parse_bytes(uint8_t *data, char *input_arg, uint16_t max_size)
 {
unsigned byte_count;
-   char *token;
+   char *token, *sp = NULL;
 
errno = 0;
-   for (byte_count = 0, token = strtok(input_arg, ":");
+   for (byte_count = 0, token = strtok_r(input_arg, ":", &sp);
(byte_count < max_size) && (token != NULL);
-   token = strtok(NULL, ":")) {
+   token = strtok_r(NULL, ":", &sp)) {
 
int number = (int)strtol(token, NULL, 16);
 
-- 
2.33.0



[PATCH v6 25/25] eal/linux: install rte_os_shim.h file

2024-11-22 Thread Jie Hai
L2fwd examples fails to be compiled because it includes
rte_os_shim.h file but cannot find it. The missing file
is not installed, install it. See [1] for more details.

[1] https://mails.dpdk.org/archives/test-report/2024-November/822571.html

Signed-off-by: Jie Hai 
---
 lib/eal/linux/include/meson.build | 1 +
 1 file changed, 1 insertion(+)

diff --git a/lib/eal/linux/include/meson.build 
b/lib/eal/linux/include/meson.build
index 7d18dd52f1c5..3f2517a24952 100644
--- a/lib/eal/linux/include/meson.build
+++ b/lib/eal/linux/include/meson.build
@@ -5,4 +5,5 @@ includes += include_directories('.')
 
 headers += files(
 'rte_os.h',
+'rte_os_shim.h',
 )
-- 
2.33.0



[PATCH v6 03/25] app/crypto-perf: replace strtok with reentrant version

2024-11-22 Thread Jie Hai
Multiple threads calling the same function may cause condition
race issues, which often leads to abnormal behavior and can cause
more serious vulnerabilities such as abnormal termination, denial
of service, and compromised data integrity.

The strtok() is non-reentrant, it is better to replace it with a
reentrant version.

Fixes: f6cefe253cc8 ("app/crypto-perf: add range/list of sizes")
Fixes: f8be1786b1b8 ("app/crypto-perf: introduce performance test application")

Signed-off-by: Jie Hai 
Acked-by: Chengwen Feng 
Acked-by: Ciara Power 
---
 app/test-crypto-perf/cperf_options_parsing.c| 17 ++---
 .../cperf_test_vector_parsing.c | 11 +++
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/app/test-crypto-perf/cperf_options_parsing.c 
b/app/test-crypto-perf/cperf_options_parsing.c
index 8abee2d68826..07130e2c27f7 100644
--- a/app/test-crypto-perf/cperf_options_parsing.c
+++ b/app/test-crypto-perf/cperf_options_parsing.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include "cperf_options.h"
 #include "cperf_test_common.h"
@@ -166,6 +167,7 @@ parse_range(const char *arg, uint32_t *min, uint32_t *max, 
uint32_t *inc)
 {
char *token;
uint32_t number;
+   char *sp = NULL;
 
char *copy_arg = strdup(arg);
 
@@ -173,7 +175,7 @@ parse_range(const char *arg, uint32_t *min, uint32_t *max, 
uint32_t *inc)
return -1;
 
errno = 0;
-   token = strtok(copy_arg, ":");
+   token = strtok_r(copy_arg, ":", &sp);
 
/* Parse minimum value */
if (token != NULL) {
@@ -187,7 +189,7 @@ parse_range(const char *arg, uint32_t *min, uint32_t *max, 
uint32_t *inc)
} else
goto err_range;
 
-   token = strtok(NULL, ":");
+   token = strtok_r(NULL, ":", &sp);
 
/* Parse increment value */
if (token != NULL) {
@@ -201,7 +203,7 @@ parse_range(const char *arg, uint32_t *min, uint32_t *max, 
uint32_t *inc)
} else
goto err_range;
 
-   token = strtok(NULL, ":");
+   token = strtok_r(NULL, ":", &sp);
 
/* Parse maximum value */
if (token != NULL) {
@@ -216,7 +218,7 @@ parse_range(const char *arg, uint32_t *min, uint32_t *max, 
uint32_t *inc)
} else
goto err_range;
 
-   if (strtok(NULL, ":") != NULL)
+   if (strtok_r(NULL, ":", &sp) != NULL)
goto err_range;
 
free(copy_arg);
@@ -235,6 +237,7 @@ parse_list(const char *arg, uint32_t *list, uint32_t *min, 
uint32_t *max)
uint8_t count = 0;
uint32_t temp_min;
uint32_t temp_max;
+   char *sp = NULL;
 
char *copy_arg = strdup(arg);
 
@@ -242,7 +245,7 @@ parse_list(const char *arg, uint32_t *list, uint32_t *min, 
uint32_t *max)
return -1;
 
errno = 0;
-   token = strtok(copy_arg, ",");
+   token = strtok_r(copy_arg, ",", &sp);
 
/* Parse first value */
if (token != NULL) {
@@ -258,7 +261,7 @@ parse_list(const char *arg, uint32_t *list, uint32_t *min, 
uint32_t *max)
} else
goto err_list;
 
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
 
while (token != NULL) {
if (count == MAX_LIST) {
@@ -280,7 +283,7 @@ parse_list(const char *arg, uint32_t *list, uint32_t *min, 
uint32_t *max)
if (number > temp_max)
temp_max = number;
 
-   token = strtok(NULL, ",");
+   token = strtok_r(NULL, ",", &sp);
}
 
if (min)
diff --git a/app/test-crypto-perf/cperf_test_vector_parsing.c 
b/app/test-crypto-perf/cperf_test_vector_parsing.c
index 737d61d4af6b..b1cc1ef3c91d 100644
--- a/app/test-crypto-perf/cperf_test_vector_parsing.c
+++ b/app/test-crypto-perf/cperf_test_vector_parsing.c
@@ -9,6 +9,7 @@
 #include 
 
 #include 
+#include 
 
 #include "cperf_options.h"
 #include "cperf_test_vectors.h"
@@ -220,8 +221,9 @@ parse_values(char *tokens, uint8_t **data, uint32_t 
*data_length)
 
uint8_t *values, *values_resized;
char *tok, *error = NULL;
+   char *sp = NULL;
 
-   tok = strtok(tokens, CPERF_VALUE_DELIMITER);
+   tok = strtok_r(tokens, CPERF_VALUE_DELIMITER, &sp);
if (tok == NULL)
return -1;
 
@@ -252,7 +254,7 @@ parse_values(char *tokens, uint8_t **data, uint32_t 
*data_length)
return -1;
}
 
-   tok = strtok(NULL, CPERF_VALUE_DELIMITER);
+   tok = strtok_r(NULL, CPERF_VALUE_DELIMITER, &sp);
if (tok == NULL)
break;
 
@@ -283,6 +285,7 @@ parse_entry(char *entry, struct cperf_test_vector *vector,
 
uint8_t *data = NULL;
char *token, *key_token;
+   char *sp = NULL;
 
if (entry == NULL) {
printf("Expected entry value\n");
@@ -290,10 +293,10 @@ parse_entry(char *entry, struct cperf_test_vector *vec

Re: [PATCH v3] doc: add security document

2024-11-22 Thread Hemant Agrawal



On 20-11-2024 08:42, Nandini Persad wrote:

This is a new document covering security protocols
implemented in DPDK.

Signed-off-by: Nandini Persad 
Signed-off-by: Thomas Monjalon 
Reviewed-by: Stephen Hemminger 
---
  doc/guides/index.rst  |   1 +
  doc/guides/security/index.rst | 336 ++
  2 files changed, 337 insertions(+)
  create mode 100644 doc/guides/security/index.rst



Reviewed-by:  Hemant Agrawal 




[RFC PATCH 21/21] net/ixgbe: use common Tx backlog entry fn

2024-11-22 Thread Bruce Richardson
Remove the custom vector Tx backlog entry function and use the standard
"ieth" one, now that all vector drivers are using the same, smaller ring
structure.

Signed-off-by: Bruce Richardson 
---
 drivers/net/ixgbe/ixgbe_rxtx_vec_common.h | 10 --
 drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c   |  4 ++--
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c|  4 ++--
 3 files changed, 4 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h 
b/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h
index 3064b92533..91828e2c54 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h
@@ -68,16 +68,6 @@ ixgbe_tx_free_bufs(struct ieth_tx_queue *txq)
return txq->tx_rs_thresh;
 }
 
-static __rte_always_inline void
-tx_backlog_entry(struct ieth_vec_tx_entry *txep,
-struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
-   int i;
-
-   for (i = 0; i < (int)nb_pkts; ++i)
-   txep[i].mbuf = tx_pkts[i];
-}
-
 static inline void
 _ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue *rxq)
 {
diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c 
b/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c
index 2336a86dd2..021e14565d 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c
@@ -597,7 +597,7 @@ ixgbe_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
n = (uint16_t)(txq->nb_tx_desc - tx_id);
if (nb_commit >= n) {
-   tx_backlog_entry(txep, tx_pkts, n);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, n);
 
for (i = 0; i < n - 1; ++i, ++tx_pkts, ++txdp)
vtx1(txdp, *tx_pkts, flags);
@@ -614,7 +614,7 @@ ixgbe_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf 
**tx_pkts,
txep = &txq->sw_ring_v[tx_id];
}
 
-   tx_backlog_entry(txep, tx_pkts, nb_commit);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, nb_commit);
 
vtx(txdp, tx_pkts, nb_commit, flags);
 
diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c 
b/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c
index 9707dd80eb..5209c21af7 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c
@@ -720,7 +720,7 @@ ixgbe_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf 
**tx_pkts,
n = (uint16_t)(txq->nb_tx_desc - tx_id);
if (nb_commit >= n) {
 
-   tx_backlog_entry(txep, tx_pkts, n);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, n);
 
for (i = 0; i < n - 1; ++i, ++tx_pkts, ++txdp)
vtx1(txdp, *tx_pkts, flags);
@@ -737,7 +737,7 @@ ixgbe_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf 
**tx_pkts,
txep = &txq->sw_ring_v[tx_id];
}
 
-   tx_backlog_entry(txep, tx_pkts, nb_commit);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, nb_commit);
 
vtx(txdp, tx_pkts, nb_commit, flags);
 
-- 
2.43.0



[RFC PATCH 20/21] net/iavf: use vector SW ring for all vector paths

2024-11-22 Thread Bruce Richardson
The AVX-512 code path used a smaller SW ring structure only containing
the mbuf pointer, but no other fields. The other fields are only used in
the scalar code path, so update all vector driver code paths (AVX2, SSE)
to use the smaller, faster structure.

Signed-off-by: Bruce Richardson 
---
 drivers/net/iavf/iavf_rxtx.c|  7 ---
 drivers/net/iavf/iavf_rxtx_vec_avx2.c   | 12 ++--
 drivers/net/iavf/iavf_rxtx_vec_avx512.c |  8 
 drivers/net/iavf/iavf_rxtx_vec_common.h |  6 --
 drivers/net/iavf/iavf_rxtx_vec_sse.c| 14 +++---
 5 files changed, 13 insertions(+), 34 deletions(-)

diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index c574b23f34..869fce00eb 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -4193,14 +4193,7 @@ iavf_set_tx_function(struct rte_eth_dev *dev)
txq = dev->data->tx_queues[i];
if (!txq)
continue;
-#ifdef CC_AVX512_SUPPORT
-   if (use_avx512)
-   iavf_txq_vec_setup_avx512(txq);
-   else
-   iavf_txq_vec_setup(txq);
-#else
iavf_txq_vec_setup(txq);
-#endif
}
 
if (no_poll_on_link_down) {
diff --git a/drivers/net/iavf/iavf_rxtx_vec_avx2.c 
b/drivers/net/iavf/iavf_rxtx_vec_avx2.c
index 25dc339303..e0c7146c9b 100644
--- a/drivers/net/iavf/iavf_rxtx_vec_avx2.c
+++ b/drivers/net/iavf/iavf_rxtx_vec_avx2.c
@@ -1736,14 +1736,14 @@ iavf_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
 {
struct ieth_tx_queue *txq = (struct ieth_tx_queue *)tx_queue;
volatile struct iavf_tx_desc *txdp;
-   struct ieth_tx_entry *txep;
+   struct ieth_vec_tx_entry *txep;
uint16_t n, nb_commit, tx_id;
/* bit2 is reserved and must be set to 1 according to Spec */
uint64_t flags = IAVF_TX_DESC_CMD_EOP | IAVF_TX_DESC_CMD_ICRC;
uint64_t rs = IAVF_TX_DESC_CMD_RS | flags;
 
if (txq->nb_tx_free < txq->tx_free_thresh)
-   iavf_tx_free_bufs(txq);
+   ieth_tx_free_bufs_vector(txq, iavf_tx_desc_done, false);
 
nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_tx_free, nb_pkts);
if (unlikely(nb_pkts == 0))
@@ -1751,13 +1751,13 @@ iavf_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
 
tx_id = txq->tx_tail;
txdp = &txq->iavf_tx_ring[tx_id];
-   txep = &txq->sw_ring[tx_id];
+   txep = &txq->sw_ring_v[tx_id];
 
txq->nb_tx_free = (uint16_t)(txq->nb_tx_free - nb_pkts);
 
n = (uint16_t)(txq->nb_tx_desc - tx_id);
if (nb_commit >= n) {
-   ieth_tx_backlog_entry(txep, tx_pkts, n);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, n);
 
iavf_vtx(txdp, tx_pkts, n - 1, flags, offload);
tx_pkts += (n - 1);
@@ -1772,10 +1772,10 @@ iavf_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
 
/* avoid reach the end of ring */
txdp = &txq->iavf_tx_ring[tx_id];
-   txep = &txq->sw_ring[tx_id];
+   txep = &txq->sw_ring_v[tx_id];
}
 
-   ieth_tx_backlog_entry(txep, tx_pkts, nb_commit);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, nb_commit);
 
iavf_vtx(txdp, tx_pkts, nb_commit, flags, offload);
 
diff --git a/drivers/net/iavf/iavf_rxtx_vec_avx512.c 
b/drivers/net/iavf/iavf_rxtx_vec_avx512.c
index 16cfd6a5b3..bda5fb3b22 100644
--- a/drivers/net/iavf/iavf_rxtx_vec_avx512.c
+++ b/drivers/net/iavf/iavf_rxtx_vec_avx512.c
@@ -2356,14 +2356,6 @@ iavf_xmit_pkts_vec_avx512(void *tx_queue, struct 
rte_mbuf **tx_pkts,
return iavf_xmit_pkts_vec_avx512_cmn(tx_queue, tx_pkts, nb_pkts, false);
 }
 
-int __rte_cold
-iavf_txq_vec_setup_avx512(struct ieth_tx_queue *txq)
-{
-   txq->vector_tx = true;
-   txq->vector_sw_ring = true;
-   return 0;
-}
-
 uint16_t
 iavf_xmit_pkts_vec_avx512_offload(void *tx_queue, struct rte_mbuf **tx_pkts,
  uint16_t nb_pkts)
diff --git a/drivers/net/iavf/iavf_rxtx_vec_common.h 
b/drivers/net/iavf/iavf_rxtx_vec_common.h
index 20d8262e7f..14569e9e3b 100644
--- a/drivers/net/iavf/iavf_rxtx_vec_common.h
+++ b/drivers/net/iavf/iavf_rxtx_vec_common.h
@@ -24,12 +24,6 @@ iavf_tx_desc_done(struct ieth_tx_queue *txq, uint16_t idx)
rte_cpu_to_le_64(IAVF_TX_DESC_DTYPE_DESC_DONE);
 }
 
-static __rte_always_inline int
-iavf_tx_free_bufs(struct ieth_tx_queue *txq)
-{
-   return ieth_tx_free_bufs(txq, iavf_tx_desc_done);
-}
-
 static inline void
 _iavf_rx_queue_release_mbufs_vec(struct iavf_rx_queue *rxq)
 {
diff --git a/drivers/net/iavf/iavf_rxtx_vec_sse.c 
b/drivers/net/iavf/iavf_rxtx_vec_sse.c
index 21ad685ff1..89f4a22271 100644
--- a/drivers/net/iavf/iavf_rxtx_vec_sse.c
+++ b/drivers/net/iavf/iavf_rxtx_vec_

[RFC PATCH 18/21] net/ice: use vector SW ring for all vector paths

2024-11-22 Thread Bruce Richardson
The AVX-512 code path used a smaller SW ring structure only containing
the mbuf pointer, but no other fields. The other fields are only used in
the scalar code path, so update all vector driver code paths to use the
smaller, faster structure.

Signed-off-by: Bruce Richardson 
---
 drivers/common/intel_eth/ieth_rxtx_vec_common.h |  7 +++
 drivers/net/ice/ice_rxtx.c  |  2 +-
 drivers/net/ice/ice_rxtx_vec_avx2.c | 12 ++--
 drivers/net/ice/ice_rxtx_vec_avx512.c   | 14 ++
 drivers/net/ice/ice_rxtx_vec_common.h   |  6 --
 drivers/net/ice/ice_rxtx_vec_sse.c  | 12 ++--
 6 files changed, 22 insertions(+), 31 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx_vec_common.h 
b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
index a4490f2dca..c8ac788f98 100644
--- a/drivers/common/intel_eth/ieth_rxtx_vec_common.h
+++ b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
@@ -87,6 +87,13 @@ ieth_tx_backlog_entry(struct ieth_tx_entry *txep, struct 
rte_mbuf **tx_pkts, uin
txep[i].mbuf = tx_pkts[i];
 }
 
+static __rte_always_inline void
+ieth_tx_backlog_entry_vec(struct ieth_vec_tx_entry *txep, struct rte_mbuf 
**tx_pkts, uint16_t nb_pkts)
+{
+   for (uint16_t i = 0; i < (int)nb_pkts; ++i)
+   txep[i].mbuf = tx_pkts[i];
+}
+
 #define IETH_VPMD_TX_MAX_FREE_BUF 64
 
 typedef int (*ieth_desc_done_fn)(struct ieth_tx_queue *txq, uint16_t idx);
diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c
index 5e58314b57..127bc604f0 100644
--- a/drivers/net/ice/ice_rxtx.c
+++ b/drivers/net/ice/ice_rxtx.c
@@ -825,7 +825,7 @@ ice_tx_queue_start(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
 
/* record what kind of descriptor cleanup we need on teardown */
txq->vector_tx = ad->tx_vec_allowed;
-   txq->vector_sw_ring = ad->tx_use_avx512;
+   txq->vector_sw_ring = txq->vector_tx;
 
dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED;
 
diff --git a/drivers/net/ice/ice_rxtx_vec_avx2.c 
b/drivers/net/ice/ice_rxtx_vec_avx2.c
index 370871c320..7799d631f8 100644
--- a/drivers/net/ice/ice_rxtx_vec_avx2.c
+++ b/drivers/net/ice/ice_rxtx_vec_avx2.c
@@ -858,7 +858,7 @@ ice_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
 {
struct ieth_tx_queue *txq = (struct ieth_tx_queue *)tx_queue;
volatile struct ice_tx_desc *txdp;
-   struct ieth_tx_entry *txep;
+   struct ieth_vec_tx_entry *txep;
uint16_t n, nb_commit, tx_id;
uint64_t flags = ICE_TD_CMD;
uint64_t rs = ICE_TX_DESC_CMD_RS | ICE_TD_CMD;
@@ -867,7 +867,7 @@ ice_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
nb_pkts = RTE_MIN(nb_pkts, txq->tx_rs_thresh);
 
if (txq->nb_tx_free < txq->tx_free_thresh)
-   ice_tx_free_bufs_vec(txq);
+   ieth_tx_free_bufs_vector(txq, ice_tx_desc_done, false);
 
nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_tx_free, nb_pkts);
if (unlikely(nb_pkts == 0))
@@ -875,13 +875,13 @@ ice_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
 
tx_id = txq->tx_tail;
txdp = &txq->ice_tx_ring[tx_id];
-   txep = &txq->sw_ring[tx_id];
+   txep = &txq->sw_ring_v[tx_id];
 
txq->nb_tx_free = (uint16_t)(txq->nb_tx_free - nb_pkts);
 
n = (uint16_t)(txq->nb_tx_desc - tx_id);
if (nb_commit >= n) {
-   ieth_tx_backlog_entry(txep, tx_pkts, n);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, n);
 
ice_vtx(txdp, tx_pkts, n - 1, flags, offload);
tx_pkts += (n - 1);
@@ -896,10 +896,10 @@ ice_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
 
/* avoid reach the end of ring */
txdp = &txq->ice_tx_ring[tx_id];
-   txep = &txq->sw_ring[tx_id];
+   txep = &txq->sw_ring_v[tx_id];
}
 
-   ieth_tx_backlog_entry(txep, tx_pkts, nb_commit);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, nb_commit);
 
ice_vtx(txdp, tx_pkts, nb_commit, flags, offload);
 
diff --git a/drivers/net/ice/ice_rxtx_vec_avx512.c 
b/drivers/net/ice/ice_rxtx_vec_avx512.c
index c3cbd601b3..6c2c76f6fc 100644
--- a/drivers/net/ice/ice_rxtx_vec_avx512.c
+++ b/drivers/net/ice/ice_rxtx_vec_avx512.c
@@ -924,16 +924,6 @@ ice_vtx(volatile struct ice_tx_desc *txdp, struct rte_mbuf 
**pkt,
}
 }
 
-static __rte_always_inline void
-ice_tx_backlog_entry_avx512(struct ieth_vec_tx_entry *txep,
-   struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
-   int i;
-
-   for (i = 0; i < (int)nb_pkts; ++i)
-   txep[i].mbuf = tx_pkts[i];
-}
-
 static __rte_always_inline uint16_t
 ice_xmit_fixed_burst_vec_avx512(void *tx_queue, struct rte_mbuf **tx_pkts,
uint16_t nb_pkts, bool do_offload)
@@ -964,7 +954,7 @@ ice_xmit_fixed_burst

[RFC PATCH 17/21] net/iavf: use common Tx queue mbuf cleanup fn

2024-11-22 Thread Bruce Richardson
Adjust iavf driver to also use the common mbuf freeing functions on Tx
queue release/cleanup. The implementation is complicated a little by the
need to integrate the additional "has_ctx" parameter for the iavf code,
but changes in other drivers are minimal - just a constant "false"
parameter.

Signed-off-by: Bruce Richardson 
---
 drivers/common/intel_eth/ieth_rxtx.h| 19 +++--
 drivers/net/i40e/i40e_rxtx.c|  6 ++--
 drivers/net/iavf/iavf_rxtx.c| 37 ++---
 drivers/net/iavf/iavf_rxtx_vec_avx512.c | 24 ++--
 drivers/net/iavf/iavf_rxtx_vec_common.h | 18 
 drivers/net/iavf/iavf_rxtx_vec_sse.c|  9 ++
 drivers/net/ice/ice_dcf_ethdev.c|  4 +--
 drivers/net/ice/ice_rxtx.c  |  6 ++--
 drivers/net/ixgbe/ixgbe_rxtx.c  |  6 ++--
 9 files changed, 28 insertions(+), 101 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx.h 
b/drivers/common/intel_eth/ieth_rxtx.h
index c8e5e1ad76..dad1ba4ae1 100644
--- a/drivers/common/intel_eth/ieth_rxtx.h
+++ b/drivers/common/intel_eth/ieth_rxtx.h
@@ -83,7 +83,6 @@ struct ieth_tx_queue {
};
struct { /* iavf driver specific values */
uint16_t ipsec_crypto_pkt_md_offset;
-   uint8_t rel_mbufs_type;
 #define IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG1 BIT(0)
 #define IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2 BIT(1)
uint8_t vlan_flag;
@@ -103,23 +102,23 @@ struct ieth_tx_queue {
};
 };
 
-#define IETH_FREE_BUFS_LOOP(txq, swr, start) do { \
+#define IETH_FREE_BUFS_LOOP(swr, nb_desc, start, end) do { \
uint16_t i = start; \
-   if (txq->tx_tail < i) { \
-   for (; i < txq->nb_tx_desc; i++) { \
+   if (end < i) { \
+   for (; i < nb_desc; i++) { \
rte_pktmbuf_free_seg(swr[i].mbuf); \
swr[i].mbuf = NULL; \
} \
i = 0; \
} \
-   for (; i < txq->tx_tail; i++) { \
+   for (; i < end; i++) { \
rte_pktmbuf_free_seg(swr[i].mbuf); \
swr[i].mbuf = NULL; \
} \
 } while(0)
 
 static inline void
-ieth_txq_release_all_mbufs(struct ieth_tx_queue *txq)
+ieth_txq_release_all_mbufs(struct ieth_tx_queue *txq, bool use_ctx)
 {
if (unlikely(!txq || !txq->sw_ring))
return;
@@ -138,14 +137,16 @@ ieth_txq_release_all_mbufs(struct ieth_tx_queue *txq)
 *  vPMD tx will not set sw_ring's mbuf to NULL after free,
 *  so need to free remains more carefully.
 */
-   const uint16_t start = txq->tx_next_dd - txq->tx_rs_thresh + 1;
+   const uint16_t start = (txq->tx_next_dd - txq->tx_rs_thresh + 1) >> 
use_ctx;
+   const uint16_t nb_desc = txq->nb_tx_desc >> use_ctx;
+   const uint16_t end = txq->tx_tail >> use_ctx;
 
if (txq->vector_sw_ring) {
struct ieth_vec_tx_entry *swr = txq->sw_ring_v;
-   IETH_FREE_BUFS_LOOP(txq, swr, start);
+   IETH_FREE_BUFS_LOOP(swr, nb_desc, start, end);
} else {
struct ieth_tx_entry *swr = txq->sw_ring;
-   IETH_FREE_BUFS_LOOP(txq, swr, start);
+   IETH_FREE_BUFS_LOOP(swr, nb_desc, start, end);
}
 }
 
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 362a71c8b2..4878b9b8aa 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1934,7 +1934,7 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
return err;
}
 
-   ieth_txq_release_all_mbufs(txq);
+   ieth_txq_release_all_mbufs(txq, false);
i40e_reset_tx_queue(txq);
dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
 
@@ -2609,7 +2609,7 @@ i40e_tx_queue_release(void *txq)
return;
}
 
-   ieth_txq_release_all_mbufs(q);
+   ieth_txq_release_all_mbufs(q, false);
rte_free(q->sw_ring);
rte_memzone_free(q->mz);
rte_free(q);
@@ -3072,7 +3072,7 @@ i40e_dev_clear_queues(struct rte_eth_dev *dev)
for (i = 0; i < dev->data->nb_tx_queues; i++) {
if (!dev->data->tx_queues[i])
continue;
-   ieth_txq_release_all_mbufs(dev->data->tx_queues[i]);
+   ieth_txq_release_all_mbufs(dev->data->tx_queues[i], false);
i40e_reset_tx_queue(dev->data->tx_queues[i]);
}
 
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index c0f7d12804..c574b23f34 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -387,24 +387,6 @@ release_rxq_mbufs(struct iavf_rx_queue *rxq)
rxq->rx_nb_avail = 0;
 }
 
-static inline void
-release_txq_mbufs(struct ieth_tx_queue *txq)
-{
-   ui

[RFC PATCH 19/21] net/i40e: use vector SW ring for all vector paths

2024-11-22 Thread Bruce Richardson
The AVX-512 code path used a smaller SW ring structure only containing
the mbuf pointer, but no other fields. The other fields are only used in
the scalar code path, so update all vector driver code paths (AVX2, SSE,
Neon, Altivec) to use the smaller, faster structure.

Signed-off-by: Bruce Richardson 
---
 drivers/net/i40e/i40e_rxtx.c |  8 +---
 drivers/net/i40e/i40e_rxtx_vec_altivec.c | 12 ++--
 drivers/net/i40e/i40e_rxtx_vec_avx2.c| 12 ++--
 drivers/net/i40e/i40e_rxtx_vec_avx512.c  | 14 ++
 drivers/net/i40e/i40e_rxtx_vec_common.h  |  6 --
 drivers/net/i40e/i40e_rxtx_vec_neon.c| 12 ++--
 drivers/net/i40e/i40e_rxtx_vec_sse.c | 12 ++--
 7 files changed, 31 insertions(+), 45 deletions(-)

diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 4878b9b8aa..05f7f380c4 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1892,7 +1892,7 @@ i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
tx_queue_id);
 
txq->vector_tx = ad->tx_vec_allowed;
-   txq->vector_sw_ring = ad->tx_use_avx512;
+   txq->vector_sw_ring = txq->vector_tx;
 
/*
 * tx_queue_id is queue id application refers to, while
@@ -3551,9 +3551,11 @@ i40e_set_tx_function(struct rte_eth_dev *dev)
}
}
 
+   if (rte_vect_get_max_simd_bitwidth() < RTE_VECT_SIMD_128)
+   ad->tx_vec_allowed = false;
+
if (ad->tx_simple_allowed) {
-   if (ad->tx_vec_allowed &&
-   rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
+   if (ad->tx_vec_allowed) {
 #ifdef RTE_ARCH_X86
if (ad->tx_use_avx512) {
 #ifdef CC_AVX512_SUPPORT
diff --git a/drivers/net/i40e/i40e_rxtx_vec_altivec.c 
b/drivers/net/i40e/i40e_rxtx_vec_altivec.c
index 2ab09eb167..7acf44d3fe 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_altivec.c
+++ b/drivers/net/i40e/i40e_rxtx_vec_altivec.c
@@ -553,14 +553,14 @@ i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 {
struct ieth_tx_queue *txq = (struct ieth_tx_queue *)tx_queue;
volatile struct i40e_tx_desc *txdp;
-   struct ieth_tx_entry *txep;
+   struct ieth_vec_tx_entry *txep;
uint16_t n, nb_commit, tx_id;
uint64_t flags = I40E_TD_CMD;
uint64_t rs = I40E_TX_DESC_CMD_RS | I40E_TD_CMD;
int i;
 
if (txq->nb_tx_free < txq->tx_free_thresh)
-   i40e_tx_free_bufs(txq);
+   ieth_tx_free_bufs_vector(txq, i40e_tx_desc_done, false);
 
nb_pkts = (uint16_t)RTE_MIN(txq->nb_tx_free, nb_pkts);
nb_commit = nb_pkts;
@@ -569,13 +569,13 @@ i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
tx_id = txq->tx_tail;
txdp = &txq->i40e_tx_ring[tx_id];
-   txep = &txq->sw_ring[tx_id];
+   txep = &txq->sw_ring_v[tx_id];
 
txq->nb_tx_free = (uint16_t)(txq->nb_tx_free - nb_pkts);
 
n = (uint16_t)(txq->nb_tx_desc - tx_id);
if (nb_commit >= n) {
-   ieth_tx_backlog_entry(txep, tx_pkts, n);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, n);
 
for (i = 0; i < n - 1; ++i, ++tx_pkts, ++txdp)
vtx1(txdp, *tx_pkts, flags);
@@ -589,10 +589,10 @@ i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
/* avoid reach the end of ring */
txdp = &txq->i40e_tx_ring[tx_id];
-   txep = &txq->sw_ring[tx_id];
+   txep = &txq->sw_ring_v[tx_id];
}
 
-   ieth_tx_backlog_entry(txep, tx_pkts, nb_commit);
+   ieth_tx_backlog_entry_vec(txep, tx_pkts, nb_commit);
 
vtx(txdp, tx_pkts, nb_commit, flags);
 
diff --git a/drivers/net/i40e/i40e_rxtx_vec_avx2.c 
b/drivers/net/i40e/i40e_rxtx_vec_avx2.c
index e32fa160bf..8f593378d3 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_avx2.c
+++ b/drivers/net/i40e/i40e_rxtx_vec_avx2.c
@@ -745,13 +745,13 @@ i40e_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
 {
struct ieth_tx_queue *txq = (struct ieth_tx_queue *)tx_queue;
volatile struct i40e_tx_desc *txdp;
-   struct ieth_tx_entry *txep;
+   struct ieth_vec_tx_entry *txep;
uint16_t n, nb_commit, tx_id;
uint64_t flags = I40E_TD_CMD;
uint64_t rs = I40E_TX_DESC_CMD_RS | I40E_TD_CMD;
 
if (txq->nb_tx_free < txq->tx_free_thresh)
-   i40e_tx_free_bufs(txq);
+   ieth_tx_free_bufs_vector(txq, i40e_tx_desc_done, false);
 
nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_tx_free, nb_pkts);
if (unlikely(nb_pkts == 0))
@@ -759,13 +759,13 @@ i40e_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
 
tx_id = txq->tx_tail;
txdp = &txq->i40e_tx_ring[tx_id];
-   txep = &txq->sw_ring[tx_id];
+   txep = &txq->sw_ring_v[tx_id];
 
   

[RFC PATCH 01/21] common/intel_eth: add pkt reassembly fn for intel drivers

2024-11-22 Thread Bruce Richardson
The code for reassembling a single, multi-mbuf packet from multiple
buffers received from the NIC is duplicated across many drivers. Rather
than having multiple copies of this function, we can create an
"intel_eth" common driver to hold such functions and consolidate
multiple functions down to a single one for easier maintenance.

Signed-off-by: Bruce Richardson 
---
 .../common/intel_eth/ieth_rxtx_vec_common.h   | 81 +++
 drivers/net/i40e/i40e_rxtx_vec_altivec.c  |  4 +-
 drivers/net/i40e/i40e_rxtx_vec_avx2.c |  4 +-
 drivers/net/i40e/i40e_rxtx_vec_avx512.c   |  4 +-
 drivers/net/i40e/i40e_rxtx_vec_common.h   | 64 +--
 drivers/net/i40e/i40e_rxtx_vec_neon.c |  4 +-
 drivers/net/i40e/i40e_rxtx_vec_sse.c  |  4 +-
 drivers/net/i40e/meson.build  |  2 +-
 drivers/net/iavf/iavf_rxtx_vec_avx2.c |  8 +-
 drivers/net/iavf/iavf_rxtx_vec_avx512.c   |  8 +-
 drivers/net/iavf/iavf_rxtx_vec_common.h   | 65 +--
 drivers/net/iavf/iavf_rxtx_vec_sse.c  |  8 +-
 drivers/net/iavf/meson.build  |  2 +-
 drivers/net/ice/ice_rxtx_vec_avx2.c   |  4 +-
 drivers/net/ice/ice_rxtx_vec_avx512.c |  8 +-
 drivers/net/ice/ice_rxtx_vec_common.h | 66 +--
 drivers/net/ice/ice_rxtx_vec_sse.c|  4 +-
 drivers/net/ice/meson.build   |  2 +-
 drivers/net/ixgbe/ixgbe_rxtx_vec_common.h | 63 +--
 drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c   |  4 +-
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c|  4 +-
 drivers/net/ixgbe/meson.build |  2 +-
 22 files changed, 123 insertions(+), 292 deletions(-)
 create mode 100644 drivers/common/intel_eth/ieth_rxtx_vec_common.h

diff --git a/drivers/common/intel_eth/ieth_rxtx_vec_common.h 
b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
new file mode 100644
index 00..0771af820c
--- /dev/null
+++ b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Intel Corporation
+ */
+
+#ifndef IETH_RXTX_VEC_COMMON_H_
+#define IETH_RXTX_VEC_COMMON_H_
+
+#include 
+#include 
+#include 
+
+#define IETH_RX_BURST 32
+
+static inline uint16_t
+ieth_rx_reassemble_packets(struct rte_mbuf **rx_bufs,
+ uint16_t nb_bufs, uint8_t *split_flags,
+ struct rte_mbuf **pkt_first_seg,
+ struct rte_mbuf **pkt_last_seg,
+ const uint8_t crc_len)
+{
+   struct rte_mbuf *pkts[IETH_RX_BURST] = {0}; /*finished pkts*/
+   struct rte_mbuf *start = *pkt_first_seg;
+   struct rte_mbuf *end = *pkt_last_seg;
+   unsigned int pkt_idx, buf_idx;
+
+   for (buf_idx = 0, pkt_idx = 0; buf_idx < nb_bufs; buf_idx++) {
+   if (end) {
+   /* processing a split packet */
+   end->next = rx_bufs[buf_idx];
+   rx_bufs[buf_idx]->data_len += crc_len;
+
+   start->nb_segs++;
+   start->pkt_len += rx_bufs[buf_idx]->data_len;
+   end = end->next;
+
+   if (!split_flags[buf_idx]) {
+   /* it's the last packet of the set */
+   start->hash = end->hash;
+   start->vlan_tci = end->vlan_tci;
+   start->ol_flags = end->ol_flags;
+   /* we need to strip crc for the whole packet */
+   start->pkt_len -= crc_len;
+   if (end->data_len > crc_len)
+   end->data_len -= crc_len;
+   else {
+   /* free up last mbuf */
+   struct rte_mbuf *secondlast = start;
+
+   start->nb_segs--;
+   while (secondlast->next != end)
+   secondlast = secondlast->next;
+   secondlast->data_len -= (crc_len - 
end->data_len);
+   secondlast->next = NULL;
+   rte_pktmbuf_free_seg(end);
+   }
+   pkts[pkt_idx++] = start;
+   start = NULL;
+   end = NULL;
+   }
+   } else{
+   /* not processing a split packet */
+   if (!split_flags[buf_idx]) {
+   /* not a split packet, save and skip */
+   pkts[pkt_idx++] = rx_bufs[buf_idx];
+   continue;
+   }
+   start = rx_bufs[buf_idx];
+ 

[RFC PATCH 02/21] common/intel_eth: provide common Tx entry structures

2024-11-22 Thread Bruce Richardson
The Tx entry structures, both vector and scalar, are common across Intel
drivers, so provide a single definition to be used everywhere.

Signed-off-by: Bruce Richardson 
---
 drivers/common/intel_eth/ieth_rxtx.h  | 29 +++
 .../net/i40e/i40e_recycle_mbufs_vec_common.c  |  2 +-
 drivers/net/i40e/i40e_rxtx.c  | 18 ++--
 drivers/net/i40e/i40e_rxtx.h  | 14 ++---
 drivers/net/i40e/i40e_rxtx_vec_altivec.c  |  2 +-
 drivers/net/i40e/i40e_rxtx_vec_avx2.c |  2 +-
 drivers/net/i40e/i40e_rxtx_vec_avx512.c   |  6 ++--
 drivers/net/i40e/i40e_rxtx_vec_common.h   |  4 +--
 drivers/net/i40e/i40e_rxtx_vec_neon.c |  2 +-
 drivers/net/i40e/i40e_rxtx_vec_sse.c  |  2 +-
 drivers/net/iavf/iavf_rxtx.c  | 12 
 drivers/net/iavf/iavf_rxtx.h  | 14 ++---
 drivers/net/iavf/iavf_rxtx_vec_avx2.c |  2 +-
 drivers/net/iavf/iavf_rxtx_vec_avx512.c   | 10 +++
 drivers/net/iavf/iavf_rxtx_vec_common.h   |  4 +--
 drivers/net/iavf/iavf_rxtx_vec_sse.c  |  2 +-
 drivers/net/ice/ice_dcf_ethdev.c  |  2 +-
 drivers/net/ice/ice_rxtx.c| 16 +-
 drivers/net/ice/ice_rxtx.h| 13 ++---
 drivers/net/ice/ice_rxtx_vec_avx2.c   |  2 +-
 drivers/net/ice/ice_rxtx_vec_avx512.c |  6 ++--
 drivers/net/ice/ice_rxtx_vec_common.h |  6 ++--
 drivers/net/ice/ice_rxtx_vec_sse.c|  2 +-
 .../ixgbe/ixgbe_recycle_mbufs_vec_common.c|  2 +-
 drivers/net/ixgbe/ixgbe_rxtx.c| 16 +-
 drivers/net/ixgbe/ixgbe_rxtx.h| 22 +++---
 drivers/net/ixgbe/ixgbe_rxtx_vec_common.h |  8 ++---
 drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c   |  2 +-
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c|  2 +-
 29 files changed, 107 insertions(+), 117 deletions(-)
 create mode 100644 drivers/common/intel_eth/ieth_rxtx.h

diff --git a/drivers/common/intel_eth/ieth_rxtx.h 
b/drivers/common/intel_eth/ieth_rxtx.h
new file mode 100644
index 00..95a3cff048
--- /dev/null
+++ b/drivers/common/intel_eth/ieth_rxtx.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2024 Intel Corporation
+ */
+
+#ifndef IETH_RXTX_H_
+#define IETH_RXTX_H_
+
+#include 
+#include 
+
+/**
+ * Structure associated with each descriptor of the TX ring of a TX queue.
+ */
+struct ieth_tx_entry
+{
+   struct rte_mbuf *mbuf; /* mbuf associated with TX desc, if any. */
+   uint16_t next_id; /* Index of next descriptor in ring. */
+   uint16_t last_id; /* Index of last scattered descriptor. */
+};
+
+/**
+ * Structure associated with each descriptor of the TX ring of a TX queue in 
vector Tx.
+ */
+struct ieth_vec_tx_entry
+{
+   struct rte_mbuf *mbuf; /* mbuf associated with TX desc, if any. */
+};
+
+#endif /* IETH_RXTX_H_ */
diff --git a/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c 
b/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c
index 14424c9921..5a23adc6a4 100644
--- a/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c
+++ b/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c
@@ -56,7 +56,7 @@ i40e_recycle_tx_mbufs_reuse_vec(void *tx_queue,
struct rte_eth_recycle_rxq_info *recycle_rxq_info)
 {
struct i40e_tx_queue *txq = tx_queue;
-   struct i40e_tx_entry *txep;
+   struct ieth_tx_entry *txep;
struct rte_mbuf **rxep;
int i, n;
uint16_t nb_recycle_mbufs;
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 839c8a5442..b628d83a42 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -378,7 +378,7 @@ i40e_build_ctob(uint32_t td_cmd,
 static inline int
 i40e_xmit_cleanup(struct i40e_tx_queue *txq)
 {
-   struct i40e_tx_entry *sw_ring = txq->sw_ring;
+   struct ieth_tx_entry *sw_ring = txq->sw_ring;
volatile struct i40e_tx_desc *txd = txq->tx_ring;
uint16_t last_desc_cleaned = txq->last_desc_cleaned;
uint16_t nb_tx_desc = txq->nb_tx_desc;
@@ -1081,8 +1081,8 @@ uint16_t
 i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
 {
struct i40e_tx_queue *txq;
-   struct i40e_tx_entry *sw_ring;
-   struct i40e_tx_entry *txe, *txn;
+   struct ieth_tx_entry *sw_ring;
+   struct ieth_tx_entry *txe, *txn;
volatile struct i40e_tx_desc *txd;
volatile struct i40e_tx_desc *txr;
struct rte_mbuf *tx_pkt;
@@ -1331,7 +1331,7 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, 
uint16_t nb_pkts)
 static __rte_always_inline int
 i40e_tx_free_bufs(struct i40e_tx_queue *txq)
 {
-   struct i40e_tx_entry *txep;
+   struct ieth_tx_entry *txep;
uint16_t tx_rs_thresh = txq->tx_rs_thresh;
uint16_t i = 0, j = 0;
struct rte_mbuf *free[RTE_I40E_TX_MAX_FREE_BUF_SZ];
@@ -1418,7 +1418,7 @@ i40e_tx_fill_hw_ring(struct i40e_tx_queue *txq,
 uint16_t

[RFC PATCH 00/21] Reduce code duplication across Intel NIC drivers

2024-11-22 Thread Bruce Richardson
This RFC attempts to reduce the amount of code duplication across a
number of Intel NIC drivers, specifically: ixgbe, i40e, iavf, and ice.

The first patch extract a function from the Rx side, otherwise the
majority of the changes are on the Tx side, leading to a converged Tx
queue structure across the 4 drivers, and a large number of common
functions.

Open question:
* How should common code across drivers within a single device class be
  managed?
  - For now, I've created an "intel_eth" folder within the "common"
driver directory, thinking about it after, it  implies to me that
it is common across driver classes.
  - Would it be better to create an "intel_common" directory within the
"net" folder?

Bruce Richardson (21):
  common/intel_eth: add pkt reassembly fn for intel drivers
  common/intel_eth: provide common Tx entry structures
  common/intel_eth: add Tx mbuf ring replenish fn
  drivers/net: align Tx queue struct field names
  drivers/net: add prefix for driver-specific structs
  common/intel_eth: merge ice and i40e Tx queue struct
  net/iavf: use common Tx queue structure
  net/ixgbe: convert Tx queue context cache field to ptr
  net/ixgbe: use common Tx queue structure
  common/intel_eth: pack Tx queue structure
  common/intel_eth: add post-Tx buffer free function
  common/intel_eth: add Tx buffer free fn for AVX-512
  net/iavf: use common Tx free fn for AVX-512
  net/ice: move Tx queue mbuf cleanup fn to common
  net/i40e: use common Tx queue mbuf cleanup fn
  net/ixgbe: use common Tx queue mbuf cleanup fn
  net/iavf: use common Tx queue mbuf cleanup fn
  net/ice: use vector SW ring for all vector paths
  net/i40e: use vector SW ring for all vector paths
  net/iavf: use vector SW ring for all vector paths
  net/ixgbe: use common Tx backlog entry fn

 drivers/common/intel_eth/ieth_rxtx.h  | 153 +++
 .../common/intel_eth/ieth_rxtx_vec_common.h   | 260 ++
 drivers/net/i40e/i40e_ethdev.c|   4 +-
 drivers/net/i40e/i40e_ethdev.h|   8 +-
 drivers/net/i40e/i40e_fdir.c  |  10 +-
 .../net/i40e/i40e_recycle_mbufs_vec_common.c  |   6 +-
 drivers/net/i40e/i40e_rxtx.c  | 194 +
 drivers/net/i40e/i40e_rxtx.h  |  61 +---
 drivers/net/i40e/i40e_rxtx_vec_altivec.c  |  26 +-
 drivers/net/i40e/i40e_rxtx_vec_avx2.c |  26 +-
 drivers/net/i40e/i40e_rxtx_vec_avx512.c   | 144 +-
 drivers/net/i40e/i40e_rxtx_vec_common.h   | 144 +-
 drivers/net/i40e/i40e_rxtx_vec_neon.c |  26 +-
 drivers/net/i40e/i40e_rxtx_vec_sse.c  |  26 +-
 drivers/net/i40e/meson.build  |   2 +-
 drivers/net/iavf/iavf.h   |   2 +-
 drivers/net/iavf/iavf_ethdev.c|   4 +-
 drivers/net/iavf/iavf_rxtx.c  | 180 +---
 drivers/net/iavf/iavf_rxtx.h  |  61 +---
 drivers/net/iavf/iavf_rxtx_vec_avx2.c |  46 ++--
 drivers/net/iavf/iavf_rxtx_vec_avx512.c   | 213 +++---
 drivers/net/iavf/iavf_rxtx_vec_common.h   | 160 +--
 drivers/net/iavf/iavf_rxtx_vec_sse.c  |  57 ++--
 drivers/net/iavf/iavf_vchnl.c |   6 +-
 drivers/net/iavf/meson.build  |   2 +-
 drivers/net/ice/ice_dcf.c |   4 +-
 drivers/net/ice/ice_dcf_ethdev.c  |  21 +-
 drivers/net/ice/ice_diagnose.c|   2 +-
 drivers/net/ice/ice_ethdev.c  |   2 +-
 drivers/net/ice/ice_ethdev.h  |   7 +-
 drivers/net/ice/ice_rxtx.c| 164 +--
 drivers/net/ice/ice_rxtx.h|  52 +---
 drivers/net/ice/ice_rxtx_vec_avx2.c   |  26 +-
 drivers/net/ice/ice_rxtx_vec_avx512.c | 153 +--
 drivers/net/ice/ice_rxtx_vec_common.h | 190 +
 drivers/net/ice/ice_rxtx_vec_sse.c|  30 +-
 drivers/net/ice/meson.build   |   2 +-
 drivers/net/ixgbe/base/ixgbe_osdep.h  |   2 +-
 drivers/net/ixgbe/ixgbe_ethdev.c  |   4 +-
 .../ixgbe/ixgbe_recycle_mbufs_vec_common.c|   6 +-
 drivers/net/ixgbe/ixgbe_rxtx.c| 137 -
 drivers/net/ixgbe/ixgbe_rxtx.h|  73 +
 drivers/net/ixgbe/ixgbe_rxtx_vec_common.h | 119 +---
 drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c   |  33 +--
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c|  33 +--
 drivers/net/ixgbe/meson.build |   2 +-
 46 files changed, 1008 insertions(+), 1875 deletions(-)
 create mode 100644 drivers/common/intel_eth/ieth_rxtx.h
 create mode 100644 drivers/common/intel_eth/ieth_rxtx_vec_common.h

--
2.43.0



[RFC PATCH 03/21] common/intel_eth: add Tx mbuf ring replenish fn

2024-11-22 Thread Bruce Richardson
Move the short function used to place mbufs on the SW Tx ring to common
code to avoid duplication.

Signed-off-by: Bruce Richardson 
---
 drivers/common/intel_eth/ieth_rxtx_vec_common.h |  7 +++
 drivers/net/i40e/i40e_rxtx_vec_altivec.c|  4 ++--
 drivers/net/i40e/i40e_rxtx_vec_avx2.c   |  4 ++--
 drivers/net/i40e/i40e_rxtx_vec_common.h | 10 --
 drivers/net/i40e/i40e_rxtx_vec_neon.c   |  4 ++--
 drivers/net/i40e/i40e_rxtx_vec_sse.c|  4 ++--
 drivers/net/iavf/iavf_rxtx_vec_avx2.c   |  4 ++--
 drivers/net/iavf/iavf_rxtx_vec_common.h | 10 --
 drivers/net/iavf/iavf_rxtx_vec_sse.c|  4 ++--
 drivers/net/ice/ice_rxtx_vec_avx2.c |  4 ++--
 drivers/net/ice/ice_rxtx_vec_common.h   | 10 --
 drivers/net/ice/ice_rxtx_vec_sse.c  |  4 ++--
 12 files changed, 23 insertions(+), 46 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx_vec_common.h 
b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
index 0771af820c..49096d2a41 100644
--- a/drivers/common/intel_eth/ieth_rxtx_vec_common.h
+++ b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include "ieth_rxtx.h"
 
 #define IETH_RX_BURST 32
 
@@ -78,4 +79,10 @@ ieth_rx_reassemble_packets(struct rte_mbuf **rx_bufs,
return pkt_idx;
 }
 
+static __rte_always_inline void
+ieth_tx_backlog_entry(struct ieth_tx_entry *txep, struct rte_mbuf **tx_pkts, 
uint16_t nb_pkts)
+{
+   for (uint16_t i = 0; i < (int)nb_pkts; ++i)
+   txep[i].mbuf = tx_pkts[i];
+}
 #endif /* IETH_RXTX_VEC_COMMON_H_ */
diff --git a/drivers/net/i40e/i40e_rxtx_vec_altivec.c 
b/drivers/net/i40e/i40e_rxtx_vec_altivec.c
index 382a4d9305..614af752b8 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_altivec.c
+++ b/drivers/net/i40e/i40e_rxtx_vec_altivec.c
@@ -575,7 +575,7 @@ i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf 
**tx_pkts,
 
n = (uint16_t)(txq->nb_tx_desc - tx_id);
if (nb_commit >= n) {
-   tx_backlog_entry(txep, tx_pkts, n);
+   ieth_tx_backlog_entry(txep, tx_pkts, n);
 
for (i = 0; i < n - 1; ++i, ++tx_pkts, ++txdp)
vtx1(txdp, *tx_pkts, flags);
@@ -592,7 +592,7 @@ i40e_xmit_fixed_burst_vec(void *tx_queue, struct rte_mbuf 
**tx_pkts,
txep = &txq->sw_ring[tx_id];
}
 
-   tx_backlog_entry(txep, tx_pkts, nb_commit);
+   ieth_tx_backlog_entry(txep, tx_pkts, nb_commit);
 
vtx(txdp, tx_pkts, nb_commit, flags);
 
diff --git a/drivers/net/i40e/i40e_rxtx_vec_avx2.c 
b/drivers/net/i40e/i40e_rxtx_vec_avx2.c
index 48909d6230..2b0a774d47 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_avx2.c
+++ b/drivers/net/i40e/i40e_rxtx_vec_avx2.c
@@ -765,7 +765,7 @@ i40e_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
 
n = (uint16_t)(txq->nb_tx_desc - tx_id);
if (nb_commit >= n) {
-   tx_backlog_entry(txep, tx_pkts, n);
+   ieth_tx_backlog_entry(txep, tx_pkts, n);
 
vtx(txdp, tx_pkts, n - 1, flags);
tx_pkts += (n - 1);
@@ -783,7 +783,7 @@ i40e_xmit_fixed_burst_vec_avx2(void *tx_queue, struct 
rte_mbuf **tx_pkts,
txep = &txq->sw_ring[tx_id];
}
 
-   tx_backlog_entry(txep, tx_pkts, nb_commit);
+   ieth_tx_backlog_entry(txep, tx_pkts, nb_commit);
 
vtx(txdp, tx_pkts, nb_commit, flags);
 
diff --git a/drivers/net/i40e/i40e_rxtx_vec_common.h 
b/drivers/net/i40e/i40e_rxtx_vec_common.h
index 3f6319ee65..676c3b1034 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_common.h
+++ b/drivers/net/i40e/i40e_rxtx_vec_common.h
@@ -84,16 +84,6 @@ i40e_tx_free_bufs(struct i40e_tx_queue *txq)
return txq->tx_rs_thresh;
 }
 
-static __rte_always_inline void
-tx_backlog_entry(struct ieth_tx_entry *txep,
-struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
-   int i;
-
-   for (i = 0; i < (int)nb_pkts; ++i)
-   txep[i].mbuf = tx_pkts[i];
-}
-
 static inline void
 _i40e_rx_queue_release_mbufs_vec(struct i40e_rx_queue *rxq)
 {
diff --git a/drivers/net/i40e/i40e_rxtx_vec_neon.c 
b/drivers/net/i40e/i40e_rxtx_vec_neon.c
index 09f52d0409..2df7f3fed2 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_neon.c
+++ b/drivers/net/i40e/i40e_rxtx_vec_neon.c
@@ -702,7 +702,7 @@ i40e_xmit_fixed_burst_vec(void *__rte_restrict tx_queue,
 
n = (uint16_t)(txq->nb_tx_desc - tx_id);
if (nb_commit >= n) {
-   tx_backlog_entry(txep, tx_pkts, n);
+   ieth_tx_backlog_entry(txep, tx_pkts, n);
 
for (i = 0; i < n - 1; ++i, ++tx_pkts, ++txdp)
vtx1(txdp, *tx_pkts, flags);
@@ -719,7 +719,7 @@ i40e_xmit_fixed_burst_vec(void *__rte_restrict tx_queue,
txep = &txq->sw_ring[tx_id];
}
 
-   tx_backlog_entry(txep, tx_pkts, nb_commit);
+   ieth_tx_backlog_entry(txep, tx_pkts, nb_commit);
 

[PATCH v1 3/3] net/e1000: initialize PTP to system time

2024-11-22 Thread Anatoly Burakov
Currently, e1000 driver initializes PTP timestamp to 0. This is different
from what kernel driver does (which initializes it to system time).

Align the DPDK driver to kernel driver by setting PTP timestamp to system
time when enabling PTP.

Note that e1000 driver always uses zero-based timestamps for PTP, so we
would only ever update the internal timecounter and not the actual NIC
registers.

Signed-off-by: Anatoly Burakov 
---
 drivers/net/e1000/igb_ethdev.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c
index d3a9181874..c695f44c4c 100644
--- a/drivers/net/e1000/igb_ethdev.c
+++ b/drivers/net/e1000/igb_ethdev.c
@@ -4817,6 +4817,9 @@ igb_timesync_enable(struct rte_eth_dev *dev)
struct e1000_hw *hw = E1000_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t tsync_ctl;
uint32_t tsauxc;
+   struct timespec ts;
+
+   memset(&ts, 0, sizeof(struct timespec));
 
/* Stop the timesync system time. */
E1000_WRITE_REG(hw, E1000_TIMINCA, 0x0);
@@ -4861,6 +4864,9 @@ igb_timesync_enable(struct rte_eth_dev *dev)
tsync_ctl |= E1000_TSYNCTXCTL_ENABLED;
E1000_WRITE_REG(hw, E1000_TSYNCTXCTL, tsync_ctl);
 
+   /* e1000 uses zero-based timestamping so only adjust timecounter */
+   igb_timesync_write_time(dev, &ts);
+
return 0;
 }
 
-- 
2.43.5



[PATCH v1 1/3] net/ixgbe: initialize PTP to system time

2024-11-22 Thread Anatoly Burakov
Currently, ixgbe driver initializes PTP timestamp to 0. This is different
from what kernel driver does (which initializes it to system time).

Align the DPDK driver to kernel driver by setting PTP timestamp to system
time when enabling PTP.

Note that ixgbe driver always uses zero-based timestamps for PTP, so we
would only ever update the internal timecounter and not the actual NIC
registers.

Signed-off-by: Anatoly Burakov 
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index d02d1e43a3..8bc706f97b 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -6924,6 +6924,12 @@ ixgbe_timesync_enable(struct rte_eth_dev *dev)
struct ixgbe_hw *hw = IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t tsync_ctl;
uint32_t tsauxc;
+   struct timespec ts;
+
+   memset(&ts, 0, sizeof(struct timespec));
+
+   /* get current system time */
+   clock_gettime(CLOCK_REALTIME, &ts);
 
/* Stop the timesync system time. */
IXGBE_WRITE_REG(hw, IXGBE_TIMINCA, 0x0);
@@ -6956,6 +6962,9 @@ ixgbe_timesync_enable(struct rte_eth_dev *dev)
 
IXGBE_WRITE_FLUSH(hw);
 
+   /* ixgbe uses zero-based timestamping so only adjust timecounter */
+   ixgbe_timesync_write_time(dev, &ts);
+
return 0;
 }
 
-- 
2.43.5



Re: [PATCH v3 1/3] ethdev: add description for KEEP CRC offload

2024-11-22 Thread Stephen Hemminger
On Fri, 19 Jul 2024 17:04:13 +0800
Jie Hai  wrote:

> From: Dengdui Huang 
> 
> The data exceeds the pkt_len in mbuf is inavailable for user.
> When KEEP CRC offload is enabled, CRC field length should be
> included in the pkt_len in mbuf. However, almost of drivers
> supported KEEP CRC feature didn't add the CRC data length to
> pkt_len. So it is very necessary to add comments for this.
> 
> Fixes: 70815c9ecadd ("ethdev: add new offload flag to keep CRC")
> Cc: sta...@dpdk.org
> 
> Signed-off-by: Dengdui Huang 
> Acked-by: Morten Brørup 
> Acked-by: Huisong Li 
> Acked-by: Jie Hai 
> ---
>  lib/ethdev/rte_ethdev.h | 6 ++
>  1 file changed, 6 insertions(+)
> 

If you put the information in doc, users would see it.
Something like this:

diff --git a/doc/guides/nics/features.rst b/doc/guides/nics/features.rst
index 0508f118fe..63b0331b06 100644
--- a/doc/guides/nics/features.rst
+++ b/doc/guides/nics/features.rst
@@ -470,8 +470,9 @@ protocol operations. See security library and PMD 
documentation for more details
 CRC offload
 ---
 
-Supports CRC stripping by hardware.
-A PMD assumed to support CRC stripping by default. PMD should advertise if it 
supports keeping CRC.
+Supports including the CRC in the received packet.
+A PMD is assumed to support CRC stripping by default,
+PMD should only advertise if it supports keeping CRC.
 
 * **[uses] rte_eth_rxconf,rte_eth_rxmode**: 
``offloads:RTE_ETH_RX_OFFLOAD_KEEP_CRC``.
 
diff --git a/doc/guides/prog_guide/mbuf_lib.rst 
b/doc/guides/prog_guide/mbuf_lib.rst
index 4ad2a21f3f..bea9111ba4 100644
--- a/doc/guides/prog_guide/mbuf_lib.rst
+++ b/doc/guides/prog_guide/mbuf_lib.rst
@@ -207,6 +207,18 @@ The list of flags and their precise meaning is described 
in the mbuf API
 documentation (rte_mbuf.h). Also refer to the testpmd source code
 (specifically the csumonly.c file) for details.
 
+CRC offload
+~~~
+
+Normally the Ethernet Cyclic Redundancy Check (CRC) is *not* included in the 
mbuf.
+Some Poll Mode Driver's support keeping the received CRC in the mbuf.
+If a packet is received with keep CRC offload setting:
+- the CRC is in included in the mbuf pkt_len and data_len
+- the CRC is present but not checked
+- the mbuf should not be directly transmitted or the received CRC will be 
include
+  in the transmit
+
+
 Dynamic fields and flags
 
 


Re: [PATCH v2 1/3] net/macb: add new driver

2024-11-22 Thread Stephen Hemminger
On Tue,  5 Nov 2024 08:41:38 +
liwencheng  wrote:

> add Phytium NIC MACB ethdev PMD driver.
> 
> Signed-off-by: liwencheng 
> ---

Several things need to be addressed before this driver can be merged.
For better review, it is preferred that drivers be broken into smaller
chunks when submitting.

  https://doc.dpdk.org/guides/contributing/new_driver.html


1. Missing documentation
   all new drivers need to have documentation in doc/guides/nics
   to describe hardware and features.

2. Missing license tag.
   These files are missing required SPDX license tags:
drivers/net/macb/base/generic_phy.h
drivers/net/macb/base/macb_errno.h
drivers/net/macb/base/macb_hw.h

3. Missing mailmap entry

4. Missing update to MAINTAINERS

5. Build fails with lastest GCC
   Warnings found:

[1307/3230] Compiling C object 
drivers/libtmp_rte_net_macb.a.p/net_macb_macb_ethdev.c.o
In file included from ../drivers/net/macb/base/macb_common.h:36,
 from ../drivers/net/macb/macb_ethdev.h:10,
 from ../drivers/net/macb/macb_rxtx.h:8,
 from ../drivers/net/macb/macb_ethdev.c:11:
../drivers/net/macb/base/macb_hw.h:1063:35: warning: initializer-string for 
array of ‘char’ is too long [-Wunterminated-string-initialization]
 1063 | GEM_STAT_TITLE(TX1519CNT, "tx_greater_than_1518_byte_frames"),
  |   ^~
../drivers/net/macb/base/macb_hw.h:1043:24: note: in definition of macro 
‘GEM_STAT_TITLE_BITS’
 1043 | .stat_string = title,   \
  |^
../drivers/net/macb/base/macb_hw.h:1063:9: note: in expansion of macro 
‘GEM_STAT_TITLE’
 1063 | GEM_STAT_TITLE(TX1519CNT, "tx_greater_than_1518_byte_frames"),
  | ^~
../drivers/net/macb/base/macb_hw.h:1088:35: warning: initializer-string for 
array of ‘char’ is too long [-Wunterminated-string-initialization]
 1088 | GEM_STAT_TITLE(RX1519CNT, "rx_greater_than_1518_byte_frames"),
  |   ^~
../drivers/net/macb/base/macb_hw.h:1043:24: note: in definition of macro 
‘GEM_STAT_TITLE_BITS’
 1043 | .stat_string = title,   \
  |^
../drivers/net/macb/base/macb_hw.h:1088:9: note: in expansion of macro 
‘GEM_STAT_TITLE’
 1088 | GEM_STAT_TITLE(RX1519CNT, "rx_greater_than_1518_byte_frames"),
  | ^~
[1326/3230] Compiling C object 
drivers/libtmp_rte_net_macb.a.p/net_macb_macb_rxtx.c.o
In file included from ../drivers/net/macb/base/macb_common.h:36,
 from ../drivers/net/macb/macb_ethdev.h:10,
 from ../drivers/net/macb/macb_rxtx.h:8,
 from ../drivers/net/macb/macb_rxtx.c:24:
../drivers/net/macb/base/macb_hw.h:1063:35: warning: initializer-string for 
array of ‘char’ is too long [-Wunterminated-string-initialization]
 1063 | GEM_STAT_TITLE(TX1519CNT, "tx_greater_than_1518_byte_frames"),
  |   ^~
../drivers/net/macb/base/macb_hw.h:1043:24: note: in definition of macro 
‘GEM_STAT_TITLE_BITS’
 1043 | .stat_string = title,   \
  |^
../drivers/net/macb/base/macb_hw.h:1063:9: note: in expansion of macro 
‘GEM_STAT_TITLE’
 1063 | GEM_STAT_TITLE(TX1519CNT, "tx_greater_than_1518_byte_frames"),
  | ^~
../drivers/net/macb/base/macb_hw.h:1088:35: warning: initializer-string for 
array of ‘char’ is too long [-Wunterminated-string-initialization]
 1088 | GEM_STAT_TITLE(RX1519CNT, "rx_greater_than_1518_byte_frames"),
  |   ^~
../drivers/net/macb/base/macb_hw.h:1043:24: note: in definition of macro 
‘GEM_STAT_TITLE_BITS’
 1043 | .stat_string = title,   \
  |^
../drivers/net/macb/base/macb_hw.h:1088:9: note: in expansion of macro 
‘GEM_STAT_TITLE’
 1088 | GEM_STAT_TITLE(RX1519CNT, "rx_greater_than_1518_byte_frames"),
  | ^~
[2338/3230] Compiling C object 
drivers/net/macb/base/libmacb_base.a.p/generic_phy.c.o
In file included from ../drivers/net/macb/base/macb_common.h:36,
 from ../drivers/net/macb/base/generic_phy.h:4,
 from ../drivers/net/macb/base/generic_phy.c:5:
../drivers/net/macb/base/macb_hw.h:1063:35: warning: initializer-string for 
array of ‘char’ is too long [-Wunterminated-string-initialization]
 1063 | GEM_STAT_TITLE(TX1519CNT, "tx_greater_than_1518_byte_frames"),
  |   ^~
../drivers/net/macb/base/macb_hw.h:1043:24: note: in definition of macro 
‘GEM_STAT_TITLE_BITS’
 1043 | .stat_string = title,   \
  | 

[PATCH v1 1/1] net/ixgbe: fix PTP initialization for E610

2024-11-22 Thread Anatoly Burakov
Current codepath does not have case labels for E610 when initializing PTP.
Add them in relevant places.

Fixes: 316637762a5f ("net/ixgbe/base: enable E610 device")

Signed-off-by: Anatoly Burakov 
---
 drivers/net/ixgbe/ixgbe_ethdev.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index eb431889c3..d02d1e43a3 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -6741,6 +6741,7 @@ ixgbe_read_systime_cyclecounter(struct rte_eth_dev *dev)
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_X550EM_a:
+   case ixgbe_mac_E610:
/* SYSTIMEL stores ns and SYSTIMEH stores seconds. */
systime_cycles = (uint64_t)IXGBE_READ_REG(hw, IXGBE_SYSTIML);
systime_cycles += (uint64_t)IXGBE_READ_REG(hw, IXGBE_SYSTIMH)
@@ -6765,6 +6766,7 @@ ixgbe_read_rx_tstamp_cyclecounter(struct rte_eth_dev *dev)
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_X550EM_a:
+   case ixgbe_mac_E610:
/* RXSTMPL stores ns and RXSTMPH stores seconds. */
rx_tstamp_cycles = (uint64_t)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
rx_tstamp_cycles += (uint64_t)IXGBE_READ_REG(hw, IXGBE_RXSTMPH)
@@ -6790,6 +6792,7 @@ ixgbe_read_tx_tstamp_cyclecounter(struct rte_eth_dev *dev)
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_X550EM_a:
+   case ixgbe_mac_E610:
/* TXSTMPL stores ns and TXSTMPH stores seconds. */
tx_tstamp_cycles = (uint64_t)IXGBE_READ_REG(hw, IXGBE_TXSTMPL);
tx_tstamp_cycles += (uint64_t)IXGBE_READ_REG(hw, IXGBE_TXSTMPH)
@@ -6838,6 +6841,7 @@ ixgbe_start_timecounters(struct rte_eth_dev *dev)
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_X550EM_a:
+   case ixgbe_mac_E610:
/* Independent of link speed. */
incval = 1;
/* Cycles read will be interpreted as ns. */
-- 
2.43.5



Re: [PATCH v2 1/3] net/macb: add new driver

2024-11-22 Thread Stephen Hemminger
On Tue,  5 Nov 2024 08:41:38 +
liwencheng  wrote:

> +
> +int genphy_read_status(struct phy_device *phydev)
> +{
> + struct macb *bp = phydev->bp;
> + uint16_t bmcr, bmsr, ctrl1000 = 0, stat1000 = 0;
> + uint32_t advertising, lp_advertising;
> + uint32_t nego;
> + uint16_t phyad = phydev->phyad;
> +
> + /* Do a fake read */
> + bmsr = macb_mdio_read(bp, phyad, GENERIC_PHY_BMSR);
> +
> + bmsr = macb_mdio_read(bp, phyad, GENERIC_PHY_BMSR);
> + bmcr = macb_mdio_read(bp, phyad, GENERIC_PHY_BMCR);
> +
> + if (bmcr & BMCR_ANENABLE) {
> + ctrl1000 = macb_mdio_read(bp, phyad, GENERIC_PHY_CTRL1000);
> + stat1000 = macb_mdio_read(bp, phyad, GENERIC_PHY_STAT1000);
> +
> + advertising = ADVERTISED_Autoneg;
> + advertising |= genphy_get_an(bp, phyad, GENERIC_PHY_ADVERISE);
> + advertising |= genphy_ctrl1000_to_ethtool_adv_t(ctrl1000);
> +
> + if (bmsr & BMSR_ANEGCOMPLETE) {
> + lp_advertising = genphy_get_an(bp, phyad, 
> GENERIC_PHY_LPA);
> + lp_advertising |= 
> genphy_stat1000_to_ethtool_lpa_t(stat1000);
> + } else {
> + lp_advertising = 0;
> + }
> +
> + nego = advertising & lp_advertising;
> + if (nego & (ADVERTISED_1000baseT_Full | 
> ADVERTISED_1000baseT_Half)) {
> + phydev->speed = SPEED_1000;
> + phydev->duplex = !!(nego & ADVERTISED_1000baseT_Full);
> + } else if (nego &
> + (ADVERTISED_100baseT_Full | 
> ADVERTISED_100baseT_Half)) {
> + phydev->speed = SPEED_100;
> + phydev->duplex = !!(nego & ADVERTISED_100baseT_Full);
> + } else {
> + phydev->speed = SPEED_10;
> + phydev->duplex = !!(nego & ADVERTISED_10baseT_Full);
> + }
> + } else {
> + phydev->speed = ((bmcr & BMCR_SPEED1000 && (bmcr & 
> BMCR_SPEED100) == 0)
> +  ? SPEED_1000
> +  : ((bmcr & BMCR_SPEED100) ? 
> SPEED_100 : SPEED_10));
> + phydev->duplex = (bmcr & BMCR_FULLDPLX) ? DUPLEX_FULL : 
> DUPLEX_HALF;
> + }
> +
> + return 0;
> +}

Always returns 0 can be void function?

> +int macb_usxgmii_pcs_resume(struct phy_device *phydev)
> +{
> + u32 config;
> + struct macb *bp = phydev->bp;
> +
> + config = gem_readl(bp, USX_CONTROL);
> +
> + /* enable signal */
> + config &= ~(GEM_BIT(RX_SYNC_RESET));
> + config |= GEM_BIT(SIGNAL_OK) | GEM_BIT(TX_EN);
> + gem_writel(bp, USX_CONTROL, config);
> +
> + return 0;
> +}

Always returns 0 can be void function?

> +int macb_usxgmii_pcs_suspend(struct phy_device *phydev)
> +{
> + uint32_t config;
> + struct macb *bp = phydev->bp;
> +
> + config = gem_readl(bp, USX_CONTROL);
> + config |= GEM_BIT(RX_SYNC_RESET);
> + /* disable signal */
> + config &= ~(GEM_BIT(SIGNAL_OK) | GEM_BIT(TX_EN));
> + gem_writel(bp, USX_CONTROL, config);
> + rte_delay_ms(1);
> + return 0;
> +}

Always returns 0 should be void?

> +
> +int macb_usxgmii_pcs_check_for_link(struct phy_device *phydev)
> +{
> + int value;
> + int link;
> + struct macb *bp = phydev->bp;
> + value = gem_readl(bp, USX_STATUS);
> + link = GEM_BFEXT(BLOCK_LOCK, value);
> + return link;
> +}

The driver is sloppy in using int where unsigned value is possible.
You lose precision doing that and are prone to sign extension bugs.

Since gem_readl() is wrapper around macb_reg_readl() and that returns u32;
this function should be returning u32 and value should be u32
The temporary variable value is not needed.

> +int macb_gbe_pcs_check_for_link(struct phy_device *phydev)
> +{
> + int value;
> + int link;
> + struct macb *bp = phydev->bp;
> +
> + value = macb_readl(bp, NSR);
> + link = MACB_BFEXT(NSR_LINK, value);
> + return link;
> +}


[PATCH v2 1/2] net/ntnic: fix incorrect error message

2024-11-22 Thread Serhii Iliushyk
Add missed error messages to the list to avoid incorrect logs.
Change order base initializers to index base initializers.
Add static assertions to control the completeness of the list of messages.

Fixes: 11ea97805ba1 ("net/ntnic: add minimal flow inline profile")

Signed-off-by: Serhii Iliushyk 
---
v2
* Change order base initializers to index base initializers
* Add static assertions to control the completeness
of the list of messages.
---
 drivers/net/ntnic/include/flow_api.h|   3 +-
 drivers/net/ntnic/include/flow_api_engine.h |   3 +-
 drivers/net/ntnic/nthw/flow_api/flow_api.c  | 164 ++--
 3 files changed, 118 insertions(+), 52 deletions(-)

diff --git a/drivers/net/ntnic/include/flow_api.h 
b/drivers/net/ntnic/include/flow_api.h
index d5382669da..dcad7f6839 100644
--- a/drivers/net/ntnic/include/flow_api.h
+++ b/drivers/net/ntnic/include/flow_api.h
@@ -168,7 +168,8 @@ enum flow_nic_err_msg_e {
ERR_ACTION_MULTIPLE_PORT_ID_UNSUPPORTED = 40,
ERR_RSS_TOO_LONG_KEY = 41,
ERR_ACTION_AGE_UNSUPPORTED_GROUP_0 = 42,
-   ERR_MSG_NO_MSG
+   ERR_MSG_NO_MSG = 43,
+   ERR_MSG_END,
 };
 
 void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error 
*error);
diff --git a/drivers/net/ntnic/include/flow_api_engine.h 
b/drivers/net/ntnic/include/flow_api_engine.h
index 5eace2614f..636c53b260 100644
--- a/drivers/net/ntnic/include/flow_api_engine.h
+++ b/drivers/net/ntnic/include/flow_api_engine.h
@@ -44,7 +44,8 @@ enum res_type_e {
RES_TPE_RPL,
RES_SCRUB_RCP,
RES_COUNT,
-   RES_INVALID
+   RES_INVALID,
+   RES_END
 };
 
 /*
diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c 
b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index d4993eb58a..842b0075ed 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -19,28 +19,31 @@
}
 
 const char *dbg_res_descr[] = {
-   /* RES_QUEUE */ "RES_QUEUE",
-   /* RES_CAT_CFN */ "RES_CAT_CFN",
-   /* RES_CAT_COT */ "RES_CAT_COT",
-   /* RES_CAT_EXO */ "RES_CAT_EXO",
-   /* RES_CAT_LEN */ "RES_CAT_LEN",
-   /* RES_KM_FLOW_TYPE */ "RES_KM_FLOW_TYPE",
-   /* RES_KM_CATEGORY */ "RES_KM_CATEGORY",
-   /* RES_HSH_RCP */ "RES_HSH_RCP",
-   /* RES_PDB_RCP */ "RES_PDB_RCP",
-   /* RES_QSL_RCP */ "RES_QSL_RCP",
-   /* RES_QSL_LTX */ "RES_QSL_LTX",
-   /* RES_QSL_QST */ "RES_QSL_QST",
-   /* RES_SLC_LR_RCP */ "RES_SLC_LR_RCP",
-   /* RES_FLM_FLOW_TYPE */ "RES_FLM_FLOW_TYPE",
-   /* RES_FLM_RCP */ "RES_FLM_RCP",
-   /* RES_TPE_RCP */ "RES_TPE_RCP",
-   /* RES_TPE_EXT */ "RES_TPE_EXT",
-   /* RES_TPE_RPL */ "RES_TPE_RPL",
-   /* RES_COUNT */ "RES_COUNT",
-   /* RES_INVALID */ "RES_INVALID"
+   [RES_QUEUE] = "RES_QUEUE",
+   [RES_CAT_CFN] = "RES_CAT_CFN",
+   [RES_CAT_COT] = "RES_CAT_COT",
+   [RES_CAT_EXO] = "RES_CAT_EXO",
+   [RES_CAT_LEN] = "RES_CAT_LEN",
+   [RES_KM_FLOW_TYPE] = "RES_KM_FLOW_TYPE",
+   [RES_KM_CATEGORY] = "RES_KM_CATEGORY",
+   [RES_HSH_RCP] = "RES_HSH_RCP",
+   [RES_PDB_RCP] = "RES_PDB_RCP",
+   [RES_QSL_RCP] = "RES_QSL_RCP",
+   [RES_QSL_QST] = "RES_QSL_QST",
+   [RES_SLC_LR_RCP] = "RES_SLC_LR_RCP",
+   [RES_FLM_FLOW_TYPE] = "RES_FLM_FLOW_TYPE",
+   [RES_FLM_RCP] = "RES_FLM_RCP",
+   [RES_TPE_RCP] = "RES_TPE_RCP",
+   [RES_TPE_EXT] = "RES_TPE_EXT",
+   [RES_TPE_RPL] = "RES_TPE_RPL",
+   [RES_SCRUB_RCP] = "RES_SCRUB_RCP",
+   [RES_COUNT] = "RES_COUNT",
+   [RES_INVALID] = "RES_INVALID"
 };
 
+static_assert(RTE_DIM(dbg_res_descr) == RES_END,
+   "The list of debug descriptions is not fully completed");
+
 static struct flow_nic_dev *dev_base;
 static rte_spinlock_t base_mtx = RTE_SPINLOCK_INITIALIZER;
 
@@ -51,38 +54,99 @@ static rte_spinlock_t base_mtx = RTE_SPINLOCK_INITIALIZER;
 static const struct {
const char *message;
 } err_msg[] = {
-   /* 00 */ { "Operation successfully completed" },
-   /* 01 */ { "Operation failed" },
-   /* 02 */ { "Memory allocation failed" },
-   /* 03 */ { "Too many output destinations" },
-   /* 04 */ { "Too many output queues for RSS" },
-   /* 05 */ { "The VLAN TPID specified is not supported" },
-   /* 06 */ { "The VxLan Push header specified is not accepted" },
-   /* 07 */ { "While interpreting VxLan Pop action, could not find a 
destination port" },
-   /* 08 */ { "Failed in creating a HW-internal VTEP port" },
-   /* 09 */ { "Too many VLAN tag matches" },
-   /* 10 */ { "IPv6 invalid header specified" },
-   /* 11 */ { "Too many tunnel ports. HW limit reached" },
-   /* 12 */ { "Unknown or unsupported flow match element received" },
-   /* 13 */ { "Match failed because of HW limitations" },
-   /* 14 */ { "Match failed because of HW resource limitations" },
-   /* 15 */ { "Match failed because of too complex element definitions" },

[PATCH v2 2/2] net/ntnic: fix of Toeplitz key and log with mask

2024-11-22 Thread Serhii Iliushyk
Toeplitz secret key word order was reversed during programming into
FPGA, which lead to unexpected rss hash values.

Fixes: 7fa0bf29e667 ("net/ntnic: add hash module")

Signed-off-by: Serhii Iliushyk 
---
 .../profile_inline/flow_api_profile_inline.c  | 61 +++
 1 file changed, 21 insertions(+), 40 deletions(-)

diff --git 
a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c 
b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index a34839e00c..fbe8ee2795 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -3825,7 +3825,6 @@ struct hsh_words {
 * is used for hash mask calculation
 */
uint8_t index;
-   uint8_t toeplitz_index; /* offset in Bytes of given [Q]W inside 
Toeplitz RSS key */
enum hw_hsh_e pe;   /* offset to header part, e.g. beginning of L4 
*/
enum hw_hsh_e ofs;  /* relative offset in BYTES to 'pe' header 
offset above */
uint16_t bit_len;   /* max length of header part in bits to fit 
into QW/W */
@@ -3874,7 +3873,6 @@ static int flow_nic_set_hasher_part_inline(struct 
flow_nic_dev *ndev, int hsh_id
/* set HW_HSH_RCP_WORD_MASK based on used QW/W and given 'bit_len' */
int mask_bit_len = bit_len;
uint32_t mask = 0x0;
-   uint32_t mask_be = 0x0;
uint32_t toeplitz_mask[9] = { 0x0 };
/* iterate through all words of QW */
uint16_t words_count = words[word].bit_len / 32;
@@ -3883,27 +3881,23 @@ static int flow_nic_set_hasher_part_inline(struct 
flow_nic_dev *ndev, int hsh_id
if (mask_bit_len >= 32) {
mask_bit_len -= 32;
mask = 0x;
-   mask_be = mask;
 
} else if (mask_bit_len > 0) {
-   /* keep bits from left to right, i.e. little to big 
endian */
-   mask_be = 0x >> (32 - mask_bit_len);
-   mask = mask_be << (32 - mask_bit_len);
+   mask = 0x >> (32 - mask_bit_len) << (32 - 
mask_bit_len);
mask_bit_len = 0;
 
} else {
mask = 0x0;
-   mask_be = 0x0;
}
 
/* reorder QW words mask from little to big endian */
res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, 
hsh_idx,
words[word].index + words_count - mask_off, mask);
-   NT_LOG(DBG, FILTER,
-   "hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, 
%d, %d, 0x%" PRIX32
+   NT_LOG_DBGX(DBG, FILTER,
+   "hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, 
%d, %d, 0x%08" PRIX32
")",
hsh_idx, words[word].index + words_count - mask_off, 
mask);
-   toeplitz_mask[words[word].toeplitz_index + mask_off - 1] = 
mask_be;
+   toeplitz_mask[words[word].index + mask_off - 1] = mask;
}
 
if (toeplitz) {
@@ -3911,9 +3905,9 @@ static int flow_nic_set_hasher_part_inline(struct 
flow_nic_dev *ndev, int hsh_id
"Partial Toeplitz RSS key mask: %08" PRIX32 " %08" 
PRIX32 " %08" PRIX32
" %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 
" %08" PRIX32
" %08" PRIX32 "",
-   toeplitz_mask[8], toeplitz_mask[7], toeplitz_mask[6], 
toeplitz_mask[5],
-   toeplitz_mask[4], toeplitz_mask[3], toeplitz_mask[2], 
toeplitz_mask[1],
-   toeplitz_mask[0]);
+   toeplitz_mask[0], toeplitz_mask[1], toeplitz_mask[2], 
toeplitz_mask[3],
+   toeplitz_mask[4], toeplitz_mask[5], toeplitz_mask[6], 
toeplitz_mask[7],
+   toeplitz_mask[8]);
NT_LOG(DBG, FILTER,
"   MSB 
 LSB");
}
@@ -4632,11 +4626,11 @@ int flow_nic_set_hasher_fields_inline(struct 
flow_nic_dev *ndev, int hsh_idx,
 * word | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
 */
struct hsh_words words[HSH_WORDS_SIZE] = {
-   { 0, 5, HW_HSH_RCP_QW0_PE, HW_HSH_RCP_QW0_OFS, 128, true },
-   { 4, 1, HW_HSH_RCP_QW4_PE, HW_HSH_RCP_QW4_OFS, 128, true },
-   { 8, 0, HW_HSH_RCP_W8_PE, HW_HSH_RCP_W8_OFS, 32, true },
+   { 0, HW_HSH_RCP_QW0_PE, HW_HSH_RCP_QW0_OFS, 128, true },
+   { 4, HW_HSH_RCP_QW4_PE, HW_HSH_RCP_QW4_OFS, 128, true },
+   { 8, HW_HSH_RCP_W8_PE, HW_HSH_RCP_W8_OFS, 32, true },
{
-   9, 255, HW_HSH_RCP_W9_PE, HW_HSH_RCP_W9_OFS, 32,
+   9, HW_HSH_RCP_W9_PE

Re: [PATCH v12 04/21] ethdev: remove use of VLAs for Windows built code

2024-11-22 Thread fengchengwen
On 2024/11/22 18:08, Konstantin Ananyev wrote:
> 
> 
>> -Original Message-
>> From: Fengchengwen 
>> Sent: Friday, November 22, 2024 1:33 AM
>> To: Andre Muezerie ; dev@dpdk.org
>> Cc: Konstantin Ananyev 
>> Subject: Re: [PATCH v12 04/21] ethdev: remove use of VLAs for Windows built 
>> code
>>
>> On 2024/11/22 5:41, Andre Muezerie wrote:
>>> From: Konstantin Ananyev 
>>>
>>> 1) ./lib/ethdev/rte_ethdev.c:3244:16
>>> : warning: ISO C90 forbids variable length array ‘xstats_names’
>>> 2) ./lib/ethdev/rte_ethdev.c:3345:17
>>> : warning: ISO C90 forbids variable length array ‘ids_copy’
>>> 3) ./lib/ethdev/rte_ethdev.c:3538:16
>>> : warning: ISO C90 forbids variable length array ‘xstats’
>>> 4) ./lib/ethdev/rte_ethdev.c:3554:17
>>> : warning: ISO C90 forbids variable length array ‘ids_copy’
>>>
>>> For 1) and 3) - just replaced VLA with arrays allocated from heap.
>>> As I understand xstats extraction belongs to control-path, so extra
>>> calloc/free is hopefully acceptable.
>>> Also ethdev xstats already doing that within
>>> rte_eth_xstats_get_id_by_name().
>>> For 2) and 4) changed the code to use fixed size array and call
>>> appropriate devops function several times, if needed.
>>
>> It will invoke PMD ops multi-times, I'm not sure whether all drivers
>> impl correctly.
> 
> Hmm..., but then there is a bug in the driver that has to be fixed, no?

Yes, such bug need to be fixed.

In this case, we maybe need more review on PMD's impl.

> 
>> And it also belong control-path, so suggest use the call/free as 1&3 case.
>>
> 



[PATCH v2 0/2] Bugfixes

2024-11-22 Thread Serhii Iliushyk
This patch set provides further fixes:

Feature RSS:
  Fix the Toeplitz key and log with a mask.
  Toeplitz's secret keyword order was reversed during programming into
  FPGA, which leads to unexpected RSS hash values.

Error handling:
  The missed error messages were added to the list to avoid incorrect logs
  Change order base initializers to index base initializers
  Add static assertions to control the completeness of the list of messages.

Serhii Iliushyk (2):
  net/ntnic: fix incorrect error message
  net/ntnic: fix of Toeplitz key and log with mask

 drivers/net/ntnic/include/flow_api.h  |   3 +-
 drivers/net/ntnic/include/flow_api_engine.h   |   3 +-
 drivers/net/ntnic/nthw/flow_api/flow_api.c| 164 --
 .../profile_inline/flow_api_profile_inline.c  |  61 +++
 4 files changed, 139 insertions(+), 92 deletions(-)

-- 
2.45.0



[PATCH v1 2/3] net/i40e: initialize PTP to system time

2024-11-22 Thread Anatoly Burakov
Currently, i40e driver initializes PTP timestamp to 0. This is different
from what kernel driver does (which initializes it to system time).

Align the DPDK driver to kernel driver by setting PTP timestamp to system
time when enabling PTP.

Note that i40e driver always uses zero-based timestamps for PTP, so we
would only ever update the internal timecounter and not the actual NIC
registers.

Signed-off-by: Anatoly Burakov 
---
 drivers/net/i40e/i40e_ethdev.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ca128c7556..30dcdc68a8 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -10556,6 +10556,9 @@ i40e_timesync_enable(struct rte_eth_dev *dev)
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
uint32_t tsync_ctl_l;
uint32_t tsync_ctl_h;
+   struct timespec ts;
+
+   memset(&ts, 0, sizeof(struct timespec));
 
/* Stop the timesync system time. */
I40E_WRITE_REG(hw, I40E_PRTTSYN_INC_L, 0x0);
@@ -10585,6 +10588,9 @@ i40e_timesync_enable(struct rte_eth_dev *dev)
I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL0, tsync_ctl_l);
I40E_WRITE_REG(hw, I40E_PRTTSYN_CTL1, tsync_ctl_h);
 
+   /* i40e uses zero-based timestamping so only adjust timecounter */
+   i40e_timesync_write_time(dev, &ts);
+
return 0;
 }
 
-- 
2.43.5



Re: rte_fib network order bug

2024-11-22 Thread Thomas Monjalon
17/11/2024 16:04, Vladimir Medvedkin:
> So, feel free to submit patches adding this feature to the control plane API,

Before discussing more changes, please let's fix the API description in 
24.11-rc4:
RTE_FIB_F_NETWORK_ORDER should be renamed RTE_FIB_F_LOOKUP_NETWORK_ORDER
so it matches what it does really.





[PATCH v1 2/2] net/ntnic: fix of Toeplitz key and log with mask

2024-11-22 Thread Serhii Iliushyk
Toeplitz secret key word order was reversed during programming into
FPGA, which lead to unexpected rss hash values.

Fixes: 7fa0bf29e667 ("net/ntnic: add hash module")

Signed-off-by: Serhii Iliushyk 
---
 .../profile_inline/flow_api_profile_inline.c  | 61 +++
 1 file changed, 21 insertions(+), 40 deletions(-)

diff --git 
a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c 
b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
index a34839e00c..fbe8ee2795 100644
--- a/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
+++ b/drivers/net/ntnic/nthw/flow_api/profile_inline/flow_api_profile_inline.c
@@ -3825,7 +3825,6 @@ struct hsh_words {
 * is used for hash mask calculation
 */
uint8_t index;
-   uint8_t toeplitz_index; /* offset in Bytes of given [Q]W inside 
Toeplitz RSS key */
enum hw_hsh_e pe;   /* offset to header part, e.g. beginning of L4 
*/
enum hw_hsh_e ofs;  /* relative offset in BYTES to 'pe' header 
offset above */
uint16_t bit_len;   /* max length of header part in bits to fit 
into QW/W */
@@ -3874,7 +3873,6 @@ static int flow_nic_set_hasher_part_inline(struct 
flow_nic_dev *ndev, int hsh_id
/* set HW_HSH_RCP_WORD_MASK based on used QW/W and given 'bit_len' */
int mask_bit_len = bit_len;
uint32_t mask = 0x0;
-   uint32_t mask_be = 0x0;
uint32_t toeplitz_mask[9] = { 0x0 };
/* iterate through all words of QW */
uint16_t words_count = words[word].bit_len / 32;
@@ -3883,27 +3881,23 @@ static int flow_nic_set_hasher_part_inline(struct 
flow_nic_dev *ndev, int hsh_id
if (mask_bit_len >= 32) {
mask_bit_len -= 32;
mask = 0x;
-   mask_be = mask;
 
} else if (mask_bit_len > 0) {
-   /* keep bits from left to right, i.e. little to big 
endian */
-   mask_be = 0x >> (32 - mask_bit_len);
-   mask = mask_be << (32 - mask_bit_len);
+   mask = 0x >> (32 - mask_bit_len) << (32 - 
mask_bit_len);
mask_bit_len = 0;
 
} else {
mask = 0x0;
-   mask_be = 0x0;
}
 
/* reorder QW words mask from little to big endian */
res |= hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, 
hsh_idx,
words[word].index + words_count - mask_off, mask);
-   NT_LOG(DBG, FILTER,
-   "hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, 
%d, %d, 0x%" PRIX32
+   NT_LOG_DBGX(DBG, FILTER,
+   "hw_mod_hsh_rcp_set(&ndev->be, HW_HSH_RCP_WORD_MASK, 
%d, %d, 0x%08" PRIX32
")",
hsh_idx, words[word].index + words_count - mask_off, 
mask);
-   toeplitz_mask[words[word].toeplitz_index + mask_off - 1] = 
mask_be;
+   toeplitz_mask[words[word].index + mask_off - 1] = mask;
}
 
if (toeplitz) {
@@ -3911,9 +3905,9 @@ static int flow_nic_set_hasher_part_inline(struct 
flow_nic_dev *ndev, int hsh_id
"Partial Toeplitz RSS key mask: %08" PRIX32 " %08" 
PRIX32 " %08" PRIX32
" %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 
" %08" PRIX32
" %08" PRIX32 "",
-   toeplitz_mask[8], toeplitz_mask[7], toeplitz_mask[6], 
toeplitz_mask[5],
-   toeplitz_mask[4], toeplitz_mask[3], toeplitz_mask[2], 
toeplitz_mask[1],
-   toeplitz_mask[0]);
+   toeplitz_mask[0], toeplitz_mask[1], toeplitz_mask[2], 
toeplitz_mask[3],
+   toeplitz_mask[4], toeplitz_mask[5], toeplitz_mask[6], 
toeplitz_mask[7],
+   toeplitz_mask[8]);
NT_LOG(DBG, FILTER,
"   MSB 
 LSB");
}
@@ -4632,11 +4626,11 @@ int flow_nic_set_hasher_fields_inline(struct 
flow_nic_dev *ndev, int hsh_idx,
 * word | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
 */
struct hsh_words words[HSH_WORDS_SIZE] = {
-   { 0, 5, HW_HSH_RCP_QW0_PE, HW_HSH_RCP_QW0_OFS, 128, true },
-   { 4, 1, HW_HSH_RCP_QW4_PE, HW_HSH_RCP_QW4_OFS, 128, true },
-   { 8, 0, HW_HSH_RCP_W8_PE, HW_HSH_RCP_W8_OFS, 32, true },
+   { 0, HW_HSH_RCP_QW0_PE, HW_HSH_RCP_QW0_OFS, 128, true },
+   { 4, HW_HSH_RCP_QW4_PE, HW_HSH_RCP_QW4_OFS, 128, true },
+   { 8, HW_HSH_RCP_W8_PE, HW_HSH_RCP_W8_OFS, 32, true },
{
-   9, 255, HW_HSH_RCP_W9_PE, HW_HSH_RCP_W9_OFS, 32,
+   9, HW_HSH_RCP_W9_PE

[PATCH v1 1/2] net/ntnic: fix incorrect error message

2024-11-22 Thread Serhii Iliushyk
Add missed error messages to the list to avoid incorrect logs

Fixes: 11ea97805ba1 ("net/ntnic: add minimal flow inline profile")

Signed-off-by: Serhii Iliushyk 
---
 drivers/net/ntnic/nthw/flow_api/flow_api.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c 
b/drivers/net/ntnic/nthw/flow_api/flow_api.c
index d4993eb58a..fd470ddd35 100644
--- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
+++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
@@ -81,6 +81,20 @@ static const struct {
/* 27 */ { "Internal creation of a tunnel end point port failed" },
/* 28 */ { "Unknown or unsupported flow action received" },
/* 29 */ { "Removing flow failed" },
+   /* 30 */ { "No output queue specified. Ignore this flow offload and 
uses default queue"},
+   /* 31 */ { "No output queue found"},
+   /* 32 */ { "Unsupported EtherType or rejected caused by offload 
policy"},
+   /* 33 */ { "Destination port specified is invalid or not reachable from 
this NIC"},
+   /* 34 */ { "Partial offload is not supported in this configuration"},
+   /* 35 */ { "Match failed because of CAT CAM exhausted"},
+   /* 36 */ { "Match failed because of CAT CAM Key clashed with an 
existing KCC Key"},
+   /* 37 */ { "Match failed because of CAT CAM write failed"},
+   /* 38 */ { "Partial flow mark too big for device"},
+   /* 39 */ { "Invalid priority value"},
+   /* 40 */ { "Multiple port_id actions for one flow is not supported"},
+   /* 41 */ { "Too long hash key for RSS"},
+   /* 42 */ { "Action AGE is not supported for flow in group 0"},
+   /* 43 */ { "Unknown error"},
 };
 
 void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error 
*error)
-- 
2.45.0



[PATCH v1 0/2] Bugfixes

2024-11-22 Thread Serhii Iliushyk
This patch set provides further fixes:

Feature RSS:
  Fix the Toeplitz key and log with a mask.
  Toeplitz's secret keyword order was reversed during programming into
  FPGA, which leads to unexpected RSS hash values.

Error handling:
  The missed error messages were added to the list to avoid incorrect logs

Serhii Iliushyk (2):
  net/ntnic: fix incorrect error message
  net/ntnic: fix of Toeplitz key and log with mask

 drivers/net/ntnic/nthw/flow_api/flow_api.c| 14 +
 .../profile_inline/flow_api_profile_inline.c  | 61 +++
 2 files changed, 35 insertions(+), 40 deletions(-)

-- 
2.45.0



Re: Doubts in JumboFrames and stats_checks tests in DTS.

2024-11-22 Thread Patrick Robb
Hi Bharati,

Welcome to the DTS mailing list. I will try to provide some answers based
on my experience running DTS at the DPDK Community Lab at UNH. I will also
flag that this "legacy" version of DTS is deprecated and getting minimal
maintenance. The majority of the current efforts for DTS are directed
towards the rewrite which exists within the /dts dir of the DPDK repo:
https://git.dpdk.org/dpdk/tree/dts

With that being said, of course the legacy repo is still useful and I
encourage you to use it, so I will provide some comments inline below:

On Fri, Nov 22, 2024 at 9:43 AM Bharati Bhole - Geminus <
c_bhara...@xsightlabs.com> wrote:

> Hi,
>
> I am Bharati Bhole. I am a new member of DTS mailing list.
> I have recently started working on DTS for my company and facing some
> issues/failures while running the DTS.
> Please help me with understanding the test cases and expected behaviours.
>
> I am trying to understand the DTS behaviour for following TCs:
>
> 1. JumboFrames :
>
>1. When the test set the max_pkt_len for testpmd and calculate the
>expected acceptable packet size, does it consider NICs supporting 2 VLANS?
>(In case of MTU update test, I have seen that 2 VLANs NIC are being
>considered while calculating acceptable packets size but in JumboFrames I
>dont see it).
>
>
No, 2 VLANs is not properly accounted for in the Jumboframes testsuite.
And, this is actually highly topical, as this is an ongoing point of
discussion in rewriting jumboframes and mtu_update for the new DTS
framework (the testcases are getting combined into 1 testsuite).  I will
paste the function from mtu_update of legacy DTS which you may be referring
to:

--

def send_packet_of_size_to_port(self, port_id: int, pktsize: int):

# The packet total size include ethernet header, ip header, and
payload.
# ethernet header length is 18 bytes, ip standard header length is
20 bytes.
# pktlen = pktsize - ETHER_HEADER_LEN
if self.kdriver in ["igb", "igc", "ixgbe"]:
max_pktlen = pktsize + ETHER_HEADER_LEN + VLAN
padding = max_pktlen - IP_HEADER_LEN - ETHER_HEADER_LEN - VLAN
else:
max_pktlen = pktsize + ETHER_HEADER_LEN + VLAN * 2
padding = max_pktlen - IP_HEADER_LEN - ETHER_HEADER_LEN
out = self.send_scapy_packet(
port_id,
f'Ether(dst=dutmac,
src="52:00:00:00:00:00")/IP()/Raw(load="\x50"*{padding})',

--

One difference between legacy DTS and the "new" DTS is that in legacy DTS a
master list of devices/drivers was maintained, and there were an endless
amount of conditions like this where a device list would be checked, and
then some behavior modified based on that list. Because this strategy leads
to bugs, it's unresponsive to changes in driver code, hard to maintain, and
for other reasons, we are no longer follow this approach in new DTS. Now,
if we want to toggle different behavior (like determine max_pkt_len for a
given MTU for a given device) that needs to be accomplished by querying
testpmd for device info (there are various testpmd runtime commands for
this). And, in situations where testpmd doesn't expose the information we
need for checking device behavior in a particular testsuite - testpmd needs
to be updated to allow for this.

I am CC'ing Nick who is the person writing the new jumboframes + MTU
testsuite, which (work in progress) is on patchwork here:
https://patchwork.dpdk.org/project/dpdk/patch/20240726141307.14410-3-npra...@iol.unh.edu/

Nick, maybe you can include the mailing list threads Thomas linke you, and
explain your current understanding of how to handle this issue? This won't
really help Bharati in the short term, but at least it will clarify to him
how this issue will be handled in the new DTS framework, which presumably
he will upgrade to using at some point.


>1.
>2. In function jumboframes_send_packet() -
>
>if received:
>   * if self.nic.startswith("fastlinq"):*
>self.verify(
>self.pmdout.check_tx_bytes(tx_pkts, rx_pkts)
>and (self.pmdout.check_tx_bytes(tx_bytes, pktsize))
>and (rx_bytes == pktsize),
>"packet pass assert error",
>)
>   * else:*
>self.verify(
>self.pmdout.check_tx_bytes(tx_pkts, rx_pkts)
>and (self.pmdout.check_tx_bytes(tx_bytes *+ 4*,
>pktsize))
>and ((rx_bytes *+ 4*) == pktsize),
>"packet pass assert error",
>)
>else:
>self.verify(rx_err == 1 or tx_pkts == 0, "packet drop
>assert error")
>return out
>
>
> Can someone please tell me why these tx_butes and rx_bytes calculations
> are different for Qlogic NICs and other NICs?
>

I do

[RFC PATCH 05/21] drivers/net: add prefix for driver-specific structs

2024-11-22 Thread Bruce Richardson
In preparation for merging the Tx structs for multiple drivers into a
single struct, rename the driver-specific pointers in each struct to
have a prefix on it, to avoid conflicts.

Signed-off-by: Bruce Richardson 
---
 drivers/net/i40e/i40e_fdir.c  |  6 +--
 .../net/i40e/i40e_recycle_mbufs_vec_common.c  |  2 +-
 drivers/net/i40e/i40e_rxtx.c  | 30 ++--
 drivers/net/i40e/i40e_rxtx.h  |  4 +-
 drivers/net/i40e/i40e_rxtx_vec_altivec.c  |  6 +--
 drivers/net/i40e/i40e_rxtx_vec_avx2.c |  6 +--
 drivers/net/i40e/i40e_rxtx_vec_avx512.c   |  8 ++--
 drivers/net/i40e/i40e_rxtx_vec_common.h   |  2 +-
 drivers/net/i40e/i40e_rxtx_vec_neon.c |  6 +--
 drivers/net/i40e/i40e_rxtx_vec_sse.c  |  6 +--
 drivers/net/iavf/iavf_rxtx.c  | 24 +-
 drivers/net/iavf/iavf_rxtx.h  |  4 +-
 drivers/net/iavf/iavf_rxtx_vec_avx2.c |  6 +--
 drivers/net/iavf/iavf_rxtx_vec_avx512.c   | 14 +++---
 drivers/net/iavf/iavf_rxtx_vec_common.h   |  2 +-
 drivers/net/iavf/iavf_rxtx_vec_sse.c  |  6 +--
 drivers/net/ice/ice_dcf_ethdev.c  |  4 +-
 drivers/net/ice/ice_rxtx.c| 48 +--
 drivers/net/ice/ice_rxtx.h|  4 +-
 drivers/net/ice/ice_rxtx_vec_avx2.c   |  6 +--
 drivers/net/ice/ice_rxtx_vec_avx512.c |  8 ++--
 drivers/net/ice/ice_rxtx_vec_common.h |  4 +-
 drivers/net/ice/ice_rxtx_vec_sse.c|  6 +--
 .../ixgbe/ixgbe_recycle_mbufs_vec_common.c|  2 +-
 drivers/net/ixgbe/ixgbe_rxtx.c| 22 -
 drivers/net/ixgbe/ixgbe_rxtx.h|  2 +-
 drivers/net/ixgbe/ixgbe_rxtx_vec_common.h |  6 +--
 drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c   |  6 +--
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c|  6 +--
 29 files changed, 128 insertions(+), 128 deletions(-)

diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 47f79ecf11..c600167634 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -1383,7 +1383,7 @@ i40e_find_available_buffer(struct rte_eth_dev *dev)
volatile struct i40e_tx_desc *tmp_txdp;
 
tmp_tail = txq->tx_tail;
-   tmp_txdp = &txq->tx_ring[tmp_tail + 1];
+   tmp_txdp = &txq->i40e_tx_ring[tmp_tail + 1];
 
do {
if ((tmp_txdp->cmd_type_offset_bsz &
@@ -1640,7 +1640,7 @@ i40e_flow_fdir_filter_programming(struct i40e_pf *pf,
 
PMD_DRV_LOG(INFO, "filling filter programming descriptor.");
fdirdp = (volatile struct i40e_filter_program_desc *)
-   (&txq->tx_ring[txq->tx_tail]);
+   (&txq->i40e_tx_ring[txq->tx_tail]);
 
fdirdp->qindex_flex_ptype_vsi =
rte_cpu_to_le_32((fdir_action->rx_queue <<
@@ -1710,7 +1710,7 @@ i40e_flow_fdir_filter_programming(struct i40e_pf *pf,
fdirdp->fd_id = rte_cpu_to_le_32(filter->soft_id);
 
PMD_DRV_LOG(INFO, "filling transmit descriptor.");
-   txdp = &txq->tx_ring[txq->tx_tail + 1];
+   txdp = &txq->i40e_tx_ring[txq->tx_tail + 1];
txdp->buffer_addr = rte_cpu_to_le_64(pf->fdir.dma_addr[txq->tx_tail >> 
1]);
 
td_cmd = I40E_TX_DESC_CMD_EOP |
diff --git a/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c 
b/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c
index 5a23adc6a4..167ee8d428 100644
--- a/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c
+++ b/drivers/net/i40e/i40e_recycle_mbufs_vec_common.c
@@ -75,7 +75,7 @@ i40e_recycle_tx_mbufs_reuse_vec(void *tx_queue,
return 0;
 
/* check DD bits on threshold descriptor */
-   if ((txq->tx_ring[txq->tx_next_dd].cmd_type_offset_bsz &
+   if ((txq->i40e_tx_ring[txq->tx_next_dd].cmd_type_offset_bsz &
rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) !=
rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE))
return 0;
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 20e72cac54..5b8edac3b2 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -379,7 +379,7 @@ static inline int
 i40e_xmit_cleanup(struct i40e_tx_queue *txq)
 {
struct ieth_tx_entry *sw_ring = txq->sw_ring;
-   volatile struct i40e_tx_desc *txd = txq->tx_ring;
+   volatile struct i40e_tx_desc *txd = txq->i40e_tx_ring;
uint16_t last_desc_cleaned = txq->last_desc_cleaned;
uint16_t nb_tx_desc = txq->nb_tx_desc;
uint16_t desc_to_clean_to;
@@ -1103,7 +1103,7 @@ i40e_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, 
uint16_t nb_pkts)
 
txq = tx_queue;
sw_ring = txq->sw_ring;
-   txr = txq->tx_ring;
+   txr = txq->i40e_tx_ring;
tx_id = txq->tx_tail;
txe = &sw_ring[tx_id];
 
@@ -1338,7 +1338,7 @@ i40e_tx_free_bufs(struct i40e_tx_queue

[RFC PATCH 06/21] common/intel_eth: merge ice and i40e Tx queue struct

2024-11-22 Thread Bruce Richardson
The queue structures fo i40e and ice drivers are virtually identical, so
merge them into a common struct. This should allow easier function
merging in future using that common struct.

Signed-off-by: Bruce Richardson 
---
 drivers/common/intel_eth/ieth_rxtx.h  | 54 +
 drivers/net/i40e/i40e_ethdev.c|  4 +-
 drivers/net/i40e/i40e_ethdev.h|  4 +-
 drivers/net/i40e/i40e_fdir.c  |  4 +-
 .../net/i40e/i40e_recycle_mbufs_vec_common.c  |  2 +-
 drivers/net/i40e/i40e_rxtx.c  | 58 +-
 drivers/net/i40e/i40e_rxtx.h  | 50 ++--
 drivers/net/i40e/i40e_rxtx_vec_altivec.c  |  4 +-
 drivers/net/i40e/i40e_rxtx_vec_avx2.c |  4 +-
 drivers/net/i40e/i40e_rxtx_vec_avx512.c   |  6 +-
 drivers/net/i40e/i40e_rxtx_vec_common.h   |  2 +-
 drivers/net/i40e/i40e_rxtx_vec_neon.c |  4 +-
 drivers/net/i40e/i40e_rxtx_vec_sse.c  |  4 +-
 drivers/net/ice/ice_dcf.c |  4 +-
 drivers/net/ice/ice_dcf_ethdev.c  | 10 ++--
 drivers/net/ice/ice_diagnose.c|  2 +-
 drivers/net/ice/ice_ethdev.c  |  2 +-
 drivers/net/ice/ice_ethdev.h  |  4 +-
 drivers/net/ice/ice_rxtx.c| 60 +--
 drivers/net/ice/ice_rxtx.h| 41 +
 drivers/net/ice/ice_rxtx_vec_avx2.c   |  4 +-
 drivers/net/ice/ice_rxtx_vec_avx512.c |  8 +--
 drivers/net/ice/ice_rxtx_vec_common.h |  8 +--
 drivers/net/ice/ice_rxtx_vec_sse.c|  6 +-
 24 files changed, 164 insertions(+), 185 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx.h 
b/drivers/common/intel_eth/ieth_rxtx.h
index 95a3cff048..8b12ff59e4 100644
--- a/drivers/common/intel_eth/ieth_rxtx.h
+++ b/drivers/common/intel_eth/ieth_rxtx.h
@@ -26,4 +26,58 @@ struct ieth_vec_tx_entry
struct rte_mbuf *mbuf; /* mbuf associated with TX desc, if any. */
 };
 
+struct ieth_tx_queue;
+
+typedef void (*ice_tx_release_mbufs_t)(struct ieth_tx_queue *txq);
+
+struct ieth_tx_queue {
+   union { /* TX ring virtual address */
+   volatile struct ice_tx_desc *ice_tx_ring;
+   volatile struct i40e_tx_desc *i40e_tx_ring;
+   };
+   volatile uint8_t *qtx_tail;   /* register address of tail */
+   struct ieth_tx_entry *sw_ring; /* virtual address of SW ring */
+   rte_iova_t tx_ring_dma;/* TX ring DMA address */
+   uint16_t nb_tx_desc;   /* number of TX descriptors */
+   uint16_t tx_tail; /* current value of tail register */
+   uint16_t nb_tx_used; /* number of TX desc used since RS bit set */
+   /* index to last TX descriptor to have been cleaned */
+   uint16_t last_desc_cleaned;
+   /* Total number of TX descriptors ready to be allocated. */
+   uint16_t nb_tx_free;
+   /* Start freeing TX buffers if there are less free descriptors than
+* this value.
+*/
+   uint16_t tx_free_thresh;
+   /* Number of TX descriptors to use before RS bit is set. */
+   uint16_t tx_rs_thresh;
+   uint8_t pthresh;   /**< Prefetch threshold register. */
+   uint8_t hthresh;   /**< Host threshold register. */
+   uint8_t wthresh;   /**< Write-back threshold reg. */
+   uint16_t port_id;  /* Device port identifier. */
+   uint16_t queue_id; /* TX queue index. */
+   uint16_t reg_idx;
+   uint64_t offloads;
+   uint16_t tx_next_dd;
+   uint16_t tx_next_rs;
+   uint64_t mbuf_errors;
+   _Bool tx_deferred_start; /* don't start this queue in dev start */
+   _Bool q_set; /* indicate if tx queue has been configured */
+   union {  /* the VSI this queue belongs to */
+   struct ice_vsi *ice_vsi;
+   struct i40e_vsi *i40e_vsi;
+   };
+   const struct rte_memzone *mz;
+
+   union {
+   struct { /* ICE driver specific values */
+   ice_tx_release_mbufs_t tx_rel_mbufs;
+   uint32_t q_teid; /* TX schedule node id. */
+   };
+   struct { /* I40E driver specific values */
+   uint8_t dcb_tc;
+   };
+   };
+};
+
 #endif /* IETH_RXTX_H_ */
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index ca128c7556..4d74513812 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3685,7 +3685,7 @@ i40e_dev_update_mbuf_stats(struct rte_eth_dev *ethdev,
struct i40e_mbuf_stats *mbuf_stats)
 {
uint16_t idx;
-   struct i40e_tx_queue *txq;
+   struct ieth_tx_queue *txq;
 
for (idx = 0; idx < ethdev->data->nb_tx_queues; idx++) {
txq = ethdev->data->tx_queues[idx];
@@ -6585,7 +6585,7 @@ i40e_dev_tx_init(struct i40e_pf *pf)
struct rte_eth_dev_data *data = pf->dev_data;
ui

[RFC PATCH 04/21] drivers/net: align Tx queue struct field names

2024-11-22 Thread Bruce Richardson
Across the various Intel drivers sometimes different names are given to
fields in the Tx queue structure which have the same function. Do some
renaming to align things better for future merging.

Signed-off-by: Bruce Richardson 
---
 drivers/net/i40e/i40e_rxtx.c|  6 +--
 drivers/net/i40e/i40e_rxtx.h|  2 +-
 drivers/net/iavf/iavf_rxtx.c| 60 -
 drivers/net/iavf/iavf_rxtx.h| 14 +++---
 drivers/net/iavf/iavf_rxtx_vec_avx2.c   | 18 
 drivers/net/iavf/iavf_rxtx_vec_avx512.c | 56 +++
 drivers/net/iavf/iavf_rxtx_vec_common.h | 24 +-
 drivers/net/iavf/iavf_rxtx_vec_sse.c| 18 
 drivers/net/iavf/iavf_vchnl.c   |  2 +-
 drivers/net/ixgbe/base/ixgbe_osdep.h|  2 +-
 drivers/net/ixgbe/ixgbe_rxtx.c  | 16 +++
 drivers/net/ixgbe/ixgbe_rxtx.h  |  6 +--
 drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c |  2 +-
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c  |  2 +-
 14 files changed, 114 insertions(+), 114 deletions(-)

diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index b628d83a42..20e72cac54 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2549,7 +2549,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
txq->vsi = vsi;
txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
-   txq->tx_ring_phys_addr = tz->iova;
+   txq->tx_ring_dma = tz->iova;
txq->tx_ring = (struct i40e_tx_desc *)tz->addr;
 
/* Allocate software ring */
@@ -2923,7 +2923,7 @@ i40e_tx_queue_init(struct i40e_tx_queue *txq)
/* clear the context structure first */
memset(&tx_ctx, 0, sizeof(tx_ctx));
tx_ctx.new_context = 1;
-   tx_ctx.base = txq->tx_ring_phys_addr / I40E_QUEUE_BASE_ADDR_UNIT;
+   tx_ctx.base = txq->tx_ring_dma / I40E_QUEUE_BASE_ADDR_UNIT;
tx_ctx.qlen = txq->nb_tx_desc;
 
 #ifdef RTE_LIBRTE_IEEE1588
@@ -3209,7 +3209,7 @@ i40e_fdir_setup_tx_resources(struct i40e_pf *pf)
txq->reg_idx = pf->fdir.fdir_vsi->base_queue;
txq->vsi = pf->fdir.fdir_vsi;
 
-   txq->tx_ring_phys_addr = tz->iova;
+   txq->tx_ring_dma = tz->iova;
txq->tx_ring = (struct i40e_tx_desc *)tz->addr;
 
/*
diff --git a/drivers/net/i40e/i40e_rxtx.h b/drivers/net/i40e/i40e_rxtx.h
index 47ece1eb7d..c5fbadc9e2 100644
--- a/drivers/net/i40e/i40e_rxtx.h
+++ b/drivers/net/i40e/i40e_rxtx.h
@@ -129,7 +129,7 @@ struct i40e_rx_queue {
  */
 struct i40e_tx_queue {
uint16_t nb_tx_desc; /**< number of TX descriptors */
-   uint64_t tx_ring_phys_addr; /**< TX ring DMA address */
+   rte_iova_t tx_ring_dma; /**< TX ring DMA address */
volatile struct i40e_tx_desc *tx_ring; /**< TX ring virtual address */
struct ieth_tx_entry *sw_ring; /**< virtual address of SW ring */
uint16_t tx_tail; /**< current value of tail register */
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index 1db34fd12f..b6d287245f 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -216,8 +216,8 @@ static inline bool
 check_tx_vec_allow(struct iavf_tx_queue *txq)
 {
if (!(txq->offloads & IAVF_TX_NO_VECTOR_FLAGS) &&
-   txq->rs_thresh >= IAVF_VPMD_TX_MAX_BURST &&
-   txq->rs_thresh <= IAVF_VPMD_TX_MAX_FREE_BUF) {
+   txq->tx_rs_thresh >= IAVF_VPMD_TX_MAX_BURST &&
+   txq->tx_rs_thresh <= IAVF_VPMD_TX_MAX_FREE_BUF) {
PMD_INIT_LOG(DEBUG, "Vector tx can be enabled on this txq.");
return true;
}
@@ -309,13 +309,13 @@ reset_tx_queue(struct iavf_tx_queue *txq)
}
 
txq->tx_tail = 0;
-   txq->nb_used = 0;
+   txq->nb_tx_used = 0;
 
txq->last_desc_cleaned = txq->nb_tx_desc - 1;
-   txq->nb_free = txq->nb_tx_desc - 1;
+   txq->nb_tx_free = txq->nb_tx_desc - 1;
 
-   txq->next_dd = txq->rs_thresh - 1;
-   txq->next_rs = txq->rs_thresh - 1;
+   txq->tx_next_dd = txq->tx_rs_thresh - 1;
+   txq->tx_next_rs = txq->tx_rs_thresh - 1;
 }
 
 static int
@@ -845,8 +845,8 @@ iavf_dev_tx_queue_setup(struct rte_eth_dev *dev,
}
 
txq->nb_tx_desc = nb_desc;
-   txq->rs_thresh = tx_rs_thresh;
-   txq->free_thresh = tx_free_thresh;
+   txq->tx_rs_thresh = tx_rs_thresh;
+   txq->tx_free_thresh = tx_free_thresh;
txq->queue_id = queue_idx;
txq->port_id = dev->data->port_id;
txq->offloads = offloads;
@@ -881,7 +881,7 @@ iavf_dev_tx_queue_setup(struct rte_eth_dev *dev,
rte_free(txq);
return -ENOMEM;
}
-   txq->tx_ring_phys_addr = mz->iova;
+   txq->tx_ring_dma = mz->iova;
txq->tx_ring = (struct iavf_tx_desc *)mz->addr;
 
txq->mz = mz;
@@ -2387,7 +2387,7 @@ iavf_xmit_cleanup(struct iavf_tx_queue *txq)
 
volatile struct iavf_tx_desc *txd = txq->tx_ring;
 
-   desc_to_clean_to = (uint16_t)(last_desc_cl

[RFC PATCH 07/21] net/iavf: use common Tx queue structure

2024-11-22 Thread Bruce Richardson
Merge in the few additional fields used by iavf driver and convert it to
using the common Tx queue structure also.

Signed-off-by: Bruce Richardson 
---
 drivers/common/intel_eth/ieth_rxtx.h| 16 +++-
 drivers/net/iavf/iavf.h |  2 +-
 drivers/net/iavf/iavf_ethdev.c  |  4 +-
 drivers/net/iavf/iavf_rxtx.c| 42 ++---
 drivers/net/iavf/iavf_rxtx.h| 49 +++--
 drivers/net/iavf/iavf_rxtx_vec_avx2.c   |  4 +-
 drivers/net/iavf/iavf_rxtx_vec_avx512.c | 14 +++
 drivers/net/iavf/iavf_rxtx_vec_common.h |  8 ++--
 drivers/net/iavf/iavf_rxtx_vec_sse.c|  8 ++--
 drivers/net/iavf/iavf_vchnl.c   |  4 +-
 10 files changed, 63 insertions(+), 88 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx.h 
b/drivers/common/intel_eth/ieth_rxtx.h
index 8b12ff59e4..986e0a6d42 100644
--- a/drivers/common/intel_eth/ieth_rxtx.h
+++ b/drivers/common/intel_eth/ieth_rxtx.h
@@ -32,8 +32,9 @@ typedef void (*ice_tx_release_mbufs_t)(struct ieth_tx_queue 
*txq);
 
 struct ieth_tx_queue {
union { /* TX ring virtual address */
-   volatile struct ice_tx_desc *ice_tx_ring;
volatile struct i40e_tx_desc *i40e_tx_ring;
+   volatile struct iavf_tx_desc *iavf_tx_ring;
+   volatile struct ice_tx_desc *ice_tx_ring;
};
volatile uint8_t *qtx_tail;   /* register address of tail */
struct ieth_tx_entry *sw_ring; /* virtual address of SW ring */
@@ -64,8 +65,9 @@ struct ieth_tx_queue {
_Bool tx_deferred_start; /* don't start this queue in dev start */
_Bool q_set; /* indicate if tx queue has been configured */
union {  /* the VSI this queue belongs to */
-   struct ice_vsi *ice_vsi;
struct i40e_vsi *i40e_vsi;
+   struct iavf_vsi *iavf_vsi;
+   struct ice_vsi *ice_vsi;
};
const struct rte_memzone *mz;
 
@@ -77,6 +79,16 @@ struct ieth_tx_queue {
struct { /* I40E driver specific values */
uint8_t dcb_tc;
};
+   struct { /* iavf driver specific values */
+   uint16_t ipsec_crypto_pkt_md_offset;
+   uint8_t rel_mbufs_type;
+#define IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG1 BIT(0)
+#define IAVF_TX_FLAGS_VLAN_TAG_LOC_L2TAG2 BIT(1)
+   uint8_t vlan_flag;
+   uint8_t tc;
+   uint8_t use_ctx : 1; /* if use the ctx desc, a packet 
needs
+ two descriptors */
+   };
};
 };
 
diff --git a/drivers/net/iavf/iavf.h b/drivers/net/iavf/iavf.h
index ad526c644c..7f52ca54f1 100644
--- a/drivers/net/iavf/iavf.h
+++ b/drivers/net/iavf/iavf.h
@@ -98,7 +98,7 @@
 
 struct iavf_adapter;
 struct iavf_rx_queue;
-struct iavf_tx_queue;
+struct ieth_tx_queue;
 
 
 struct iavf_ipsec_crypto_stats {
diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c
index 7f80cd6258..3d3803f5e9 100644
--- a/drivers/net/iavf/iavf_ethdev.c
+++ b/drivers/net/iavf/iavf_ethdev.c
@@ -954,7 +954,7 @@ static int
 iavf_start_queues(struct rte_eth_dev *dev)
 {
struct iavf_rx_queue *rxq;
-   struct iavf_tx_queue *txq;
+   struct ieth_tx_queue *txq;
int i;
uint16_t nb_txq, nb_rxq;
 
@@ -1885,7 +1885,7 @@ iavf_dev_update_mbuf_stats(struct rte_eth_dev *ethdev,
struct iavf_mbuf_stats *mbuf_stats)
 {
uint16_t idx;
-   struct iavf_tx_queue *txq;
+   struct ieth_tx_queue *txq;
 
for (idx = 0; idx < ethdev->data->nb_tx_queues; idx++) {
txq = ethdev->data->tx_queues[idx];
diff --git a/drivers/net/iavf/iavf_rxtx.c b/drivers/net/iavf/iavf_rxtx.c
index 2d0f8eda79..c0f7d12804 100644
--- a/drivers/net/iavf/iavf_rxtx.c
+++ b/drivers/net/iavf/iavf_rxtx.c
@@ -213,7 +213,7 @@ check_rx_vec_allow(struct iavf_rx_queue *rxq)
 }
 
 static inline bool
-check_tx_vec_allow(struct iavf_tx_queue *txq)
+check_tx_vec_allow(struct ieth_tx_queue *txq)
 {
if (!(txq->offloads & IAVF_TX_NO_VECTOR_FLAGS) &&
txq->tx_rs_thresh >= IAVF_VPMD_TX_MAX_BURST &&
@@ -282,7 +282,7 @@ reset_rx_queue(struct iavf_rx_queue *rxq)
 }
 
 static inline void
-reset_tx_queue(struct iavf_tx_queue *txq)
+reset_tx_queue(struct ieth_tx_queue *txq)
 {
struct ieth_tx_entry *txe;
uint32_t i, size;
@@ -388,7 +388,7 @@ release_rxq_mbufs(struct iavf_rx_queue *rxq)
 }
 
 static inline void
-release_txq_mbufs(struct iavf_tx_queue *txq)
+release_txq_mbufs(struct ieth_tx_queue *txq)
 {
uint16_t i;
 
@@ -778,7 +778,7 @@ iavf_dev_tx_queue_setup(struct rte_eth_dev *dev,
struct iavf_info *vf =
IAVF_DEV_PRIVATE_TO_VF(dev->data->dev_private);
struct iavf_vsi *vsi = &vf->vsi;
-   struct iavf_tx_queue *txq;
+   struct ieth_tx_queue *txq;
const struct rte_mem

Re: [PATCH v1 1/2] net/ntnic: fix incorrect error message

2024-11-22 Thread Stephen Hemminger
On Fri, 22 Nov 2024 17:50:21 +0100
Serhii Iliushyk  wrote:

> diff --git a/drivers/net/ntnic/nthw/flow_api/flow_api.c 
> b/drivers/net/ntnic/nthw/flow_api/flow_api.c
> index d4993eb58a..fd470ddd35 100644
> --- a/drivers/net/ntnic/nthw/flow_api/flow_api.c
> +++ b/drivers/net/ntnic/nthw/flow_api/flow_api.c
> @@ -81,6 +81,20 @@ static const struct {
>   /* 27 */ { "Internal creation of a tunnel end point port failed" },
>   /* 28 */ { "Unknown or unsupported flow action received" },
>   /* 29 */ { "Removing flow failed" },
> + /* 30 */ { "No output queue specified. Ignore this flow offload and 
> uses default queue"},
> + /* 31 */ { "No output queue found"},
> + /* 32 */ { "Unsupported EtherType or rejected caused by offload 
> policy"},
> + /* 33 */ { "Destination port specified is invalid or not reachable from 
> this NIC"},
> + /* 34 */ { "Partial offload is not supported in this configuration"},
> + /* 35 */ { "Match failed because of CAT CAM exhausted"},
> + /* 36 */ { "Match failed because of CAT CAM Key clashed with an 
> existing KCC Key"},
> + /* 37 */ { "Match failed because of CAT CAM write failed"},
> + /* 38 */ { "Partial flow mark too big for device"},
> + /* 39 */ { "Invalid priority value"},
> + /* 40 */ { "Multiple port_id actions for one flow is not supported"},
> + /* 41 */ { "Too long hash key for RSS"},
> + /* 42 */ { "Action AGE is not supported for flow in group 0"},
> + /* 43 */ { "Unknown error"},
>  };
>  

Tables like this often get out of sync. Some suggestions.

Use index base initializers, like:

const char *dbg_res_descr[] = {
[ RES_QUEUE] = "RES_QUEUE",
[ RES_CAT_CFN] =  "RES_CAT_CFN",

PS, why is this string table not static?

Still have to handle NULL string if table ends up missing an element.

Should also check that table has all the strings:

Like:
static_assert(RTE_DIM(err_msg) == ERR_MSG_NO_MSG);

void flow_nic_set_error(enum flow_nic_err_msg_e msg, struct rte_flow_error 
*error)
{
assert(msg < ERR_MSG_NO_MSG);



1. 


Re: [PATCH v3 1/3] ethdev: add description for KEEP CRC offload

2024-11-22 Thread Stephen Hemminger
On Fri, 19 Jul 2024 17:04:13 +0800
Jie Hai  wrote:

> From: Dengdui Huang 
> 
> The data exceeds the pkt_len in mbuf is inavailable for user.
  unavailable

> When KEEP CRC offload is enabled, CRC field length should be
> included in the pkt_len in mbuf. However, almost of drivers
> supported KEEP CRC feature didn't add the CRC data length to
> pkt_len. So it is very necessary to add comments for this.

All drivers must do the same thing, or this is a serious bug
in the drivers. Just changing a comment is not going to be helpful.

To fix this right:
 1. Do a test with one of the original drivers in DPDK that has this
feature. I would suggest ixgbe, mlx5 or bnxt.

 2. Add a test to the PMD tests that validates this (if there is not
one already).

 3. Put the documentation in a place where it shows up in user documentation.
Either in doxygen comment or in doc/guides/nics

 4. Verify that all devices conform to the desired behavior

I can help, but only have some old mlx5 cards to test here.
Just putting comment in ethdev.h is not enough.




Re: rte_fib network order bug

2024-11-22 Thread Robin Jarry

Vladimir Medvedkin, Nov 17, 2024 at 16:04:

[Robin]
I had not understood that it was *only* the lookups that were network 
order


[Morten]
When I saw the byte order flag the first time, it was not clear to me 
either that it only affected lookups - I too thought it covered the 
entire API of the library. This needs to be emphasized in the 
description of the flag. And the flag's name should contain LOOKUP 
[Morten] > And/or rename RTE_FIB_F_NETWORK_ORDER to 
RTE_FIB_F_NETWORK_ORDER_LOOKUP or similar.


There is a clear comment for this flag that it has effects on lookup. 
Repeating the statement with an exclamation mark seems too much. 
Moreover, at first this flag was named "RTE_FIB_FLAG_LOOKUP_BE" and it 
was suggested for renaming here: 
https://inbox.dpdk.org/dev/d4swpkoprd5z.87yiet3y...@redhat.com/


This is my bad then. I had misunderstood what this flag was for. 
I should have been more careful. You had clearly stated that it was only 
affecting the lookup.


So, feel free to submit patches adding this feature to the control 
plane API, but let's consider:


I can commit to working on that topic if we can get a consensus. In my 
opinion there are two different approaches:


1) Change all IPv4 routing *APIs* to only use network order addresses
=

This would make them consistent with all networking stacks (linux, vpp, 
bsd, etc.) and would avoid confusion from users (like me) who naively 
used these libraries with addresses generated with inet_pton() or 
addresses taken verbatim from IPv4 packet headers.


More importantly, it would make them consistent on big-endian and 
little-endian architectures. Currently, the same code could work 
(without any byte swap) on aarch4, but would not work on x86_64.


It would also make them consistent with their IPv6 counterparts which do 
not require any byteswap.


This would be a drastic and breaking change but I think this would be 
the better solution in the long run.


To ensure that potential users of these libraries will not miss this 
change, the uint32_t parameters should be changed to a rte_ipv4_addr

structure that follows the same idea than rte_ipv6_addr.

We could also simply use rte_be32_t types everywhere but it would expose 
potential users of these APIs with bugs that could not be found at 
compilation.


Internally, all these routing libraries would continue using host order 
integers, the changes I am suggesting only affect the public API.


2) Implement network order via opt-in flags
===

This would allow the same thing as solution 1) but would keep the 
default behaviour which I find confusing and inconsistent with IPv6 and 
with all IPv4 networking stacks that I know.


The other concern I have with that second solution is that the public 
APIs would continue using uint32_t parameters which would be only 
correct when the network-order mode is not enabled.


On the other hand, it does not break any API for users that do not use 
the flags.


There would need to be an additional RTE_IPV4_BE() macro to declare IPv4 
addresses in network order.


Any thoughts?



[RFC PATCH 13/21] net/iavf: use common Tx free fn for AVX-512

2024-11-22 Thread Bruce Richardson
Switch the iavf driver to use the common Tx free function. This requires
one additional parameter to that function, since iavf sometimes uses
context descriptors which means that we have double the descriptors per
SW ring slot.

Signed-off-by: Bruce Richardson 
---
 .../common/intel_eth/ieth_rxtx_vec_common.h   |   6 +-
 drivers/net/i40e/i40e_rxtx_vec_avx512.c   |   2 +-
 drivers/net/iavf/iavf_rxtx_vec_avx512.c   | 119 +-
 drivers/net/ice/ice_rxtx_vec_avx512.c |   2 +-
 4 files changed, 7 insertions(+), 122 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx_vec_common.h 
b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
index 61b48c88da..a4490f2dca 100644
--- a/drivers/common/intel_eth/ieth_rxtx_vec_common.h
+++ b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
@@ -158,7 +158,7 @@ ieth_tx_free_bufs(struct ieth_tx_queue *txq, 
ieth_desc_done_fn desc_done)
 }
 
 static __rte_always_inline int
-ieth_tx_free_bufs_vector(struct ieth_tx_queue *txq, ieth_desc_done_fn 
desc_done)
+ieth_tx_free_bufs_vector(struct ieth_tx_queue *txq, ieth_desc_done_fn 
desc_done, bool ctx_descs)
 {
int nb_free = 0;
struct rte_mbuf *free[IETH_VPMD_TX_MAX_FREE_BUF];
@@ -168,13 +168,13 @@ ieth_tx_free_bufs_vector(struct ieth_tx_queue *txq, 
ieth_desc_done_fn desc_done)
if (!desc_done(txq, txq->tx_next_dd))
return 0;
 
-   const uint32_t n = txq->tx_rs_thresh;
+   const uint32_t n = txq->tx_rs_thresh >> ctx_descs;
 
/* first buffer to free from S/W ring is at index
 * tx_next_dd - (tx_rs_thresh - 1)
 */
struct ieth_vec_tx_entry *txep = txq->sw_ring_v;
-   txep += txq->tx_next_dd - (n - 1);
+   txep += (txq->tx_next_dd >> ctx_descs) - (n - 1);
 
if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE && (n & 31) == 0) 
{
struct rte_mempool *mp = txep[0].mbuf->pool;
diff --git a/drivers/net/i40e/i40e_rxtx_vec_avx512.c 
b/drivers/net/i40e/i40e_rxtx_vec_avx512.c
index 23415c4949..0ab3a4f02c 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_avx512.c
+++ b/drivers/net/i40e/i40e_rxtx_vec_avx512.c
@@ -829,7 +829,7 @@ i40e_xmit_fixed_burst_vec_avx512(void *tx_queue, struct 
rte_mbuf **tx_pkts,
uint64_t rs = I40E_TX_DESC_CMD_RS | I40E_TD_CMD;
 
if (txq->nb_tx_free < txq->tx_free_thresh)
-   ieth_tx_free_bufs_vector(txq, i40e_tx_desc_done);
+   ieth_tx_free_bufs_vector(txq, i40e_tx_desc_done, false);
 
nb_commit = nb_pkts = (uint16_t)RTE_MIN(txq->nb_tx_free, nb_pkts);
if (unlikely(nb_pkts == 0))
diff --git a/drivers/net/iavf/iavf_rxtx_vec_avx512.c 
b/drivers/net/iavf/iavf_rxtx_vec_avx512.c
index c774c0c365..391fbfcd4d 100644
--- a/drivers/net/iavf/iavf_rxtx_vec_avx512.c
+++ b/drivers/net/iavf/iavf_rxtx_vec_avx512.c
@@ -1844,121 +1844,6 @@ 
iavf_recv_scattered_pkts_vec_avx512_flex_rxd_offload(void *rx_queue,
true);
 }
 
-static __rte_always_inline int
-iavf_tx_free_bufs_avx512(struct ieth_tx_queue *txq)
-{
-   struct ieth_vec_tx_entry *txep;
-   uint32_t n;
-   uint32_t i;
-   int nb_free = 0;
-   struct rte_mbuf *m, *free[IAVF_VPMD_TX_MAX_FREE_BUF];
-
-   /* check DD bits on threshold descriptor */
-   if ((txq->iavf_tx_ring[txq->tx_next_dd].cmd_type_offset_bsz &
-rte_cpu_to_le_64(IAVF_TXD_QW1_DTYPE_MASK)) !=
-   rte_cpu_to_le_64(IAVF_TX_DESC_DTYPE_DESC_DONE))
-   return 0;
-
-   n = txq->tx_rs_thresh >> txq->use_ctx;
-
-/* first buffer to free from S/W ring is at index
- * tx_next_dd - (tx_rs_thresh-1)
- */
-   txep = (void *)txq->sw_ring;
-   txep += (txq->tx_next_dd >> txq->use_ctx) - (n - 1);
-
-   if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE && (n & 31) == 0) 
{
-   struct rte_mempool *mp = txep[0].mbuf->pool;
-   struct rte_mempool_cache *cache = rte_mempool_default_cache(mp,
-   rte_lcore_id());
-   void **cache_objs;
-
-   if (!cache || cache->len == 0)
-   goto normal;
-
-   cache_objs = &cache->objs[cache->len];
-
-   if (n > RTE_MEMPOOL_CACHE_MAX_SIZE) {
-   rte_mempool_ops_enqueue_bulk(mp, (void *)txep, n);
-   goto done;
-   }
-
-   /* The cache follows the following algorithm
-*   1. Add the objects to the cache
-*   2. Anything greater than the cache min value (if it 
crosses the
-*   cache flush threshold) is flushed to the ring.
-*/
-   /* Add elements back into the cache */
-   uint32_t copied = 0;
-   /* n is multiple of 32 */
-   while (copied < n) {
-#ifdef RTE_ARCH_64
-   const __m512i a = _mm512_loadu_si512(&txep[c

[RFC PATCH 15/21] net/i40e: use common Tx queue mbuf cleanup fn

2024-11-22 Thread Bruce Richardson
Update driver to be similar to the "ice" driver and use the common mbuf
ring cleanup code on shutdown of a Tx queue.

Signed-off-by: Bruce Richardson 
---
 drivers/net/i40e/i40e_ethdev.h |  4 +-
 drivers/net/i40e/i40e_rxtx.c   | 71 --
 drivers/net/i40e/i40e_rxtx.h   |  1 -
 3 files changed, 10 insertions(+), 66 deletions(-)

diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 8c8c0a1bcf..0da85b1212 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -1260,12 +1260,12 @@ struct i40e_adapter {
 
/* For RSS reta table update */
uint8_t rss_reta_updated;
-#ifdef RTE_ARCH_X86
+
+   /* used only on x86, zero on other architectures */
bool rx_use_avx2;
bool rx_use_avx512;
bool tx_use_avx2;
bool tx_use_avx512;
-#endif
 };
 
 /**
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 29df978019..362a71c8b2 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -30,6 +30,7 @@
 #include "base/i40e_type.h"
 #include "i40e_ethdev.h"
 #include "i40e_rxtx.h"
+#include "ieth_rxtx.h"
 
 #define DEFAULT_TX_RS_THRESH   32
 #define DEFAULT_TX_FREE_THRESH 32
@@ -1875,6 +1876,7 @@ i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
int err;
struct ieth_tx_queue *txq;
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+   const struct i40e_adapter *ad = 
I40E_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
 
PMD_INIT_FUNC_TRACE();
 
@@ -1889,6 +1891,9 @@ i40e_dev_tx_queue_start(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
PMD_DRV_LOG(WARNING, "TX queue %u is deferred start",
tx_queue_id);
 
+   txq->vector_tx = ad->tx_vec_allowed;
+   txq->vector_sw_ring = ad->tx_use_avx512;
+
/*
 * tx_queue_id is queue id application refers to, while
 * rxq->reg_idx is the real queue index.
@@ -1929,7 +1934,7 @@ i40e_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
return err;
}
 
-   i40e_tx_queue_release_mbufs(txq);
+   ieth_txq_release_all_mbufs(txq);
i40e_reset_tx_queue(txq);
dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
 
@@ -2604,7 +2609,7 @@ i40e_tx_queue_release(void *txq)
return;
}
 
-   i40e_tx_queue_release_mbufs(q);
+   ieth_txq_release_all_mbufs(q);
rte_free(q->sw_ring);
rte_memzone_free(q->mz);
rte_free(q);
@@ -2701,66 +2706,6 @@ i40e_reset_rx_queue(struct i40e_rx_queue *rxq)
rxq->rxrearm_nb = 0;
 }
 
-void
-i40e_tx_queue_release_mbufs(struct ieth_tx_queue *txq)
-{
-   struct rte_eth_dev *dev;
-   uint16_t i;
-
-   if (!txq || !txq->sw_ring) {
-   PMD_DRV_LOG(DEBUG, "Pointer to txq or sw_ring is NULL");
-   return;
-   }
-
-   dev = &rte_eth_devices[txq->port_id];
-
-   /**
-*  vPMD tx will not set sw_ring's mbuf to NULL after free,
-*  so need to free remains more carefully.
-*/
-#ifdef CC_AVX512_SUPPORT
-   if (dev->tx_pkt_burst == i40e_xmit_pkts_vec_avx512) {
-   struct ieth_vec_tx_entry *swr = (void *)txq->sw_ring;
-
-   i = txq->tx_next_dd - txq->tx_rs_thresh + 1;
-   if (txq->tx_tail < i) {
-   for (; i < txq->nb_tx_desc; i++) {
-   rte_pktmbuf_free_seg(swr[i].mbuf);
-   swr[i].mbuf = NULL;
-   }
-   i = 0;
-   }
-   for (; i < txq->tx_tail; i++) {
-   rte_pktmbuf_free_seg(swr[i].mbuf);
-   swr[i].mbuf = NULL;
-   }
-   return;
-   }
-#endif
-   if (dev->tx_pkt_burst == i40e_xmit_pkts_vec_avx2 ||
-   dev->tx_pkt_burst == i40e_xmit_pkts_vec) {
-   i = txq->tx_next_dd - txq->tx_rs_thresh + 1;
-   if (txq->tx_tail < i) {
-   for (; i < txq->nb_tx_desc; i++) {
-   rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
-   txq->sw_ring[i].mbuf = NULL;
-   }
-   i = 0;
-   }
-   for (; i < txq->tx_tail; i++) {
-   rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
-   txq->sw_ring[i].mbuf = NULL;
-   }
-   } else {
-   for (i = 0; i < txq->nb_tx_desc; i++) {
-   if (txq->sw_ring[i].mbuf) {
-   rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
-   txq->sw_ring[i].mbuf = NULL;
-   }
-   }
-   }
-}
-
 static int
 i40e_tx_done_cleanup_full(struct ieth_tx_queue *txq,
u

[RFC PATCH 16/21] net/ixgbe: use common Tx queue mbuf cleanup fn

2024-11-22 Thread Bruce Richardson
Update driver to use the common cleanup function.

Signed-off-by: Bruce Richardson 
---
 drivers/net/ixgbe/ixgbe_rxtx.c| 22 +++---
 drivers/net/ixgbe/ixgbe_rxtx.h|  1 -
 drivers/net/ixgbe/ixgbe_rxtx_vec_common.h | 28 ++-
 drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c   |  7 --
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c|  7 --
 5 files changed, 5 insertions(+), 60 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index e80bd6fccc..0d5f4803e5 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2334,21 +2334,6 @@ ixgbe_recv_pkts_lro_bulk_alloc(void *rx_queue, struct 
rte_mbuf **rx_pkts,
  *
  **/
 
-static void __rte_cold
-ixgbe_tx_queue_release_mbufs(struct ieth_tx_queue *txq)
-{
-   unsigned i;
-
-   if (txq->sw_ring != NULL) {
-   for (i = 0; i < txq->nb_tx_desc; i++) {
-   if (txq->sw_ring[i].mbuf != NULL) {
-   rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
-   txq->sw_ring[i].mbuf = NULL;
-   }
-   }
-   }
-}
-
 static int
 ixgbe_tx_done_cleanup_full(struct ieth_tx_queue *txq, uint32_t free_cnt)
 {
@@ -2472,7 +2457,7 @@ static void __rte_cold
 ixgbe_tx_queue_release(struct ieth_tx_queue *txq)
 {
if (txq != NULL && txq->ops != NULL) {
-   txq->ops->release_mbufs(txq);
+   ieth_txq_release_all_mbufs(txq);
txq->ops->free_swring(txq);
rte_memzone_free(txq->mz);
rte_free(txq);
@@ -2526,7 +2511,6 @@ ixgbe_reset_tx_queue(struct ieth_tx_queue *txq)
 }
 
 static const struct ixgbe_txq_ops def_txq_ops = {
-   .release_mbufs = ixgbe_tx_queue_release_mbufs,
.free_swring = ixgbe_tx_free_swring,
.reset = ixgbe_reset_tx_queue,
 };
@@ -3380,7 +3364,7 @@ ixgbe_dev_clear_queues(struct rte_eth_dev *dev)
struct ieth_tx_queue *txq = dev->data->tx_queues[i];
 
if (txq != NULL) {
-   txq->ops->release_mbufs(txq);
+   ieth_txq_release_all_mbufs(txq);
txq->ops->reset(txq);
dev->data->tx_queue_state[i] = 
RTE_ETH_QUEUE_STATE_STOPPED;
}
@@ -5654,7 +5638,7 @@ ixgbe_dev_tx_queue_stop(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
}
 
if (txq->ops != NULL) {
-   txq->ops->release_mbufs(txq);
+   ieth_txq_release_all_mbufs(txq);
txq->ops->reset(txq);
}
dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h
index 5b56e48498..0a990ee1ca 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx.h
@@ -181,7 +181,6 @@ struct ixgbe_advctx_info {
 };
 
 struct ixgbe_txq_ops {
-   void (*release_mbufs)(struct ieth_tx_queue *txq);
void (*free_swring)(struct ieth_tx_queue *txq);
void (*reset)(struct ieth_tx_queue *txq);
 };
diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h 
b/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h
index c2fcc51610..3064b92533 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_common.h
@@ -78,32 +78,6 @@ tx_backlog_entry(struct ieth_vec_tx_entry *txep,
txep[i].mbuf = tx_pkts[i];
 }
 
-static inline void
-_ixgbe_tx_queue_release_mbufs_vec(struct ieth_tx_queue *txq)
-{
-   unsigned int i;
-   struct ieth_vec_tx_entry *txe;
-   const uint16_t max_desc = (uint16_t)(txq->nb_tx_desc - 1);
-
-   if (txq->sw_ring == NULL || txq->nb_tx_free == max_desc)
-   return;
-
-   /* release the used mbufs in sw_ring */
-   for (i = txq->tx_next_dd - (txq->tx_rs_thresh - 1);
-i != txq->tx_tail;
-i = (i + 1) % txq->nb_tx_desc) {
-   txe = &txq->sw_ring_v[i];
-   rte_pktmbuf_free_seg(txe->mbuf);
-   }
-   txq->nb_tx_free = max_desc;
-
-   /* reset tx_entry */
-   for (i = 0; i < txq->nb_tx_desc; i++) {
-   txe = &txq->sw_ring_v[i];
-   txe->mbuf = NULL;
-   }
-}
-
 static inline void
 _ixgbe_rx_queue_release_mbufs_vec(struct ixgbe_rx_queue *rxq)
 {
@@ -208,6 +182,8 @@ ixgbe_txq_vec_setup_default(struct ieth_tx_queue *txq,
/* leave the first one for overflow */
txq->sw_ring_v = txq->sw_ring_v + 1;
txq->ops = txq_ops;
+   txq->vector_tx = 1;
+   txq->vector_sw_ring = 1;
 
return 0;
 }
diff --git a/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c 
b/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c
index b51072b294..2336a86dd2 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c
@@ -633,12 +633,6 @@ ixgbe_xmit_fixed_burst_vec(void *tx_qu

[RFC PATCH 14/21] net/ice: move Tx queue mbuf cleanup fn to common

2024-11-22 Thread Bruce Richardson
The functions to loop over the Tx queue and clean up all the mbufs on
it, e.g. for queue shutdown, is not device specific and so can move into
the common/intel_eth driver. Only complication is ensuring that the
correct ring format, either minimal vector or full structure, is used.
Ice driver currently uses two functions and a function pointer to help
with this - though actually one of those functions uses a further check
inside it - so we can simplify this down to just one common function,
with a flag set in the appropriate place. This avoids checking for
AVX-512-specific functions, which were the only function using the
smaller struct in this driver.

Signed-off-by: Bruce Richardson 
---
 drivers/common/intel_eth/ieth_rxtx.h  | 49 -
 drivers/net/ice/ice_dcf_ethdev.c  |  5 +--
 drivers/net/ice/ice_ethdev.h  |  3 +-
 drivers/net/ice/ice_rxtx.c| 33 +
 drivers/net/ice/ice_rxtx_vec_common.h | 51 ---
 drivers/net/ice/ice_rxtx_vec_sse.c|  4 +--
 6 files changed, 61 insertions(+), 84 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx.h 
b/drivers/common/intel_eth/ieth_rxtx.h
index c336ec81b3..c8e5e1ad76 100644
--- a/drivers/common/intel_eth/ieth_rxtx.h
+++ b/drivers/common/intel_eth/ieth_rxtx.h
@@ -65,6 +65,8 @@ struct ieth_tx_queue {
rte_iova_t tx_ring_dma;/* TX ring DMA address */
_Bool tx_deferred_start; /* don't start this queue in dev start */
_Bool q_set; /* indicate if tx queue has been configured */
+   _Bool vector_tx; /* port is using vector TX */
+   _Bool vector_sw_ring;/* port is using vectorized SW ring 
(ieth_vec_tx_entry) */
union {  /* the VSI this queue belongs to */
struct i40e_vsi *i40e_vsi;
struct iavf_vsi *iavf_vsi;
@@ -74,7 +76,6 @@ struct ieth_tx_queue {
 
union {
struct { /* ICE driver specific values */
-   ice_tx_release_mbufs_t tx_rel_mbufs;
uint32_t q_teid; /* TX schedule node id. */
};
struct { /* I40E driver specific values */
@@ -102,4 +103,50 @@ struct ieth_tx_queue {
};
 };
 
+#define IETH_FREE_BUFS_LOOP(txq, swr, start) do { \
+   uint16_t i = start; \
+   if (txq->tx_tail < i) { \
+   for (; i < txq->nb_tx_desc; i++) { \
+   rte_pktmbuf_free_seg(swr[i].mbuf); \
+   swr[i].mbuf = NULL; \
+   } \
+   i = 0; \
+   } \
+   for (; i < txq->tx_tail; i++) { \
+   rte_pktmbuf_free_seg(swr[i].mbuf); \
+   swr[i].mbuf = NULL; \
+   } \
+} while(0)
+
+static inline void
+ieth_txq_release_all_mbufs(struct ieth_tx_queue *txq)
+{
+   if (unlikely(!txq || !txq->sw_ring))
+   return;
+
+   if (!txq->vector_tx) {
+   for (uint16_t i = 0; i < txq->nb_tx_desc; i++) {
+   if (txq->sw_ring[i].mbuf != NULL) {
+   rte_pktmbuf_free_seg(txq->sw_ring[i].mbuf);
+   txq->sw_ring[i].mbuf = NULL;
+   }
+   }
+   return;
+   }
+
+   /**
+*  vPMD tx will not set sw_ring's mbuf to NULL after free,
+*  so need to free remains more carefully.
+*/
+   const uint16_t start = txq->tx_next_dd - txq->tx_rs_thresh + 1;
+
+   if (txq->vector_sw_ring) {
+   struct ieth_vec_tx_entry *swr = txq->sw_ring_v;
+   IETH_FREE_BUFS_LOOP(txq, swr, start);
+   } else {
+   struct ieth_tx_entry *swr = txq->sw_ring;
+   IETH_FREE_BUFS_LOOP(txq, swr, start);
+   }
+}
+
 #endif /* IETH_RXTX_H_ */
diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c
index b5bab35d77..54d17875bb 100644
--- a/drivers/net/ice/ice_dcf_ethdev.c
+++ b/drivers/net/ice/ice_dcf_ethdev.c
@@ -24,6 +24,7 @@
 #include "ice_generic_flow.h"
 #include "ice_dcf_ethdev.h"
 #include "ice_rxtx.h"
+#include "ieth_rxtx.h"
 
 #define DCF_NUM_MACADDR_MAX  64
 
@@ -500,7 +501,7 @@ ice_dcf_tx_queue_stop(struct rte_eth_dev *dev, uint16_t 
tx_queue_id)
}
 
txq = dev->data->tx_queues[tx_queue_id];
-   txq->tx_rel_mbufs(txq);
+   ieth_txq_release_all_mbufs(txq);
reset_tx_queue(txq);
dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STOPPED;
 
@@ -650,7 +651,7 @@ ice_dcf_stop_queues(struct rte_eth_dev *dev)
txq = dev->data->tx_queues[i];
if (!txq)
continue;
-   txq->tx_rel_mbufs(txq);
+   ieth_txq_release_all_mbufs(txq);
reset_tx_queue(txq);
dev->data->tx_queue_state[i] = RTE_ETH_QUEUE_STATE_STOPPED;
}
d

[RFC PATCH 09/21] net/ixgbe: use common Tx queue structure

2024-11-22 Thread Bruce Richardson
Merge in additional fields used by the ixgbe driver and then convert it
over to using the common Tx queue structure.

Signed-off-by: Bruce Richardson 
---
 drivers/common/intel_eth/ieth_rxtx.h  | 14 +++-
 drivers/net/ixgbe/ixgbe_ethdev.c  |  4 +-
 .../ixgbe/ixgbe_recycle_mbufs_vec_common.c|  2 +-
 drivers/net/ixgbe/ixgbe_rxtx.c| 64 +--
 drivers/net/ixgbe/ixgbe_rxtx.h| 56 ++--
 drivers/net/ixgbe/ixgbe_rxtx_vec_common.h | 10 +--
 drivers/net/ixgbe/ixgbe_rxtx_vec_neon.c   | 10 +--
 drivers/net/ixgbe/ixgbe_rxtx_vec_sse.c| 10 +--
 8 files changed, 68 insertions(+), 102 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx.h 
b/drivers/common/intel_eth/ieth_rxtx.h
index 986e0a6d42..9f8a1d7141 100644
--- a/drivers/common/intel_eth/ieth_rxtx.h
+++ b/drivers/common/intel_eth/ieth_rxtx.h
@@ -35,9 +35,13 @@ struct ieth_tx_queue {
volatile struct i40e_tx_desc *i40e_tx_ring;
volatile struct iavf_tx_desc *iavf_tx_ring;
volatile struct ice_tx_desc *ice_tx_ring;
+   volatile union ixgbe_adv_tx_desc *ixgbe_tx_ring;
};
volatile uint8_t *qtx_tail;   /* register address of tail */
-   struct ieth_tx_entry *sw_ring; /* virtual address of SW ring */
+   union {
+   struct ieth_tx_entry *sw_ring; /* virtual address of SW ring */
+   struct ieth_vec_tx_entry *sw_ring_v;
+   };
rte_iova_t tx_ring_dma;/* TX ring DMA address */
uint16_t nb_tx_desc;   /* number of TX descriptors */
uint16_t tx_tail; /* current value of tail register */
@@ -89,6 +93,14 @@ struct ieth_tx_queue {
uint8_t use_ctx : 1; /* if use the ctx desc, a packet 
needs
  two descriptors */
};
+   struct { /* ixgbe specific values */
+   const struct ixgbe_txq_ops *ops;
+   struct ixgbe_advctx_info *ctx_cache;
+   uint32_t ctx_curr;
+#ifdef RTE_LIB_SECURITY
+   uint8_t using_ipsec;  /**< indicates that IPsec TX 
feature is in use */
+#endif
+   };
};
 };
 
diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c
index eb431889c3..e774c51f67 100644
--- a/drivers/net/ixgbe/ixgbe_ethdev.c
+++ b/drivers/net/ixgbe/ixgbe_ethdev.c
@@ -1116,7 +1116,7 @@ eth_ixgbe_dev_init(struct rte_eth_dev *eth_dev, void 
*init_params __rte_unused)
 * RX and TX function.
 */
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
-   struct ixgbe_tx_queue *txq;
+   struct ieth_tx_queue *txq;
/* TX queue function in primary, set by last queue initialized
 * Tx queue may not initialized by primary process
 */
@@ -1621,7 +1621,7 @@ eth_ixgbevf_dev_init(struct rte_eth_dev *eth_dev)
 * RX function
 */
if (rte_eal_process_type() != RTE_PROC_PRIMARY) {
-   struct ixgbe_tx_queue *txq;
+   struct ieth_tx_queue *txq;
/* TX queue function in primary, set by last queue initialized
 * Tx queue may not initialized by primary process
 */
diff --git a/drivers/net/ixgbe/ixgbe_recycle_mbufs_vec_common.c 
b/drivers/net/ixgbe/ixgbe_recycle_mbufs_vec_common.c
index 546825f334..d6edc9d0aa 100644
--- a/drivers/net/ixgbe/ixgbe_recycle_mbufs_vec_common.c
+++ b/drivers/net/ixgbe/ixgbe_recycle_mbufs_vec_common.c
@@ -51,7 +51,7 @@ uint16_t
 ixgbe_recycle_tx_mbufs_reuse_vec(void *tx_queue,
struct rte_eth_recycle_rxq_info *recycle_rxq_info)
 {
-   struct ixgbe_tx_queue *txq = tx_queue;
+   struct ieth_tx_queue *txq = tx_queue;
struct ieth_tx_entry *txep;
struct rte_mbuf **rxep;
int i, n;
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 96eafd52a0..e80bd6fccc 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -98,7 +98,7 @@
  * Return the total number of buffers freed.
  */
 static __rte_always_inline int
-ixgbe_tx_free_bufs(struct ixgbe_tx_queue *txq)
+ixgbe_tx_free_bufs(struct ieth_tx_queue *txq)
 {
struct ieth_tx_entry *txep;
uint32_t status;
@@ -195,7 +195,7 @@ tx1(volatile union ixgbe_adv_tx_desc *txdp, struct rte_mbuf 
**pkts)
  * Copy mbuf pointers to the S/W ring.
  */
 static inline void
-ixgbe_tx_fill_hw_ring(struct ixgbe_tx_queue *txq, struct rte_mbuf **pkts,
+ixgbe_tx_fill_hw_ring(struct ieth_tx_queue *txq, struct rte_mbuf **pkts,
  uint16_t nb_pkts)
 {
volatile union ixgbe_adv_tx_desc *txdp = 
&(txq->ixgbe_tx_ring[txq->tx_tail]);
@@ -231,7 +231,7 @@ static inline uint16_t
 tx_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 uint16_t nb_pkts)
 {
-   struct ixgbe_tx_queue 

[RFC PATCH 11/21] common/intel_eth: add post-Tx buffer free function

2024-11-22 Thread Bruce Richardson
The actions taken for post-Tx buffer free for the SSE and AVX drivers
for i40e, iavf and ice drivers are all common, so centralize those in
common/intel_eth driver.

Signed-off-by: Bruce Richardson 
---
 .../common/intel_eth/ieth_rxtx_vec_common.h   | 72 +++
 drivers/net/i40e/i40e_rxtx_vec_common.h   | 72 +++
 drivers/net/iavf/iavf_rxtx_vec_common.h   | 61 +++-
 drivers/net/ice/ice_rxtx_vec_common.h | 61 +++-
 4 files changed, 99 insertions(+), 167 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx_vec_common.h 
b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
index 49096d2a41..aadc3dcfac 100644
--- a/drivers/common/intel_eth/ieth_rxtx_vec_common.h
+++ b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
@@ -8,6 +8,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "ieth_rxtx.h"
 
 #define IETH_RX_BURST 32
@@ -85,4 +86,75 @@ ieth_tx_backlog_entry(struct ieth_tx_entry *txep, struct 
rte_mbuf **tx_pkts, uin
for (uint16_t i = 0; i < (int)nb_pkts; ++i)
txep[i].mbuf = tx_pkts[i];
 }
+
+#define IETH_VPMD_TX_MAX_FREE_BUF 64
+
+typedef int (*ieth_desc_done_fn)(struct ieth_tx_queue *txq, uint16_t idx);
+
+static __rte_always_inline int
+ieth_tx_free_bufs(struct ieth_tx_queue *txq, ieth_desc_done_fn desc_done)
+{
+   struct ieth_tx_entry *txep;
+   uint32_t n;
+   uint32_t i;
+   int nb_free = 0;
+   struct rte_mbuf *m, *free[IETH_VPMD_TX_MAX_FREE_BUF];
+
+   /* check DD bits on threshold descriptor */
+   if (!desc_done(txq, txq->tx_next_dd))
+   return 0;
+
+   n = txq->tx_rs_thresh;
+
+/* first buffer to free from S/W ring is at index
+ * tx_next_dd - (tx_rs_thresh-1)
+ */
+   txep = &txq->sw_ring[txq->tx_next_dd - (n - 1)];
+
+   if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) {
+   for (i = 0; i < n; i++) {
+   free[i] = txep[i].mbuf;
+   /* no need to reset txep[i].mbuf in vector path */
+   }
+   rte_mempool_put_bulk(free[0]->pool, (void **)free, n);
+   goto done;
+   }
+
+   m = rte_pktmbuf_prefree_seg(txep[0].mbuf);
+   if (likely(m != NULL)) {
+   free[0] = m;
+   nb_free = 1;
+   for (i = 1; i < n; i++) {
+   m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
+   if (likely(m != NULL)) {
+   if (likely(m->pool == free[0]->pool)) {
+   free[nb_free++] = m;
+   } else {
+   rte_mempool_put_bulk(free[0]->pool,
+(void *)free,
+nb_free);
+   free[0] = m;
+   nb_free = 1;
+   }
+   }
+   }
+   rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
+   } else {
+   for (i = 1; i < n; i++) {
+   m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
+   if (m != NULL)
+   rte_mempool_put(m->pool, m);
+   }
+   }
+
+done:
+   /* buffers were freed, update counters */
+   txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + txq->tx_rs_thresh);
+   txq->tx_next_dd = (uint16_t)(txq->tx_next_dd + txq->tx_rs_thresh);
+   if (txq->tx_next_dd >= txq->nb_tx_desc)
+   txq->tx_next_dd = (uint16_t)(txq->tx_rs_thresh - 1);
+
+   return txq->tx_rs_thresh;
+}
+
 #endif /* IETH_RXTX_VEC_COMMON_H_ */
diff --git a/drivers/net/i40e/i40e_rxtx_vec_common.h 
b/drivers/net/i40e/i40e_rxtx_vec_common.h
index 66e38994a5..60f2130f4d 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_common.h
+++ b/drivers/net/i40e/i40e_rxtx_vec_common.h
@@ -16,72 +16,18 @@
 #pragma GCC diagnostic ignored "-Wcast-qual"
 #endif
 
+static inline int
+i40e_tx_desc_done(struct ieth_tx_queue *txq, uint16_t idx)
+{
+   return (txq->i40e_tx_ring[idx].cmd_type_offset_bsz &
+   rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) ==
+   rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE);
+}
+
 static __rte_always_inline int
 i40e_tx_free_bufs(struct ieth_tx_queue *txq)
 {
-   struct ieth_tx_entry *txep;
-   uint32_t n;
-   uint32_t i;
-   int nb_free = 0;
-   struct rte_mbuf *m, *free[RTE_I40E_TX_MAX_FREE_BUF_SZ];
-
-   /* check DD bits on threshold descriptor */
-   if ((txq->i40e_tx_ring[txq->tx_next_dd].cmd_type_offset_bsz &
-   rte_cpu_to_le_64(I40E_TXD_QW1_DTYPE_MASK)) !=
-   rte_cpu_to_le_64(I40E_TX_DESC_DTYPE_DESC_DONE))
-   return 0;
-
-   n = txq->tx_rs_thresh;
-
-/* first buf

[RFC PATCH 12/21] common/intel_eth: add Tx buffer free fn for AVX-512

2024-11-22 Thread Bruce Richardson
AVX-512 code paths for ice and i40e drivers are common, and differ from
the regular post-Tx free function in that the SW ring from which the
buffers are freed does not contain anything other than the mbuf pointer.
Merge these into a common function in common/intel_eth saving
duplication.

Signed-off-by: Bruce Richardson 
---
 .../common/intel_eth/ieth_rxtx_vec_common.h   |  93 ++
 drivers/net/i40e/i40e_rxtx_vec_avx512.c   | 114 +
 drivers/net/ice/ice_rxtx_vec_avx512.c | 117 +-
 3 files changed, 95 insertions(+), 229 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx_vec_common.h 
b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
index aadc3dcfac..61b48c88da 100644
--- a/drivers/common/intel_eth/ieth_rxtx_vec_common.h
+++ b/drivers/common/intel_eth/ieth_rxtx_vec_common.h
@@ -157,4 +157,97 @@ ieth_tx_free_bufs(struct ieth_tx_queue *txq, 
ieth_desc_done_fn desc_done)
return txq->tx_rs_thresh;
 }
 
+static __rte_always_inline int
+ieth_tx_free_bufs_vector(struct ieth_tx_queue *txq, ieth_desc_done_fn 
desc_done)
+{
+   int nb_free = 0;
+   struct rte_mbuf *free[IETH_VPMD_TX_MAX_FREE_BUF];
+   struct rte_mbuf *m;
+
+   /* check DD bits on threshold descriptor */
+   if (!desc_done(txq, txq->tx_next_dd))
+   return 0;
+
+   const uint32_t n = txq->tx_rs_thresh;
+
+   /* first buffer to free from S/W ring is at index
+* tx_next_dd - (tx_rs_thresh - 1)
+*/
+   struct ieth_vec_tx_entry *txep = txq->sw_ring_v;
+   txep += txq->tx_next_dd - (n - 1);
+
+   if (txq->offloads & RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE && (n & 31) == 0) 
{
+   struct rte_mempool *mp = txep[0].mbuf->pool;
+   void **cache_objs;
+   struct rte_mempool_cache *cache = rte_mempool_default_cache(mp,
+   rte_lcore_id());
+
+   if (!cache || cache->len == 0)
+   goto normal;
+
+   cache_objs = &cache->objs[cache->len];
+
+   if (n > RTE_MEMPOOL_CACHE_MAX_SIZE) {
+   rte_mempool_ops_enqueue_bulk(mp, (void *)txep, n);
+   goto done;
+   }
+
+   /* The cache follows the following algorithm
+*   1. Add the objects to the cache
+*   2. Anything greater than the cache min value (if it
+*   crosses the cache flush threshold) is flushed to the ring.
+*/
+   /* Add elements back into the cache */
+   uint32_t copied = 0;
+   /* n is multiple of 32 */
+   while (copied < n) {
+   memcpy(&cache_objs[copied], &txep[copied], 32 * 
sizeof(void *));
+   copied += 32;
+   }
+   cache->len += n;
+
+   if (cache->len >= cache->flushthresh) {
+   rte_mempool_ops_enqueue_bulk(mp, 
&cache->objs[cache->size],
+cache->len - cache->size);
+   cache->len = cache->size;
+   }
+   goto done;
+   }
+
+normal:
+   m = rte_pktmbuf_prefree_seg(txep[0].mbuf);
+   if (likely(m)) {
+   free[0] = m;
+   nb_free = 1;
+   for (uint32_t i = 1; i < n; i++) {
+   m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
+   if (likely(m)) {
+   if (likely(m->pool == free[0]->pool)) {
+   free[nb_free++] = m;
+   } else {
+   rte_mempool_put_bulk(free[0]->pool, 
(void *)free, nb_free);
+   free[0] = m;
+   nb_free = 1;
+   }
+   }
+   }
+   rte_mempool_put_bulk(free[0]->pool, (void **)free, nb_free);
+   } else {
+   for (uint32_t i = 1; i < n; i++) {
+   m = rte_pktmbuf_prefree_seg(txep[i].mbuf);
+   if (m)
+   rte_mempool_put(m->pool, m);
+   }
+   }
+
+done:
+   /* buffers were freed, update counters */
+   txq->nb_tx_free = (uint16_t)(txq->nb_tx_free + txq->tx_rs_thresh);
+   txq->tx_next_dd = (uint16_t)(txq->tx_next_dd + txq->tx_rs_thresh);
+   if (txq->tx_next_dd >= txq->nb_tx_desc)
+   txq->tx_next_dd = (uint16_t)(txq->tx_rs_thresh - 1);
+
+   return txq->tx_rs_thresh;
+}
+
 #endif /* IETH_RXTX_VEC_COMMON_H_ */
diff --git a/drivers/net/i40e/i40e_rxtx_vec_avx512.c 
b/drivers/net/i40e/i40e_rxtx_vec_avx512.c
index b4b38d7db6..23415c4949 100644
--- a/drivers/net/i40e/i40e_rxtx_vec_avx512.c
+++ b/drivers/net/i40e/i40e_rxtx_vec_avx512.c
@@ -754,118 +754,6 @@ i40e_recv_scattered_pkts_vec_avx512(void *rx_queue,

[RFC PATCH 08/21] net/ixgbe: convert Tx queue context cache field to ptr

2024-11-22 Thread Bruce Richardson
Rather than having a two element array of context cache values inside
the Tx queue structure, convert it to a pointer to a cache at the end of
the structure. This makes future merging of the structure easier as we
don't need the "ixgbe_advctx_info" struct defined when defining a
combined queue structure.

Signed-off-by: Bruce Richardson 
---
 drivers/net/ixgbe/ixgbe_rxtx.c | 7 ---
 drivers/net/ixgbe/ixgbe_rxtx.h | 4 ++--
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index c3b704c201..96eafd52a0 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2522,8 +2522,7 @@ ixgbe_reset_tx_queue(struct ixgbe_tx_queue *txq)
txq->last_desc_cleaned = (uint16_t)(txq->nb_tx_desc - 1);
txq->nb_tx_free = (uint16_t)(txq->nb_tx_desc - 1);
txq->ctx_curr = 0;
-   memset((void *)&txq->ctx_cache, 0,
-   IXGBE_CTX_NUM * sizeof(struct ixgbe_advctx_info));
+   memset(txq->ctx_cache, 0, IXGBE_CTX_NUM * sizeof(struct 
ixgbe_advctx_info));
 }
 
 static const struct ixgbe_txq_ops def_txq_ops = {
@@ -2741,10 +2740,12 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
}
 
/* First allocate the tx queue data structure */
-   txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct 
ixgbe_tx_queue),
+   txq = rte_zmalloc_socket("ethdev TX queue", sizeof(struct 
ixgbe_tx_queue) +
+   sizeof(struct ixgbe_advctx_info) * 
IXGBE_CTX_NUM,
 RTE_CACHE_LINE_SIZE, socket_id);
if (txq == NULL)
return -ENOMEM;
+   txq->ctx_cache = RTE_PTR_ADD(txq, sizeof(struct ixgbe_tx_queue));
 
/*
 * Allocate TX ring hardware descriptors. A memzone large enough to
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.h b/drivers/net/ixgbe/ixgbe_rxtx.h
index 4e437f95e3..8efb46e07a 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.h
+++ b/drivers/net/ixgbe/ixgbe_rxtx.h
@@ -215,8 +215,8 @@ struct ixgbe_tx_queue {
uint8_t wthresh;   /**< Write-back threshold reg. */
uint64_t offloads; /**< Tx offload flags of RTE_ETH_TX_OFFLOAD_* */
uint32_tctx_curr;  /**< Hardware context states. */
-   /** Hardware context0 history. */
-   struct ixgbe_advctx_info ctx_cache[IXGBE_CTX_NUM];
+   /** Hardware context history. */
+   struct ixgbe_advctx_info *ctx_cache;
const struct ixgbe_txq_ops *ops;   /**< txq ops */
_Bool tx_deferred_start; /**< not in global dev start. */
 #ifdef RTE_LIB_SECURITY
-- 
2.43.0



[RFC PATCH 10/21] common/intel_eth: pack Tx queue structure

2024-11-22 Thread Bruce Richardson
Move some fields about to better pack the Tx queue structure and make
sure all data used by the vector codepaths is on the first cacheline of
the structure. Checking with "pahole" on 64-bit build, only one 6-byte
hole is left in the structure - on second cacheline - after this patch.

As part of the reordering, move the p/h/wthresh values to the
ixgbe-specific part of the union. That is the only driver which actually
uses those values. i40e and ice drivers just record the values for later
return, so we can drop them from the Tx queue structure for those
drivers and just report the defaults in all cases.

Signed-off-by: Bruce Richardson 
---
 drivers/common/intel_eth/ieth_rxtx.h | 12 +---
 drivers/net/i40e/i40e_rxtx.c |  9 +++--
 drivers/net/ice/ice_rxtx.c   |  9 +++--
 3 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/drivers/common/intel_eth/ieth_rxtx.h 
b/drivers/common/intel_eth/ieth_rxtx.h
index 9f8a1d7141..c336ec81b3 100644
--- a/drivers/common/intel_eth/ieth_rxtx.h
+++ b/drivers/common/intel_eth/ieth_rxtx.h
@@ -42,7 +42,6 @@ struct ieth_tx_queue {
struct ieth_tx_entry *sw_ring; /* virtual address of SW ring */
struct ieth_vec_tx_entry *sw_ring_v;
};
-   rte_iova_t tx_ring_dma;/* TX ring DMA address */
uint16_t nb_tx_desc;   /* number of TX descriptors */
uint16_t tx_tail; /* current value of tail register */
uint16_t nb_tx_used; /* number of TX desc used since RS bit set */
@@ -56,16 +55,14 @@ struct ieth_tx_queue {
uint16_t tx_free_thresh;
/* Number of TX descriptors to use before RS bit is set. */
uint16_t tx_rs_thresh;
-   uint8_t pthresh;   /**< Prefetch threshold register. */
-   uint8_t hthresh;   /**< Host threshold register. */
-   uint8_t wthresh;   /**< Write-back threshold reg. */
uint16_t port_id;  /* Device port identifier. */
uint16_t queue_id; /* TX queue index. */
uint16_t reg_idx;
-   uint64_t offloads;
uint16_t tx_next_dd;
uint16_t tx_next_rs;
+   uint64_t offloads;
uint64_t mbuf_errors;
+   rte_iova_t tx_ring_dma;/* TX ring DMA address */
_Bool tx_deferred_start; /* don't start this queue in dev start */
_Bool q_set; /* indicate if tx queue has been configured */
union {  /* the VSI this queue belongs to */
@@ -97,9 +94,10 @@ struct ieth_tx_queue {
const struct ixgbe_txq_ops *ops;
struct ixgbe_advctx_info *ctx_cache;
uint32_t ctx_curr;
-#ifdef RTE_LIB_SECURITY
+   uint8_t pthresh;   /**< Prefetch threshold register. */
+   uint8_t hthresh;   /**< Host threshold register. */
+   uint8_t wthresh;   /**< Write-back threshold reg. */
uint8_t using_ipsec;  /**< indicates that IPsec TX 
feature is in use */
-#endif
};
};
 };
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index fce3f5ec2a..29df978019 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2539,9 +2539,6 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
txq->nb_tx_desc = nb_desc;
txq->tx_rs_thresh = tx_rs_thresh;
txq->tx_free_thresh = tx_free_thresh;
-   txq->pthresh = tx_conf->tx_thresh.pthresh;
-   txq->hthresh = tx_conf->tx_thresh.hthresh;
-   txq->wthresh = tx_conf->tx_thresh.wthresh;
txq->queue_id = queue_idx;
txq->reg_idx = reg_idx;
txq->port_id = dev->data->port_id;
@@ -3310,9 +3307,9 @@ i40e_txq_info_get(struct rte_eth_dev *dev, uint16_t 
queue_id,
 
qinfo->nb_desc = txq->nb_tx_desc;
 
-   qinfo->conf.tx_thresh.pthresh = txq->pthresh;
-   qinfo->conf.tx_thresh.hthresh = txq->hthresh;
-   qinfo->conf.tx_thresh.wthresh = txq->wthresh;
+   qinfo->conf.tx_thresh.pthresh = I40E_DEFAULT_TX_PTHRESH;
+   qinfo->conf.tx_thresh.hthresh = I40E_DEFAULT_TX_HTHRESH;
+   qinfo->conf.tx_thresh.wthresh = I40E_DEFAULT_TX_WTHRESH;
 
qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
qinfo->conf.tx_rs_thresh = txq->tx_rs_thresh;
diff --git a/drivers/net/ice/ice_rxtx.c b/drivers/net/ice/ice_rxtx.c
index 20ebda68c7..9606ac7862 100644
--- a/drivers/net/ice/ice_rxtx.c
+++ b/drivers/net/ice/ice_rxtx.c
@@ -1492,9 +1492,6 @@ ice_tx_queue_setup(struct rte_eth_dev *dev,
txq->nb_tx_desc = nb_desc;
txq->tx_rs_thresh = tx_rs_thresh;
txq->tx_free_thresh = tx_free_thresh;
-   txq->pthresh = tx_conf->tx_thresh.pthresh;
-   txq->hthresh = tx_conf->tx_thresh.hthresh;
-   txq->wthresh = tx_conf->tx_thresh.wthresh;
txq->queue_id = queue_idx;
 
txq->reg_idx = vsi->base_queue + queue_idx;
@@ -1583,9 +1580,9 @@ ice_txq_info_get(struct rte_eth_dev *dev, uint16_t 
queue_id,
 
qinfo->n