Re: [PATCH] mldev: disable build on Windows

2023-03-11 Thread Thomas Monjalon
10/03/2023 23:54, Stephen Hemminger:
> On Fri, 10 Mar 2023 12:06:35 -0800
> Tyler Retzlaff  wrote:
> 
> > On Fri, Mar 10, 2023 at 10:07:17AM +0100, David Marchand wrote:
> > > Caught by UNH lab, Windows compilation is broken because of symbol
> > > exports:
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_bfloat16_to_float32
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_float16_to_float32
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_float32_to_bfloat16
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_float32_to_float16
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_float32_to_int16
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_float32_to_int8
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_float32_to_uint16
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_float32_to_uint8
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_int16_to_float32
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_int8_to_float32
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_uint16_to_float32
> > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > >   rte_ml_io_uint8_to_float32
> > > 
> > > Disable Windows build until this is fixed.  
> > 
> > is someone committed to do this?
> 
> This is not hard to fix, please fix the Windows build rather than disabling.

I think we may need to change how the NEON implementation is selected,
without using weak references.

Feel free to submit a patch.




Re: [PATCH v3] kni: fix possible alloc_q starvation when mbufs are exhausted

2023-03-11 Thread Thomas Monjalon
04/01/2023 15:34, Ferruh Yigit:
> On 1/4/2023 11:57 AM, Matt wrote:
> > Hi Ferruh,
> > 
> > In my case, the traffic is not large, so I can't see the impact.
> > I also tested under high load(>2Mpps with 2 DPDK cores and 2 kernel threads)
> > and found no significant difference in performance either.
> > I think the reason should be that it will not
> > run to 'kni_fifo_count(kni->alloc_q) == 0' under high load.
> > 
> 
> I agree, additional check most likely hit on the low bandwidth,
> thanks for checking for performance impact.
> 
> > On Tue, Jan 3, 2023 at 8:47 PM Ferruh Yigit  > > wrote:
> > 
> > On 12/30/2022 4:23 AM, Yangchao Zhou wrote:
> > > In some scenarios, mbufs returned by rte_kni_rx_burst are not freed
> > > immediately. So kni_allocate_mbufs may be failed, but we don't know.
> > >
> > > Even worse, when alloc_q is completely exhausted, kni_net_tx in
> > > rte_kni.ko will drop all tx packets. kni_allocate_mbufs is never
> > > called again, even if the mbufs are eventually freed.
> > >
> > > In this patch, we try to allocate mbufs for alloc_q when it is empty.
> > >
> > > According to historical experience, the performance bottleneck of KNI
> > > is offen the usleep_range of kni thread in rte_kni.ko.
> > > The check of kni_fifo_count is trivial and the cost should be
> > acceptable.
> > >
> > 
> > Hi Yangchao,
> > 
> > Are you observing any performance impact with this change in you use
> > case?
> > 
> > 
> > > Fixes: 3e12a98fe397 ("kni: optimize Rx burst")
> > > Cc: sta...@dpdk.org 
> > >
> > > Signed-off-by: Yangchao Zhou  > >
> 
> Acked-by: Ferruh Yigit 

Applied, thanks.




Re: [PATCH v3] lib/bpf: Rename bpf function names to avoid potential conflict with libpcap

2023-03-11 Thread Thomas Monjalon
06/03/2023 16:42, Martzki:
> The library libpcap has their function 'bpf_validate' either so there would
> be a multiple definition issue when linking with librte_bpf.a and libpcap.a
> statically (Same as http://dpdk.org/patch/52631). So just rename the
> function names to avoid such issue.
> 
> Signed-off-by: Martzki 

Please could you provide you first name and last name?





Re: [PATCH v11 0/3] Fix cmdline_poll and testpmd signal handling

2023-03-11 Thread Thomas Monjalon
19/02/2023 18:53, Stephen Hemminger:
> On Fri,  3 Feb 2023 11:14:06 -0800
> Stephen Hemminger  wrote:
> 
> > This patchset keeps uncovering bad practices in the cmdline library
> > around end of file and signal handling.
> > 
> > Stephen Hemminger (3):
> >   cmdline: make rdline status not private
> >   cmdline: handle EOF in cmdline_poll
> >   testpmd: cleanup cleanly from signal
> > 
> >  app/test-pmd/cmdline.c| 29 +
> >  app/test-pmd/testpmd.c| 77 ---
> >  app/test-pmd/testpmd.h|  1 +
> >  lib/cmdline/cmdline.c | 11 +++--
> >  lib/cmdline/cmdline.h |  6 +++
> >  lib/cmdline/cmdline_private.h |  6 ---
> >  6 files changed, 62 insertions(+), 68 deletions(-)
> > 
> 
> Could this please be merged for 23.03?
> There are Ack's.
> The only CI failure is a bogus performance test failure.

There was no review from testpmd maintainers.

I've added Cc: sta...@dpdk.org.
Applied, thanks.




[PATCH] ml/cnxk: fix updating error code and message

2023-03-11 Thread Srikanth Yalavarthi
Error code reported by applications is incorrect, as the value
is not being set by error get function. For error subtype not
supported by driver, the error message reported is incorrect.

Fixes: 57c37b852f2c ("ml/cnxk: support firmware error code query")

Signed-off-by: Srikanth Yalavarthi 
---
 drivers/ml/cnxk/cn10k_ml_ops.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/ml/cnxk/cn10k_ml_ops.c b/drivers/ml/cnxk/cn10k_ml_ops.c
index 5b77e47322..7d5eb97668 100644
--- a/drivers/ml/cnxk/cn10k_ml_ops.c
+++ b/drivers/ml/cnxk/cn10k_ml_ops.c
@@ -2210,7 +2210,10 @@ cn10k_ml_op_error_get(struct rte_ml_dev *dev, struct 
rte_ml_op *op, struct rte_m
/* Copy sub error message */
if (error_code->s.etype == ML_ETYPE_HW_NONFATAL) {
strcat(msg, " : ");
-   strcat(msg, ml_stype_db_hw_nf[error_code->s.stype].msg);
+   if (error_code->s.stype < PLT_DIM(ml_stype_db_hw_nf))
+   strcat(msg, ml_stype_db_hw_nf[error_code->s.stype].msg);
+   else
+   strcat(msg, "UNKNOWN ERROR");
}
 
if (error_code->s.etype == ML_ETYPE_DRIVER) {
@@ -2219,6 +,7 @@ cn10k_ml_op_error_get(struct rte_ml_dev *dev, struct 
rte_ml_op *op, struct rte_m
}
 
plt_strlcpy(error->message, msg, sizeof(error->message));
+   error->errcode = error_code->u64;
 
return 0;
 }
-- 
2.17.1



[PATCH] mldev: remove weak symbols use in type conversions

2023-03-11 Thread Srikanth Yalavarthi
Drop use of weak symbols to select the type conversion
functions. Select NEON implementation only on Aarch64
builds. Enable windows build.

Fixes: 3c54f91ad8c9 ("mldev: disable build on Windows")

Signed-off-by: Srikanth Yalavarthi 
---
 lib/mldev/meson.build  |  9 ++---
 lib/mldev/mldev_utils_scalar.c | 24 
 2 files changed, 14 insertions(+), 19 deletions(-)

diff --git a/lib/mldev/meson.build b/lib/mldev/meson.build
index 51ba809465..c9db42257b 100644
--- a/lib/mldev/meson.build
+++ b/lib/mldev/meson.build
@@ -1,21 +1,16 @@
 # SPDX-License-Identifier: BSD-3-Clause
 # Copyright (c) 2022 Marvell.
 
-if is_windows
-build = false
-reason = 'not supported on Windows'
-subdir_done()
-endif
-
 sources = files(
 'rte_mldev_pmd.c',
 'rte_mldev.c',
 'mldev_utils.c',
-'mldev_utils_scalar.c',
 )
 
 if dpdk_conf.has('RTE_ARCH_ARM64')
 sources += files('mldev_utils_neon.c')
+else
+sources += files('mldev_utils_scalar.c')
 endif
 
 headers = files(
diff --git a/lib/mldev/mldev_utils_scalar.c b/lib/mldev/mldev_utils_scalar.c
index 40320ed3ef..322b009f5d 100644
--- a/lib/mldev/mldev_utils_scalar.c
+++ b/lib/mldev/mldev_utils_scalar.c
@@ -84,7 +84,7 @@ union float32 {
uint32_t u;
 };
 
-__rte_weak int
+int
 rte_ml_io_float32_to_int8(float scale, uint64_t nb_elements, void *input, void 
*output)
 {
float *input_buffer;
@@ -116,7 +116,7 @@ rte_ml_io_float32_to_int8(float scale, uint64_t 
nb_elements, void *input, void *
return 0;
 }
 
-__rte_weak int
+int
 rte_ml_io_int8_to_float32(float scale, uint64_t nb_elements, void *input, void 
*output)
 {
int8_t *input_buffer;
@@ -139,7 +139,7 @@ rte_ml_io_int8_to_float32(float scale, uint64_t 
nb_elements, void *input, void *
return 0;
 }
 
-__rte_weak int
+int
 rte_ml_io_float32_to_uint8(float scale, uint64_t nb_elements, void *input, 
void *output)
 {
float *input_buffer;
@@ -171,7 +171,7 @@ rte_ml_io_float32_to_uint8(float scale, uint64_t 
nb_elements, void *input, void
return 0;
 }
 
-__rte_weak int
+int
 rte_ml_io_uint8_to_float32(float scale, uint64_t nb_elements, void *input, 
void *output)
 {
uint8_t *input_buffer;
@@ -194,7 +194,7 @@ rte_ml_io_uint8_to_float32(float scale, uint64_t 
nb_elements, void *input, void
return 0;
 }
 
-__rte_weak int
+int
 rte_ml_io_float32_to_int16(float scale, uint64_t nb_elements, void *input, 
void *output)
 {
float *input_buffer;
@@ -226,7 +226,7 @@ rte_ml_io_float32_to_int16(float scale, uint64_t 
nb_elements, void *input, void
return 0;
 }
 
-__rte_weak int
+int
 rte_ml_io_int16_to_float32(float scale, uint64_t nb_elements, void *input, 
void *output)
 {
int16_t *input_buffer;
@@ -249,7 +249,7 @@ rte_ml_io_int16_to_float32(float scale, uint64_t 
nb_elements, void *input, void
return 0;
 }
 
-__rte_weak int
+int
 rte_ml_io_float32_to_uint16(float scale, uint64_t nb_elements, void *input, 
void *output)
 {
float *input_buffer;
@@ -281,7 +281,7 @@ rte_ml_io_float32_to_uint16(float scale, uint64_t 
nb_elements, void *input, void
return 0;
 }
 
-__rte_weak int
+int
 rte_ml_io_uint16_to_float32(float scale, uint64_t nb_elements, void *input, 
void *output)
 {
uint16_t *input_buffer;
@@ -429,7 +429,7 @@ __float32_to_float16_scalar_rtn(float x)
return u16;
 }
 
-__rte_weak int
+int
 rte_ml_io_float32_to_float16(uint64_t nb_elements, void *input, void *output)
 {
float *input_buffer;
@@ -513,7 +513,7 @@ __float16_to_float32_scalar_rtx(uint16_t f16)
return f32.f;
 }
 
-__rte_weak int
+int
 rte_ml_io_float16_to_float32(uint64_t nb_elements, void *input, void *output)
 {
uint16_t *input_buffer;
@@ -614,7 +614,7 @@ __float32_to_bfloat16_scalar_rtn(float x)
return u16;
 }
 
-__rte_weak int
+int
 rte_ml_io_float32_to_bfloat16(uint64_t nb_elements, void *input, void *output)
 {
float *input_buffer;
@@ -696,7 +696,7 @@ __bfloat16_to_float32_scalar_rtx(uint16_t f16)
return f32.f;
 }
 
-__rte_weak int
+int
 rte_ml_io_bfloat16_to_float32(uint64_t nb_elements, void *input, void *output)
 {
uint16_t *input_buffer;
-- 
2.17.1



RE: [EXT] Re: [PATCH] mldev: disable build on Windows

2023-03-11 Thread Srikanth Yalavarthi
> -Original Message-
> From: Thomas Monjalon 
> Sent: 11 March 2023 13:42
> To: Tyler Retzlaff ; Stephen Hemminger
> 
> Cc: dev@dpdk.org; David Marchand ;
> dev@dpdk.org; Srikanth Yalavarthi 
> Subject: [EXT] Re: [PATCH] mldev: disable build on Windows
> 
> External Email
> 
> --
> 10/03/2023 23:54, Stephen Hemminger:
> > On Fri, 10 Mar 2023 12:06:35 -0800
> > Tyler Retzlaff  wrote:
> >
> > > On Fri, Mar 10, 2023 at 10:07:17AM +0100, David Marchand wrote:
> > > > Caught by UNH lab, Windows compilation is broken because of symbol
> > > > exports:
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_bfloat16_to_float32
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_float16_to_float32
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_float32_to_bfloat16
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_float32_to_float16
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_float32_to_int16
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_float32_to_int8
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_float32_to_uint16
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_float32_to_uint8
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_int16_to_float32
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_int8_to_float32
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_uint16_to_float32
> > > > rte_mldev_exports.def : error LNK2001: unresolved external symbol
> > > > rte_ml_io_uint8_to_float32
> > > >
> > > > Disable Windows build until this is fixed.
> > >
> > > is someone committed to do this?
> >
> > This is not hard to fix, please fix the Windows build rather than disabling.
> 
> I think we may need to change how the NEON implementation is selected,
> without using weak references.
> 
> Feel free to submit a patch.
> 

I have submitted a patch to remove weak symbols and enable windows build. I 
could run windows build with MinGW-w64, but not a native build.
http://patches.dpdk.org/project/dpdk/patch/20230311145056.16386-1-syalavar...@marvell.com/



[PATCH] mldev: fix identical code in conditional branches

2023-03-11 Thread Srikanth Yalavarthi
Fix identical code in different conditional branches in float32
to float16 conversion function. Issue reported in coverity scan.

Coverity issue: 383651
Fixes: 9637de38a2e3 ("mldev: add scalar type conversion")

Signed-off-by: Srikanth Yalavarthi 
---
 lib/mldev/mldev_utils_scalar.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/lib/mldev/mldev_utils_scalar.c b/lib/mldev/mldev_utils_scalar.c
index 40320ed3ef..00c3aa60bf 100644
--- a/lib/mldev/mldev_utils_scalar.c
+++ b/lib/mldev/mldev_utils_scalar.c
@@ -336,10 +336,7 @@ __float32_to_float16_scalar_rtn(float x)
switch (f32_e) {
case (0): /* float32: zero or subnormal number */
f16_e = 0;
-   if (f32_m == 0) /* zero */
-   f16_m = 0;
-   else /* subnormal number, convert to zero */
-   f16_m = 0;
+   f16_m = 0; /* convert to zero */
break;
case (FP32_MASK_E >> FP32_LSB_E): /* float32: infinity or nan */
f16_e = FP16_MASK_E >> FP16_LSB_E;
-- 
2.17.1



[PATCH] mldev: remove variable self assignment in dev init

2023-03-11 Thread Srikanth Yalavarthi
Fix variable self assignment in rte_ml_devinit.
Issue reported by coverity scan.

Coverity issue: 383652
Fixes: ea80eafbd4d8 ("mldev: add PMD functions")

Signed-off-by: Srikanth Yalavarthi 
---
 lib/mldev/rte_mldev.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/lib/mldev/rte_mldev.c b/lib/mldev/rte_mldev.c
index eeddb8e874..50ebeb1bfe 100644
--- a/lib/mldev/rte_mldev.c
+++ b/lib/mldev/rte_mldev.c
@@ -186,7 +186,6 @@ rte_ml_dev_init(size_t dev_max)
}
 
ml_dev_globals.max_devs = dev_max;
-   ml_dev_globals.devs = ml_dev_globals.devs;
 
return 0;
 }
-- 
2.17.1



[PATCH v6 00/12] Implementation of mldev test application

2023-03-11 Thread Srikanth Yalavarthi
Machine learning device APIs test application
=

This series of patches introduces a test application for machine
learning device APIs. A test framework is implemented with multiple
test enabled, to validate the device, model and fast-path functions.
New tests can be added using the test framework.


List of tests supported
---

1) device_ops: Test case to validate device re-configuration

2) model_ops: Collection of 4 sub-tests to validate model slow APIs.
Each sub-test would invoke the slow path model APIs (load / start /
stop / unload) in different order.

3) inference_ordered: Test case to validate execution of end-to-end
inferences on ML device with one active model at a time. This test
can execute inference requests for multiple models, with inferences
for a model executed after completion of inferences for a previously
loaded model.

4) inference_interleave: Test case to validate end-to-end inferences
with multiple active models concurrently. This case would work as a
stress test to validate ML device.


Options supported the by tests include burst size for enqueuing and
dequeuing inference requests, enabling multiple queue pairs with a
user specified value for queue size. Support is also enabled for
batch inferencing, output validation and statistics.

v6:
* Enable error count
* Fix segfault due to incorrect i/o size types
* Revert i/o size variables to uint64_t

v5:
* Cleanup of header includes
* Addressed issues with unclean patches
* Changed input/output size variables to uint32_t
* Rebase over main branch

v4:
* Updated model_id as uint16_t
* Updated license info in SVG files
* Updated release notes

v3:
* Code rebase


Srikanth Yalavarthi (12):
  app/mldev: implement test framework for mldev
  app/mldev: add common test functions
  app/mldev: add test case to validate device ops
  app/mldev: add test case to validate model ops
  app/mldev: add ordered inference test case
  app/mldev: add test case to interleave inferences
  app/mldev: enable support for burst inferences
  app/mldev: enable support for queue pairs and size
  app/mldev: enable support for inference batches
  app/mldev: enable support for inference validation
  app/mldev: enable reporting stats in mldev app
  app/mldev: add documentation for mldev test cases

 .mailmap  |1 +
 MAINTAINERS   |2 +
 app/meson.build   |1 +
 app/test-mldev/meson.build|   24 +
 app/test-mldev/ml_common.h|   29 +
 app/test-mldev/ml_main.c  |  113 ++
 app/test-mldev/ml_options.c   |  325 +
 app/test-mldev/ml_options.h   |   57 +
 app/test-mldev/ml_test.c  |   41 +
 app/test-mldev/ml_test.h  |   76 ++
 app/test-mldev/parser.c   |  380 ++
 app/test-mldev/parser.h   |   55 +
 app/test-mldev/test_common.c  |  136 ++
 app/test-mldev/test_common.h  |   27 +
 app/test-mldev/test_device_ops.c  |  228 
 app/test-mldev/test_device_ops.h  |   17 +
 app/test-mldev/test_inference_common.c| 1128 +
 app/test-mldev/test_inference_common.h|   75 ++
 app/test-mldev/test_inference_interleave.c|  118 ++
 app/test-mldev/test_inference_ordered.c   |  116 ++
 app/test-mldev/test_model_common.c|  164 +++
 app/test-mldev/test_model_common.h|   46 +
 app/test-mldev/test_model_ops.c   |  428 +++
 app/test-mldev/test_model_ops.h   |   20 +
 doc/guides/rel_notes/release_23_03.rst|8 +
 .../tools/img/mldev_inference_interleave.svg  |  669 ++
 .../tools/img/mldev_inference_ordered.svg |  528 
 .../tools/img/mldev_model_ops_subtest_a.svg   |  420 ++
 .../tools/img/mldev_model_ops_subtest_b.svg   |  423 +++
 .../tools/img/mldev_model_ops_subtest_c.svg   |  366 ++
 .../tools/img/mldev_model_ops_subtest_d.svg   |  424 +++
 doc/guides/tools/index.rst|1 +
 doc/guides/tools/testmldev.rst|  441 +++
 33 files changed, 6887 insertions(+)
 create mode 100644 app/test-mldev/meson.build
 create mode 100644 app/test-mldev/ml_common.h
 create mode 100644 app/test-mldev/ml_main.c
 create mode 100644 app/test-mldev/ml_options.c
 create mode 100644 app/test-mldev/ml_options.h
 create mode 100644 app/test-mldev/ml_test.c
 create mode 100644 app/test-mldev/ml_test.h
 create mode 100644 app/test-mldev/parser.c
 create mode 100644 app/test-mldev/parser.h
 create mode 100644 app/test-mldev/test_common.c
 create mode 100644 app/test-mldev/test_common.h
 create mode 100644 app/test-mldev/test_device_ops.c
 create mode 100644 app/test-mldev/test_device_ops.h
 create mode 100644 app/test-mldev/test_inference_common.c
 create mod

[PATCH v6 01/12] app/mldev: implement test framework for mldev

2023-03-11 Thread Srikanth Yalavarthi
Implemented framework for mldev test application. New test cases
can be added using the framework. Support is also enabled to add
options specific to the test cases. User can launch the tests by
specifying the name of test as part of launch arguments.

Code to parse command line arguments is imported from
test-eventdev, with support to parse additional data types.

Common arguments supported include:

test: name of the test application to run
dev_id  : device id of the ML device
socket_id   : socket_id of application resources
debug   : enable debugging
help: print help

Sample launch command:
./dpdk-test-mldev -- --test  --dev_id  \
--socket_id 

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Shivah Shankar S 
Acked-by: Anup Prabhu 
---
 .mailmap   |   1 +
 MAINTAINERS|   1 +
 app/meson.build|   1 +
 app/test-mldev/meson.build |  17 ++
 app/test-mldev/ml_common.h |  29 ++
 app/test-mldev/ml_main.c   | 113 
 app/test-mldev/ml_options.c| 155 ++
 app/test-mldev/ml_options.h|  31 ++
 app/test-mldev/ml_test.c   |  41 +++
 app/test-mldev/ml_test.h   |  76 +
 app/test-mldev/parser.c| 380 +
 app/test-mldev/parser.h|  55 
 doc/guides/rel_notes/release_23_03.rst |   8 +
 13 files changed, 908 insertions(+)
 create mode 100644 app/test-mldev/meson.build
 create mode 100644 app/test-mldev/ml_common.h
 create mode 100644 app/test-mldev/ml_main.c
 create mode 100644 app/test-mldev/ml_options.c
 create mode 100644 app/test-mldev/ml_options.h
 create mode 100644 app/test-mldev/ml_test.c
 create mode 100644 app/test-mldev/ml_test.h
 create mode 100644 app/test-mldev/parser.c
 create mode 100644 app/test-mldev/parser.h

diff --git a/.mailmap b/.mailmap
index f3303ca6ec..61d0d94d16 100644
--- a/.mailmap
+++ b/.mailmap
@@ -112,6 +112,7 @@ Anoob Joseph  

 Antara Ganesh Kolar 
 Anthony Fee 
 Antonio Fischetti 
+Anup Prabhu 
 Anupam Kapoor 
 Apeksha Gupta 
 Archana Muniganti  
diff --git a/MAINTAINERS b/MAINTAINERS
index d99eec0298..b0fd46ef02 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -480,6 +480,7 @@ Machine Learning device API - EXPERIMENTAL
 M: Srikanth Yalavarthi 
 F: lib/mldev/
 F: doc/guides/prog_guide/mldev.rst
+F: app/test-mldev
 
 DMA device API - EXPERIMENTAL
 M: Chengwen Feng 
diff --git a/app/meson.build b/app/meson.build
index e32ea4bd5c..74d2420f67 100644
--- a/app/meson.build
+++ b/app/meson.build
@@ -23,6 +23,7 @@ apps = [
 'test-fib',
 'test-flow-perf',
 'test-gpudev',
+'test-mldev',
 'test-pipeline',
 'test-pmd',
 'test-regex',
diff --git a/app/test-mldev/meson.build b/app/test-mldev/meson.build
new file mode 100644
index 00..8ca2e1a1c1
--- /dev/null
+++ b/app/test-mldev/meson.build
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2022 Marvell.
+
+if is_windows
+build = false
+reason = 'not supported on Windows'
+subdir_done()
+endif
+
+sources = files(
+'ml_main.c',
+'ml_options.c',
+'ml_test.c',
+'parser.c',
+)
+
+deps += ['mldev']
diff --git a/app/test-mldev/ml_common.h b/app/test-mldev/ml_common.h
new file mode 100644
index 00..065180b619
--- /dev/null
+++ b/app/test-mldev/ml_common.h
@@ -0,0 +1,29 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#ifndef _ML_COMMON_
+#define _ML_COMMON_
+
+#include 
+
+#define CLNRM "\x1b[0m"
+#define CLRED "\x1b[31m"
+#define CLGRN "\x1b[32m"
+#define CLYEL "\x1b[33m"
+
+#define ML_STR_FMT 20
+
+#define ml_err(fmt, args...) fprintf(stderr, CLRED "error: %s() " fmt CLNRM 
"\n", __func__, ##args)
+
+#define ml_info(fmt, args...) fprintf(stdout, CLYEL "" fmt CLNRM "\n", ##args)
+
+#define ml_dump(str, fmt, val...) printf("\t%-*s : " fmt "\n", ML_STR_FMT, 
str, ##val)
+
+#define ml_dump_begin(str) printf("\t%-*s :\n\t{\n", ML_STR_FMT, str)
+
+#define ml_dump_list(str, id, val) printf("\t%*s[%2u] : %s\n", ML_STR_FMT - 4, 
str, id, val)
+
+#define ml_dump_end printf("\b\t}\n\n")
+
+#endif /* _ML_COMMON_*/
diff --git a/app/test-mldev/ml_main.c b/app/test-mldev/ml_main.c
new file mode 100644
index 00..940e609c9a
--- /dev/null
+++ b/app/test-mldev/ml_main.c
@@ -0,0 +1,113 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#include 
+#include 
+#include 
+
+#include "ml_common.h"
+#include "ml_test.h"
+
+struct ml_options opt;
+struct ml_test *test;
+
+int
+main(int argc, char **argv)
+{
+   uint16_t mldevs;
+   int ret;
+
+   ret = rte_eal_init(argc, argv);
+   if (ret < 0)
+   rte_panic("invalid EAL arguments\n");
+   argc -= ret;
+   argv += ret;
+
+   mldevs = rte_ml_dev_count();
+   if (!mldevs)
+   rte_panic("no mldev devices found\n");
+

[PATCH v6 04/12] app/mldev: add test case to validate model ops

2023-03-11 Thread Srikanth Yalavarthi
Added test case to validate model operations. Model ops test
is a collection of sub-tests. Each sub-test invokes the model
operations in a specific order.

Sub-test A: (load -> start -> stop -> unload) x n
Sub-test B: load x n -> start x n -> stop x n -> unload x n
Sub-test C: load x n + (start  + stop) x n + unload x n
Sub-test D: (load + start) x n -> (stop + unload) x n

Added internal functions to handle model load, start, stop and
unload. List of models to be used for testing can be specified
through application argument "--models"

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/meson.build |   2 +
 app/test-mldev/ml_options.c|  44 ++-
 app/test-mldev/ml_options.h|   6 +
 app/test-mldev/test_model_common.c | 158 +++
 app/test-mldev/test_model_common.h |  34 +++
 app/test-mldev/test_model_ops.c| 428 +
 app/test-mldev/test_model_ops.h|  20 ++
 7 files changed, 689 insertions(+), 3 deletions(-)
 create mode 100644 app/test-mldev/test_model_common.c
 create mode 100644 app/test-mldev/test_model_common.h
 create mode 100644 app/test-mldev/test_model_ops.c
 create mode 100644 app/test-mldev/test_model_ops.h

diff --git a/app/test-mldev/meson.build b/app/test-mldev/meson.build
index 60ea23d142..b09e1ccc8a 100644
--- a/app/test-mldev/meson.build
+++ b/app/test-mldev/meson.build
@@ -14,6 +14,8 @@ sources = files(
 'parser.c',
 'test_common.c',
 'test_device_ops.c',
+'test_model_common.c',
+'test_model_ops.c',
 )
 
 deps += ['mldev']
diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index b0837dde14..91259e1427 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -22,6 +22,7 @@ ml_options_default(struct ml_options *opt)
strlcpy(opt->test_name, "device_ops", ML_TEST_NAME_MAX_LEN);
opt->dev_id = 0;
opt->socket_id = SOCKET_ID_ANY;
+   opt->nb_filelist = 0;
opt->debug = false;
 }
 
@@ -58,11 +59,47 @@ ml_parse_socket_id(struct ml_options *opt, const char *arg)
return 0;
 }
 
+static int
+ml_parse_models(struct ml_options *opt, const char *arg)
+{
+   const char *delim = ",";
+   char models[PATH_MAX];
+   char *token;
+   int ret = 0;
+
+   strlcpy(models, arg, PATH_MAX);
+
+   token = strtok(models, delim);
+   while (token != NULL) {
+   strlcpy(opt->filelist[opt->nb_filelist].model, token, PATH_MAX);
+   opt->nb_filelist++;
+
+   if (opt->nb_filelist >= ML_TEST_MAX_MODELS) {
+   ml_err("Exceeded model count, max = %d\n", 
ML_TEST_MAX_MODELS);
+   ret = -EINVAL;
+   break;
+   }
+   token = strtok(NULL, delim);
+   }
+
+   if (opt->nb_filelist == 0) {
+   ml_err("Models list is empty. Need at least one model for the 
test");
+   ret = -EINVAL;
+   }
+
+   return ret;
+}
+
 static void
 ml_dump_test_options(const char *testname)
 {
if (strcmp(testname, "device_ops") == 0)
printf("\n");
+
+   if (strcmp(testname, "model_ops") == 0) {
+   printf("\t\t--models   : comma separated list of 
models\n");
+   printf("\n");
+   }
 }
 
 static void
@@ -80,9 +117,9 @@ print_usage(char *program)
ml_test_dump_names(ml_dump_test_options);
 }
 
-static struct option lgopts[] = {{ML_TEST, 1, 0, 0}, {ML_DEVICE_ID, 1, 0, 
0},
-{ML_SOCKET_ID, 1, 0, 0}, {ML_DEBUG, 0, 0, 0},
-{ML_HELP, 0, 0, 0},  {NULL, 0, 0, 0}};
+static struct option lgopts[] = {
+   {ML_TEST, 1, 0, 0},  {ML_DEVICE_ID, 1, 0, 0}, {ML_SOCKET_ID, 1, 0, 0}, 
{ML_MODELS, 1, 0, 0},
+   {ML_DEBUG, 0, 0, 0}, {ML_HELP, 0, 0, 0},  {NULL, 0, 0, 0}};
 
 static int
 ml_opts_parse_long(int opt_idx, struct ml_options *opt)
@@ -93,6 +130,7 @@ ml_opts_parse_long(int opt_idx, struct ml_options *opt)
{ML_TEST, ml_parse_test_name},
{ML_DEVICE_ID, ml_parse_dev_id},
{ML_SOCKET_ID, ml_parse_socket_id},
+   {ML_MODELS, ml_parse_models},
};
 
for (i = 0; i < RTE_DIM(parsermap); i++) {
diff --git a/app/test-mldev/ml_options.h b/app/test-mldev/ml_options.h
index 6899cc2f88..61e938d2e2 100644
--- a/app/test-mldev/ml_options.h
+++ b/app/test-mldev/ml_options.h
@@ -15,13 +15,19 @@
 #define ML_TEST ("test")
 #define ML_DEVICE_ID ("dev_id")
 #define ML_SOCKET_ID ("socket_id")
+#define ML_MODELS("models")
 #define ML_DEBUG ("debug")
 #define ML_HELP ("help")
 
+struct ml_filelist {
+   char model[PATH_MAX];
+};
+
 struct ml_options {
char test_name[ML_TEST_NAME_MAX_LEN];
int16_t dev_id;
int socket_id;
+   struct ml_filelist filelist[ML_TEST_MAX_MODELS];
uint8_t nb_filelist;
bool deb

[PATCH v6 02/12] app/mldev: add common test functions

2023-03-11 Thread Srikanth Yalavarthi
Added common functions used by all tests. Common code
includes functions to check capabilities, options, and
handle ML devices.

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/meson.build   |   1 +
 app/test-mldev/test_common.c | 136 +++
 app/test-mldev/test_common.h |  27 +++
 3 files changed, 164 insertions(+)
 create mode 100644 app/test-mldev/test_common.c
 create mode 100644 app/test-mldev/test_common.h

diff --git a/app/test-mldev/meson.build b/app/test-mldev/meson.build
index 8ca2e1a1c1..964bb9ddc4 100644
--- a/app/test-mldev/meson.build
+++ b/app/test-mldev/meson.build
@@ -12,6 +12,7 @@ sources = files(
 'ml_options.c',
 'ml_test.c',
 'parser.c',
+'test_common.c',
 )
 
 deps += ['mldev']
diff --git a/app/test-mldev/test_common.c b/app/test-mldev/test_common.c
new file mode 100644
index 00..8c4da4609a
--- /dev/null
+++ b/app/test-mldev/test_common.c
@@ -0,0 +1,136 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "ml_common.h"
+#include "test_common.h"
+
+bool
+ml_test_cap_check(struct ml_options *opt)
+{
+   struct rte_ml_dev_info dev_info;
+
+   rte_ml_dev_info_get(opt->dev_id, &dev_info);
+   if (dev_info.max_models == 0) {
+   ml_err("Not enough mldev models supported = %u", 
dev_info.max_models);
+   return false;
+   }
+
+   return true;
+}
+
+int
+ml_test_opt_check(struct ml_options *opt)
+{
+   uint16_t dev_count;
+   int socket_id;
+
+   RTE_SET_USED(opt);
+
+   dev_count = rte_ml_dev_count();
+   if (dev_count == 0) {
+   ml_err("No ML devices found");
+   return -ENODEV;
+   }
+
+   if (opt->dev_id >= dev_count) {
+   ml_err("Invalid option dev_id = %d", opt->dev_id);
+   return -EINVAL;
+   }
+
+   socket_id = rte_ml_dev_socket_id(opt->dev_id);
+   if (!((opt->socket_id != SOCKET_ID_ANY) || (opt->socket_id != 
socket_id))) {
+   ml_err("Invalid option, socket_id = %d\n", opt->socket_id);
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+void
+ml_test_opt_dump(struct ml_options *opt)
+{
+   ml_options_dump(opt);
+}
+
+int
+ml_test_device_configure(struct ml_test *test, struct ml_options *opt)
+{
+   struct test_common *t = ml_test_priv(test);
+   struct rte_ml_dev_config dev_config;
+   int ret;
+
+   ret = rte_ml_dev_info_get(opt->dev_id, &t->dev_info);
+   if (ret != 0) {
+   ml_err("Failed to get mldev info, dev_id = %d\n", opt->dev_id);
+   return ret;
+   }
+
+   /* configure device */
+   dev_config.socket_id = opt->socket_id;
+   dev_config.nb_models = t->dev_info.max_models;
+   dev_config.nb_queue_pairs = t->dev_info.max_queue_pairs;
+   ret = rte_ml_dev_configure(opt->dev_id, &dev_config);
+   if (ret != 0) {
+   ml_err("Failed to configure ml device, dev_id = %d\n", 
opt->dev_id);
+   return ret;
+   }
+
+   return 0;
+}
+
+int
+ml_test_device_close(struct ml_test *test, struct ml_options *opt)
+{
+   struct test_common *t = ml_test_priv(test);
+   int ret = 0;
+
+   RTE_SET_USED(t);
+
+   /* close device */
+   ret = rte_ml_dev_close(opt->dev_id);
+   if (ret != 0)
+   ml_err("Failed to close ML device, dev_id = %d\n", opt->dev_id);
+
+   return ret;
+}
+
+int
+ml_test_device_start(struct ml_test *test, struct ml_options *opt)
+{
+   struct test_common *t = ml_test_priv(test);
+   int ret;
+
+   RTE_SET_USED(t);
+
+   /* start device */
+   ret = rte_ml_dev_start(opt->dev_id);
+   if (ret != 0) {
+   ml_err("Failed to start ml device, dev_id = %d\n", opt->dev_id);
+   return ret;
+   }
+
+   return 0;
+}
+
+int
+ml_test_device_stop(struct ml_test *test, struct ml_options *opt)
+{
+   struct test_common *t = ml_test_priv(test);
+   int ret = 0;
+
+   RTE_SET_USED(t);
+
+   /* stop device */
+   ret = rte_ml_dev_stop(opt->dev_id);
+   if (ret != 0)
+   ml_err("Failed to stop ML device, dev_id = %d\n", opt->dev_id);
+
+   return ret;
+}
diff --git a/app/test-mldev/test_common.h b/app/test-mldev/test_common.h
new file mode 100644
index 00..cb286adcd6
--- /dev/null
+++ b/app/test-mldev/test_common.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#ifndef _ML_TEST_COMMON_
+#define _ML_TEST_COMMON_
+
+#include 
+
+#include "ml_common.h"
+#include "ml_test.h"
+
+struct test_common {
+   struct ml_options *opt;
+   enum ml_test_result result;
+   struct rte_ml_dev_info dev_info;
+};
+
+bool ml_test_cap_check(struct ml_options *opt);
+int ml_test_opt_check(struct ml_options *opt);
+void ml_test_opt_dump(struct ml_options *

[PATCH v6 05/12] app/mldev: add ordered inference test case

2023-03-11 Thread Srikanth Yalavarthi
Added an ordered test case to execute inferences with single
or multiple models. In this test case inference requests for
a model are enqueued after completion of all requests for
the previous model. Test supports inference repetitions.

Operations sequence when testing with N models and R reps,

(load -> start -> (enqueue + dequeue) x R -> stop -> unload) x N

Test case can be executed by selecting "inference_ordered" test
and repetitions can be specified through "--repetitions" argument.

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/meson.build  |   2 +
 app/test-mldev/ml_options.c |  73 ++-
 app/test-mldev/ml_options.h |  17 +-
 app/test-mldev/test_inference_common.c  | 567 
 app/test-mldev/test_inference_common.h  |  61 +++
 app/test-mldev/test_inference_ordered.c | 115 +
 app/test-mldev/test_model_common.h  |  10 +
 7 files changed, 833 insertions(+), 12 deletions(-)
 create mode 100644 app/test-mldev/test_inference_common.c
 create mode 100644 app/test-mldev/test_inference_common.h
 create mode 100644 app/test-mldev/test_inference_ordered.c

diff --git a/app/test-mldev/meson.build b/app/test-mldev/meson.build
index b09e1ccc8a..475d76d126 100644
--- a/app/test-mldev/meson.build
+++ b/app/test-mldev/meson.build
@@ -16,6 +16,8 @@ sources = files(
 'test_device_ops.c',
 'test_model_common.c',
 'test_model_ops.c',
+'test_inference_common.c',
+'test_inference_ordered.c',
 )
 
 deps += ['mldev']
diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index 91259e1427..b7215a7e88 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -23,6 +23,7 @@ ml_options_default(struct ml_options *opt)
opt->dev_id = 0;
opt->socket_id = SOCKET_ID_ANY;
opt->nb_filelist = 0;
+   opt->repetitions = 1;
opt->debug = false;
 }
 
@@ -90,6 +91,60 @@ ml_parse_models(struct ml_options *opt, const char *arg)
return ret;
 }
 
+static int
+ml_parse_filelist(struct ml_options *opt, const char *arg)
+{
+   const char *delim = ",";
+   char filelist[PATH_MAX];
+   char *token;
+
+   if (opt->nb_filelist >= ML_TEST_MAX_MODELS) {
+   ml_err("Exceeded filelist count, max = %d\n", 
ML_TEST_MAX_MODELS);
+   return -1;
+   }
+
+   strlcpy(filelist, arg, PATH_MAX);
+
+   /* model */
+   token = strtok(filelist, delim);
+   if (token == NULL) {
+   ml_err("Invalid filelist, model not specified = %s\n", arg);
+   return -EINVAL;
+   }
+   strlcpy(opt->filelist[opt->nb_filelist].model, token, PATH_MAX);
+
+   /* input */
+   token = strtok(NULL, delim);
+   if (token == NULL) {
+   ml_err("Invalid filelist, input not specified = %s\n", arg);
+   return -EINVAL;
+   }
+   strlcpy(opt->filelist[opt->nb_filelist].input, token, PATH_MAX);
+
+   /* output */
+   token = strtok(NULL, delim);
+   if (token == NULL) {
+   ml_err("Invalid filelist, output not specified = %s\n", arg);
+   return -EINVAL;
+   }
+   strlcpy(opt->filelist[opt->nb_filelist].output, token, PATH_MAX);
+
+   opt->nb_filelist++;
+
+   if (opt->nb_filelist == 0) {
+   ml_err("Empty filelist. Need at least one filelist entry for 
the test.");
+   return -EINVAL;
+   }
+
+   return 0;
+}
+
+static int
+ml_parse_repetitions(struct ml_options *opt, const char *arg)
+{
+   return parser_read_uint64(&opt->repetitions, arg);
+}
+
 static void
 ml_dump_test_options(const char *testname)
 {
@@ -100,6 +155,12 @@ ml_dump_test_options(const char *testname)
printf("\t\t--models   : comma separated list of 
models\n");
printf("\n");
}
+
+   if (strcmp(testname, "inference_ordered") == 0) {
+   printf("\t\t--filelist : comma separated list of model, 
input and output\n"
+  "\t\t--repetitions  : number of inference 
repetitions\n");
+   printf("\n");
+   }
 }
 
 static void
@@ -118,8 +179,9 @@ print_usage(char *program)
 }
 
 static struct option lgopts[] = {
-   {ML_TEST, 1, 0, 0},  {ML_DEVICE_ID, 1, 0, 0}, {ML_SOCKET_ID, 1, 0, 0}, 
{ML_MODELS, 1, 0, 0},
-   {ML_DEBUG, 0, 0, 0}, {ML_HELP, 0, 0, 0},  {NULL, 0, 0, 0}};
+   {ML_TEST, 1, 0, 0},   {ML_DEVICE_ID, 1, 0, 0}, {ML_SOCKET_ID, 1, 0, 0},
+   {ML_MODELS, 1, 0, 0}, {ML_FILELIST, 1, 0, 0},  {ML_REPETITIONS, 1, 0, 
0},
+   {ML_DEBUG, 0, 0, 0},  {ML_HELP, 0, 0, 0},  {NULL, 0, 0, 0}};
 
 static int
 ml_opts_parse_long(int opt_idx, struct ml_options *opt)
@@ -127,10 +189,9 @@ ml_opts_parse_long(int opt_idx, struct ml_options *opt)
unsigned int i;
 
struct long_opt_parser parsermap[] = {
-   {ML_TEST, ml_parse_test_name},
-   {ML_DEVI

[PATCH v6 03/12] app/mldev: add test case to validate device ops

2023-03-11 Thread Srikanth Yalavarthi
Added test case to validate device handling operations. Device ops
test is a collection of multiple sub-tests. Enabled sub-test to
validate device reconfiguration. Set device_ops as the default test.

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/meson.build   |   1 +
 app/test-mldev/ml_options.c  |   5 +-
 app/test-mldev/ml_options.h  |   2 +
 app/test-mldev/test_device_ops.c | 228 +++
 app/test-mldev/test_device_ops.h |  17 +++
 5 files changed, 251 insertions(+), 2 deletions(-)
 create mode 100644 app/test-mldev/test_device_ops.c
 create mode 100644 app/test-mldev/test_device_ops.h

diff --git a/app/test-mldev/meson.build b/app/test-mldev/meson.build
index 964bb9ddc4..60ea23d142 100644
--- a/app/test-mldev/meson.build
+++ b/app/test-mldev/meson.build
@@ -13,6 +13,7 @@ sources = files(
 'ml_test.c',
 'parser.c',
 'test_common.c',
+'test_device_ops.c',
 )
 
 deps += ['mldev']
diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index 521e9a2f97..b0837dde14 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -19,7 +19,7 @@ void
 ml_options_default(struct ml_options *opt)
 {
memset(opt, 0, sizeof(*opt));
-   strlcpy(opt->test_name, "ml_test", ML_TEST_NAME_MAX_LEN);
+   strlcpy(opt->test_name, "device_ops", ML_TEST_NAME_MAX_LEN);
opt->dev_id = 0;
opt->socket_id = SOCKET_ID_ANY;
opt->debug = false;
@@ -61,7 +61,8 @@ ml_parse_socket_id(struct ml_options *opt, const char *arg)
 static void
 ml_dump_test_options(const char *testname)
 {
-   RTE_SET_USED(testname);
+   if (strcmp(testname, "device_ops") == 0)
+   printf("\n");
 }
 
 static void
diff --git a/app/test-mldev/ml_options.h b/app/test-mldev/ml_options.h
index 05311a9a47..6899cc2f88 100644
--- a/app/test-mldev/ml_options.h
+++ b/app/test-mldev/ml_options.h
@@ -9,6 +9,7 @@
 #include 
 
 #define ML_TEST_NAME_MAX_LEN 32
+#define ML_TEST_MAX_MODELS   8
 
 /* Options names */
 #define ML_TEST ("test")
@@ -21,6 +22,7 @@ struct ml_options {
char test_name[ML_TEST_NAME_MAX_LEN];
int16_t dev_id;
int socket_id;
+   uint8_t nb_filelist;
bool debug;
 };
 
diff --git a/app/test-mldev/test_device_ops.c b/app/test-mldev/test_device_ops.c
new file mode 100644
index 00..be0c5f0780
--- /dev/null
+++ b/app/test-mldev/test_device_ops.c
@@ -0,0 +1,228 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "test_device_ops.h"
+
+static bool
+test_device_cap_check(struct ml_options *opt)
+{
+   if (!ml_test_cap_check(opt))
+   return false;
+
+   return true;
+}
+
+static int
+test_device_opt_check(struct ml_options *opt)
+{
+   int ret;
+
+   /* check common opts */
+   ret = ml_test_opt_check(opt);
+   if (ret != 0)
+   return ret;
+
+   return 0;
+}
+
+static void
+test_device_opt_dump(struct ml_options *opt)
+{
+   /* dump common opts */
+   ml_test_opt_dump(opt);
+}
+
+static int
+test_device_setup(struct ml_test *test, struct ml_options *opt)
+{
+   struct test_device *t;
+   void *test_device;
+   int ret = 0;
+
+   /* allocate for test structure */
+   test_device = rte_zmalloc_socket(test->name, sizeof(struct test_device),
+RTE_CACHE_LINE_SIZE, opt->socket_id);
+   if (test_device == NULL) {
+   ml_err("failed to allocate memory for test_model");
+   ret = -ENOMEM;
+   goto error;
+   }
+   test->test_priv = test_device;
+   t = ml_test_priv(test);
+
+   t->cmn.result = ML_TEST_FAILED;
+   t->cmn.opt = opt;
+
+   /* get device info */
+   ret = rte_ml_dev_info_get(opt->dev_id, &t->cmn.dev_info);
+   if (ret < 0) {
+   ml_err("failed to get device info");
+   goto error;
+   }
+
+   return 0;
+
+error:
+   if (test_device != NULL)
+   rte_free(test_device);
+
+   return ret;
+}
+
+static void
+test_device_destroy(struct ml_test *test, struct ml_options *opt)
+{
+   struct test_device *t;
+
+   RTE_SET_USED(opt);
+
+   t = ml_test_priv(test);
+   if (t != NULL)
+   rte_free(t);
+}
+
+static int
+test_device_reconfigure(struct ml_test *test, struct ml_options *opt)
+{
+   struct rte_ml_dev_config dev_config;
+   struct rte_ml_dev_qp_conf qp_conf;
+   struct test_device *t;
+   uint16_t qp_id = 0;
+   int ret = 0;
+
+   t = ml_test_priv(test);
+
+   /* configure with default options */
+   ret = ml_test_device_configure(test, opt);
+   if (ret != 0)
+   return ret;
+
+   /* setup one queue pair with nb_desc = 1 */
+   qp_conf.nb_desc = 1;
+   qp_conf.cb = NULL;
+
+   ret = rte_ml_dev_queue_pair_s

[PATCH v6 06/12] app/mldev: add test case to interleave inferences

2023-03-11 Thread Srikanth Yalavarthi
Added test case to interleave inference requests from multiple
models. Interleaving would load and start all models and launch
inference requests for the models using available queue-pairs

Operations sequence when testing with N models and R reps,

(load + start) x N -> (enqueue + dequeue) x N x R ...
-> (stop + unload) x N

Test can be executed by selecting "inference_interleave" test.

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/meson.build |   1 +
 app/test-mldev/ml_options.c|   3 +-
 app/test-mldev/test_inference_interleave.c | 114 +
 3 files changed, 117 insertions(+), 1 deletion(-)
 create mode 100644 app/test-mldev/test_inference_interleave.c

diff --git a/app/test-mldev/meson.build b/app/test-mldev/meson.build
index 475d76d126..41d22fb22c 100644
--- a/app/test-mldev/meson.build
+++ b/app/test-mldev/meson.build
@@ -18,6 +18,7 @@ sources = files(
 'test_model_ops.c',
 'test_inference_common.c',
 'test_inference_ordered.c',
+'test_inference_interleave.c',
 )
 
 deps += ['mldev']
diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index b7215a7e88..f9e3ce8e6f 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -156,7 +156,8 @@ ml_dump_test_options(const char *testname)
printf("\n");
}
 
-   if (strcmp(testname, "inference_ordered") == 0) {
+   if ((strcmp(testname, "inference_ordered") == 0) ||
+   (strcmp(testname, "inference_interleave") == 0)) {
printf("\t\t--filelist : comma separated list of model, 
input and output\n"
   "\t\t--repetitions  : number of inference 
repetitions\n");
printf("\n");
diff --git a/app/test-mldev/test_inference_interleave.c 
b/app/test-mldev/test_inference_interleave.c
new file mode 100644
index 00..9cf4cfa197
--- /dev/null
+++ b/app/test-mldev/test_inference_interleave.c
@@ -0,0 +1,114 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2022 Marvell.
+ */
+
+#include 
+#include 
+
+#include "ml_common.h"
+#include "test_inference_common.h"
+
+static int
+test_inference_interleave_driver(struct ml_test *test, struct ml_options *opt)
+{
+   struct test_inference *t;
+   uint16_t fid = 0;
+   int ret = 0;
+
+   t = ml_test_priv(test);
+
+   ret = ml_inference_mldev_setup(test, opt);
+   if (ret != 0)
+   return ret;
+
+   ret = ml_inference_mem_setup(test, opt);
+   if (ret != 0)
+   return ret;
+
+   /* load and start all models */
+   for (fid = 0; fid < opt->nb_filelist; fid++) {
+   ret = ml_model_load(test, opt, &t->model[fid], fid);
+   if (ret != 0)
+   goto error;
+
+   ret = ml_model_start(test, opt, &t->model[fid], fid);
+   if (ret != 0)
+   goto error;
+
+   ret = ml_inference_iomem_setup(test, opt, fid);
+   if (ret != 0)
+   goto error;
+   }
+
+   /* launch inference requests */
+   ret = ml_inference_launch_cores(test, opt, 0, opt->nb_filelist - 1);
+   if (ret != 0) {
+   ml_err("failed to launch cores");
+   goto error;
+   }
+
+   rte_eal_mp_wait_lcore();
+
+   /* stop and unload all models */
+   for (fid = 0; fid < opt->nb_filelist; fid++) {
+   ret = ml_inference_result(test, opt, fid);
+   if (ret != ML_TEST_SUCCESS)
+   goto error;
+
+   ml_inference_iomem_destroy(test, opt, fid);
+
+   ret = ml_model_stop(test, opt, &t->model[fid], fid);
+   if (ret != 0)
+   goto error;
+
+   ret = ml_model_unload(test, opt, &t->model[fid], fid);
+   if (ret != 0)
+   goto error;
+   }
+
+   ml_inference_mem_destroy(test, opt);
+
+   ret = ml_inference_mldev_destroy(test, opt);
+   if (ret != 0)
+   return ret;
+
+   t->cmn.result = ML_TEST_SUCCESS;
+
+   return 0;
+
+error:
+   ml_inference_mem_destroy(test, opt);
+   for (fid = 0; fid < opt->nb_filelist; fid++) {
+   ml_inference_iomem_destroy(test, opt, fid);
+   ml_model_stop(test, opt, &t->model[fid], fid);
+   ml_model_unload(test, opt, &t->model[fid], fid);
+   }
+
+   t->cmn.result = ML_TEST_FAILED;
+
+   return ret;
+}
+
+static int
+test_inference_interleave_result(struct ml_test *test, struct ml_options *opt)
+{
+   struct test_inference *t;
+
+   RTE_SET_USED(opt);
+
+   t = ml_test_priv(test);
+
+   return t->cmn.result;
+}
+
+static const struct ml_test_ops inference_interleave = {
+   .cap_check = test_inference_cap_check,
+   .opt_check = test_inference_opt_check,
+   .opt_dump = test_inference_opt_dump

[PATCH v6 07/12] app/mldev: enable support for burst inferences

2023-03-11 Thread Srikanth Yalavarthi
Added 'burst_size' support for inference tests. Burst size
controls the number of inference requests handled during
the burst enqueue and dequeue operations of the test case.

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/ml_options.c|  26 ++--
 app/test-mldev/ml_options.h|   2 +
 app/test-mldev/test_inference_common.c | 160 -
 app/test-mldev/test_inference_common.h |   4 +
 4 files changed, 182 insertions(+), 10 deletions(-)

diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index f9e3ce8e6f..7fbf9c5678 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -24,6 +24,7 @@ ml_options_default(struct ml_options *opt)
opt->socket_id = SOCKET_ID_ANY;
opt->nb_filelist = 0;
opt->repetitions = 1;
+   opt->burst_size = 1;
opt->debug = false;
 }
 
@@ -145,6 +146,12 @@ ml_parse_repetitions(struct ml_options *opt, const char 
*arg)
return parser_read_uint64(&opt->repetitions, arg);
 }
 
+static int
+ml_parse_burst_size(struct ml_options *opt, const char *arg)
+{
+   return parser_read_uint16(&opt->burst_size, arg);
+}
+
 static void
 ml_dump_test_options(const char *testname)
 {
@@ -159,7 +166,8 @@ ml_dump_test_options(const char *testname)
if ((strcmp(testname, "inference_ordered") == 0) ||
(strcmp(testname, "inference_interleave") == 0)) {
printf("\t\t--filelist : comma separated list of model, 
input and output\n"
-  "\t\t--repetitions  : number of inference 
repetitions\n");
+  "\t\t--repetitions  : number of inference 
repetitions\n"
+  "\t\t--burst_size   : inference burst size\n");
printf("\n");
}
 }
@@ -179,10 +187,11 @@ print_usage(char *program)
ml_test_dump_names(ml_dump_test_options);
 }
 
-static struct option lgopts[] = {
-   {ML_TEST, 1, 0, 0},   {ML_DEVICE_ID, 1, 0, 0}, {ML_SOCKET_ID, 1, 0, 0},
-   {ML_MODELS, 1, 0, 0}, {ML_FILELIST, 1, 0, 0},  {ML_REPETITIONS, 1, 0, 
0},
-   {ML_DEBUG, 0, 0, 0},  {ML_HELP, 0, 0, 0},  {NULL, 0, 0, 0}};
+static struct option lgopts[] = {{ML_TEST, 1, 0, 0},  {ML_DEVICE_ID, 1, 0, 
0},
+{ML_SOCKET_ID, 1, 0, 0},  {ML_MODELS, 1, 0, 0},
+{ML_FILELIST, 1, 0, 0},   {ML_REPETITIONS, 1, 
0, 0},
+{ML_BURST_SIZE, 1, 0, 0}, {ML_DEBUG, 0, 0, 0},
+{ML_HELP, 0, 0, 0},   {NULL, 0, 0, 0}};
 
 static int
 ml_opts_parse_long(int opt_idx, struct ml_options *opt)
@@ -190,9 +199,10 @@ ml_opts_parse_long(int opt_idx, struct ml_options *opt)
unsigned int i;
 
struct long_opt_parser parsermap[] = {
-   {ML_TEST, ml_parse_test_name},  {ML_DEVICE_ID, 
ml_parse_dev_id},
-   {ML_SOCKET_ID, ml_parse_socket_id}, {ML_MODELS, 
ml_parse_models},
-   {ML_FILELIST, ml_parse_filelist},   {ML_REPETITIONS, 
ml_parse_repetitions},
+   {ML_TEST, ml_parse_test_name},{ML_DEVICE_ID, 
ml_parse_dev_id},
+   {ML_SOCKET_ID, ml_parse_socket_id},   {ML_MODELS, 
ml_parse_models},
+   {ML_FILELIST, ml_parse_filelist}, {ML_REPETITIONS, 
ml_parse_repetitions},
+   {ML_BURST_SIZE, ml_parse_burst_size},
};
 
for (i = 0; i < RTE_DIM(parsermap); i++) {
diff --git a/app/test-mldev/ml_options.h b/app/test-mldev/ml_options.h
index 6a13f97a30..00342d8a0c 100644
--- a/app/test-mldev/ml_options.h
+++ b/app/test-mldev/ml_options.h
@@ -18,6 +18,7 @@
 #define ML_MODELS  ("models")
 #define ML_FILELIST("filelist")
 #define ML_REPETITIONS ("repetitions")
+#define ML_BURST_SIZE  ("burst_size")
 #define ML_DEBUG   ("debug")
 #define ML_HELP   ("help")
 
@@ -34,6 +35,7 @@ struct ml_options {
struct ml_filelist filelist[ML_TEST_MAX_MODELS];
uint8_t nb_filelist;
uint64_t repetitions;
+   uint16_t burst_size;
bool debug;
 };
 
diff --git a/app/test-mldev/test_inference_common.c 
b/app/test-mldev/test_inference_common.c
index 6a6999d524..35323306de 100644
--- a/app/test-mldev/test_inference_common.c
+++ b/app/test-mldev/test_inference_common.c
@@ -124,6 +124,132 @@ ml_dequeue_single(void *arg)
return 0;
 }
 
+/* Enqueue inference requests with burst size greater than 1 */
+static int
+ml_enqueue_burst(void *arg)
+{
+   struct test_inference *t = ml_test_priv((struct ml_test *)arg);
+   struct ml_core_args *args;
+   uint16_t ops_count;
+   uint64_t model_enq;
+   uint16_t burst_enq;
+   uint32_t lcore_id;
+   uint16_t pending;
+   uint16_t idx;
+   uint16_t fid;
+   uint16_t i;
+   int ret;
+
+   lcore_id = rte_lcore_id();
+   args = &t->args[lcore_id];
+   model_enq = 0;
+
+   if (args->nb_reqs == 0)
+   return 0

[PATCH v6 11/12] app/mldev: enable reporting stats in mldev app

2023-03-11 Thread Srikanth Yalavarthi
Enable reporting driver xstats and inference end-to-end
latency and throughput in mldev inference tests. Reporting
of stats can be enabled using "--stats" option.

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/ml_options.c|  22 ++--
 app/test-mldev/ml_options.h|   2 +
 app/test-mldev/test_inference_common.c | 140 +
 app/test-mldev/test_inference_common.h |   8 ++
 app/test-mldev/test_inference_interleave.c |   4 +
 app/test-mldev/test_inference_ordered.c|   1 +
 6 files changed, 169 insertions(+), 8 deletions(-)

diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index 9dfa5ec0d8..769c3bffd1 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -30,6 +30,7 @@ ml_options_default(struct ml_options *opt)
opt->queue_size = 1;
opt->batches = 0;
opt->tolerance = 0.0;
+   opt->stats = false;
opt->debug = false;
 }
 
@@ -216,7 +217,8 @@ ml_dump_test_options(const char *testname)
   "\t\t--queue_pairs  : number of queue pairs to 
create\n"
   "\t\t--queue_size   : size fo queue-pair\n"
   "\t\t--batches  : number of batches of input\n"
-  "\t\t--tolerance: maximum tolerance (%%) for 
output validation\n");
+  "\t\t--tolerance: maximum tolerance (%%) for 
output validation\n"
+  "\t\t--stats: enable reporting performance 
statistics\n");
printf("\n");
}
 }
@@ -236,13 +238,12 @@ print_usage(char *program)
ml_test_dump_names(ml_dump_test_options);
 }
 
-static struct option lgopts[] = {{ML_TEST, 1, 0, 0},  {ML_DEVICE_ID, 1, 0, 
0},
-{ML_SOCKET_ID, 1, 0, 0},  {ML_MODELS, 1, 0, 0},
-{ML_FILELIST, 1, 0, 0},   {ML_REPETITIONS, 1, 
0, 0},
-{ML_BURST_SIZE, 1, 0, 0}, {ML_QUEUE_PAIRS, 1, 
0, 0},
-{ML_QUEUE_SIZE, 1, 0, 0}, {ML_BATCHES, 1, 0, 
0},
-{ML_TOLERANCE, 1, 0, 0},  {ML_DEBUG, 0, 0, 0},
-{ML_HELP, 0, 0, 0},   {NULL, 0, 0, 0}};
+static struct option lgopts[] = {
+   {ML_TEST, 1, 0, 0},   {ML_DEVICE_ID, 1, 0, 0},   {ML_SOCKET_ID, 1, 
0, 0},
+   {ML_MODELS, 1, 0, 0}, {ML_FILELIST, 1, 0, 0},{ML_REPETITIONS, 
1, 0, 0},
+   {ML_BURST_SIZE, 1, 0, 0}, {ML_QUEUE_PAIRS, 1, 0, 0}, {ML_QUEUE_SIZE, 1, 
0, 0},
+   {ML_BATCHES, 1, 0, 0},{ML_TOLERANCE, 1, 0, 0},   {ML_STATS, 0, 0, 
0},
+   {ML_DEBUG, 0, 0, 0},  {ML_HELP, 0, 0, 0},{NULL, 0, 0, 0}};
 
 static int
 ml_opts_parse_long(int opt_idx, struct ml_options *opt)
@@ -277,6 +278,11 @@ ml_options_parse(struct ml_options *opt, int argc, char 
**argv)
while ((opts = getopt_long(argc, argv, "", lgopts, &opt_idx)) != EOF) {
switch (opts) {
case 0: /* parse long options */
+   if (!strcmp(lgopts[opt_idx].name, "stats")) {
+   opt->stats = true;
+   break;
+   }
+
if (!strcmp(lgopts[opt_idx].name, "debug")) {
opt->debug = true;
break;
diff --git a/app/test-mldev/ml_options.h b/app/test-mldev/ml_options.h
index 7f3db29656..beb0fe69c6 100644
--- a/app/test-mldev/ml_options.h
+++ b/app/test-mldev/ml_options.h
@@ -23,6 +23,7 @@
 #define ML_QUEUE_SIZE  ("queue_size")
 #define ML_BATCHES ("batches")
 #define ML_TOLERANCE   ("tolerance")
+#define ML_STATS   ("stats")
 #define ML_DEBUG   ("debug")
 #define ML_HELP   ("help")
 
@@ -45,6 +46,7 @@ struct ml_options {
uint16_t queue_size;
uint16_t batches;
float tolerance;
+   bool stats;
bool debug;
 };
 
diff --git a/app/test-mldev/test_inference_common.c 
b/app/test-mldev/test_inference_common.c
index b605c1f5d3..e85f32be60 100644
--- a/app/test-mldev/test_inference_common.c
+++ b/app/test-mldev/test_inference_common.c
@@ -6,6 +6,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,6 +38,17 @@
}   
   \
} while (0)
 
+static void
+print_line(uint16_t len)
+{
+   uint16_t i;
+
+   for (i = 0; i < len; i++)
+   printf("-");
+
+   printf("\n");
+}
+
 /* Enqueue inference requests with burst size equal to 1 */
 static int
 ml_enqueue_single(void *arg)
@@ -46,6 +58,7 @@ ml_enqueue_single(void *arg)
struct rte_ml_op *op = NULL;
struct ml_core_args *args;
uint64_t model_enq = 0;
+   uint64_t start_cycle;
uint32_t burst_enq;
uint32_t lcore_id;
uint16_t fid;
@@ -53,6 +66

[PATCH v6 08/12] app/mldev: enable support for queue pairs and size

2023-03-11 Thread Srikanth Yalavarthi
Added support to create multiple queue-pairs per device to
enqueue and dequeue inference requests. Number of queue pairs
to be created can be specified through "--queue_pairs" option.
Support is also enabled to control the number of descriptors
per each queue pair through "--queue_size" option. Inference
requests for a model are distributed across all available
queue-pairs.

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/ml_options.c| 40 ++---
 app/test-mldev/ml_options.h|  4 ++
 app/test-mldev/test_common.c   |  2 +-
 app/test-mldev/test_inference_common.c | 79 +-
 app/test-mldev/test_inference_common.h |  1 +
 5 files changed, 102 insertions(+), 24 deletions(-)

diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index 7fbf9c5678..c81dec6e30 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -25,6 +25,8 @@ ml_options_default(struct ml_options *opt)
opt->nb_filelist = 0;
opt->repetitions = 1;
opt->burst_size = 1;
+   opt->queue_pairs = 1;
+   opt->queue_size = 1;
opt->debug = false;
 }
 
@@ -152,11 +154,30 @@ ml_parse_burst_size(struct ml_options *opt, const char 
*arg)
return parser_read_uint16(&opt->burst_size, arg);
 }
 
+static int
+ml_parse_queue_pairs(struct ml_options *opt, const char *arg)
+{
+   int ret;
+
+   ret = parser_read_uint16(&opt->queue_pairs, arg);
+
+   return ret;
+}
+
+static int
+ml_parse_queue_size(struct ml_options *opt, const char *arg)
+{
+   return parser_read_uint16(&opt->queue_size, arg);
+}
+
 static void
 ml_dump_test_options(const char *testname)
 {
-   if (strcmp(testname, "device_ops") == 0)
+   if (strcmp(testname, "device_ops") == 0) {
+   printf("\t\t--queue_pairs  : number of queue pairs to 
create\n"
+  "\t\t--queue_size   : size fo queue-pair\n");
printf("\n");
+   }
 
if (strcmp(testname, "model_ops") == 0) {
printf("\t\t--models   : comma separated list of 
models\n");
@@ -167,7 +188,9 @@ ml_dump_test_options(const char *testname)
(strcmp(testname, "inference_interleave") == 0)) {
printf("\t\t--filelist : comma separated list of model, 
input and output\n"
   "\t\t--repetitions  : number of inference 
repetitions\n"
-  "\t\t--burst_size   : inference burst size\n");
+  "\t\t--burst_size   : inference burst size\n"
+  "\t\t--queue_pairs  : number of queue pairs to 
create\n"
+  "\t\t--queue_size   : size fo queue-pair\n");
printf("\n");
}
 }
@@ -187,11 +210,11 @@ print_usage(char *program)
ml_test_dump_names(ml_dump_test_options);
 }
 
-static struct option lgopts[] = {{ML_TEST, 1, 0, 0},  {ML_DEVICE_ID, 1, 0, 
0},
-{ML_SOCKET_ID, 1, 0, 0},  {ML_MODELS, 1, 0, 0},
-{ML_FILELIST, 1, 0, 0},   {ML_REPETITIONS, 1, 
0, 0},
-{ML_BURST_SIZE, 1, 0, 0}, {ML_DEBUG, 0, 0, 0},
-{ML_HELP, 0, 0, 0},   {NULL, 0, 0, 0}};
+static struct option lgopts[] = {
+   {ML_TEST, 1, 0, 0},   {ML_DEVICE_ID, 1, 0, 0},   {ML_SOCKET_ID, 1, 
0, 0},
+   {ML_MODELS, 1, 0, 0}, {ML_FILELIST, 1, 0, 0},{ML_REPETITIONS, 
1, 0, 0},
+   {ML_BURST_SIZE, 1, 0, 0}, {ML_QUEUE_PAIRS, 1, 0, 0}, {ML_QUEUE_SIZE, 1, 
0, 0},
+   {ML_DEBUG, 0, 0, 0},  {ML_HELP, 0, 0, 0},{NULL, 0, 0, 0}};
 
 static int
 ml_opts_parse_long(int opt_idx, struct ml_options *opt)
@@ -202,7 +225,8 @@ ml_opts_parse_long(int opt_idx, struct ml_options *opt)
{ML_TEST, ml_parse_test_name},{ML_DEVICE_ID, 
ml_parse_dev_id},
{ML_SOCKET_ID, ml_parse_socket_id},   {ML_MODELS, 
ml_parse_models},
{ML_FILELIST, ml_parse_filelist}, {ML_REPETITIONS, 
ml_parse_repetitions},
-   {ML_BURST_SIZE, ml_parse_burst_size},
+   {ML_BURST_SIZE, ml_parse_burst_size}, {ML_QUEUE_PAIRS, 
ml_parse_queue_pairs},
+   {ML_QUEUE_SIZE, ml_parse_queue_size},
};
 
for (i = 0; i < RTE_DIM(parsermap); i++) {
diff --git a/app/test-mldev/ml_options.h b/app/test-mldev/ml_options.h
index 00342d8a0c..c4018ee9d1 100644
--- a/app/test-mldev/ml_options.h
+++ b/app/test-mldev/ml_options.h
@@ -19,6 +19,8 @@
 #define ML_FILELIST("filelist")
 #define ML_REPETITIONS ("repetitions")
 #define ML_BURST_SIZE  ("burst_size")
+#define ML_QUEUE_PAIRS ("queue_pairs")
+#define ML_QUEUE_SIZE  ("queue_size")
 #define ML_DEBUG   ("debug")
 #define ML_HELP   ("help")
 
@@ -36,6 +38,8 @@ struct ml_options {
uint8_t nb_filelist;
uint64_t repetitions;
uint16_t burst_size;
+   uint16_t queue_

[PATCH v6 09/12] app/mldev: enable support for inference batches

2023-03-11 Thread Srikanth Yalavarthi
Enabled support to execute multiple batches of inferences
per each enqueue request. Input and reference for the test
should be appropriately provided for multi-batch run. Number
of batches can be specified through "--batches" option.

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/ml_options.c| 15 ---
 app/test-mldev/ml_options.h|  2 ++
 app/test-mldev/test_inference_common.c | 22 +-
 app/test-mldev/test_model_common.c |  6 ++
 app/test-mldev/test_model_common.h |  1 +
 5 files changed, 34 insertions(+), 12 deletions(-)

diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index c81dec6e30..499bfde899 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -27,6 +27,7 @@ ml_options_default(struct ml_options *opt)
opt->burst_size = 1;
opt->queue_pairs = 1;
opt->queue_size = 1;
+   opt->batches = 0;
opt->debug = false;
 }
 
@@ -170,6 +171,12 @@ ml_parse_queue_size(struct ml_options *opt, const char 
*arg)
return parser_read_uint16(&opt->queue_size, arg);
 }
 
+static int
+ml_parse_batches(struct ml_options *opt, const char *arg)
+{
+   return parser_read_uint16(&opt->batches, arg);
+}
+
 static void
 ml_dump_test_options(const char *testname)
 {
@@ -190,7 +197,8 @@ ml_dump_test_options(const char *testname)
   "\t\t--repetitions  : number of inference 
repetitions\n"
   "\t\t--burst_size   : inference burst size\n"
   "\t\t--queue_pairs  : number of queue pairs to 
create\n"
-  "\t\t--queue_size   : size fo queue-pair\n");
+  "\t\t--queue_size   : size fo queue-pair\n"
+  "\t\t--batches  : number of batches of input\n");
printf("\n");
}
 }
@@ -214,7 +222,8 @@ static struct option lgopts[] = {
{ML_TEST, 1, 0, 0},   {ML_DEVICE_ID, 1, 0, 0},   {ML_SOCKET_ID, 1, 
0, 0},
{ML_MODELS, 1, 0, 0}, {ML_FILELIST, 1, 0, 0},{ML_REPETITIONS, 
1, 0, 0},
{ML_BURST_SIZE, 1, 0, 0}, {ML_QUEUE_PAIRS, 1, 0, 0}, {ML_QUEUE_SIZE, 1, 
0, 0},
-   {ML_DEBUG, 0, 0, 0},  {ML_HELP, 0, 0, 0},{NULL, 0, 0, 0}};
+   {ML_BATCHES, 1, 0, 0},{ML_DEBUG, 0, 0, 0},   {ML_HELP, 0, 0, 0},
+   {NULL, 0, 0, 0}};
 
 static int
 ml_opts_parse_long(int opt_idx, struct ml_options *opt)
@@ -226,7 +235,7 @@ ml_opts_parse_long(int opt_idx, struct ml_options *opt)
{ML_SOCKET_ID, ml_parse_socket_id},   {ML_MODELS, 
ml_parse_models},
{ML_FILELIST, ml_parse_filelist}, {ML_REPETITIONS, 
ml_parse_repetitions},
{ML_BURST_SIZE, ml_parse_burst_size}, {ML_QUEUE_PAIRS, 
ml_parse_queue_pairs},
-   {ML_QUEUE_SIZE, ml_parse_queue_size},
+   {ML_QUEUE_SIZE, ml_parse_queue_size}, {ML_BATCHES, 
ml_parse_batches},
};
 
for (i = 0; i < RTE_DIM(parsermap); i++) {
diff --git a/app/test-mldev/ml_options.h b/app/test-mldev/ml_options.h
index c4018ee9d1..48fe064150 100644
--- a/app/test-mldev/ml_options.h
+++ b/app/test-mldev/ml_options.h
@@ -21,6 +21,7 @@
 #define ML_BURST_SIZE  ("burst_size")
 #define ML_QUEUE_PAIRS ("queue_pairs")
 #define ML_QUEUE_SIZE  ("queue_size")
+#define ML_BATCHES ("batches")
 #define ML_DEBUG   ("debug")
 #define ML_HELP   ("help")
 
@@ -40,6 +41,7 @@ struct ml_options {
uint16_t burst_size;
uint16_t queue_pairs;
uint16_t queue_size;
+   uint16_t batches;
bool debug;
 };
 
diff --git a/app/test-mldev/test_inference_common.c 
b/app/test-mldev/test_inference_common.c
index b4ad3c4b72..0f281aed6c 100644
--- a/app/test-mldev/test_inference_common.c
+++ b/app/test-mldev/test_inference_common.c
@@ -50,7 +50,7 @@ ml_enqueue_single(void *arg)
goto retry;
 
op->model_id = t->model[fid].id;
-   op->nb_batches = t->model[fid].info.batch_size;
+   op->nb_batches = t->model[fid].nb_batches;
op->mempool = t->op_pool;
 
op->input.addr = req->input;
@@ -163,7 +163,7 @@ ml_enqueue_burst(void *arg)
 
for (i = 0; i < ops_count; i++) {
args->enq_ops[i]->model_id = t->model[fid].id;
-   args->enq_ops[i]->nb_batches = t->model[fid].info.batch_size;
+   args->enq_ops[i]->nb_batches = t->model[fid].nb_batches;
args->enq_ops[i]->mempool = t->op_pool;
 
args->enq_ops[i]->input.addr = args->reqs[i]->input;
@@ -359,6 +359,11 @@ test_inference_opt_dump(struct ml_options *opt)
ml_dump("queue_pairs", "%u", opt->queue_pairs);
ml_dump("queue_size", "%u", opt->queue_size);
 
+   if (opt->batches == 0)
+   ml_dump("batches", "%u (default)", opt->batches);
+   else
+   ml_dump("batches", "%u", opt->batches);
+
ml_dump_begin("filelist");

[PATCH v6 10/12] app/mldev: enable support for inference validation

2023-03-11 Thread Srikanth Yalavarthi
Enabled support to validate inference output with reference
output provided by the user. Validation would be successful
only when the inference outputs are within the 'tolerance'
specified through command line option "--tolerance".

Signed-off-by: Srikanth Yalavarthi 
Acked-by: Anup Prabhu 
---
 app/test-mldev/meson.build |   2 +-
 app/test-mldev/ml_options.c|  36 -
 app/test-mldev/ml_options.h|   3 +
 app/test-mldev/test_inference_common.c | 216 -
 app/test-mldev/test_inference_common.h |   1 +
 app/test-mldev/test_model_common.h |   1 +
 6 files changed, 248 insertions(+), 11 deletions(-)

diff --git a/app/test-mldev/meson.build b/app/test-mldev/meson.build
index 41d22fb22c..15db534dc2 100644
--- a/app/test-mldev/meson.build
+++ b/app/test-mldev/meson.build
@@ -21,4 +21,4 @@ sources = files(
 'test_inference_interleave.c',
 )
 
-deps += ['mldev']
+deps += ['mldev', 'hash']
diff --git a/app/test-mldev/ml_options.c b/app/test-mldev/ml_options.c
index 499bfde899..9dfa5ec0d8 100644
--- a/app/test-mldev/ml_options.c
+++ b/app/test-mldev/ml_options.c
@@ -4,6 +4,7 @@
 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -28,6 +29,7 @@ ml_options_default(struct ml_options *opt)
opt->queue_pairs = 1;
opt->queue_size = 1;
opt->batches = 0;
+   opt->tolerance = 0.0;
opt->debug = false;
 }
 
@@ -133,6 +135,13 @@ 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);
+   if (token != NULL)
+   strlcpy(opt->filelist[opt->nb_filelist].reference, token, 
PATH_MAX);
+   else
+   memset(opt->filelist[opt->nb_filelist].reference, 0, PATH_MAX);
+
opt->nb_filelist++;
 
if (opt->nb_filelist == 0) {
@@ -177,6 +186,14 @@ ml_parse_batches(struct ml_options *opt, const char *arg)
return parser_read_uint16(&opt->batches, arg);
 }
 
+static int
+ml_parse_tolerance(struct ml_options *opt, const char *arg)
+{
+   opt->tolerance = fabs(atof(arg));
+
+   return 0;
+}
+
 static void
 ml_dump_test_options(const char *testname)
 {
@@ -193,12 +210,13 @@ ml_dump_test_options(const char *testname)
 
if ((strcmp(testname, "inference_ordered") == 0) ||
(strcmp(testname, "inference_interleave") == 0)) {
-   printf("\t\t--filelist : comma separated list of model, 
input and output\n"
+   printf("\t\t--filelist : comma separated list of model, 
input, output and reference\n"
   "\t\t--repetitions  : number of inference 
repetitions\n"
   "\t\t--burst_size   : inference burst size\n"
   "\t\t--queue_pairs  : number of queue pairs to 
create\n"
   "\t\t--queue_size   : size fo queue-pair\n"
-  "\t\t--batches  : number of batches of input\n");
+  "\t\t--batches  : number of batches of input\n"
+  "\t\t--tolerance: maximum tolerance (%%) for 
output validation\n");
printf("\n");
}
 }
@@ -218,12 +236,13 @@ print_usage(char *program)
ml_test_dump_names(ml_dump_test_options);
 }
 
-static struct option lgopts[] = {
-   {ML_TEST, 1, 0, 0},   {ML_DEVICE_ID, 1, 0, 0},   {ML_SOCKET_ID, 1, 
0, 0},
-   {ML_MODELS, 1, 0, 0}, {ML_FILELIST, 1, 0, 0},{ML_REPETITIONS, 
1, 0, 0},
-   {ML_BURST_SIZE, 1, 0, 0}, {ML_QUEUE_PAIRS, 1, 0, 0}, {ML_QUEUE_SIZE, 1, 
0, 0},
-   {ML_BATCHES, 1, 0, 0},{ML_DEBUG, 0, 0, 0},   {ML_HELP, 0, 0, 0},
-   {NULL, 0, 0, 0}};
+static struct option lgopts[] = {{ML_TEST, 1, 0, 0},  {ML_DEVICE_ID, 1, 0, 
0},
+{ML_SOCKET_ID, 1, 0, 0},  {ML_MODELS, 1, 0, 0},
+{ML_FILELIST, 1, 0, 0},   {ML_REPETITIONS, 1, 
0, 0},
+{ML_BURST_SIZE, 1, 0, 0}, {ML_QUEUE_PAIRS, 1, 
0, 0},
+{ML_QUEUE_SIZE, 1, 0, 0}, {ML_BATCHES, 1, 0, 
0},
+{ML_TOLERANCE, 1, 0, 0},  {ML_DEBUG, 0, 0, 0},
+{ML_HELP, 0, 0, 0},   {NULL, 0, 0, 0}};
 
 static int
 ml_opts_parse_long(int opt_idx, struct ml_options *opt)
@@ -236,6 +255,7 @@ ml_opts_parse_long(int opt_idx, struct ml_options *opt)
{ML_FILELIST, ml_parse_filelist}, {ML_REPETITIONS, 
ml_parse_repetitions},
{ML_BURST_SIZE, ml_parse_burst_size}, {ML_QUEUE_PAIRS, 
ml_parse_queue_pairs},
{ML_QUEUE_SIZE, ml_parse_queue_size}, {ML_BATCHES, 
ml_parse_batches},
+   {ML_TOLERANCE, ml_parse_tolerance},
};
 
for (i = 0; i < RTE_DIM(parsermap); i++) {
diff --git a/app/test-mldev/ml_options.h b/app/test-mldev/ml_options.h

RE: [EXT] [PATCH v2] crypto/ccp: bug fixes for ccp device probe flow

2023-03-11 Thread Akhil Goyal
> Subject: [EXT] [PATCH v2] crypto/ccp: bug fixes for ccp device probe flow
> - Rebasing patch([v1] crypto/ccp: bug fixes for ccp device probe flow)

Please write a meaningful patch title and description
Also add fixes tag.
Add Cc sta...@dpdk.org so that fix can be backported.

> 
> Signed-off-by: Sunil Uttarwar 
> ---
>  drivers/crypto/ccp/rte_ccp_pmd.c | 8 
>  1 file changed, 8 deletions(-)
> 
> diff --git a/drivers/crypto/ccp/rte_ccp_pmd.c
> b/drivers/crypto/ccp/rte_ccp_pmd.c
> index a5271d7227..5d1a4445de 100644
> --- a/drivers/crypto/ccp/rte_ccp_pmd.c
> +++ b/drivers/crypto/ccp/rte_ccp_pmd.c
> @@ -19,7 +19,6 @@
>  /**
>   * Global static parameter used to find if CCP device is already initialized.
>   */
> -static unsigned int ccp_pmd_init_done;
>  uint8_t ccp_cryptodev_driver_id;
>  uint8_t cryptodev_cnt;
> 
> @@ -192,8 +191,6 @@ cryptodev_ccp_remove(struct rte_pci_device *pci_dev)
>   if (dev == NULL)
>   return -ENODEV;
> 
> - ccp_pmd_init_done = 0;
> -
>   RTE_LOG(INFO, PMD, "Closing ccp device %s on numa socket %u\n",
>   name, rte_socket_id());
> 
> @@ -278,10 +275,6 @@ cryptodev_ccp_probe(struct rte_pci_driver *pci_drv
> __rte_unused,
>   .auth_opt = CCP_PMD_AUTH_OPT_CCP,
>   };
> 
> - if (ccp_pmd_init_done) {
> - RTE_LOG(INFO, PMD, "CCP PMD already initialized\n");
> - return -EFAULT;
> - }
>   rte_pci_device_name(&pci_dev->addr, name, sizeof(name));
>   if (name[0] == '\0')
>   return -EINVAL;
> @@ -300,7 +293,6 @@ cryptodev_ccp_probe(struct rte_pci_driver *pci_drv
> __rte_unused,
>   rc = cryptodev_ccp_create(name, pci_dev, &init_params, pci_drv);
>   if (rc)
>   return rc;
> - ccp_pmd_init_done = 1;
>   return 0;
>  }
> 
> --
> 2.25.1



RE: [PATCH v2] crypto/ccp: fix PCI probing

2023-03-11 Thread Akhil Goyal
> 
> Acked-by: Sunil Uttarwar 
> 
> Subject: [PATCH v2] crypto/ccp: fix PCI probing
> 
> Caution: This message originated from an External Source. Use proper caution
> when opening attachments, clicking links, or responding.
> 
> 
> This driver has been converted from a vdev driver to a pci driver some time 
> ago.
> This conversion is buggy as it tries to probe any pci devices present on a 
> system
> for *each* probe request from the PCI bus.
> 
> Rely on the passed pci device and only probe what is requested.
> 
> While at it:
> - stop copying the pci device object content into a local private copy,
> - rely on the PCI identifier and remove internal ccp_device_version
>   identifier,
> - ccp_list can be made static,
> 
> With this done, all the code parsing Linux sysfs can be dropped.
> 
> Fixes: 889317b7ecb3 ("crypto/ccp: convert driver from vdev to PCI")
> Cc: sta...@dpdk.org
> 
> Signed-off-by: David Marchand 

Applied to dpdk-next-crypto.

Thanks.


RE: [PATCH] crypto/qat: fix SM3 auth mode

2023-03-11 Thread Akhil Goyal
> > Subject: [PATCH] crypto/qat: fix SM3 auth mode
> >
> > The SM3 auth mode is now set to 0 for QAT, to support plain hash only.
> > This should also be added to the capabilities for GEN3 and GEN4.
> > SM3 HMAC is not supported.
> >
> > Fixes: 75fd4bbc94ab ("crypto/qat: support SM3 hash algorithm")
> > Cc: arkadiuszx.kusz...@intel.com
> > Cc: sta...@dpdk.org
> >
> > Signed-off-by: Ciara Power 
> Acked-by: Arek Kusztal 
Applied to dpdk-next-crypto

Thanks.



RE: [dpdk-dev v1] crypto/openssl: fix of ASAN heap-use-after-free

2023-03-11 Thread Akhil Goyal
> > Subject: [dpdk-dev v1] crypto/openssl: fix of ASAN heap-use-after-free
> >
> > fix of ASAN report on heap-use-after-free error on tmp buffer.
> >
> > Fixes: d7bd42f6db19 ("crypto/openssl: update RSA routine with 3.0 EVP
> > API")
> > Cc: kai...@intel.com
> >
> > Signed-off-by: Kai Ji 
> > ---
> >  drivers/crypto/openssl/rte_openssl_pmd.c | 4 ++--
> >  1 file changed, 2 insertions(+), 2 deletions(-)
> >
> 
> [CP]
> Need to add cc for sta...@dpdk.org
> 
> Acked-by: Ciara Power 
Applied to dpdk-next-crypto
Cc: sta...@dpdk.org
Thanks.


RE: [EXT] [PATCH] app/crypto-perf: fix test file memory leak

2023-03-11 Thread Akhil Goyal
> A memory leak was detected using the AddressSanitizer tool,
> when running the crypto-perf application with a test vector file.
> 
> The strdup function used returns a pointer to a null-terminated byte
> string, which must be freed after use. This patch frees the pointer in
> an error case, and also after a successful run.
> 
> Fixes: f8be1786b1b8 ("app/crypto-perf: introduce performance test
> application")
> Cc: sta...@dpdk.org
> 
> Signed-off-by: Ciara Power 
Acked-by: Akhil Goyal 

Applied to dpdk-next-crypto



[PATCH] app/flow-perf: replace RTE_BE32/16 with rte_cpu_to_be_32/16 for variables

2023-03-11 Thread Harold Huang
In DPDK, the macros RTE_BE32 or RTE_BE16 are usually used for
constant values. And functions such as rte_cpu_to_be_32 or
rte_cpu_to_be_16 are optimized for variables.

Signed-off-by: Harold Huang 
---
 app/test-flow-perf/actions_gen.c | 28 ++--
 app/test-flow-perf/items_gen.c   |  2 +-
 2 files changed, 15 insertions(+), 15 deletions(-)

diff --git a/app/test-flow-perf/actions_gen.c b/app/test-flow-perf/actions_gen.c
index f1d5931325..c2499ad2d0 100644
--- a/app/test-flow-perf/actions_gen.c
+++ b/app/test-flow-perf/actions_gen.c
@@ -262,7 +262,7 @@ add_set_src_ipv4(struct rte_flow_action *actions,
ip = 1;
 
/* IPv4 value to be set is random each time */
-   set_ipv4[para.core_idx].ipv4_addr = RTE_BE32(ip + 1);
+   set_ipv4[para.core_idx].ipv4_addr = rte_cpu_to_be_32(ip + 1);
 
actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_SRC;
actions[actions_counter].conf = &set_ipv4[para.core_idx];
@@ -281,7 +281,7 @@ add_set_dst_ipv4(struct rte_flow_action *actions,
ip = 1;
 
/* IPv4 value to be set is random each time */
-   set_ipv4[para.core_idx].ipv4_addr = RTE_BE32(ip + 1);
+   set_ipv4[para.core_idx].ipv4_addr = rte_cpu_to_be_32(ip + 1);
 
actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_IPV4_DST;
actions[actions_counter].conf = &set_ipv4[para.core_idx];
@@ -348,7 +348,7 @@ add_set_src_tp(struct rte_flow_action *actions,
/* TP src port is random each time */
tp = tp % 0x;
 
-   set_tp[para.core_idx].port = RTE_BE16(tp & 0x);
+   set_tp[para.core_idx].port = rte_cpu_to_be_16(tp & 0x);
 
actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_SRC;
actions[actions_counter].conf = &set_tp[para.core_idx];
@@ -370,7 +370,7 @@ add_set_dst_tp(struct rte_flow_action *actions,
if (tp > 0x)
tp = tp >> 16;
 
-   set_tp[para.core_idx].port = RTE_BE16(tp & 0x);
+   set_tp[para.core_idx].port = rte_cpu_to_be_16(tp & 0x);
 
actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_SET_TP_DST;
actions[actions_counter].conf = &set_tp[para.core_idx];
@@ -388,7 +388,7 @@ add_inc_tcp_ack(struct rte_flow_action *actions,
if (!para.unique_data)
ack_value = 1;
 
-   value[para.core_idx] = RTE_BE32(ack_value);
+   value[para.core_idx] = rte_cpu_to_be_32(ack_value);
 
actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_ACK;
actions[actions_counter].conf = &value[para.core_idx];
@@ -406,7 +406,7 @@ add_dec_tcp_ack(struct rte_flow_action *actions,
if (!para.unique_data)
ack_value = 1;
 
-   value[para.core_idx] = RTE_BE32(ack_value);
+   value[para.core_idx] = rte_cpu_to_be_32(ack_value);
 
actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_ACK;
actions[actions_counter].conf = &value[para.core_idx];
@@ -424,7 +424,7 @@ add_inc_tcp_seq(struct rte_flow_action *actions,
if (!para.unique_data)
seq_value = 1;
 
-   value[para.core_idx] = RTE_BE32(seq_value);
+   value[para.core_idx] = rte_cpu_to_be_32(seq_value);
 
actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_INC_TCP_SEQ;
actions[actions_counter].conf = &value[para.core_idx];
@@ -442,7 +442,7 @@ add_dec_tcp_seq(struct rte_flow_action *actions,
if (!para.unique_data)
seq_value = 1;
 
-   value[para.core_idx] = RTE_BE32(seq_value);
+   value[para.core_idx] = rte_cpu_to_be_32(seq_value);
 
actions[actions_counter].type = RTE_FLOW_ACTION_TYPE_DEC_TCP_SEQ;
actions[actions_counter].conf = &value[para.core_idx];
@@ -560,7 +560,7 @@ add_vlan_header(uint8_t **header, uint64_t data,
vlan_value = VLAN_VALUE;
 
memset(&vlan_hdr, 0, sizeof(struct rte_vlan_hdr));
-   vlan_hdr.vlan_tci = RTE_BE16(vlan_value);
+   vlan_hdr.vlan_tci = rte_cpu_to_be_16(vlan_value);
 
if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_IPV4))
vlan_hdr.eth_proto = RTE_BE16(RTE_ETHER_TYPE_IPV4);
@@ -586,7 +586,7 @@ add_ipv4_header(uint8_t **header, uint64_t data,
 
memset(&ipv4_hdr, 0, sizeof(struct rte_ipv4_hdr));
ipv4_hdr.src_addr = RTE_IPV4(127, 0, 0, 1);
-   ipv4_hdr.dst_addr = RTE_BE32(ip_dst);
+   ipv4_hdr.dst_addr = rte_cpu_to_be_32(ip_dst);
ipv4_hdr.version_ihl = RTE_IPV4_VHL_DEF;
if (data & FLOW_ITEM_MASK(RTE_FLOW_ITEM_TYPE_UDP))
ipv4_hdr.next_proto_id = RTE_IP_TYPE_UDP;
@@ -652,7 +652,7 @@ add_vxlan_header(uint8_t **header, uint64_t data,
 
memset(&vxlan_hdr, 0, sizeof(struct rte_vxlan_hdr));
 
-   vxlan_hdr.vx_vni = (RTE_BE32(vni_value)) >> 16;
+   vxlan_hdr.vx_vni = (rte_cpu_to_be_32(vni_value)) >> 16;
vxlan_hdr.vx_flags = 0x8;
 
memcpy(*header, &vxlan_hdr, sizeof(vxlan_hdr));
@@ -675,7 +675,7 @@ add_vxlan_gpe_header(uint8_t **hea

[PATCH v4] lib/bpf: Rename bpf function names to avoid potential conflict with libpcap

2023-03-11 Thread J.J. Martzki
The library libpcap has their function 'bpf_validate' either so there would
be a multiple definition issue when linking with librte_bpf.a and libpcap.a
statically (Same as http://dpdk.org/patch/52631). So just rename the
function names to avoid such issue.

Signed-off-by: J.J. Martzki 

---
v4:
* Update my name.
v3:
* Rewrite the commit message.
v2:
* Rename all functions in bpf_impl.h.
* Adjust the commit message.
---
 lib/bpf/bpf.c   |  6 +++---
 lib/bpf/bpf_convert.c   |  3 ---
 lib/bpf/bpf_impl.h  | 10 --
 lib/bpf/bpf_jit_arm64.c |  2 +-
 lib/bpf/bpf_jit_x86.c   |  2 +-
 lib/bpf/bpf_load.c  |  4 ++--
 lib/bpf/bpf_validate.c  |  2 +-
 7 files changed, 12 insertions(+), 17 deletions(-)

diff --git a/lib/bpf/bpf.c b/lib/bpf/bpf.c
index 1e1dd42a58..f218a8f2b0 100644
--- a/lib/bpf/bpf.c
+++ b/lib/bpf/bpf.c
@@ -31,14 +31,14 @@ rte_bpf_get_jit(const struct rte_bpf *bpf, struct 
rte_bpf_jit *jit)
 }
 
 int
-bpf_jit(struct rte_bpf *bpf)
+rte_bpf_jit(struct rte_bpf *bpf)
 {
int32_t rc;
 
 #if defined(RTE_ARCH_X86_64)
-   rc = bpf_jit_x86(bpf);
+   rc = rte_bpf_jit_x86(bpf);
 #elif defined(RTE_ARCH_ARM64)
-   rc = bpf_jit_arm64(bpf);
+   rc = rte_bpf_jit_arm64(bpf);
 #else
rc = -ENOTSUP;
 #endif
diff --git a/lib/bpf/bpf_convert.c b/lib/bpf/bpf_convert.c
index 9563274c9c..d441be6663 100644
--- a/lib/bpf/bpf_convert.c
+++ b/lib/bpf/bpf_convert.c
@@ -23,11 +23,8 @@
 #include 
 #include 
 
-/* Workaround name conflicts with libpcap */
-#define bpf_validate(f, len) bpf_validate_libpcap(f, len)
 #include 
 #include 
-#undef bpf_validate
 
 #include "bpf_impl.h"
 #include "bpf_def.h"
diff --git a/lib/bpf/bpf_impl.h b/lib/bpf/bpf_impl.h
index b4d8e87c6d..e955b74181 100644
--- a/lib/bpf/bpf_impl.h
+++ b/lib/bpf/bpf_impl.h
@@ -17,12 +17,10 @@ struct rte_bpf {
uint32_t stack_sz;
 };
 
-extern int bpf_validate(struct rte_bpf *bpf);
-
-extern int bpf_jit(struct rte_bpf *bpf);
-
-extern int bpf_jit_x86(struct rte_bpf *);
-extern int bpf_jit_arm64(struct rte_bpf *);
+extern int rte_bpf_validate(struct rte_bpf *bpf);
+extern int rte_bpf_jit(struct rte_bpf *bpf);
+extern int rte_bpf_jit_x86(struct rte_bpf *bpf);
+extern int rte_bpf_jit_arm64(struct rte_bpf *bpf);
 
 extern int rte_bpf_logtype;
 
diff --git a/lib/bpf/bpf_jit_arm64.c b/lib/bpf/bpf_jit_arm64.c
index db79ff7385..d1ab5f8fbf 100644
--- a/lib/bpf/bpf_jit_arm64.c
+++ b/lib/bpf/bpf_jit_arm64.c
@@ -1393,7 +1393,7 @@ emit(struct a64_jit_ctx *ctx, struct rte_bpf *bpf)
  * Produce a native ISA version of the given BPF code.
  */
 int
-bpf_jit_arm64(struct rte_bpf *bpf)
+rte_bpf_jit_arm64(struct rte_bpf *bpf)
 {
struct a64_jit_ctx ctx;
size_t size;
diff --git a/lib/bpf/bpf_jit_x86.c b/lib/bpf/bpf_jit_x86.c
index c1a30e0386..182004ac7d 100644
--- a/lib/bpf/bpf_jit_x86.c
+++ b/lib/bpf/bpf_jit_x86.c
@@ -1490,7 +1490,7 @@ emit(struct bpf_jit_state *st, const struct rte_bpf *bpf)
  * produce a native ISA version of the given BPF code.
  */
 int
-bpf_jit_x86(struct rte_bpf *bpf)
+rte_bpf_jit_x86(struct rte_bpf *bpf)
 {
int32_t rc;
uint32_t i;
diff --git a/lib/bpf/bpf_load.c b/lib/bpf/bpf_load.c
index 1e17df6ce0..2c4bca3586 100644
--- a/lib/bpf/bpf_load.c
+++ b/lib/bpf/bpf_load.c
@@ -108,9 +108,9 @@ rte_bpf_load(const struct rte_bpf_prm *prm)
return NULL;
}
 
-   rc = bpf_validate(bpf);
+   rc = rte_bpf_validate(bpf);
if (rc == 0) {
-   bpf_jit(bpf);
+   rte_bpf_jit(bpf);
if (mprotect(bpf, bpf->sz, PROT_READ) != 0)
rc = -ENOMEM;
}
diff --git a/lib/bpf/bpf_validate.c b/lib/bpf/bpf_validate.c
index 61cbb42216..2d3d899966 100644
--- a/lib/bpf/bpf_validate.c
+++ b/lib/bpf/bpf_validate.c
@@ -2302,7 +2302,7 @@ evaluate(struct bpf_verifier *bvf)
 }
 
 int
-bpf_validate(struct rte_bpf *bpf)
+rte_bpf_validate(struct rte_bpf *bpf)
 {
int32_t rc;
struct bpf_verifier bvf;
-- 
2.37.1 (Apple Git-137.1)



Re: [PATCH] net/sfc: invalidate switch port entry on representor unplug

2023-03-11 Thread Andrew Rybchenko

On 3/10/23 20:07, Ivan Malov wrote:

Once allocated, a switch port list entry always stays there,
even after unplugging the ethdev that created it. Currently,
the entry's ethdev ID is not cleared on unplug. Referencing
the ethdev ID of a detached representor from a flow rule is
going to succeed, which is a bug. Also, if the user unplugs
endpoint "A" representor and plugs one for "B" instead, the
latter will pick the same ethdev ID as the gone representor,
but it will have a new port list entry added for it. If the
user tries to reference the ethdev ID from a flow rule, the
code will fetch the wrong entry ("A" rather than "B") since
it sits closer to the list head. That is a serious bug, too.

Make the driver invalidate ethdev ID field on ethdev unplug.

Fixes: 1fb65e4dae8a ("net/sfc: support flow action port ID in transfer rules")
Fixes: a62ec90522a6 ("net/sfc: add port representors infrastructure")
Cc: sta...@dpdk.org

Signed-off-by: Ivan Malov 
Reviewed-by: Andy Moreton 


Acked-by: Andrew Rybchenko 




Re: [PATCH v2] net/sfc: stop misuse of Rx ingress m-port metadata on EF100

2023-03-11 Thread Andrew Rybchenko

On 3/10/23 20:01, Ivan Malov wrote:

The driver supports representor functionality. In it,
packets coming from VFs to the dedicated back-end Rx
queue get demultiplexed into front-end Rx queues of
representor ethdevs as per the per-packet metadata
indicating logical HW ingress ports. On transmit,
packets are provided with symmetrical metadata
by front-end Tx queues, and the back-end queue
transforms the data into so-called Tx override
descriptors. These let the packets bypass flow
lookup and go directly to the represented VFs.

However, in the Rx part, the driver extracts
the said metadata on every HW Rx queue, that
is, not just on the one used by representors
Doing so leads to a buggy behaviour. It is
revealed by operating testpmd as follows:

dpdk-testpmd -a :c6:00.0 -a :c6:00.1 -- -i

testpmd> flow create 0 transfer pattern port_representor \
  port_id is 0 / end actions port_representor port_id 1 / end
Flow rule #0 created

testpmd> set fwd io
testpmd> start tx_first

testpmd> flow destroy 0 rule 0
Flow rule #0 destroyed

testpmd> stop

   -- Forward statistics for port 0  -
   RX-packets: 19196498   RX-dropped: 0 RX-total: 19196498
   TX-packets: 19196535   TX-dropped: 0 TX-total: 19196535
   ---

   -- Forward statistics for port 1  -
   RX-packets: 19196503   RX-dropped: 0 RX-total: 19196503
   TX-packets: 19196530   TX-dropped: 0 TX-total: 19196530
   ---

In this scenario, two physical functions of the adapter
do not have any corresponding "back-to-back" forwarder
on peer host. Packets transmitted from port 0 can only
be forwarded to port 1 by means of a special flow rule.

The flow rule indeed works, but destroying it does not
stop forwarding. Port statistics carry on incrementing.

Also, it is apparent that forwarding in the opposite
direction must not have worked in this case as the
flow is meant to target only one of the directions.

Because of the bug, the first 32 mbufs received
as a result of the flow rule operation have the
said metadata present. In io mode, testpmd does
not tamper with mbufs and passes them directly
to transmit path, so this data remains in them
instructing the PMD to override destinations
of the packets via Tx option descriptors.

Expected behaviour is as follows:

   -- Forward statistics for port 0  -
   RX-packets: 0  RX-dropped: 0 RX-total: 0
   TX-packets: 15787496   TX-dropped: 0 TX-total: 15787496
   ---

   -- Forward statistics for port 1  -
   RX-packets: 15787464   RX-dropped: 0 RX-total: 15787464
   TX-packets: 32 TX-dropped: 0 TX-total: 32
   ---

These figures show the rule work only for one direction.
Also, removing the flow shall cause forwarding to cease.

Provided patch fixes the bug accordingly.

Fixes: d0f981a3efd8 ("net/sfc: handle ingress mport in EF100 Rx prefix")
Cc: sta...@dpdk.org

Signed-off-by: Ivan Malov 
Reviewed-by: Andy Moreton 


Better now, but I still have a question. See below.


---
  v2: address community review notes

  drivers/net/sfc/sfc_dp_rx.h| 1 +
  drivers/net/sfc/sfc_ef100_rx.c | 9 +
  drivers/net/sfc/sfc_rx.c   | 3 +++
  3 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 246adbd87c..8a504bdcf1 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -69,6 +69,7 @@ struct sfc_dp_rx_qcreate_info {
/** Receive queue flags initializer */
unsigned intflags;
  #define SFC_RXQ_FLAG_RSS_HASH 0x1
+#define SFC_RXQ_FLAG_INGRESS_MPORT 0x2
  
  	/** Rx queue size */

unsigned intrxq_entries;
diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c
index b7e3397f77..09e5a271d5 100644
--- a/drivers/net/sfc/sfc_ef100_rx.c
+++ b/drivers/net/sfc/sfc_ef100_rx.c
@@ -823,6 +823,9 @@ sfc_ef100_rx_qcreate(uint16_t port_id, uint16_t queue_id,
if (rxq->nic_dma_info->nb_regions > 0)
rxq->flags |= SFC_EF100_RXQ_NIC_DMA_MAP;
  
+	if (info->flags & SFC_RXQ_FLAG_INGRESS_MPORT)

+   rxq->flags |= SFC_EF100_RXQ_INGRESS_MPORT;
+
sfc_ef100_rx_debug(rxq, "RxQ doorbell is %p", rxq->doorbell);
  
  	*dp_rxqp = &rxq->dp;

@@ -889,10 +892,8 @@ sfc_ef100_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned 
int evq_read_ptr,
else
rxq->flags &= ~SFC_EF100_RXQ_USER_MARK;
  
-	if ((unsup_rx_prefix_fields &

-(1U << EFX_RX_PREFIX_FIELD_INGRESS_MPORT)) == 0)