On Sun, 7 Jun 2026 at 17:04, Stephen Hemminger
<[email protected]> wrote:
>
> Libraries that use EAL_REGISTER_TAILQ insert a pointer to a static
> struct rte_tailq_elem into the process-local tailq list via a
> constructor, but have no matching destructor. When such a library
> is loaded as a dependency of a plugin via dlopen() and later
> unloaded via dlclose(), the list retains a dangling pointer to the
> now-unmapped static. Reloading the plugin crashes in
> rte_eal_tailq_local_register() when it traverses the stale entry.
>
> Add rte_eal_tailq_unregister() and extend the EAL_REGISTER_TAILQ
> macro to emit an RTE_FINI destructor alongside the existing
> RTE_INIT constructor. Every library that uses the macro
> automatically gets both sides; no per-library changes are needed.
>
> Bugzilla ID: 1081
> Fixes: 873a61c7526b ("tailq: introduce dynamic register system")
> Cc: [email protected]
>
> Signed-off-by: Stephen Hemminger <[email protected]>
> ---
>  lib/eal/common/eal_common_tailqs.c |  8 ++++++++
>  lib/eal/include/rte_tailq.h        | 17 +++++++++++++++++
>  2 files changed, 25 insertions(+)
>
> diff --git a/lib/eal/common/eal_common_tailqs.c 
> b/lib/eal/common/eal_common_tailqs.c
> index c581f43b6f..714f91d0ec 100644
> --- a/lib/eal/common/eal_common_tailqs.c
> +++ b/lib/eal/common/eal_common_tailqs.c
> @@ -148,6 +148,14 @@ rte_eal_tailq_register(struct rte_tailq_elem *t)
>         return -1;
>  }
>
> +RTE_EXPORT_SYMBOL(rte_eal_tailq_unregister)
> +void
> +rte_eal_tailq_unregister(struct rte_tailq_elem *t)
> +{
> +       TAILQ_REMOVE(&rte_tailq_elem_head, t, next);
> +       t->head = NULL;
> +}

This cleans up the local storage which is good, but it leaves an entry
reserved in the mcfg->tailq_head[] array.


-- 
David Marchand

Reply via email to