[PATCH v16 00/23] NXP DPAA driver enhancements and fixes

Hemant Agrawal hemant.agrawal at nxp.com
Tue Sep 29 12:45:26 CEST 2026




NXP Confidential
> -----Original Message-----
> From: Stephen Hemminger <stephen at networkplumber.org>
> Sent: 28 September 2026 23:54
> To: Hemant Agrawal <hemant.agrawal at nxp.com>
> Cc: thomas at monjalon.net; dev at dpdk.org
> Subject: Re: [PATCH v16 00/23] NXP DPAA driver enhancements and fixes
> Importance: High
>
> On Mon, 28 Sep 2026 12:28:26 +0530
> Hemant Agrawal <hemant.agrawal at nxp.com> wrote:
>
> > This series collects a set of fixes and enhancements for the NXP DPAA
> > bus, mempool, dma, crypto and net drivers targeting 26.11.
> >
> > It includes memory-leak and resource-cleanup fixes on the device
> > remove/close paths, more robust frame queue and congestion-group
> > shutdown, secondary-process safety guards, BPID and cgrid lifecycle
> >
> > It includes memory-leak and resource-cleanup fixes on the device
> > remove/close paths, more robust frame queue and congestion-group
> > shutdown, secondary-process safety guards, BPID and cgrid lifecycle
> > handling, and several new features: offline (O/H) port device support,
> > enhanced virtual storage profile (VSP) port support, fmcless Rx queue
> > configuration via devargs, Rx/Tx taildrop threshold devargs, non
> > fmX-macY shared Ethernet naming, and DMA scatter-gather and
> > errata-workaround devargs. Documentation and release notes are updated
> > accordingly.
> >
> > v16:
> > * rebased on main
>
> More AI review feedback.
>
> Subject: Re: [PATCH v16 00/23] NXP DPAA driver updates
>
> v16 applies cleanly to main (edd57b2).  Every commit builds with
> -Dwerror=true: gcc 13.3 on x86, covering bus/dpaa, common/dpaax,
> mempool/dpaa, net/dpaa, crypto/dpaa_sec, dma/dpaa and event/dpaa.
> dma/dpaa was also built with RTE_DMA_DPAA_ERRATA_ERR050757 defined.
> Not built for arm64.
>
> The v14 errors are fixed: bman_release_fast() no longer publishes stack bytes,
> and dpaa_ol_remove() no longer double frees dev_private.
> Also resolved: fmbm_tfrc is exposed and the BMI static_assert is exact, the
> unused VSP fields are gone, dma/dpaa rejects secondary probe, and
> check_fd() is race free.  The taildrop getenv() fallback is now justified in the
> commit message; dropping that item.
>
> What remains blocking: the O/H port in patch 21 cannot be enabled or
> configured as submitted, and the new mempool destructor in patch 13 frees
> EAL memory at process exit.
>
> Errors
> ------
>
> Patch 13/23: drivers: release DPAA bpid on driver destructor
>
>   dpaa_mpool_finish() is an RTE_FINI destructor that does
>
>       rte_free(rte_dpaa_bpid_info);
>
>   The commit message says the destructor must not touch bman_pool
>   because EAL memory may already be gone, and then frees EAL memory.
>   rte_eal_cleanup() calls rte_eal_memory_detach() before returning
>   ("after this point, any DPDK pointers will become dangling").  Any
>   application that calls rte_eal_cleanup() before exit, testpmd
>   included, will rte_free() unmapped memory in this destructor.
>
>   It is also wrong in a secondary.  There rte_dpaa_bpid_info is not a
>   local allocation; the Rx path installs the primary's shared array:
>
>       rte_dpaa_bpid_info = fq->bp_array;   /* dpaa_rxtx.c:924, :1449 */
>
>   A secondary that exits frees the primary's live BPID table.
>
>   Releasing the BPIDs from the static flag table is fine.  Drop the
>   rte_free() from the destructor.
>
dropped `rte_free(rte_dpaa_bpid_info)` from the RTE_FINI destructor. Right on both counts - `rte_eal_cleanup()` detaches EAL memory before destructors run, and in a secondary the array is the primary's (installed from `fq->bp_array`). BPID release from the static flag table is kept.

> Patch 21/23: drivers: add offline (O/H) port device support
>
>   drv_oldev can never be enabled.  dpaa_bus_parse_bus_args() does
>
>       RTE_EAL_DEVARGS_FOREACH("dpaa", devargs)
>
>   but the bus is registered as RTE_REGISTER_BUS(dpaa_bus, ...), so its
>   name is "dpaa_bus".  rte_devargs_next() compares against
>   da->bus->name, never matches, and oldev_enabled stays 0.  The dpaa.rst
>   example "bus=dpaa,drv_oldev=1" is worse: rte_devargs_layers_parse()
>   fails with "Could not find bus" and EAL init aborts.
>
>   Even with that fixed, drv_bh_port cannot reach the device.  The OL
>   block in dpaa_create_device_list() never sets dev->device.devargs,
>   unlike the ETH, SEC and QDMA blocks, which use
>   rte_bus_find_devargs().  A lookup would not match anyway:
>   rte_dpaa_bus_parse() only accepts fmX-macY, fmX-ohY, fmX-onicY and
>   dpaa_sec-N, and the device is named "oldev1".  So
>   dpaa_ol_get_bh_port_name() always returns 0, and
>   dpaa_ol_tx_queue_setup() fails with -EINVAL once Rx is set up.
>
>   This needs to be tested end to end.

`drv_oldev` is now usable - bus devargs matched against `rte_dpaa_bus.name` ("dpaa_bus"), OL device gets devargs via `rte_bus_find_devargs()`, `rte_dpaa_bus_parse()` accepts `oldevN`, dpaa.rst examples corrected.

>
> Warnings
> --------
>
> Patch 05/23: bus/dpaa: scan max BPID from DTS
>
>   bman_pool_max = start + count is taken from fsl,bpid-range without a
>   bound.  bman_create_portal() does
>
>       u8 bpid = 0;
>       while (bpid < bman_pool_max) {
>               bm_isr_bscn_mask(p, bpid, 0);
>               bpid++;
>       }
>
>   A value above 255 never terminates.  A value above 64 writes past
>   BM_REG_SCN(1); bm_isr_bscn_mask() only covers bpid 0..63, and struct
>   bman_depletion is 64 bits.  Clamp to 64 and reject count == 0.
>
Fixed

> Patch 08/23: drivers: add DPAA cgrid cleanup support
>
>   The CGR created for a queue whose FQ init fails is still leaked.
>   dpaa_rx_queue_init() and dpaa_tx_queue_init() call qman_create_cgr()
>   and then qman_init_fq().  If qman_init_fq() fails they return an
>   error, and nb_rx_cgr / nb_tx_cgr is only incremented on success.
>   The error path then skips qman_delete_cgr() for that entry, and
>   rte_free(cgr_rx) leaves it linked on cgr_cbs.  That is the same
>   dangling pointer this patch sets out to fix.  Count the CGR when
>   qman_create_cgr() succeeds, or delete it in the helper on failure.
>
>   qman_pending_fq_by_cgrid() returns -ERANGE ("none left") whenever the
>   CGR byte count is zero.  A scheduled FQ with CGE set and a matching
>   cgid is a member whether or not it holds frames.  So an empty stale
>   FQ survives, and its CGRID is deleted and released while still
>   referenced, contrary to the rule stated in the commit message.
>   Close is not a fast path; scan unconditionally there.
>
fixed

> Patch 09/23: bus/dpaa: improve FQ shutdown with channel validation
>
>   The commit message describes things not in the diff.  The
>   pool-channel-range parsing is added here, not "in an earlier patch".
>   Nothing here cleans up CGRID or other queue parameters on shutdown.
>   The base code has no portal affinity check for pool channels to
>   remove.
>
>   The FQRN drain loop is unbounded:
>
>       do {
>               qm_dqrr_drain_nomatch(&p->p);
>               found_fqrn = qm_mr_drain(&p->p, FQRN);
>               cpu_relax();
>       } while (!found_fqrn);
>
>   With QM_SDQCR_CHANNELS_DEDICATED the portal only dequeues its own
>   channel.  If the FQ is scheduled on another portal's dedicated
>   channel, FQRN never arrives and this spins forever.  That is
>   pre-existing, but patch 08 now calls qman_shutdown_fq_by_fqid()
>   (qp == NULL, so the caller's affine portal) on stale FQs left by a
>   previous run.  Push-mode Rx queues are exactly FQs on another
>   portal's dedicated channel.  Return -EBUSY when a dedicated channel
>   is not p->config->channel, or bound the loop.
>
fixed
> Patch 14/23: dma/dpaa: add devargs for SG and errata workaround
>
>   RTE_PMD_REGISTER_PARAM_STRING() is invoked with an #ifdef inside its
>   argument list.  Directives inside macro arguments are undefined
>   behaviour (C11 6.10.3p11).  GCC accepts it; other compilers need
>   not.  Build the string with a separate macro defined under the
>   #ifdef.
>
Fixed

> Patch 20/23: net/dpaa: enhance VSP port support
>
>   dpaa_eth_rx_queue_setup() now writes
>
>       dpaa_intf->vsp[vsp_id].vsp_bp[0] =
> DPAA_MEMPOOL_TO_POOL_INFO(mp);
>
>   before any bound check.  dpaa_port_vsp_update() then reads
>   vsp[vsp_id].vsp_handle; only dpaa_port_vsp_configure() checks
>   vsp_id < DPAA_VSP_PROFILE_MAX_NUM.  vsp_id comes from the FMC
>   direct_relative_profile_id.  The check in update was also loosened
>   from vsp_id >= num_profiles to vsp_id >= base_profile_id +
>   num_profiles, both of which come from the DTS vsp-window.  Check
>   against DPAA_VSP_PROFILE_MAX_NUM before first use.
>
>   The commit message covers the ONIC port type and the cleanup
>   signature.  It does not mention several other changes:
>
>   - struct dpaa_if_vsp replaces the per-profile arrays.
>   - dpaa_eth_dev_stop() changes for ONIC.
>   - dpaa_port_vsp_update() now returns -EINVAL where it returned 0.
>   - The same-bpid shortcut is removed, so every Rx queue setup frees
>     and reconfigures the VSP.

fixed
>
> Patch 21/23: drivers: add offline (O/H) port device support
>
>   dpaa_ol_tx_queue_setup() silently skips ASK_CTRL_SET_DPDK_INFO when
>   Rx has not been set up yet:
>
>       if (dpaa_intf->bp_info == NULL || dpaa_intf->rx_queues == NULL)
>               return 0;
>
>   testpmd start_port() sets up Tx queues before Rx, so on first start
>   the kernel is never told the FQs.  ethdev does not order queue
>   setup.  Issue the ioctl from dev_start, where both are known.
>
>   dpaa_ol_probe() has no process-type handling.  A secondary runs
>   dpaa_oldev_init(), creating dynamic FQs and issuing ioctls against
>   state the primary owns.  Either attach with
>   rte_eth_dev_attach_secondary() or reject the secondary as patch 06
>   does for dma/dpaa.  As written, the secondary branch in
>   dpaa_ol_remove() is unreachable.
>
fixed
> Info
> ----
>
> Patch 05/23: "if (!bman_ip_rev)" is dead now that the else branch
>   sets BMAN_REV21.
>
Fixed

> Patch 07/23: The stated motivation is push-mode Rx queue shutdown, but
>   nothing in the series shuts down a net/dpaa Rx queue by descriptor.
>   The only callers of qman_shutdown_fq(fq) are dpaa_sec and oldev.
>
> Patch 08/23: __rte_internal appears twice on
>   qman_pending_fq_by_cgrid().  RTE_EXPORT_INTERNAL_SYMBOL(
>   qman_release_fqid_range) is added here, but its first user outside
>   the bus is patch 22.
>
> Patch 12/23: dpaa_port_fmc_port_parse() parses the name before the
>   OH check, which does not use the result.  It logs DPAA_PMD_ERR for
>   any port name without "MAC/" or "OFFLINE/", although the caller
>   treats that as "not this port".  It also logs DPAA_PMD_INFO for
>   every port on every probe.  Both should be DEBUG.
>
> Patch 13/23: RTE_PRIORITY_104 is a driver-local define in the RTE_
>   namespace.
>
> Patch 21/23:
>   - rte_pmd_dpaa_ol_*() and ask_set_fq_info() return the raw ioctl()
>     result (-1) on failure, mixed with -ENODEV from check_fd().
>     Return -errno.
>   - rte_dpaa_bus_oldev_enabled() is exported and has no users.
>   - dpaa_ol_devops can be const.
>   - The meson.build copyright changes to 2018-2021 in a 2026 patch.
>   - rte_pmd_dpaa_oldev.h is not in doc/api/doxy-api-index.md and has
>     no extern "C" guard.
>
> Patch 23/23:
>   - The FMCLESS default Rx queue count change in patch 16
>     (rte_lcore_count() to DPAA_MAX_NUM_PCD_QUEUES) is user visible and
>     not in the release notes.
>   - The new rte_pmd_dpaa_ol_* API is not listed.
>   - Five top-level entries for one driver family; fold them into one
>     "Updated NXP DPAA drivers" entry with sub-bullets.
>
> Pre-existing, not introduced here: in dpaa_dev_init() the "FMC initializes
> failed" path does goto free_rx with ret still 0, so probe succeeds with no Rx
> queues.


More information about the dev mailing list