DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [RFC v4 00/11] Add vduse live migration features
From: Eugenio Pérez @ 2026-07-07 12:44 UTC (permalink / raw)
  To: Maxime Coquelin; +Cc: Yongji Xie, david.marchand, dev, mst, jasowangio, chenbox

This series introduces features to the VDUSE (vDPA Device in Userspace) driver
to support Live Migration.

Currently, DPDK does not support VDUSE devices live migration because the
driver lacks a mechanism to suspend the device and quiesce the rings to
initiate the switchover.  This series implements the suspend operation to
address this limitation.

Furthermore, enabling Live Migration for devices with control virtqueue needs
two additional features.  Both of them are included in this series.

* Address Spaces (ASID) support: This allows QEMU to isolate and intercept the
  device's CVQ. By doing so, QEMU is able to migrate the device status
  transparently, without requiring the device to support state save and
  restore.
* QUEUE_ENABLE: This allows QEMU to control when the dataplane virtqueues are
  enabled.  This ensures the dataplane is started after the device
  configuration has been fully restores via the CVQ.

Last but not least, it enables the VIRTIO_NET_F_STATUS feature.  This allows the
device to signal the driver that it needs to send gratuitous ARP with
VIRTIO_NET_S_ANNOUNCE, reducing the Live Migration downtime.

v4:
* Sync headers with Linux's latest existing and proposed UAPI.  Both
  files constants and new ioctl VDUSE_SET_FEATURES.
* Check for more error conditions and clarified some error messages in
  ready message processing.
* Add relevant release notes.
* Fix cosmetic whitespaces & checkpath errors.
* Fix error path of vhost_user_iotlb_init and vhost_user_iotlb_init_one.
* Fix commits author.

v3:
* Replace incorrect '%lx' DEBUG print format specifier with PRIx64

v2:
* Following latest comments on kernel series about VDUSE features, not checking
  API version but only check if VDUSE_GET_FEATURES success.
* Move the start and last declarations in the braces as gcc 8 does not like
  them interleaved with statements. Actually, I think the move was a mistake in
  the first version.
  https://mails.dpdk.org/archives/test-report/2026-February/958175.html

Eugenio Pérez (4):
  uapi: align VDUSE header for ASID
  vhost: Support VDUSE QUEUE_READY feature
  vhost: Support vduse suspend feature
  doc: add release notes for VDUSE live migration support

Maxime Coquelin (7):
  vhost: introduce ASID support
  vhost: add VDUSE API version negotiation
  vhost: add virtqueues groups support to VDUSE
  vhost: add ASID support to VDUSE IOTLB operations
  vhost: claim VDUSE support for API version 1
  vhost: add net status feature to VDUSE
  uapi: Align vduse.h for enable and suspend VDUSE messages

 doc/guides/rel_notes/release_26_07.rst |  17 ++
 kernel/linux/uapi/linux/vduse.h        | 121 ++++++++++++-
 lib/vhost/iotlb.c                      | 233 +++++++++++++++----------
 lib/vhost/iotlb.h                      |  14 +-
 lib/vhost/vduse.c                      | 212 ++++++++++++++++++++--
 lib/vhost/vduse.h                      |   3 +-
 lib/vhost/vhost.c                      |  16 +-
 lib/vhost/vhost.h                      |  16 +-
 lib/vhost/vhost_user.c                 |  13 +-
 9 files changed, 503 insertions(+), 142 deletions(-)

-- 
2.55.0


^ permalink raw reply

* Re: [PATCH v4] dts: update test suite names to be clear and consistent
From: Luca Vizzarro @ 2026-07-07 12:43 UTC (permalink / raw)
  To: Andrew Bailey, patrickrobb1997; +Cc: dev, lylavoie, knimoji, ahassick
In-Reply-To: <20260511160013.78676-1-abailey@iol.unh.edu>

Looks ok to me. Thank you Andrew.

The only thing I'd suggest is to use `git mv` next time you rename 
files. The diff is quite chaotic and not easy to read unfortunately.

I would prefer if you were to send a v5 doing that just to be extra sure 
that no bugs were introduced in the process.

Reviewed-by: Luca Vizzarro <luca.vizzarro@arm.com>

^ permalink raw reply

* Re: [PATCH] dts: fix topology capability comparison
From: Luca Vizzarro @ 2026-07-07 12:01 UTC (permalink / raw)
  To: Thomas Monjalon, dev
  Cc: stable, Patrick Robb, Dean Marx, Juraj Linkeš,
	Jeremy Spewock
In-Reply-To: <20260510194935.182258-1-thomas@monjalon.net>

Thank you Thomas for this fix. Looks good to me

Reviewed-by: Luca Vizzarro <luca.vizzarro@arm.com>

^ permalink raw reply

* [PATCH v2] dev: fix hotplug notification to secondary
From: David Marchand @ 2026-07-07 11:55 UTC (permalink / raw)
  To: dev; +Cc: fengchengwen
In-Reply-To: <20260706145510.680077-1-david.marchand@redhat.com>

There was a logical error when making some last minute change.
Fix the no_shconf evaluation.

Bugzilla ID: 1963
Fixes: 1a2e26d8701d ("dev: skip multi-process in hotplug")

Signed-off-by: David Marchand <david.marchand@redhat.com>
---
Changes since v1:
- separated the unit test from the fix,

---
 lib/eal/common/eal_common_dev.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/eal/common/eal_common_dev.c b/lib/eal/common/eal_common_dev.c
index 9ed62a20e0..b43b0a4bb3 100644
--- a/lib/eal/common/eal_common_dev.c
+++ b/lib/eal/common/eal_common_dev.c
@@ -269,7 +269,7 @@ rte_dev_probe(const char *devargs)
 {
 	const struct internal_config *internal_conf =
 		eal_get_internal_configuration();
-	bool do_mp = !!internal_conf->no_shconf;
+	bool do_mp = internal_conf->no_shconf == 0;
 	struct eal_dev_mp_req req;
 	struct rte_device *dev;
 	int ret;
@@ -428,7 +428,7 @@ rte_dev_remove(struct rte_device *dev)
 {
 	const struct internal_config *internal_conf =
 		eal_get_internal_configuration();
-	bool do_mp = !!internal_conf->no_shconf;
+	bool do_mp = internal_conf->no_shconf == 0;
 	struct eal_dev_mp_req req;
 	char *devargs;
 	int ret;
-- 
2.54.0


^ permalink raw reply related

* [PATCH] net/enic: fix null dereference in flow query count
From: Alexey Simakov @ 2026-07-07 11:44 UTC (permalink / raw)
  To: John Daley, Hyong Youb Kim; +Cc: dev, stable, Alexey Simakov

begin_fm() can return NULL when the flow manager is not initialized.
enic_fm_flow_query_count() did not check the return value, leading
to a NULL pointer dereference on flowman_cmd() and end_fm().

Add NULL check that returns -ENOTSUP with a descriptive error
message via rte_flow_error_set().

Fixes: ea7768b5bba8 ("net/enic: add flow implementation based on Flow Manager API")
Cc: stable@dpdk.org

Signed-off-by: Alexey Simakov <bigalex934@gmail.com>
---
 drivers/net/enic/enic_fm_flow.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/net/enic/enic_fm_flow.c b/drivers/net/enic/enic_fm_flow.c
index 4b0a513977..28e2a9c1e4 100644
--- a/drivers/net/enic/enic_fm_flow.c
+++ b/drivers/net/enic/enic_fm_flow.c
@@ -2904,6 +2904,13 @@ enic_fm_flow_query_count(struct rte_eth_dev *dev,
 
 	ENICPMD_FUNC_TRACE();
 	fm = begin_fm(pmd_priv(dev));
+
+	if (!fm) {
+		return rte_flow_error_set(error, ENOTSUP,
+			RTE_FLOW_ERROR_TYPE_UNSPECIFIED, NULL,
+			"enic: flowman is not initialized");
+	}
+
 	query = data;
 	fm_flow = flow->fm;
 	if (!fm_flow->counter_valid) {
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH] dev: fix hotplug notification to secondary
From: David Marchand @ 2026-07-07 11:41 UTC (permalink / raw)
  To: dev; +Cc: fengchengwen, Thomas Monjalon, Anatoly Burakov
In-Reply-To: <20260706145510.680077-1-david.marchand@redhat.com>

On Mon, 6 Jul 2026 at 16:55, David Marchand <david.marchand@redhat.com> wrote:
>
> There was a logical error when making some last minute change.
> Fix the no_shconf evaluation.
>
> Besides, we currently have no unit test checking device hotplug in the
> fast-tests testsuite.
> Instead, we rely on rcX tags validations when non regression tests
> relying on the multiprocess examples are run.
>
> Add some basic unit test that does not cover all that the examples do
> yet provide a first gate on multiprocess changes.
>
> Bugzilla ID: 1963
> Fixes: 1a2e26d8701d ("dev: skip multi-process in hotplug")
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>

There are some issues with the added test.

The new test is failing on LoongArch CI.
LoongArch CI seems to have a list of excluded tests, and it excludes
multiprocess related tests.
So I guess I'll need LoongArch people to update their tests.

I also have a build issue when disabling net/null.

The AI bot also pointed out some leak in the test exit/error paths.

So I'll send a v2, but I'll separate the EAL fix from the unit test so
that I can merge the fix quickly.


-- 
David Marchand


^ permalink raw reply

* RE: [PATCH v3 0/8] doc: build for all public headers
From: Marat Khalili @ 2026-07-07 11:23 UTC (permalink / raw)
  To: Marat Khalili
  Cc: dev@dpdk.org, thomas@monjalon.net, bruce.richardson@intel.com
In-Reply-To: <20260707085048.15295-1-marat.khalili@huawei.com>

Will answer the AI code review comments here.

> ## Patch 1/8: doc: detect ignored public headers
> 
> ### Errors
> 
> **Error: Resource leak in meson.build `run_command()` usage**
> The `run_command()` calls capture stdout into variables (`doc_built_dirs`, `doc_indexed_headers`) but
> there is no error handling for the command execution itself beyond `check: true`.
> If the `sed` command fails partway through (e.g., file read error, permission issue), the script
> continues with potentially incomplete data.
> While `check: true` will cause meson to fail, the failure mode is not graceful.

Requirement for the setup to survive unreadable source files is clearly excessive.
And meson reports specific command that failed quite well already.

> ### Warnings
> 
> **Warning: Hardcoded meson version check without rationale**
> Line `check_docs = is_linux and meson.version().version_compare('>= 0.60.0')` introduces a version
> check for meson 0.60.0 without explanation.
> 
> **Suggested fix:** Add a comment explaining why meson 0.60.0 is required (likely for `fs.name()` or
> another feature used in the check).

Meson prints source lines and versions required during the setup already.
Not sure who would ever benefit from this comment.

> **Warning: `run_command()` assumes specific sed implementation**
> The `sed` commands use `--regexp-extended` which is a GNU sed extension.
> On systems with BSD sed (macOS, FreeBSD), this will fail.

The check is explicitly limited to Linux.

> **Warning: Global variables `doc_built_dirs` and `doc_indexed_headers` lack context**
> These variables are set in the top-level `meson.build` but used in `drivers/meson.build` and
> `lib/meson.build` without clear documentation of their contract.

The names are self-descriptive IMO.

> ## Patch 3/8: doc: fix typos in rte_avp_common.h
> 
> ### Warnings
> 
> **Warning: Missing closing brace on line 271**
> Line 271 adds `@{` for "Access AVP device version values" but there is no corresponding `@}` to close
> this group.
> All three macros that follow (`RTE_AVP_GET_RELEASE_VERSION`, etc.) will be grouped, but the group is
> never closed.

Grouping commands are imbalanced in the file now, so the patch has to have them
imbalanced for the result to be balanced. Instead of the patch the AI reviewer
should have checked the resulting file or the fact that it builds.

> ## Patch 5/8: doc: fix typos in rte_bus_vmbus.h
> 
> ### Warnings
> 
> **Warning: Incomplete parameter documentation in `rte_vmbus_chan_send_sglist()`**
> The function takes a `flags` parameter (visible in the function signature in the actual driver code),
> but the patch removes `@param flags` from the documentation without verifying that the parameter does
> not exist.

Not sure how the model checked the function signature, but the parameter does not exist.
Which is why documentation failed to build before and builds now.

> **Warning: Parameter name mismatch in `rte_vmbus_chan_recv_raw()`**
> Documentation refers to `@param channel` but the actual parameter name is `chan` (as used in the
> corrected version).
> This is fixed by the patch, but worth noting for consistency checks.

The model notes the discrepancy that the patch already fixes.

> ## Patch 8/8: doc: add missing headers to doxy-api-index.md
> 
> ### Warnings
> 
> **Warning: BPF list formatting inconsistency**
> Lines 219-223 introduce a nested bullet list for BPF headers:
> ```markdown
>   [member](@ref rte_member.h)
>   * BPF:
>     [load and execute](@ref rte_bpf.h),
>     ...
> ```
> This creates a sub-list with only one parent item.

Nested bullet lists are used in other places in the file and even in the same patch,
seem to be a good practice actually. Not sure what "only one parent item" means.

> **Warning: Comma inconsistency in "containers" section**
> Line 231 adds `[member](@ref rte_member.h)` followed immediately by a new bullet for BPF, but previous
> list items in the same block end with commas.

Customary in the file last item in the list does not end with a comma.
The rendering was verified in the web browser.

> ---
> 
> ## Summary by Patch
> 
> | Patch | Errors | Warnings | Info |
> |-------|--------|----------|------|
> | 1/8   | 0      | 3        | 0    |
> | 2/8   | 0      | 0        | 1    |
> | 3/8   | 0      | 1        | 0    |
> | 4/8   | 0      | 0        | 0    |
> | 5/8   | 0      | 2        | 0    |
> | 6/8   | 0      | 0        | 0    |
> | 7/8   | 0      | 0        | 1    |
> | 8/8   | 0      | 2        | 0    |

Interestingly, the one found Error did not make it to the table.

This error and all 8 warnings are addressed above and not the actual problems.

^ permalink raw reply

* [PATCH] net/enic: fix possible null dereference in notify set
From: Alexey Simakov @ 2026-07-07 11:20 UTC (permalink / raw)
  To: John Daley, Hyong Youb Kim, Sujith Sankar, David Marchand,
	Neil Horman
  Cc: dev, stable, Alexey Simakov

The memset of notify_addr in vnic_dev_notify_setcmd() was performed
unconditionally before the device reset check. When the device is in
reset, vnic_dev_notify_set() skips the notification buffer allocation,
leaving notify_addr as NULL. The subsequent call to
vnic_dev_notify_setcmd() would then dereference the NULL pointer via
memset.

Move the memset inside the existing !vnic_dev_in_reset() guard where
notify_addr is guaranteed to be valid.

Fixes: 9913fbb91df0 ("enic/base: common code")
Cc: stable@dpdk.org

Signed-off-by: Alexey Simakov <bigalex934@gmail.com>
---
 drivers/net/enic/base/vnic_dev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/enic/base/vnic_dev.c b/drivers/net/enic/base/vnic_dev.c
index ba8ecc16f2..e6d34622af 100644
--- a/drivers/net/enic/base/vnic_dev.c
+++ b/drivers/net/enic/base/vnic_dev.c
@@ -964,8 +964,8 @@ int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
 	int wait = 1000;
 	int r;
 
-	memset(notify_addr, 0, sizeof(struct vnic_devcmd_notify));
 	if (!vnic_dev_in_reset(vdev)) {
+		memset(notify_addr, 0, sizeof(struct vnic_devcmd_notify));
 		vdev->notify = notify_addr;
 		vdev->notify_pa = notify_pa;
 	}
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH] dev: hide internal type for device comparison
From: Bruce Richardson @ 2026-07-07 11:04 UTC (permalink / raw)
  To: David Marchand; +Cc: dev
In-Reply-To: <20260706150636.839560-1-david.marchand@redhat.com>

On Mon, Jul 06, 2026 at 05:06:36PM +0200, David Marchand wrote:
> rte_dev_cmp_t is a type used only in bus operations.
> Since no public API references it, remove it from exported types.
> Thanks to this, we can remove the dependency of bus_driver.h to
> rte_dev.h.
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply

* Re: [PATCH] drivers/bus: remove blocklist evaluation when probing a device
From: Bruce Richardson @ 2026-07-07 11:02 UTC (permalink / raw)
  To: David Marchand
  Cc: dev, Parav Pandit, Xueming Li, Hemant Agrawal, Sachin Saxena,
	Chenbo Xia, Nipun Gupta, Long Li, Wei Hu, Chengwen Feng
In-Reply-To: <20260706150611.839502-1-david.marchand@redhat.com>

On Mon, Jul 06, 2026 at 05:06:11PM +0200, David Marchand wrote:
> .probe_device is called from EAL, that already evaluated if the device
> is blocklisted.
> 
> Fixes: be29c42523d8 ("bus: implement probe in EAL")
> 
> Signed-off-by: David Marchand <david.marchand@redhat.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply

* [PATCH] net/enic: fix potential null dereference in flow mask check
From: Alexey Simakov @ 2026-07-07  8:58 UTC (permalink / raw)
  To: Thomas Monjalon, John Daley, Hyong Youb Kim, Nelson Escobar
  Cc: dev, stable, Alexey Simakov

The functions enic_copy_item_ipv4_v1(), enic_copy_item_udp_v1(), and
enic_copy_item_tcp_v1() each initialize a local 'mask' variable from
item->mask and substitute it with a hardcoded mask if NULL. However,
the subsequent mask_exact_match() call uses item->mask directly
instead of the local 'mask' variable, which will dereference NULL
when item->mask is NULL.

Use the local 'mask' variable (which has been validated and possibly
substituted) instead of item->mask.

Fixes: aa3d2ff82198 ("net/enic: flow API for Legacy NICs")
Cc: stable@dpdk.org

Signed-off-by: Alexey Simakov <bigalex934@gmail.com>
---
 .mailmap                     | 1 +
 drivers/net/enic/enic_flow.c | 6 +++---
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/.mailmap b/.mailmap
index 4b5eb0c841..b154cd25a9 100644
--- a/.mailmap
+++ b/.mailmap
@@ -71,6 +71,7 @@ Alexander Skorichenko <askorichenko@netgate.com>
 Alexander Solganik <solganik@gmail.com>
 Alexander V Gutkin <alexander.v.gutkin@intel.com>
 Alexandre Ferrieux <alexandre.ferrieux@orange.com>
+Alexey Simakov <bigalex934@gmail.com>
 Alexey Kardashevskiy <aik@ozlabs.ru>
 Alfredo Cardigliano <cardigliano@ntop.org>
 Ali Alnubani <alialnu@nvidia.com> <alialnu@mellanox.com>
diff --git a/drivers/net/enic/enic_flow.c b/drivers/net/enic/enic_flow.c
index 758000ea21..539b0eb725 100644
--- a/drivers/net/enic/enic_flow.c
+++ b/drivers/net/enic/enic_flow.c
@@ -407,7 +407,7 @@ enic_copy_item_ipv4_v1(struct copy_item_args *arg)
 
 	/* check that the supplied mask exactly matches capability */
 	if (!mask_exact_match((const uint8_t *)&supported_mask,
-			      (const uint8_t *)item->mask, sizeof(*mask))) {
+			      (const uint8_t *)mask, sizeof(*mask))) {
 		ENICPMD_LOG(ERR, "IPv4 exact match mask");
 		return ENOTSUP;
 	}
@@ -445,7 +445,7 @@ enic_copy_item_udp_v1(struct copy_item_args *arg)
 
 	/* check that the supplied mask exactly matches capability */
 	if (!mask_exact_match((const uint8_t *)&supported_mask,
-			      (const uint8_t *)item->mask, sizeof(*mask))) {
+			      (const uint8_t *)mask, sizeof(*mask))) {
 		ENICPMD_LOG(ERR, "UDP exact match mask");
 		return ENOTSUP;
 	}
@@ -484,7 +484,7 @@ enic_copy_item_tcp_v1(struct copy_item_args *arg)
 
 	/* check that the supplied mask exactly matches capability */
 	if (!mask_exact_match((const uint8_t *)&supported_mask,
-			     (const uint8_t *)item->mask, sizeof(*mask))) {
+			     (const uint8_t *)mask, sizeof(*mask))) {
 		ENICPMD_LOG(ERR, "TCP exact match mask");
 		return ENOTSUP;
 	}
-- 
2.34.1


^ permalink raw reply related

* [PATCH v3 8/8] doc: add missing headers to doxy-api-index.md
From: Marat Khalili @ 2026-07-07  8:50 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson
In-Reply-To: <20260707085048.15295-1-marat.khalili@huawei.com>

Make sure all public headers are listed in `doxy-api-index.md` to be
reachable in HTML version. Presumably each of them should contain at
least a general file description, though this is not checked now.

The only header still omitted is rte_pmd_bphy.h since it needs writing
multiple new doxygen descriptions which could not be done on the spot,
so it is excluded from the build (tracked by bug 1962 in bugzilla).

Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
 doc/api/doxy-api-index.md | 120 +++++++++++++++++++++++++++++++++-----
 1 file changed, 105 insertions(+), 15 deletions(-)

diff --git a/doc/api/doxy-api-index.md b/doc/api/doxy-api-index.md
index 929604211946..f5c084c2c5a9 100644
--- a/doc/api/doxy-api-index.md
+++ b/doc/api/doxy-api-index.md
@@ -9,14 +9,24 @@ API
 The public API headers are grouped by topics:
 
 - **device**:
+  [bus](@ref rte_bus.h),
   [dev](@ref rte_dev.h),
   [ethdev](@ref rte_ethdev.h),
+  [cman](@ref rte_cman.h),
+  [ethdev trace fp](@ref rte_ethdev_trace_fp.h),
+  [dev info](@ref rte_dev_info.h),
   [ethctrl](@ref rte_eth_ctrl.h),
   [rte_flow](@ref rte_flow.h),
   [rte_tm](@ref rte_tm.h),
   [rte_mtr](@ref rte_mtr.h),
   [bbdev](@ref rte_bbdev.h),
+  [bbdev op](@ref rte_bbdev_op.h),
+  [bbdev trace fp](@ref rte_bbdev_trace_fp.h),
   [cryptodev](@ref rte_cryptodev.h),
+  [crypto](@ref rte_crypto.h),
+  [crypto sym](@ref rte_crypto_sym.h),
+  [crypto asym](@ref rte_crypto_asym.h),
+  [cryptodev trace fp](@ref rte_cryptodev_trace_fp.h),
   [security](@ref rte_security.h),
   [compressdev](@ref rte_compressdev.h),
   [compress](@ref rte_comp.h),
@@ -25,6 +35,8 @@ The public API headers are grouped by topics:
   [dmadev](@ref rte_dmadev.h),
   [gpudev](@ref rte_gpudev.h),
   [eventdev](@ref rte_eventdev.h),
+  [event ring](@ref rte_event_ring.h),
+  [eventdev trace fp](@ref rte_eventdev_trace_fp.h),
   [event_eth_rx_adapter](@ref rte_event_eth_rx_adapter.h),
   [event_eth_tx_adapter](@ref rte_event_eth_tx_adapter.h),
   [event_timer_adapter](@ref rte_event_timer_adapter.h),
@@ -33,17 +45,27 @@ The public API headers are grouped by topics:
   [event_vector_adapter](@ref rte_event_vector_adapter.h),
   [rawdev](@ref rte_rawdev.h),
   [metrics](@ref rte_metrics.h),
+  [metrics telemetry](@ref rte_metrics_telemetry.h),
   [bitrate](@ref rte_bitrate.h),
   [latency](@ref rte_latencystats.h),
   [devargs](@ref rte_devargs.h),
   [PCI](@ref rte_pci.h),
+  [PCI dev feature defs](@ref rte_pci_dev_feature_defs.h),
+  [PCI dev features](@ref rte_pci_dev_features.h),
+  [bus PCI](@ref rte_bus_pci.h),
   [vdev](@ref rte_bus_vdev.h),
+  [vmbus](@ref rte_bus_vmbus.h),
+  [vmbus reg](@ref rte_vmbus_reg.h),
   [vfio](@ref rte_vfio.h)
 
 - **device specific**:
   [softnic](@ref rte_eth_softnic.h),
   [bond](@ref rte_eth_bond.h),
+  [bond 8023ad](@ref rte_eth_bond_8023ad.h),
   [vhost](@ref rte_vhost.h),
+  [vhost async](@ref rte_vhost_async.h),
+  [vhost crypto](@ref rte_vhost_crypto.h),
+  [eth vhost](@ref rte_eth_vhost.h),
   [vdpa](@ref rte_vdpa.h),
   [ixgbe](@ref rte_pmd_ixgbe.h),
   [i40e](@ref rte_pmd_i40e.h),
@@ -53,6 +75,7 @@ The public API headers are grouped by topics:
   [cnxk_crypto](@ref rte_pmd_cnxk_crypto.h),
   [cnxk_eventdev](@ref rte_pmd_cnxk_eventdev.h),
   [cnxk_mempool](@ref rte_pmd_cnxk_mempool.h),
+  [cnxk gpio](@ref rte_pmd_cnxk_gpio.h),
   [dpaa](@ref rte_pmd_dpaa.h),
   [dpaa2](@ref rte_pmd_dpaa2.h),
   [mlx5](@ref rte_pmd_mlx5.h),
@@ -60,25 +83,40 @@ The public API headers are grouped by topics:
   [dpaa2_cmdif](@ref rte_pmd_dpaa2_cmdif.h),
   [dpaax_qdma](@ref rte_pmd_dpaax_qdma.h),
   [crypto_scheduler](@ref rte_cryptodev_scheduler.h),
+  [crypto scheduler operations](@ref rte_cryptodev_scheduler_operations.h),
   [dlb2](@ref rte_pmd_dlb2.h),
-  [ifpga](@ref rte_pmd_ifpga.h)
+  [ifpga](@ref rte_pmd_ifpga.h),
+  [avp common](@ref rte_avp_common.h),
+  [avp fifo](@ref rte_avp_fifo.h),
+  [ntnic](@ref rte_pmd_ntnic.h),
+  [ring](@ref rte_eth_ring.h),
+  [txgbe](@ref rte_pmd_txgbe.h),
+  [ntb](@ref rte_pmd_ntb.h),
+  [acc cfg](@ref rte_acc_cfg.h),
+  [acc common cfg](@ref rte_acc_common_cfg.h),
+  [fpga 5gnr fec](@ref rte_pmd_fpga_5gnr_fec.h)
 
 - **memory**:
   [per-lcore](@ref rte_per_lcore.h),
   [lcore variables](@ref rte_lcore_var.h),
+  [EAL memconfig](@ref rte_eal_memconfig.h),
   [memseg](@ref rte_memory.h),
   [memzone](@ref rte_memzone.h),
   [mempool](@ref rte_mempool.h),
+  [mempool trace fp](@ref rte_mempool_trace_fp.h),
   [malloc](@ref rte_malloc.h),
   [memcpy](@ref rte_memcpy.h)
 
 - **timers**:
   [cycles](@ref rte_cycles.h),
+  [time](@ref rte_time.h),
   [timer](@ref rte_timer.h),
   [alarm](@ref rte_alarm.h)
 
 - **locks**:
   [atomic](@ref rte_atomic.h),
+  [stdatomic](@ref rte_stdatomic.h),
+  [lock annotations](@ref rte_lock_annotations.h),
   [mcslock](@ref rte_mcslock.h),
   [pflock](@ref rte_pflock.h),
   [rwlock](@ref rte_rwlock.h),
@@ -103,13 +141,18 @@ The public API headers are grouped by topics:
   [launch](@ref rte_launch.h),
   [lcore](@ref rte_lcore.h),
   [service cores](@ref rte_service.h),
+  [service component](@ref rte_service_component.h),
   [keepalive](@ref rte_keepalive.h),
   [power/freq](@ref rte_power_cpufreq.h),
   [power/uncore](@ref rte_power_uncore.h),
-  [PMD power](@ref rte_power_pmd_mgmt.h)
+  [PMD power](@ref rte_power_pmd_mgmt.h),
+  [power guest channel](@ref rte_power_guest_channel.h),
+  [power qos](@ref rte_power_qos.h)
 
 - **layers**:
   [ethernet](@ref rte_ether.h),
+  [net](@ref rte_net.h),
+  [net CRC](@ref rte_net_crc.h),
   [MACsec](@ref rte_macsec.h),
   [ARP](@ref rte_arp.h),
   [HIGIG](@ref rte_higig.h),
@@ -119,6 +162,7 @@ The public API headers are grouped by topics:
   [IPsec group](@ref rte_ipsec_group.h),
   [IPsec SA](@ref rte_ipsec_sa.h),
   [IPsec SAD](@ref rte_ipsec_sad.h),
+  [IP](@ref rte_ip.h),
   [IPv4](@ref rte_ip4.h),
   [IPv6](@ref rte_ip6.h),
   [frag/reass](@ref rte_ip_frag.h),
@@ -139,12 +183,15 @@ The public API headers are grouped by topics:
   [PDCP](@ref rte_pdcp.h),
   [L2TPv2](@ref rte_l2tpv2.h),
   [PPP](@ref rte_ppp.h),
-  [IB](@ref rte_ib.h)
+  [IB](@ref rte_ib.h),
+  [PTP](@ref rte_ptp.h)
 
 - **QoS**:
   [metering](@ref rte_meter.h),
   [scheduler](@ref rte_sched.h),
-  [RED congestion](@ref rte_red.h)
+  [sched common](@ref rte_sched_common.h),
+  [RED congestion](@ref rte_red.h),
+  [PIE](@ref rte_pie.h)
 
 - **routing**:
   [LPM IPv4 route](@ref rte_lpm.h),
@@ -168,18 +215,28 @@ The public API headers are grouped by topics:
   [distributor](@ref rte_distributor.h),
   [EFD](@ref rte_efd.h),
   [ACL](@ref rte_acl.h),
-  [member](@ref rte_member.h),
-  [BPF](@ref rte_bpf.h)
+  [ACL osdep](@ref rte_acl_osdep.h),
+  [member](@ref rte_member.h)
+  * BPF:
+    [load and execute](@ref rte_bpf.h),
+    [machine code](@ref bpf_def.h),
+    [port filters](@ref rte_bpf_ethdev.h),
+    [validate debug](@ref rte_bpf_validate_debug.h)
 
 - **containers**:
   [mbuf](@ref rte_mbuf.h),
+  [mbuf core](@ref rte_mbuf_core.h),
+  [mbuf ptype](@ref rte_mbuf_ptype.h),
+  [mbuf dyn](@ref rte_mbuf_dyn.h),
+  [mbuf history](@ref rte_mbuf_history.h),
   [mbuf pool ops](@ref rte_mbuf_pool_ops.h),
   [ring](@ref rte_ring.h),
   [soring](@ref rte_soring.h),
   [stack](@ref rte_stack.h),
   [tailq](@ref rte_tailq.h),
   [bitset](@ref rte_bitset.h),
-  [bitmap](@ref rte_bitmap.h)
+  [bitmap](@ref rte_bitmap.h),
+  [fbarray](@ref rte_fbarray.h)
 
 - **packet framework**:
   * [port](@ref rte_port.h):
@@ -188,21 +245,28 @@ The public API headers are grouped by topics:
     [frag](@ref rte_port_frag.h),
     [reass](@ref rte_port_ras.h),
     [sched](@ref rte_port_sched.h),
-    [src/sink](@ref rte_port_source_sink.h)
+    [src/sink](@ref rte_port_source_sink.h),
+    [fd](@ref rte_port_fd.h),
+    [sym crypto](@ref rte_port_sym_crypto.h),
+    [eventdev](@ref rte_port_eventdev.h)
   * [table](@ref rte_table.h):
     [lpm IPv4](@ref rte_table_lpm.h),
     [lpm IPv6](@ref rte_table_lpm_ipv6.h),
     [ACL](@ref rte_table_acl.h),
     [hash](@ref rte_table_hash.h),
     [array](@ref rte_table_array.h),
-    [stub](@ref rte_table_stub.h)
+    [stub](@ref rte_table_stub.h),
+    [LRU](@ref rte_lru.h),
+    [hash cuckoo](@ref rte_table_hash_cuckoo.h),
+    [hash func](@ref rte_table_hash_func.h)
   * [pipeline](@ref rte_pipeline.h)
     [port_in_action](@ref rte_port_in_action.h)
     [table_action](@ref rte_table_action.h)
   * SWX pipeline:
     [control](@ref rte_swx_ctl.h),
     [extern](@ref rte_swx_extern.h),
-    [pipeline](@ref rte_swx_pipeline.h)
+    [pipeline](@ref rte_swx_pipeline.h),
+    [IPsec](@ref rte_swx_ipsec.h)
   * SWX port:
     [port](@ref rte_swx_port.h),
     [ethdev](@ref rte_swx_port_ethdev.h),
@@ -211,8 +275,11 @@ The public API headers are grouped by topics:
     [src/sink](@ref rte_swx_port_source_sink.h)
   * SWX table:
     [table](@ref rte_swx_table.h),
-    [table_em](@ref rte_swx_table_em.h)
-    [table_wm](@ref rte_swx_table_wm.h)
+    [table_em](@ref rte_swx_table_em.h),
+    [table_wm](@ref rte_swx_table_wm.h),
+    [hash func](@ref rte_swx_hash_func.h),
+    [table learner](@ref rte_swx_table_learner.h),
+    [table selector](@ref rte_swx_table_selector.h)
   * [graph](@ref rte_graph.h):
     [graph_worker](@ref rte_graph_worker.h),
     [graph_feature_arc](@ref rte_graph_feature_arc.h),
@@ -222,7 +289,22 @@ The public API headers are grouped by topics:
     [ip4_node](@ref rte_node_ip4_api.h),
     [ip6_node](@ref rte_node_ip6_api.h),
     [udp4_input_node](@ref rte_node_udp4_input_api.h),
-    [mbuf_dynfield](@ref rte_node_mbuf_dynfield.h)
+    [mbuf_dynfield](@ref rte_node_mbuf_dynfield.h),
+    [pkt cls api](@ref rte_node_pkt_cls_api.h)
+
+- **cmdline**:
+  [cmdline](@ref cmdline.h),
+  [parse](@ref cmdline_parse.h),
+  [parse num](@ref cmdline_parse_num.h),
+  [parse bool](@ref cmdline_parse_bool.h),
+  [parse ipaddr](@ref cmdline_parse_ipaddr.h),
+  [parse etheraddr](@ref cmdline_parse_etheraddr.h),
+  [parse string](@ref cmdline_parse_string.h),
+  [parse portlist](@ref cmdline_parse_portlist.h),
+  [rdline](@ref cmdline_rdline.h),
+  [vt100](@ref cmdline_vt100.h),
+  [socket](@ref cmdline_socket.h),
+  [cirbuf](@ref cmdline_cirbuf.h)
 
 - **basic**:
   [bitops](@ref rte_bitops.h),
@@ -234,7 +316,9 @@ The public API headers are grouped by topics:
   [argument parsing](@ref rte_argparse.h),
   [ptr_compress](@ref rte_ptr_compress.h),
   [string](@ref rte_string_fns.h),
-  [thread](@ref rte_thread.h)
+  [thread](@ref rte_thread.h),
+  [reciprocal](@ref rte_reciprocal.h),
+  [UUID](@ref rte_uuid.h)
 
 - **debug**:
   [jobstats](@ref rte_jobstats.h),
@@ -247,11 +331,17 @@ The public API headers are grouped by topics:
   [log](@ref rte_log.h),
   [errno](@ref rte_errno.h),
   [trace](@ref rte_trace.h),
-  [trace_point](@ref rte_trace_point.h)
+  [EAL trace](@ref rte_eal_trace.h),
+  [trace_point](@ref rte_trace_point.h),
+  [trace point register](@ref rte_trace_point_register.h)
 
 - **misc**:
   [EAL config](@ref rte_eal.h),
+  [class](@ref rte_class.h),
   [common](@ref rte_common.h),
+  [epoll](@ref rte_epoll.h),
+  [hypervisor](@ref rte_hypervisor.h),
+  [OS](@ref rte_os.h),
   [experimental APIs](@ref rte_compat.h),
   [version](@ref rte_version.h)
 
-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 7/8] doc: add missing drivers to doxy-api.conf.in
From: Marat Khalili @ 2026-07-07  8:50 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson
In-Reply-To: <20260707085048.15295-1-marat.khalili@huawei.com>

Make sure all drivers declaring public headers are added to
`doxy-api.conf.in` to trigger documentation generation. Sort them.

The only driver still omitted is cnxk_bphy since it needs writing
multiple new doxygen descriptions which could not be done on the spot
(tracked by bug 1962 in bugzilla).

Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
 doc/api/doxy-api.conf.in | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index 2cb152d6db98..1620027215a9 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -5,15 +5,20 @@ PROJECT_NAME            = DPDK
 PROJECT_NUMBER          = @VERSION@
 USE_MDFILE_AS_MAINPAGE  = @TOPDIR@/doc/api/doxy-api-index.md
 INPUT                   = @TOPDIR@/doc/api/doxy-api-index.md \
+                          @TOPDIR@/drivers/baseband/acc \
+                          @TOPDIR@/drivers/baseband/fpga_5gnr_fec \
+                          @TOPDIR@/drivers/bus/pci \
                           @TOPDIR@/drivers/bus/vdev \
+                          @TOPDIR@/drivers/bus/vmbus \
                           @TOPDIR@/drivers/common/dpaax \
                           @TOPDIR@/drivers/crypto/cnxk \
                           @TOPDIR@/drivers/crypto/scheduler \
-                          @TOPDIR@/drivers/event/dlb2 \
                           @TOPDIR@/drivers/event/cnxk \
+                          @TOPDIR@/drivers/event/dlb2 \
                           @TOPDIR@/drivers/mempool/cnxk \
                           @TOPDIR@/drivers/mempool/dpaa2 \
                           @TOPDIR@/drivers/net/ark \
+                          @TOPDIR@/drivers/net/avp \
                           @TOPDIR@/drivers/net/bnxt \
                           @TOPDIR@/drivers/net/bonding \
                           @TOPDIR@/drivers/net/cnxk \
@@ -23,9 +28,16 @@ INPUT                   = @TOPDIR@/doc/api/doxy-api-index.md \
                           @TOPDIR@/drivers/net/intel/iavf \
                           @TOPDIR@/drivers/net/intel/ixgbe \
                           @TOPDIR@/drivers/net/mlx5 \
+                          @TOPDIR@/drivers/net/ntnic \
+                          @TOPDIR@/drivers/net/ring \
                           @TOPDIR@/drivers/net/softnic \
+                          @TOPDIR@/drivers/net/txgbe \
+                          @TOPDIR@/drivers/net/vhost \
+                          @TOPDIR@/drivers/power/kvm_vm \
+                          @TOPDIR@/drivers/raw/cnxk_gpio \
                           @TOPDIR@/drivers/raw/dpaa2_cmdif \
                           @TOPDIR@/drivers/raw/ifpga \
+                          @TOPDIR@/drivers/raw/ntb \
                           @TOPDIR@/lib/eal/include \
                           @TOPDIR@/lib/eal/include/generic \
                           @TOPDIR@/lib/acl \
-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 6/8] doc: add missing globs to doxy-api.conf.in
From: Marat Khalili @ 2026-07-07  8:50 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson
In-Reply-To: <20260707085048.15295-1-marat.khalili@huawei.com>

Public headers starting from `cmdline` (except for `cmdline.h` itself)
and `bpf_def.h` were not previously included in the documentation build.

Add missing file patterns (globs) to include all public headers.

Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
 doc/api/doxy-api.conf.in | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/doc/api/doxy-api.conf.in b/doc/api/doxy-api.conf.in
index bedd94468150..2cb152d6db98 100644
--- a/doc/api/doxy-api.conf.in
+++ b/doc/api/doxy-api.conf.in
@@ -88,7 +88,8 @@ INPUT                   = @TOPDIR@/doc/api/doxy-api-index.md \
                           @TOPDIR@/lib/vhost
 INPUT                   += @API_EXAMPLES@
 FILE_PATTERNS           = rte_*.h \
-                          cmdline.h
+                          cmdline*.h \
+                          bpf_def.h
 PREDEFINED              = __DOXYGEN__ \
                           RTE_ATOMIC \
                           RTE_HAS_CPUSET \
-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 5/8] doc: fix typos in rte_bus_vmbus.h
From: Marat Khalili @ 2026-07-07  8:50 UTC (permalink / raw)
  To: Long Li, Wei Hu; +Cc: dev, thomas, bruce.richardson
In-Reply-To: <20260707085048.15295-1-marat.khalili@huawei.com>

This file contained multiple doxygen issues that prevented successful
documentation build (missing, extra, misspelt parameter names etc). It
was not discovered previously because the driver despite the presence of
public headers was not included in the documentation build.

Fix invalid doxygen parameters annotations.

Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
 drivers/bus/vmbus/rte_bus_vmbus.h | 33 +++++++++++++++++++------------
 1 file changed, 20 insertions(+), 13 deletions(-)

diff --git a/drivers/bus/vmbus/rte_bus_vmbus.h b/drivers/bus/vmbus/rte_bus_vmbus.h
index 2e9898ed7fb6..7f3ebd823201 100644
--- a/drivers/bus/vmbus/rte_bus_vmbus.h
+++ b/drivers/bus/vmbus/rte_bus_vmbus.h
@@ -111,7 +111,7 @@ int rte_vmbus_max_channels(const struct rte_vmbus_device *device);
  *
  * @param primary
  *   A pointer to primary VMBUS channel
- * @param chan
+ * @param new_chan
  *   A pointer to a secondary VMBUS channel pointer that will be filled.
  * @return
  *   - 0 Success; channel opened.
@@ -158,6 +158,8 @@ bool rte_vmbus_chan_rx_empty(const struct vmbus_channel *channel);
 /**
  * Send the specified buffer on the given channel
  *
+ * @param dev
+ *	A pointer to a rte_vmbus_device structure describing the device
  * @param channel
  *	Pointer to vmbus_channel structure.
  * @param type
@@ -184,7 +186,9 @@ int rte_vmbus_chan_send(struct rte_vmbus_device *dev,
 /**
  * Explicitly signal host that data is available
  *
- * @param
+ * @param dev
+ *	A pointer to a rte_vmbus_device structure describing the device
+ * @param channel
  *	Pointer to vmbus_channel structure.
  *
  * Used when batching multiple sends and only signaling host
@@ -203,11 +207,10 @@ struct iova_list {
 /**
  * Send a scattered buffer on the given channel
  *
+ * @param dev
+ *	A pointer to a rte_vmbus_device structure describing the device
  * @param channel
  *	Pointer to vmbus_channel structure.
- * @param type
- *	Type of packet that is being send e.g. negotiate, time
- *	packet etc.
  * @param gpa
  *	Array of buffers to send
  * @param gpacnt
@@ -218,8 +221,6 @@ struct iova_list {
  *	 Maximum size of what the buffer will hold
  * @param xact
  *	Identifier of the request
- * @param flags
- *	Message type inband, rxbuf, gpa
  * @param need_sig
  *	Is host signal tx is required (optional)
  *
@@ -234,13 +235,15 @@ int rte_vmbus_chan_send_sglist(struct rte_vmbus_device *dev,
  * Receive response to request on the given channel
  * skips the channel header.
  *
- * @param channel
+ * @param dev
+ *	A pointer to a rte_vmbus_device structure describing the device
+ * @param chan
  *	Pointer to vmbus_channel structure.
  * @param data
  *	Pointer to the buffer you want to receive the data into.
  * @param len
  *	Pointer to size of receive buffer (in/out)
- * @param
+ * @param request_id
  *	Pointer to received transaction_id
  * @return
  *   On success, returns 0
@@ -255,7 +258,7 @@ int rte_vmbus_chan_recv(struct rte_vmbus_device *dev,
  * Receive response to request on the given channel
  * includes the channel header.
  *
- * @param channel
+ * @param chan
  *	Pointer to vmbus_channel structure.
  * @param data
  *	Pointer to the buffer you want to receive the data into.
@@ -272,7 +275,9 @@ int rte_vmbus_chan_recv_raw(struct vmbus_channel *chan,
  * Notify host of bytes read (after recv_raw)
  * Signals host if required.
  *
- * @param channel
+ * @param dev
+ *	A pointer to a rte_vmbus_device structure describing the device
+ * @param chan
  *	Pointer to vmbus_channel structure.
  * @param bytes_read
  *	Number of bytes read since last signal
@@ -284,7 +289,7 @@ void rte_vmbus_chan_signal_read(struct rte_vmbus_device *dev,
 /**
  * Determine sub channel index of the given channel
  *
- * @param channel
+ * @param chan
  *	Pointer to vmbus_channel structure.
  * @return
  *   Sub channel index (0 for primary)
@@ -309,7 +314,9 @@ void rte_vmbus_set_latency(const struct rte_vmbus_device *dev,
 /**
  * For debug dump contents of ring buffer.
  *
- * @param channel
+ * @param f
+ *	Output file to dump to.
+ * @param chan
  *	Pointer to vmbus_channel structure.
  */
 void rte_vmbus_chan_dump(FILE *f, const struct vmbus_channel *chan);
-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 4/8] doc: fix typos in rte_bus_pci.h
From: Marat Khalili @ 2026-07-07  8:50 UTC (permalink / raw)
  To: Chenbo Xia, Nipun Gupta; +Cc: dev, thomas, bruce.richardson
In-Reply-To: <20260707085048.15295-1-marat.khalili@huawei.com>

This file contained a couple of doxygen typos that prevented successful
documentation build. It was not discovered previously because the driver
despite the presence of public headers was not included in the
documentation build.

Fix doxygen typos (replace `@bar` with `@p bar`).

Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
 drivers/bus/pci/rte_bus_pci.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.h
index 19a7b15b99fd..22a7beb1fc4c 100644
--- a/drivers/bus/pci/rte_bus_pci.h
+++ b/drivers/bus/pci/rte_bus_pci.h
@@ -222,7 +222,7 @@ int rte_pci_write_config(const struct rte_pci_device *device,
  * @param len
  *   The length of the data buffer.
  * @param offset
- *   The offset into MMIO space described by @bar.
+ *   The offset into MMIO space described by @p bar.
  * @return
  *   Number of bytes read on success, negative on error.
  */
@@ -246,7 +246,7 @@ int rte_pci_mmio_read(const struct rte_pci_device *device, int bar,
  * @param len
  *   The length of the data buffer.
  * @param offset
- *   The offset into MMIO space described by @bar.
+ *   The offset into MMIO space described by @p bar.
  * @return
  *   Number of bytes written on success, negative on error.
  */
-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 3/8] doc: fix typos in rte_avp_common.h
From: Marat Khalili @ 2026-07-07  8:50 UTC (permalink / raw)
  To: Steven Webster, Matt Peters; +Cc: dev, thomas, bruce.richardson
In-Reply-To: <20260707085048.15295-1-marat.khalili@huawei.com>

The file contained doxygen typos that caused `unbalanced grouping
commands` errors and prevented successful documentation build. It was
not discovered previously because: (1) the driver despite the presence
of public headers was not included in the documentation build, and (2)
versions of doxygen before 1.9 did not fully parse and verify the syntax
of the file unless it contained the `@file` tag.

Make sure all doxygen grouping commands are balanced.

Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
 drivers/net/avp/rte_avp_common.h | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/avp/rte_avp_common.h b/drivers/net/avp/rte_avp_common.h
index ffdf07cd8098..da84a1a3649c 100644
--- a/drivers/net/avp/rte_avp_common.h
+++ b/drivers/net/avp/rte_avp_common.h
@@ -117,7 +117,7 @@ struct __rte_cache_aligned __rte_packed_begin rte_avp_desc {
 } __rte_packed_end;
 
 
-/**{ AVP device features */
+/**@{ AVP device features */
 #define RTE_AVP_FEATURE_VLAN_OFFLOAD (1 << 0) /**< Emulated HW VLAN offload */
 /**@} */
 
@@ -160,14 +160,14 @@ struct __rte_cache_aligned __rte_packed_begin rte_avp_desc {
 #define RTE_AVP_MAX_MSIX_VECTORS 1
 /**@} */
 
-/**@} AVP Migration status/ack register values */
+/**@{ AVP Migration status/ack register values */
 #define RTE_AVP_MIGRATION_NONE      0 /**< Migration never executed */
 #define RTE_AVP_MIGRATION_DETACHED  1 /**< Device attached during migration */
 #define RTE_AVP_MIGRATION_ATTACHED  2 /**< Device reattached during migration */
 #define RTE_AVP_MIGRATION_ERROR     3 /**< Device failed to attach/detach */
 /**@} */
 
-/**@} AVP MMIO Register Offsets */
+/**@{ AVP MMIO Register Offsets */
 #define RTE_AVP_REGISTER_BASE 0
 #define RTE_AVP_INTERRUPT_MASK_OFFSET (RTE_AVP_REGISTER_BASE + 0)
 #define RTE_AVP_INTERRUPT_STATUS_OFFSET (RTE_AVP_REGISTER_BASE + 4)
@@ -175,7 +175,7 @@ struct __rte_cache_aligned __rte_packed_begin rte_avp_desc {
 #define RTE_AVP_MIGRATION_ACK_OFFSET (RTE_AVP_REGISTER_BASE + 12)
 /**@} */
 
-/**@} AVP Interrupt Status Mask */
+/**@{ AVP Interrupt Status Mask */
 #define RTE_AVP_MIGRATION_INTERRUPT_MASK (1 << 1)
 #define RTE_AVP_APP_INTERRUPTS_MASK      0xFFFFFFFF
 #define RTE_AVP_NO_INTERRUPTS_MASK       0
@@ -268,7 +268,7 @@ RTE_AVP_MAKE_VERSION(RTE_AVP_RELEASE_VERSION_1, \
 		     RTE_AVP_MINOR_VERSION_13)
 
 /**
- * Access AVP device version values
+ * @{ Access AVP device version values
  */
 #define RTE_AVP_GET_RELEASE_VERSION(_version) (((_version) >> 16) & 0xffff)
 #define RTE_AVP_GET_MAJOR_VERSION(_version) (((_version) >> 8) & 0xff)
-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 2/8] doc: document rte_os.h
From: Marat Khalili @ 2026-07-07  8:50 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson
In-Reply-To: <20260707085048.15295-1-marat.khalili@huawei.com>

File rte_os.h did not previously have a generic version to generate
documentation from, but its OS-specific version was installed. Since it
is now verified that documentation is generated for all public headers,
add a generic stub containing description of this file.

Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
 lib/eal/include/generic/rte_os.h | 13 +++++++++++++
 1 file changed, 13 insertions(+)
 create mode 100644 lib/eal/include/generic/rte_os.h

diff --git a/lib/eal/include/generic/rte_os.h b/lib/eal/include/generic/rte_os.h
new file mode 100644
index 000000000000..aa96321aefc4
--- /dev/null
+++ b/lib/eal/include/generic/rte_os.h
@@ -0,0 +1,13 @@
+/* SPDX-License-Identifier: BSD-3-Clause
+ * Copyright(c) 2010-2019 Intel Corporation
+ */
+
+#ifndef _RTE_OS_H_
+#define _RTE_OS_H_
+
+/**
+ * This header should contain any definition
+ * which is not supported natively or named differently in the local OS.
+ */
+
+#endif /* _RTE_OS_H_ */
-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 1/8] doc: detect ignored public headers
From: Marat Khalili @ 2026-07-07  8:50 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev, thomas
In-Reply-To: <20260707085048.15295-1-marat.khalili@huawei.com>

Some public headers were omitted from doc/api/doxy-api-index.md and/or
doc/api/doxy-api.conf.in. Add checks to meson configuration detecting
and warning about these.

Suggested-by: Bruce Richardson <bruce.richardson@intel.com>
Signed-off-by: Marat Khalili <marat.khalili@huawei.com>
---
 drivers/meson.build | 17 +++++++++++++++++
 lib/meson.build     | 23 +++++++++++++++++++++++
 meson.build         | 19 +++++++++++++++++++
 3 files changed, 59 insertions(+)

diff --git a/drivers/meson.build b/drivers/meson.build
index 102a8262e588..09c063660291 100644
--- a/drivers/meson.build
+++ b/drivers/meson.build
@@ -287,6 +287,23 @@ foreach subpath:subdirs
         dpdk_headers += headers
         dpdk_drivers_headers += driver_sdk_headers
 
+        if check_docs and headers.length() > 0
+            foreach h:headers
+                hname = fs.name(h)
+                if not hname.startswith('rte_')
+                    warning('public header @0@ name does not start with "rte_"'.format(h))
+                endif
+                if hname not in doc_indexed_headers
+                    warning('public header @0@ is not listed in @1@'.format(h, doc_index_path))
+                endif
+            endforeach
+            doc_dir = 'drivers/' + drv_path
+            if doc_dir not in doc_built_dirs
+                warning('public header directory @0@ is not listed in @1@'.format(doc_dir,
+                    doc_build_path))
+            endif
+        endif
+
         if headers.length() > 0
             dpdk_includes += include_directories(drv_path)
         endif
diff --git a/lib/meson.build b/lib/meson.build
index af5c160cb800..073d3ead23c8 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -209,6 +209,29 @@ foreach l:libraries
     dpdk_indirect_headers += indirect_headers
     dpdk_drivers_headers += driver_sdk_headers
 
+    if check_docs and headers.length() > 0
+        foreach h:headers
+            hname = fs.name(h)
+            if not (hname.startswith('rte_') or hname.startswith('cmdline'))
+                warning('public header @0@ name does not start with "rte_" or "cmdline"'.format(h))
+            endif
+            if hname not in doc_indexed_headers
+                warning('public header @0@ is not listed in @1@'.format(h, doc_index_path))
+            endif
+        endforeach
+        if l == 'eal'
+            doc_dirs = ['lib/eal/include', 'lib/eal/include/generic']
+        else
+            doc_dirs = ['lib/' + l]
+        endif
+        foreach d:doc_dirs
+            if d not in doc_built_dirs
+                warning('public header directory @0@ is not listed in @1@'.format(d,
+                    doc_build_path))
+            endif
+        endforeach
+    endif
+
     libname = 'rte_' + name
     includes += include_directories(l)
     dpdk_includes += include_directories(l)
diff --git a/meson.build b/meson.build
index b01010ffa076..2488c54f1b17 100644
--- a/meson.build
+++ b/meson.build
@@ -88,6 +88,25 @@ if is_linux
     global_inc += include_directories('kernel/linux')
 endif
 
+# on linux, try to check that documentation sources are correctly built and indexed
+check_docs = is_linux and meson.version().version_compare('>= 0.60.0')
+
+if check_docs
+    doc_build_path = 'doc/api/doxy-api.conf.in'
+    doc_build_file = dpdk_source_root / doc_build_path
+    doc_built_dirs = run_command('sed', '--regexp-extended', '--quiet',
+        # Extract and print the file path immediately following @TOPDIR@/ .
+        's#^(INPUT *=)? *@TOPDIR@/([^ ]*)( .*|\\\\|)$#\\2#p',
+        doc_build_file, check: true).stdout().strip('\n').split('\n')
+
+    doc_index_path = 'doc/api/doxy-api-index.md'
+    doc_index_file = dpdk_source_root / doc_index_path
+    doc_indexed_headers = run_command('sed', '--regexp-extended', '--quiet',
+        # Extract and print the (@ref ...) contents.
+        's#^.*\\(@ref ([^)]*)\\).*$#\\1#p',
+        doc_index_file, check: true).stdout().strip('\n').split('\n')
+endif
+
 # build libs and drivers
 subdir('lib')
 subdir('drivers')
-- 
2.43.0


^ permalink raw reply related

* [PATCH v3 0/8] doc: build for all public headers
From: Marat Khalili @ 2026-07-07  8:50 UTC (permalink / raw)
  Cc: dev, thomas, bruce.richardson
In-Reply-To: <20260706105256.79904-1-marat.khalili@huawei.com>

It was noticed that not all public headers were included in the doxygen
build, and once built not all files were listed in the index file
serving as a point of entry for the HTML version.

Bruce Richardson provided an idea and a draft implementation of the
configuration-time check, which I optimized to avoid repeat grep calls
and expanded to include indexing check.

After all drivers and public headers were included, multiple small
problems have surfaced fixes for which (with one exception covered by
bug 1962) are also included in this patch set.

v3:
* added fixes for typos in rte_avp_common.h that tripped doxygen 1.9+;
* fixed variable name typo in lib/meson.build introduced in v1;

v2:
* switched from `splitlines()` to `strip('\n').split('\n')` for
  compatibility with older versions of meson;
* rebased on fresh main and updated BPF header links in the index file
  (note: following other examples BPF links are formatted as a sublist);

Marat Khalili (8):
  doc: detect ignored public headers
  doc: document rte_os.h
  doc: fix typos in rte_avp_common.h
  doc: fix typos in rte_bus_pci.h
  doc: fix typos in rte_bus_vmbus.h
  doc: add missing globs to doxy-api.conf.in
  doc: add missing drivers to doxy-api.conf.in
  doc: add missing headers to doxy-api-index.md

 doc/api/doxy-api-index.md         | 120 ++++++++++++++++++++++++++----
 doc/api/doxy-api.conf.in          |  17 ++++-
 drivers/bus/pci/rte_bus_pci.h     |   4 +-
 drivers/bus/vmbus/rte_bus_vmbus.h |  33 ++++----
 drivers/meson.build               |  17 +++++
 drivers/net/avp/rte_avp_common.h  |  10 +--
 lib/eal/include/generic/rte_os.h  |  13 ++++
 lib/meson.build                   |  23 ++++++
 meson.build                       |  19 +++++
 9 files changed, 219 insertions(+), 37 deletions(-)
 create mode 100644 lib/eal/include/generic/rte_os.h

-- 
2.43.0


^ permalink raw reply

* Inquiry about status of accepted patch net/bnxt/tf_core: fix null deref on pool use allocation
From: Simakov Aleksey @ 2026-07-07  8:04 UTC (permalink / raw)
  To: kishore.padmanabha@broadcom.com
  Cc: dev@dpdk.org, ajit.khaparde@broadcom.com, stable@dpdk.org,
	denserg.edu@gmail.com

Hello!

I hope this message finds you well.

I am writing to inquire about the status of patch https://patches.dpdk.org/project/dpdk/patch/20260603041557.115956-1-denserg.edu@gmail.com/
It was marked as "Accepted" in Patchwork over a month ago, but I noticed that it has not yet been merged into any of the DPDK branches.

Could you please clarify the current status of this patch?

Thank you for your time

^ permalink raw reply

* Re: [PATCH v4 4/4] test/dma: skip instance suite on low burst capacity
From: fengchengwen @ 2026-07-07  1:41 UTC (permalink / raw)
  To: Raghavendra Ningoji, dev
  Cc: david.marchand, bruce.richardson, selwin.sebastian,
	bhagyada.modali, rjarry, thomas
In-Reply-To: <20260706115533.2937512-5-raghavendra.ningoji@amd.com>

On 7/6/2026 7:55 PM, Raghavendra Ningoji wrote:
> test_dmadev_setup() aborts the entire "DMA dev instance" test suite
> with a hard failure when rte_dma_burst_capacity() reports fewer than
> 32 descriptors. Some DMA engines expose a small hardware ring; for
> example a 32-entry ring that reserves one slot to distinguish a full
> ring from an empty one leaves only 31 descriptors usable. Such a
> device genuinely cannot run the instance tests, which enqueue 32-deep
> bursts, but it should be reported as skipped rather than failed.
> 
> Return TEST_SKIPPED instead, matching test_dmadev_burst_setup() which
> already skips (rather than fails) when the capacity is below 64.
> 
> Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
> ---
>  app/test/test_dmadev.c | 8 ++++++--
>  1 file changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/app/test/test_dmadev.c b/app/test/test_dmadev.c
> index 5488a1af33..1cfa8c1e10 100644
> --- a/app/test/test_dmadev.c
> +++ b/app/test/test_dmadev.c
> @@ -1397,8 +1397,12 @@ test_dmadev_setup(void)
>  	if (rte_dma_stats_get(dev_id, vchan, &stats) != 0)
>  		ERR_RETURN("Error with rte_dma_stats_get()\n");
>  
> -	if (rte_dma_burst_capacity(dev_id, vchan) < 32)
> -		ERR_RETURN("Error: Device does not have sufficient burst capacity to run tests");
> +	if (rte_dma_burst_capacity(dev_id, vchan) < 32) {
> +		RTE_LOG(ERR, USER1,
> +			"DMA Dev %u: insufficient burst capacity (32 required), skipping tests\n",
> +			dev_id);
> +		return TEST_SKIPPED;
> +	}

This approach is also acceptable, but I think this test, as a community
"free gift", should be supported as much as possible. So I would suggest
you modify the relevant code to support this test, but it is not mandatory.

Thanks

>  
>  	if (stats.completed != 0 || stats.submitted != 0 || stats.errors != 0)
>  		ERR_RETURN("Error device stats are not all zero: completed = %"PRIu64", "


^ permalink raw reply

* Re: [PATCH v4 1/4] dma/ae4dma: introduce AMD AE4DMA DMA PMD
From: fengchengwen @ 2026-07-07  1:24 UTC (permalink / raw)
  To: Raghavendra Ningoji, dev
  Cc: david.marchand, bruce.richardson, selwin.sebastian,
	bhagyada.modali, rjarry, thomas
In-Reply-To: <20260706115533.2937512-2-raghavendra.ningoji@amd.com>

On 7/6/2026 7:55 PM, Raghavendra Ningoji wrote:
> Add the skeleton of a new dmadev poll-mode driver for the AMD AE4DMA
> hardware DMA engine, providing only PCI probe/remove and per-queue
> hardware initialisation. An AE4DMA engine exposes 16 hardware command
> queues, each with a 32-entry descriptor ring; the PMD maps each
> hardware channel to its own dmadev with a single virtual channel,
> so a PCI function appears as 16 dmadevs named "<pci-bdf>-ch0" ..
> "<pci-bdf>-ch15".
> 
> This patch only registers the PCI driver, allocates the dmadev
> objects, reserves the per-queue descriptor rings and programs the
> hardware queue base addresses. Control and data path operations are
> added in subsequent patches.
> 
> Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
> ---
>  .mailmap                               |   1 +
>  MAINTAINERS                            |   5 +
>  doc/guides/dmadevs/ae4dma.rst          |  53 +++++++
>  doc/guides/dmadevs/index.rst           |   1 +
>  doc/guides/rel_notes/release_26_07.rst |   7 +
>  drivers/dma/ae4dma/ae4dma_dmadev.c     | 200 +++++++++++++++++++++++++
>  drivers/dma/ae4dma/ae4dma_hw_defs.h    | 151 +++++++++++++++++++
>  drivers/dma/ae4dma/ae4dma_internal.h   | 114 ++++++++++++++
>  drivers/dma/ae4dma/meson.build         |  13 ++
>  drivers/dma/meson.build                |   1 +
>  usertools/dpdk-devbind.py              |   5 +-
>  11 files changed, 550 insertions(+), 1 deletion(-)
>  create mode 100644 doc/guides/dmadevs/ae4dma.rst
>  create mode 100644 drivers/dma/ae4dma/ae4dma_dmadev.c
>  create mode 100644 drivers/dma/ae4dma/ae4dma_hw_defs.h
>  create mode 100644 drivers/dma/ae4dma/ae4dma_internal.h
>  create mode 100644 drivers/dma/ae4dma/meson.build
> 
> diff --git a/.mailmap b/.mailmap
> index 89ba6ff..71a6256 100644
> --- a/.mailmap
> +++ b/.mailmap
> @@ -1329,6 +1329,7 @@ Radu Bulie <radu-andrei.bulie@nxp.com>
>  Radu Nicolau <radu.nicolau@intel.com>
>  Rafael Ávila de Espíndola <espindola@scylladb.com>
>  Rafal Kozik <rk@semihalf.com>
> +Raghavendra Ningoji <raghavendra.ningoji@amd.com>
>  Ragothaman Jayaraman <rjayaraman@caviumnetworks.com>
>  Rahul Bhansali <rbhansali@marvell.com>
>  Rahul Gupta <rahul.gupta@broadcom.com>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 9143d02..2e27af4 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -1361,6 +1361,11 @@ F: doc/guides/compressdevs/features/zsda.ini
>  DMAdev Drivers
>  --------------
>  
> +AMD AE4DMA
> +M: Bhagyada Modali <bhagyada.modali@amd.com>
> +F: drivers/dma/ae4dma/
> +F: doc/guides/dmadevs/ae4dma.rst
> +
>  Intel IDXD - EXPERIMENTAL
>  M: Bruce Richardson <bruce.richardson@intel.com>
>  M: Kevin Laatz <kevin.laatz@intel.com>
> diff --git a/doc/guides/dmadevs/ae4dma.rst b/doc/guides/dmadevs/ae4dma.rst
> new file mode 100644
> index 0000000..eeed55c
> --- /dev/null
> +++ b/doc/guides/dmadevs/ae4dma.rst
> @@ -0,0 +1,53 @@
> +..  SPDX-License-Identifier: BSD-3-Clause
> +    Copyright(c) 2026 Advanced Micro Devices, Inc.
> +
> +.. include:: <isonum.txt>
> +
> +AMD AE4DMA DMA Device Driver
> +============================
> +
> +The ``ae4dma`` dmadev driver is a poll-mode driver (PMD) for the
> +AMD AE4DMA hardware DMA engine. The engine exposes 16 independent
> +hardware command queues, each with a ring of 32 descriptors. The PMD
> +maps each hardware command queue to a separate DPDK dmadev with a
> +single virtual channel, so a single PCI function appears as 16 dmadevs
> +named ``<pci-bdf>-ch0`` through ``<pci-bdf>-ch15``.
> +
> +The driver supports memory-to-memory copy operations only.
> +
> +Hardware Requirements
> +---------------------
> +
> +The ``dpdk-devbind.py`` script can be used to list AE4DMA devices on
> +the system::
> +
> +   dpdk-devbind.py --status-dev dma
> +
> +AE4DMA devices appear with vendor ID ``0x1022`` and device ID
> +``0x149b``.
> +
> +Compilation
> +-----------
> +
> +The driver is built as part of the standard DPDK build on x86 platforms
> +using ``meson`` and ``ninja``; no extra configuration is required.
> +
> +Device Setup
> +------------
> +
> +The AE4DMA device must be bound to a DPDK-compatible kernel module such
> +as ``vfio-pci`` before it can be used::
> +
> +   dpdk-devbind.py -b vfio-pci <pci-bdf>
> +
> +Initialization
> +~~~~~~~~~~~~~~
> +
> +On probe the PMD performs the following steps for each PCI function:
> +
> +* Reads BAR0 and programs the common configuration register with the
> +  number of hardware queues to enable (16).
> +* For each hardware queue it allocates a 32-entry descriptor ring in
> +  IOVA-contiguous memory, programs the queue base address and ring
> +  depth into the per-queue registers, and enables the queue.
> +* Interrupts are masked; completion is polled by the application.
> diff --git a/doc/guides/dmadevs/index.rst b/doc/guides/dmadevs/index.rst
> index 56beb17..9739959 100644
> --- a/doc/guides/dmadevs/index.rst
> +++ b/doc/guides/dmadevs/index.rst
> @@ -11,6 +11,7 @@ an application through DMA API.
>     :maxdepth: 1
>     :numbered:
>  
> +   ae4dma
>     cnxk
>     dpaa
>     dpaa2
> diff --git a/doc/guides/rel_notes/release_26_07.rst b/doc/guides/rel_notes/release_26_07.rst
> index f012d47..9a78a7e 100644
> --- a/doc/guides/rel_notes/release_26_07.rst
> +++ b/doc/guides/rel_notes/release_26_07.rst
> @@ -63,6 +63,13 @@ New Features
>      ``rte_eal_init`` and the application is responsible for probing each device,
>    * ``--auto-probing`` enables the initial bus probing, which is the current default behavior.
>  
> +* **Added AMD AE4DMA DMA PMD.**
> +
> +  Added a new ``dma/ae4dma`` driver for the AMD AE4DMA hardware DMA engine.
> +  Each PCI function exposes 16 hardware command queues; the PMD registers one
> +  dmadev per channel with a single virtual channel and supports
> +  memory-to-memory copy operations.
> +
>  
>  Removed Items
>  -------------
> diff --git a/drivers/dma/ae4dma/ae4dma_dmadev.c b/drivers/dma/ae4dma/ae4dma_dmadev.c
> new file mode 100644
> index 0000000..bf0d3bb
> --- /dev/null
> +++ b/drivers/dma/ae4dma/ae4dma_dmadev.c
> @@ -0,0 +1,200 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2026 Advanced Micro Devices, Inc. All rights reserved.
> + */
> +
> +#include <errno.h>
> +#include <inttypes.h>
> +#include <stdio.h>
> +#include <string.h>
> +
> +#include <rte_bus_pci.h>
> +#include <bus_pci_driver.h>
> +#include <rte_dmadev_pmd.h>
> +#include <rte_malloc.h>
> +
> +#include "ae4dma_internal.h"
> +
> +/*
> + * One dmadev per AE4DMA hardware channel; each dmadev has exactly one
> + * virtual channel. The HW's per-queue register block must be densely
> + * packed right after the engine-common config register at BAR0+0; the
> + * build-time check below catches an accidental layout change.
> + */
> +static_assert(sizeof(struct ae4dma_hwq_regs) == 32,
> +		"ae4dma_hwq_regs stride changed; per-queue offset math will break");
> +
> +RTE_LOG_REGISTER_DEFAULT(ae4dma_pmd_logtype, INFO);
> +
> +#define AE4DMA_PMD_NAME dmadev_ae4dma
> +
> +static const struct rte_memzone *
> +ae4dma_queue_dma_zone_reserve(const char *queue_name,
> +		uint32_t queue_size, int socket_id)
> +{
> +	return rte_memzone_reserve_aligned(queue_name, queue_size,
> +			socket_id, RTE_MEMZONE_IOVA_CONTIG, queue_size);
> +}
> +
> +static int
> +ae4dma_add_queue(struct ae4dma_dmadev *dev, struct rte_pci_device *pci,
> +		uint8_t qn, const char *pci_name)
> +{
> +	const struct rte_memzone *q_mz;
> +	struct ae4dma_cmd_queue *cmd_q;
> +	uint32_t dma_addr_lo, dma_addr_hi;
> +
> +	dev->io_regs = pci->mem_resource[AE4DMA_PCIE_BAR].addr;
> +
> +	cmd_q = &dev->cmd_q;
> +	cmd_q->id = qn;
> +	cmd_q->qidx = 0;
> +	cmd_q->qsize = AE4DMA_QUEUE_SIZE(AE4DMA_QUEUE_DESC_SIZE);
> +	cmd_q->hwq_regs = (volatile struct ae4dma_hwq_regs *)dev->io_regs + (qn + 1);
> +
> +	/*
> +	 * Memzone name must be globally unique. Embed PCI BDF so multiple
> +	 * PCI functions probed concurrently don't collide.
> +	 */
> +	snprintf(cmd_q->memz_name, sizeof(cmd_q->memz_name),
> +			"ae4dma_%s_q%u", pci_name, (unsigned int)qn);
> +
> +	q_mz = ae4dma_queue_dma_zone_reserve(cmd_q->memz_name,
> +			cmd_q->qsize, rte_socket_id());
> +	if (q_mz == NULL) {
> +		AE4DMA_PMD_ERR("memzone reserve failed for %s", cmd_q->memz_name);
> +		return -ENOMEM;
> +	}
> +
> +	cmd_q->mz = q_mz;
> +	cmd_q->qbase_addr = q_mz->addr;
> +	cmd_q->qbase_desc = q_mz->addr;
> +	cmd_q->qbase_phys_addr = q_mz->iova;
> +
> +	AE4DMA_WRITE_REG(&cmd_q->hwq_regs->max_idx, AE4DMA_DESCRIPTORS_PER_CMDQ);
> +	AE4DMA_WRITE_REG(&cmd_q->hwq_regs->control_reg.control_raw,
> +			AE4DMA_CMD_QUEUE_ENABLE);
> +	AE4DMA_WRITE_REG(&cmd_q->hwq_regs->intr_status_reg.intr_status_raw,
> +			AE4DMA_DISABLE_INTR);
> +	cmd_q->next_write = AE4DMA_READ_REG(&cmd_q->hwq_regs->write_idx);
> +	cmd_q->next_read = AE4DMA_READ_REG(&cmd_q->hwq_regs->read_idx);
> +
> +	dma_addr_lo = lower_32_bits(cmd_q->qbase_phys_addr);
> +	AE4DMA_WRITE_REG(&cmd_q->hwq_regs->qbase_lo, dma_addr_lo);
> +	dma_addr_hi = upper_32_bits(cmd_q->qbase_phys_addr);
> +	AE4DMA_WRITE_REG(&cmd_q->hwq_regs->qbase_hi, dma_addr_hi);
> +
> +	return 0;
> +}
> +
> +static void
> +ae4dma_channel_dev_name(char *out, size_t outlen, const char *pci_name,
> +		unsigned int ch)
> +{
> +	snprintf(out, outlen, "%s-ch%u", pci_name, ch);
> +}
> +
> +static int
> +ae4dma_dmadev_create(const char *name, struct rte_pci_device *dev, uint8_t qn)
> +{
> +	char hwq_dev_name[RTE_DEV_NAME_MAX_LEN] = {0};
> +	struct ae4dma_dmadev *ae4dma;
> +	struct rte_dma_dev *dmadev;
> +
> +	ae4dma_channel_dev_name(hwq_dev_name, sizeof(hwq_dev_name), name, qn);
> +
> +	dmadev = rte_dma_pmd_allocate(hwq_dev_name, dev->device.numa_node,
> +			sizeof(struct ae4dma_dmadev));
> +	if (dmadev == NULL) {
> +		AE4DMA_PMD_ERR("Unable to allocate dma device");
> +		return -ENOMEM;
> +	}
> +	dmadev->device = &dev->device;
> +	dmadev->fp_obj->dev_private = dmadev->data->dev_private;
> +
> +	ae4dma = dmadev->data->dev_private;
> +
> +	if (ae4dma_add_queue(ae4dma, dev, qn, name) != 0)
> +		goto init_error;
> +	return 0;
> +
> +init_error:
> +	AE4DMA_PMD_ERR("Failed to create dmadev %s", hwq_dev_name);
> +	rte_dma_pmd_release(hwq_dev_name);
> +	return -ENOMEM;
> +}
> +
> +static int
> +ae4dma_dmadev_probe(struct rte_pci_driver *drv __rte_unused,
> +		struct rte_pci_device *dev)
> +{
> +	char chname[RTE_DEV_NAME_MAX_LEN];
> +	uint32_t q_per_eng;
> +	void *mmio_base;
> +	char name[32];
> +	int ret = 0;
> +	uint8_t i;
> +
> +	rte_pci_device_name(&dev->addr, name, sizeof(name));
> +	AE4DMA_PMD_INFO("Init %s on NUMA node %d", name, dev->device.numa_node);
> +
> +	mmio_base = dev->mem_resource[AE4DMA_PCIE_BAR].addr;
> +	if (mmio_base == NULL) {
> +		AE4DMA_PMD_ERR("%s: BAR%d not mapped", name, AE4DMA_PCIE_BAR);
> +		return -ENODEV;
> +	}
> +
> +	/* Program the per-engine HW queue count once. */
> +	AE4DMA_WRITE_REG_OFFSET(mmio_base, AE4DMA_COMMON_CONFIG_OFFSET,
> +			AE4DMA_MAX_HW_QUEUES);
> +	q_per_eng = AE4DMA_READ_REG_OFFSET(mmio_base, AE4DMA_COMMON_CONFIG_OFFSET);
> +	AE4DMA_PMD_INFO("%s: AE4DMA queues per engine = %u", name, q_per_eng);
> +
> +	for (i = 0; i < AE4DMA_MAX_HW_QUEUES; i++) {
> +		ret = ae4dma_dmadev_create(name, dev, i);
> +		if (ret != 0) {
> +			AE4DMA_PMD_ERR("%s create dmadev %u failed!", name, i);
> +			while (i > 0) {
> +				i--;
> +				ae4dma_channel_dev_name(chname, sizeof(chname), name, i);
> +				rte_dma_pmd_release(chname);
> +			}
> +			break;
> +		}
> +	}
> +	return ret;
> +}
> +
> +static int
> +ae4dma_dmadev_remove(struct rte_pci_device *dev)
> +{
> +	char chname[RTE_DEV_NAME_MAX_LEN];
> +	unsigned int i;
> +	char name[32];
> +
> +	rte_pci_device_name(&dev->addr, name, sizeof(name));
> +
> +	AE4DMA_PMD_INFO("Closing %s on NUMA node %d",
> +			name, dev->device.numa_node);
> +
> +	for (i = 0; i < AE4DMA_MAX_HW_QUEUES; i++) {
> +		ae4dma_channel_dev_name(chname, sizeof(chname), name, i);
> +		rte_dma_pmd_release(chname);
> +	}
> +	return 0;
> +}
> +
> +static const struct rte_pci_id pci_id_ae4dma_map[] = {
> +	{ RTE_PCI_DEVICE(AMD_VENDOR_ID, AE4DMA_DEVICE_ID) },
> +	{ .vendor_id = 0, /* sentinel */ },
> +};
> +
> +static struct rte_pci_driver ae4dma_pmd_drv = {
> +	.id_table = pci_id_ae4dma_map,
> +	.drv_flags = RTE_PCI_DRV_NEED_MAPPING,
> +	.probe = ae4dma_dmadev_probe,
> +	.remove = ae4dma_dmadev_remove,
> +};
> +
> +RTE_PMD_REGISTER_PCI(AE4DMA_PMD_NAME, ae4dma_pmd_drv);
> +RTE_PMD_REGISTER_PCI_TABLE(AE4DMA_PMD_NAME, pci_id_ae4dma_map);
> +RTE_PMD_REGISTER_KMOD_DEP(AE4DMA_PMD_NAME, "* igb_uio | uio_pci_generic | vfio-pci");
> diff --git a/drivers/dma/ae4dma/ae4dma_hw_defs.h b/drivers/dma/ae4dma/ae4dma_hw_defs.h
> new file mode 100644
> index 0000000..278fe77
> --- /dev/null
> +++ b/drivers/dma/ae4dma/ae4dma_hw_defs.h
> @@ -0,0 +1,151 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2026 Advanced Micro Devices, Inc. All rights reserved.
> + */
> +
> +#ifndef __AE4DMA_HW_DEFS_H__
> +#define __AE4DMA_HW_DEFS_H__
> +
> +#include <stdint.h>
> +
> +#include <rte_bitops.h>
> +
> +#define AE4DMA_BIT(nr)			(1UL << (nr))

Why not use RTE_BIT32() in rte_bitops.h which already included ?

> +
> +/* ae4dma device details */
> +#define AMD_VENDOR_ID	0x1022
> +#define AE4DMA_DEVICE_ID	0x149b
> +#define AE4DMA_PCIE_BAR 0
> +
> +/*
> + * An AE4DMA engine has 16 DMA queues. Each queue supports up to 32
> + * descriptors (31 outstanding).
> + */
> +#define AE4DMA_MAX_HW_QUEUES        16
> +#define AE4DMA_QUEUE_START_INDEX    0
> +#define AE4DMA_CMD_QUEUE_ENABLE		0x1
> +#define AE4DMA_CMD_QUEUE_DISABLE	0x0
> +
> +/* Common to all queues */
> +#define AE4DMA_COMMON_CONFIG_OFFSET 0x00
> +
> +#define AE4DMA_DISABLE_INTR 0x01
> +
> +/* Descriptor status */
> +enum ae4dma_dma_status {
> +	AE4DMA_DMA_DESC_SUBMITTED = 0,
> +	AE4DMA_DMA_DESC_VALIDATED = 1,
> +	AE4DMA_DMA_DESC_PROCESSED = 2,
> +	AE4DMA_DMA_DESC_COMPLETED = 3,
> +	AE4DMA_DMA_DESC_ERROR = 4,
> +};
> +
> +/* Descriptor error-code */
> +enum ae4dma_dma_err {
> +	AE4DMA_DMA_ERR_NO_ERR = 0,
> +	AE4DMA_DMA_ERR_INV_HEADER = 1,
> +	AE4DMA_DMA_ERR_INV_STATUS = 2,
> +	AE4DMA_DMA_ERR_INV_LEN = 3,
> +	AE4DMA_DMA_ERR_INV_SRC = 4,
> +	AE4DMA_DMA_ERR_INV_DST = 5,
> +	AE4DMA_DMA_ERR_INV_ALIGN = 6,
> +	AE4DMA_DMA_ERR_UNKNOWN = 7,
> +};
> +
> +/* HW Queue status */
> +enum ae4dma_hwqueue_status {
> +	AE4DMA_HWQUEUE_EMPTY = 0,
> +	AE4DMA_HWQUEUE_FULL = 1,
> +	AE4DMA_HWQUEUE_NOT_EMPTY = 4,
> +};
> +/*
> + * descriptor for AE4DMA commands
> + * 8 32-bit words:
> + * word 0: source memory type; destination memory type ; control bits
> + * word 1: desc_id; error code; status
> + * word 2: length
> + * word 3: reserved
> + * word 4: upper 32 bits of source pointer
> + * word 5: low 32 bits of source pointer
> + * word 6: upper 32 bits of destination pointer
> + * word 7: low 32 bits of destination pointer
> + */
> +
> +/* AE4DMA Descriptor - DWORD0 - Controls bits: Reserved for future use */
> +#define AE4DMA_DWORD0_STOP_ON_COMPLETION	AE4DMA_BIT(0)
> +#define AE4DMA_DWORD0_INTERRUPT_ON_COMPLETION	AE4DMA_BIT(1)
> +#define AE4DMA_DWORD0_START_OF_MESSAGE		AE4DMA_BIT(3)
> +#define AE4DMA_DWORD0_END_OF_MESSAGE		AE4DMA_BIT(4)
> +#define AE4DMA_DWORD0_DESTINATION_MEMORY_TYPE	RTE_GENMASK64(5, 4)
> +#define AE4DMA_DWORD0_SOURCE_MEMEORY_TYPE	RTE_GENMASK64(7, 6)
> +
> +#define AE4DMA_DWORD0_DESTINATION_MEMORY_TYPE_MEMORY    (0x0)
> +#define AE4DMA_DWORD0_DESTINATION_MEMORY_TYPE_IOMEMORY  (1<<4)
> +#define AE4DMA_DWORD0_SOURCE_MEMEORY_TYPE_MEMORY    (0x0)
> +#define AE4DMA_DWORD0_SOURCE_MEMEORY_TYPE_IOMEMORY  (1<<6)

How about use RTE_BIT32(6) ?

Thanks

> +
> +struct ae4dma_desc_dword0 {
> +	uint8_t byte0;
> +	uint8_t byte1;
> +	uint16_t timestamp;
> +};
> +
> +struct ae4dma_desc_dword1 {
> +	uint8_t status;
> +	uint8_t err_code;
> +	uint16_t desc_id;
> +};
> +
> +struct ae4dma_desc {
> +	struct ae4dma_desc_dword0 dw0;
> +	struct ae4dma_desc_dword1 dw1;
> +	uint32_t length;
> +	uint32_t reserved;
> +	uint32_t src_lo;
> +	uint32_t src_hi;
> +	uint32_t dst_lo;
> +	uint32_t dst_hi;
> +};
> +
> +/*
> + * Registers for each queue :4 bytes length
> + * Effective address : offset + reg
> + */
> +struct ae4dma_hwq_regs {
> +	union {
> +		uint32_t control_raw;
> +		struct {
> +			uint32_t queue_enable: 1;
> +			uint32_t reserved_internal: 31;
> +		} control;
> +	} control_reg;
> +
> +	union {
> +		uint32_t status_raw;
> +		struct {
> +			uint32_t reserved0: 1;
> +			/* 0–empty, 1–full, 2–stopped, 3–error , 4–Not Empty */
> +			uint32_t queue_status: 2;
> +			uint32_t reserved1: 21;
> +			uint32_t interrupt_type: 4;
> +			uint32_t reserved2: 4;
> +		} status;
> +	} status_reg;
> +
> +	uint32_t max_idx;
> +	uint32_t read_idx;
> +	uint32_t write_idx;
> +
> +	union {
> +		uint32_t intr_status_raw;
> +		struct {
> +			uint32_t intr_status: 1;
> +			uint32_t reserved: 31;
> +		} intr_status;
> +	} intr_status_reg;
> +
> +	uint32_t qbase_lo;
> +	uint32_t qbase_hi;
> +
> +};
> +
> +#endif /* AE4DMA_HW_DEFS_H */
> diff --git a/drivers/dma/ae4dma/ae4dma_internal.h b/drivers/dma/ae4dma/ae4dma_internal.h
> new file mode 100644
> index 0000000..1f1f30f
> --- /dev/null
> +++ b/drivers/dma/ae4dma/ae4dma_internal.h
> @@ -0,0 +1,114 @@
> +/* SPDX-License-Identifier: BSD-3-Clause
> + * Copyright(c) 2026 Advanced Micro Devices, Inc. All rights reserved.
> + */
> +
> +#ifndef _AE4DMA_INTERNAL_H_
> +#define _AE4DMA_INTERNAL_H_
> +
> +#include <stdint.h>
> +
> +#include <rte_byteorder.h>
> +#include <rte_dmadev.h>
> +#include <rte_io.h>
> +#include <rte_memzone.h>
> +
> +#include "ae4dma_hw_defs.h"
> +
> +/* Return bits 32-63 of a 64-bit number. */
> +#define upper_32_bits(n) ((uint32_t)(((n) >> 16) >> 16))
> +
> +/* Return bits 0-31 of a 64-bit number. */
> +#define lower_32_bits(n) ((uint32_t)((n) & 0xffffffff))
> +
> +/*
> + * Hardware ring depth (slots per queue); fixed at 32 per the AE4DMA
> + * spec and must be a power of two. The engine reserves one slot to tell
> + * a full ring from an empty one (full when (write + 1) % max == read),
> + * so at most nb_desc - 1 (31) descriptors can be outstanding.
> + */
> +#define AE4DMA_DESCRIPTORS_PER_CMDQ	32
> +#define AE4DMA_QUEUE_DESC_SIZE		sizeof(struct ae4dma_desc)
> +#define AE4DMA_QUEUE_SIZE(n)		(AE4DMA_DESCRIPTORS_PER_CMDQ * (n))
> +
> +/* AE4DMA registers Write/Read */
> +static inline void ae4dma_pci_reg_write(void *base, int offset,
> +		uint32_t value)
> +{
> +	volatile void *reg_addr = ((uint8_t *)base + offset);
> +
> +	rte_write32((rte_cpu_to_le_32(value)), reg_addr);
> +}
> +
> +static inline uint32_t ae4dma_pci_reg_read(void *base, int offset)
> +{
> +	volatile void *reg_addr = ((uint8_t *)base + offset);
> +
> +	return rte_le_to_cpu_32(rte_read32(reg_addr));
> +}
> +
> +#define AE4DMA_READ_REG_OFFSET(hw_addr, reg_offset) \
> +	ae4dma_pci_reg_read(hw_addr, reg_offset)
> +
> +#define AE4DMA_WRITE_REG_OFFSET(hw_addr, reg_offset, value) \
> +	ae4dma_pci_reg_write(hw_addr, reg_offset, value)
> +
> +#define AE4DMA_READ_REG(hw_addr) \
> +	ae4dma_pci_reg_read((void *)(uintptr_t)(hw_addr), 0)
> +
> +#define AE4DMA_WRITE_REG(hw_addr, value) \
> +	ae4dma_pci_reg_write((void *)(uintptr_t)(hw_addr), 0, value)
> +
> +/* A structure describing an AE4DMA command queue. */
> +struct __rte_cache_aligned ae4dma_cmd_queue {
> +	char memz_name[RTE_MEMZONE_NAMESIZE];
> +	const struct rte_memzone *mz;
> +	volatile struct ae4dma_hwq_regs *hwq_regs;
> +
> +	struct rte_dma_vchan_conf qcfg;
> +	struct rte_dma_stats stats;
> +	/* Queue address */
> +	struct ae4dma_desc *qbase_desc;
> +	void *qbase_addr;
> +	rte_iova_t qbase_phys_addr;
> +	enum ae4dma_dma_err status[AE4DMA_DESCRIPTORS_PER_CMDQ];
> +	/* Queue identifier */
> +	uint64_t id;    /* queue id */
> +	uint64_t qidx;  /* queue index */
> +	uint64_t qsize; /* queue size */
> +	/*
> +	 * Free-running 16-bit ring indices (wrap at 2^16), as required by the
> +	 * dmadev API. The HW ring slot is derived as ((hw_base + idx) &
> +	 * (nb_desc - 1)), which is why nb_desc is rounded up to a power of two.
> +	 */
> +	uint16_t next_read;  /* ring_idx of the next completion to reap */
> +	uint16_t next_write; /* ring_idx assigned to the next enqueue */
> +	uint16_t last_write; /* next_write at last submit; for submitted stat */
> +	/*
> +	 * HW ring slot that free-running index 0 maps to. read_idx is HW-owned
> +	 * (read-only), so on start we anchor to wherever the HW consumer sits
> +	 * instead of forcing the HW indices to 0.
> +	 */
> +	uint16_t hw_base;
> +};
> +
> +/*
> + * One dmadev per AE4DMA hardware channel: probe creates AE4DMA_MAX_HW_QUEUES
> + * dmadevs per PCI function, each owning a single HW command queue.
> + */
> +struct ae4dma_dmadev {
> +	void *io_regs;
> +	struct ae4dma_cmd_queue cmd_q; /* single HW queue owned by this dmadev */
> +};
> +
> +extern int ae4dma_pmd_logtype;
> +#define RTE_LOGTYPE_AE4DMA_PMD ae4dma_pmd_logtype
> +
> +#define AE4DMA_PMD_LOG(level, ...) \
> +	RTE_LOG_LINE_PREFIX(level, AE4DMA_PMD, "%s(): ", __func__, __VA_ARGS__)
> +
> +#define AE4DMA_PMD_DEBUG(...)  AE4DMA_PMD_LOG(DEBUG, __VA_ARGS__)
> +#define AE4DMA_PMD_INFO(...)   AE4DMA_PMD_LOG(INFO, __VA_ARGS__)
> +#define AE4DMA_PMD_ERR(...)    AE4DMA_PMD_LOG(ERR, __VA_ARGS__)
> +#define AE4DMA_PMD_WARN(...)   AE4DMA_PMD_LOG(WARNING, __VA_ARGS__)
> +
> +#endif /* _AE4DMA_INTERNAL_H_ */
> diff --git a/drivers/dma/ae4dma/meson.build b/drivers/dma/ae4dma/meson.build
> new file mode 100644
> index 0000000..9f43141
> --- /dev/null
> +++ b/drivers/dma/ae4dma/meson.build
> @@ -0,0 +1,13 @@
> +# SPDX-License-Identifier: BSD-3-Clause
> +# Copyright 2026 Advanced Micro Devices, Inc. All rights reserved.
> +
> +if not is_linux
> +    build = false
> +    reason = 'only supported on Linux'
> +    subdir_done()
> +endif
> +
> +build = dpdk_conf.has('RTE_ARCH_X86')
> +reason = 'only supported on x86'
> +sources = files('ae4dma_dmadev.c')
> +deps += ['bus_pci', 'dmadev']
> diff --git a/drivers/dma/meson.build b/drivers/dma/meson.build
> index e0d94db..c230ac5 100644
> --- a/drivers/dma/meson.build
> +++ b/drivers/dma/meson.build
> @@ -2,6 +2,7 @@
>  # Copyright 2021 HiSilicon Limited
>  
>  drivers = [
> +        'ae4dma',
>          'cnxk',
>          'dpaa',
>          'dpaa2',
> diff --git a/usertools/dpdk-devbind.py b/usertools/dpdk-devbind.py
> index 93f2383..7d09f15 100755
> --- a/usertools/dpdk-devbind.py
> +++ b/usertools/dpdk-devbind.py
> @@ -86,6 +86,9 @@ cnxk_npa = {'Class': '08', 'Vendor': '177d', 'Device': 'a0fb,a0fc',
>  cn9k_ree = {'Class': '08', 'Vendor': '177d', 'Device': 'a0f4',
>              'SVendor': None, 'SDevice': None}
>  
> +amd_ae4dma = {'Class': '08', 'Vendor': '1022', 'Device': '149b',
> +              'SVendor': None, 'SDevice': None}
> +
>  virtio_blk = {'Class': '01', 'Vendor': "1af4", 'Device': '1001,1042',
>                'SVendor': None, 'SDevice': None}
>  
> @@ -95,7 +98,7 @@ cnxk_ml = {'Class': '08', 'Vendor': '177d', 'Device': 'a092',
>  network_devices = [network_class, cavium_pkx, avp_vnic, ifpga_class]
>  baseband_devices = [acceleration_class]
>  crypto_devices = [encryption_class, intel_processor_class]
> -dma_devices = [cnxk_dma, hisilicon_dma,
> +dma_devices = [amd_ae4dma, cnxk_dma, hisilicon_dma,
>                 intel_idxd_gnrd, intel_idxd_dmr, intel_idxd_spr,
>                 intel_ioat_bdw, intel_ioat_icx, intel_ioat_skx,
>                 odm_dma]


^ permalink raw reply

* Re: [PATCH v4 3/4] dma/ae4dma: add data path operations
From: fengchengwen @ 2026-07-07  1:19 UTC (permalink / raw)
  To: Raghavendra Ningoji, dev
  Cc: david.marchand, bruce.richardson, selwin.sebastian,
	bhagyada.modali, rjarry, thomas
In-Reply-To: <20260706115533.2937512-4-raghavendra.ningoji@amd.com>

On 7/6/2026 7:55 PM, Raghavendra Ningoji wrote:
> Implement the dmadev fast path (copy, submit, completed,
> completed_status and burst_capacity) for the AMD AE4DMA PMD and wire
> the entry points through fp_obj in ae4dma_dmadev_create().
> 
> The framework-visible ring index is a free-running 16-bit value; the
> HW ring slot is derived as (hw_base + idx) & (nb_desc - 1), which is
> why the vchan ring depth is kept a power of two. completed() and
> completed_status() always report the last completed ring_idx via
> last_idx, even when no new op is reaped, as required by the dmadev
> API. Only memory-to-memory copy is advertised, so fp_obj->fill is
> left zero-initialised.
> 
> AE4DMA-specific completion handling: the engine reports completion by
> advancing the per-queue read_idx register rather than reliably writing
> a status word back, so the driver uses read_idx as the source of truth
> and only reads the descriptor err_code byte to flag failures.
> 
> Signed-off-by: Raghavendra Ningoji <raghavendra.ningoji@amd.com>
> ---
>  doc/guides/dmadevs/ae4dma.rst      |  24 +++
>  drivers/dma/ae4dma/ae4dma_dmadev.c | 245 +++++++++++++++++++++++++++++
>  2 files changed, 269 insertions(+)
> 
> diff --git a/doc/guides/dmadevs/ae4dma.rst b/doc/guides/dmadevs/ae4dma.rst
> index eeed55c..10446ca 100644
> --- a/doc/guides/dmadevs/ae4dma.rst
> +++ b/doc/guides/dmadevs/ae4dma.rst
> @@ -51,3 +51,27 @@ On probe the PMD performs the following steps for each PCI function:
>    IOVA-contiguous memory, programs the queue base address and ring
>    depth into the per-queue registers, and enables the queue.
>  * Interrupts are masked; completion is polled by the application.
> +
> +Usage
> +-----
> +
> +Once a dmadev has been started, copies are submitted with
> +``rte_dma_copy()`` and completions are reaped with ``rte_dma_completed()``
> +or ``rte_dma_completed_status()``. See the
> +:ref:`Enqueue / Dequeue API <dmadev_enqueue_dequeue>` section of the
> +dmadev library documentation for details.
> +
> +Limitations
> +-----------
> +
> +* Only memory-to-memory copies are supported. Fill, scatter-gather and
> +  any other operation types are not advertised in
> +  ``rte_dma_info::dev_capa``.
> +* The maximum number of descriptors per virtual channel is fixed by
> +  hardware at 32, and the engine reserves one slot to distinguish a full
> +  ring from an empty one, so at most 31 operations can be outstanding
> +  (``rte_dma_burst_capacity()`` returns at most 31). The PMD rounds the
> +  requested ring size up to a power of two and clamps it to 32.
> +* Only a single virtual channel per dmadev is supported; use the 16
> +  per-PCI-function dmadevs to obtain channel-level parallelism.
> +* Interrupt-driven completion is not supported.
> diff --git a/drivers/dma/ae4dma/ae4dma_dmadev.c b/drivers/dma/ae4dma/ae4dma_dmadev.c
> index 9910e11..8fcb0d5 100644
> --- a/drivers/dma/ae4dma/ae4dma_dmadev.c
> +++ b/drivers/dma/ae4dma/ae4dma_dmadev.c
> @@ -162,6 +162,76 @@ ae4dma_dev_close(struct rte_dma_dev *dev)
>  	return 0;
>  }
>  
> +/* Ring the doorbell: publish all enqueued descriptors to the hardware. */
> +static inline void
> +__submit(struct ae4dma_dmadev *ae4dma)
> +{
> +	struct ae4dma_cmd_queue *cmd_q = &ae4dma->cmd_q;
> +	uint16_t nb = cmd_q->qcfg.nb_desc;
> +
> +	if (nb == 0)
> +		return;
> +
> +	/* The HW producer index is the ring slot of the next free descriptor. */
> +	AE4DMA_WRITE_REG(&cmd_q->hwq_regs->write_idx,
> +			(cmd_q->hw_base + cmd_q->next_write) & (nb - 1));
> +	cmd_q->stats.submitted += (uint16_t)(cmd_q->next_write - cmd_q->last_write);
> +	cmd_q->last_write = cmd_q->next_write;
> +}
> +
> +static int
> +ae4dma_submit(void *dev_private, uint16_t vchan __rte_unused)
> +{
> +	struct ae4dma_dmadev *ae4dma = dev_private;
> +
> +	__submit(ae4dma);
> +	return 0;
> +}
> +
> +/* Write a copy descriptor; returns the free-running ring_idx assigned to it. */
> +static inline int
> +__write_desc_copy(void *dev_private, rte_iova_t src, rte_iova_t dst,
> +		uint32_t len, uint64_t flags)
> +{
> +	struct ae4dma_dmadev *ae4dma = dev_private;
> +	struct ae4dma_cmd_queue *cmd_q = &ae4dma->cmd_q;
> +	uint16_t ring_idx = cmd_q->next_write;
> +	uint16_t nb = cmd_q->qcfg.nb_desc;
> +	struct ae4dma_desc *dma_desc;
> +	uint16_t in_flight;
> +
> +	if (nb == 0)
> +		return -EINVAL;
> +
> +	/* Reserve one slot to distinguish full from empty on the ring. */
> +	in_flight = (uint16_t)(cmd_q->next_write - cmd_q->next_read);
> +	if (in_flight >= nb - 1)
> +		return -ENOSPC;
> +
> +	dma_desc = &cmd_q->qbase_desc[(cmd_q->hw_base + ring_idx) & (nb - 1)];
> +	memset(dma_desc, 0, sizeof(*dma_desc));
> +	dma_desc->length = len;
> +	dma_desc->src_hi = upper_32_bits(src);
> +	dma_desc->src_lo = lower_32_bits(src);
> +	dma_desc->dst_hi = upper_32_bits(dst);
> +	dma_desc->dst_lo = lower_32_bits(dst);
> +
> +	cmd_q->next_write++;
> +	if (flags & RTE_DMA_OP_FLAG_SUBMIT)
> +		__submit(ae4dma);
> +
> +	/* dmadev ring_idx is a free-running 16-bit value, not a ring slot. */
> +	return ring_idx;
> +}
> +
> +/* Enqueue a copy operation onto the ae4dma device. */
> +static int
> +ae4dma_enqueue_copy(void *dev_private, uint16_t vchan __rte_unused,
> +		rte_iova_t src, rte_iova_t dst, uint32_t length, uint64_t flags)
> +{
> +	return __write_desc_copy(dev_private, src, dst, length, flags);
> +}
> +
>  static int
>  ae4dma_dev_dump(const struct rte_dma_dev *dev, FILE *f)
>  {
> @@ -192,6 +262,174 @@ ae4dma_dev_dump(const struct rte_dma_dev *dev, FILE *f)
>  	return 0;
>  }
>  
> +/* Translate an AE4DMA descriptor error code to the dmadev status code. */
> +static inline enum rte_dma_status_code
> +__translate_status_ae4dma_to_dma(enum ae4dma_dma_err status)
> +{
> +	switch (status) {
> +	case AE4DMA_DMA_ERR_NO_ERR:
> +		return RTE_DMA_STATUS_SUCCESSFUL;
> +	case AE4DMA_DMA_ERR_INV_LEN:
> +		return RTE_DMA_STATUS_INVALID_LENGTH;
> +	case AE4DMA_DMA_ERR_INV_SRC:
> +		return RTE_DMA_STATUS_INVALID_SRC_ADDR;
> +	case AE4DMA_DMA_ERR_INV_DST:
> +		return RTE_DMA_STATUS_INVALID_DST_ADDR;
> +	default:
> +		return RTE_DMA_STATUS_ERROR_UNKNOWN;
> +	}
> +}
> +
> +/*
> + * Scan the HW queue for completed descriptors (non-blocking).
> + *
> + * The AE4DMA engine signals completion by advancing the per-queue
> + * read_idx register; it does not (reliably) write a status value back
> + * into the descriptor. We therefore use the HW read_idx register as the
> + * source of truth and only inspect the descriptor dw1.err_code byte to
> + * classify each completion as success or failure.
> + *
> + * next_read/next_write are free-running 16-bit indices; the HW ring slot
> + * is ((hw_base + idx) & mask) and the number of in-flight ops is
> + * (next_write - next_read), both relying on nb_desc being a power of two.
> + */
> +static inline uint16_t
> +ae4dma_scan_hwq(struct ae4dma_cmd_queue *cmd_q, uint16_t max_ops,
> +		uint16_t *failed_count)
> +{
> +	volatile struct ae4dma_desc *hw_desc;
> +	uint16_t events_count = 0, fails = 0;
> +	uint16_t nb = cmd_q->qcfg.nb_desc;
> +	uint16_t hw_read_pos, tail_pos;
> +	uint16_t newly_done, in_flight;
> +	uint16_t scan_cap, mask;
> +
> +	*failed_count = 0;
> +	if (nb == 0)
> +		return 0;
> +	mask = nb - 1;
> +
> +	in_flight = (uint16_t)(cmd_q->next_write - cmd_q->next_read);
> +	if (in_flight == 0)
> +		return 0;
> +
> +	/* Descriptors HW has consumed since our last visit: [tail, read). */
> +	hw_read_pos = (uint16_t)(AE4DMA_READ_REG(&cmd_q->hwq_regs->read_idx) & mask);
> +	tail_pos = (uint16_t)((cmd_q->hw_base + cmd_q->next_read) & mask);
> +	newly_done = (uint16_t)((hw_read_pos - tail_pos) & mask);
> +	if (newly_done == 0)
> +		return 0;
> +
> +	scan_cap = newly_done;
> +	if (scan_cap > in_flight)
> +		scan_cap = in_flight;
> +	if (scan_cap > max_ops)
> +		scan_cap = max_ops;
> +
> +	while (events_count < scan_cap) {
> +		uint16_t slot = (cmd_q->hw_base + cmd_q->next_read + events_count) & mask;
> +		uint8_t hw_status, hw_err;
> +
> +		hw_desc = &cmd_q->qbase_desc[slot];
> +		hw_status = hw_desc->dw1.status;
> +		hw_err = hw_desc->dw1.err_code;
> +
> +		/*
> +		 * read_idx advancing is the definitive completion signal.
> +		 * The per-descriptor status byte is informational and may
> +		 * not yet be written when we observe it, so a slot is only
> +		 * a failure if the HW flagged DESC_ERROR or set err_code.
> +		 */
> +		if (hw_status == AE4DMA_DMA_DESC_ERROR ||
> +				hw_err != AE4DMA_DMA_ERR_NO_ERR) {
> +			fails++;
> +			AE4DMA_PMD_WARN("Desc failed: status=%u err=%u",
> +					hw_status, hw_err);
> +		}
> +		cmd_q->status[events_count] = (enum ae4dma_dma_err)hw_err;
> +		events_count++;
> +	}
> +
> +	cmd_q->next_read += events_count;
> +	cmd_q->stats.completed += events_count;
> +	cmd_q->stats.errors += fails;
> +	*failed_count = fails;
> +	return events_count;
> +}
> +
> +/* Returns successful operations count and sets error flag if any errors. */
> +static uint16_t
> +ae4dma_completed(void *dev_private, uint16_t vchan __rte_unused,
> +		const uint16_t max_ops, uint16_t *last_idx, bool *has_error)
> +{
> +	struct ae4dma_dmadev *ae4dma = dev_private;
> +	struct ae4dma_cmd_queue *cmd_q = &ae4dma->cmd_q;
> +	uint16_t err_count = 0;
> +	uint16_t cpl_count;
> +
> +	*has_error = false;
> +	cpl_count = ae4dma_scan_hwq(cmd_q, max_ops, &err_count);
> +
> +	/*
> +	 * last_idx always reports the ring_idx of the most recently completed
> +	 * op, even when this call reaps nothing (matches the dmadev contract
> +	 * and the ioat/idxd drivers).
> +	 */
> +	if (last_idx != NULL)
> +		*last_idx = (uint16_t)(cmd_q->next_read - 1);

1\ the last_idx always non-NULL for driver, so no need for 'if (last_idx != NULL)'
2\ last_idx should be the last success completed index

> +
> +	if (err_count != 0)
> +		*has_error = true;
> +
> +	return cpl_count - err_count;

Consider four reqests, the hardware mark each request as following:
    req1   success
    req2   err
    req3   success
    req4   err

the cpl_count will be 4, and err_count will be 2

It will return 2 in current impl, and last_idx will be the req4's
But in this function, it should return 1, and last_idx should be req1's

Thanks

> +}
> +
> +static uint16_t
> +ae4dma_completed_status(void *dev_private, uint16_t vchan __rte_unused,
> +		uint16_t max_ops, uint16_t *last_idx,
> +		enum rte_dma_status_code *status)
> +{
> +	struct ae4dma_dmadev *ae4dma = dev_private;
> +	struct ae4dma_cmd_queue *cmd_q = &ae4dma->cmd_q;
> +	uint16_t err_count = 0;
> +	uint16_t cpl_count;
> +	uint16_t i;
> +
> +	cpl_count = ae4dma_scan_hwq(cmd_q, max_ops, &err_count);
> +
> +	if (last_idx != NULL)
> +		*last_idx = (uint16_t)(cmd_q->next_read - 1);
> +
> +	if (likely(err_count == 0)) {
> +		for (i = 0; i < cpl_count; i++)
> +			status[i] = RTE_DMA_STATUS_SUCCESSFUL;
> +	} else {
> +		for (i = 0; i < cpl_count; i++)
> +			status[i] = __translate_status_ae4dma_to_dma(cmd_q->status[i]);
> +	}
> +
> +	return cpl_count;
> +}
> +
> +/* Get the remaining capacity of the ring. */
> +static uint16_t
> +ae4dma_burst_capacity(const void *dev_private, uint16_t vchan __rte_unused)
> +{
> +	const struct ae4dma_dmadev *ae4dma = dev_private;
> +	const struct ae4dma_cmd_queue *cmd_q = &ae4dma->cmd_q;
> +	uint16_t nb = cmd_q->qcfg.nb_desc;
> +	uint16_t in_flight;
> +
> +	if (nb == 0)
> +		return 0;
> +
> +	/* One slot reserved to distinguish full from empty. */
> +	in_flight = (uint16_t)(cmd_q->next_write - cmd_q->next_read);
> +	if (in_flight >= nb - 1)
> +		return 0;
> +	return (uint16_t)(nb - 1 - in_flight);
> +}
> +
>  static int
>  ae4dma_stats_get(const struct rte_dma_dev *dev, uint16_t vchan __rte_unused,
>  		struct rte_dma_stats *rte_stats, uint32_t size __rte_unused)
> @@ -339,6 +577,13 @@ ae4dma_dmadev_create(const char *name, struct rte_pci_device *dev, uint8_t qn)
>  	dmadev->fp_obj->dev_private = dmadev->data->dev_private;
>  	dmadev->dev_ops = &ae4dma_dmadev_ops;
>  
> +	dmadev->fp_obj->burst_capacity = ae4dma_burst_capacity;
> +	dmadev->fp_obj->completed = ae4dma_completed;
> +	dmadev->fp_obj->completed_status = ae4dma_completed_status;
> +	dmadev->fp_obj->copy = ae4dma_enqueue_copy;
> +	dmadev->fp_obj->submit = ae4dma_submit;
> +	/* fill capability not advertised: leave fp_obj->fill as zero-initialised. */
> +
>  	ae4dma = dmadev->data->dev_private;
>  
>  	if (ae4dma_add_queue(ae4dma, dev, qn, name) != 0)


^ permalink raw reply

* [PATCH 26.11 4/4] test/cfgfile: test for long lines in file
From: Bruce Richardson @ 2026-07-06 16:23 UTC (permalink / raw)
  To: dev; +Cc: Bruce Richardson, Cristian Dumitrescu
In-Reply-To: <20260706162348.460489-1-bruce.richardson@intel.com>

The test_cfgfiles directory already had a line_too_long.ini file in it,
but this a) did not exceed the line length that the library could manage
and b) was not actually used in any test case.

Fix this by expanding the long line so it does trigger an error, and
adding a test case for it.

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
---
 app/test/test_cfgfile.c                  | 20 ++++++++++++++++++++
 app/test/test_cfgfiles/line_too_long.ini |  2 +-
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/app/test/test_cfgfile.c b/app/test/test_cfgfile.c
index 12da87aa5a..f056fe2d4d 100644
--- a/app/test/test_cfgfile.c
+++ b/app/test/test_cfgfile.c
@@ -376,6 +376,25 @@ test_cfgfile_invalid_key_value_pair(void)
 	return 0;
 }
 
+static int
+test_cfgfile_line_too_long(void)
+{
+	struct rte_cfgfile *cfgfile;
+	char filename[PATH_MAX];
+	int ret;
+
+	ret = make_tmp_file(filename, "line_too_long", line_too_long_ini);
+	TEST_ASSERT_SUCCESS(ret, "Failed to setup temp file");
+
+	cfgfile = rte_cfgfile_load(filename, 0);
+	TEST_ASSERT_NULL(cfgfile, "Expected failure did not occur");
+
+	ret = remove(filename);
+	TEST_ASSERT_SUCCESS(ret, "Failed to remove file");
+
+	return 0;
+}
+
 static int
 test_cfgfile_empty_key_value_pair(void)
 {
@@ -555,6 +574,7 @@ unit_test_suite test_cfgfile_suite  = {
 		TEST_CASE(test_cfgfile_invalid_section_header),
 		TEST_CASE(test_cfgfile_invalid_comment),
 		TEST_CASE(test_cfgfile_invalid_key_value_pair),
+		TEST_CASE(test_cfgfile_line_too_long),
 		TEST_CASE(test_cfgfile_empty_key_value_pair),
 		TEST_CASE(test_cfgfile_missing_section),
 		TEST_CASE(test_cfgfile_global_properties),
diff --git a/app/test/test_cfgfiles/line_too_long.ini b/app/test/test_cfgfiles/line_too_long.ini
index 1dce164838..2683cd2938 100644
--- a/app/test/test_cfgfiles/line_too_long.ini
+++ b/app/test/test_cfgfiles/line_too_long.ini
@@ -1,3 +1,3 @@
 [section1]
 ; this is section 1
-012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
+0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789
-- 
2.53.0


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox