DPDK-dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] eal: fix function versioning with LTO
@ 2026-06-02 22:57 Stephen Hemminger
  2026-06-03 10:01 ` David Marchand
  0 siblings, 1 reply; 5+ messages in thread
From: Stephen Hemminger @ 2026-06-02 22:57 UTC (permalink / raw)
  To: dev; +Cc: Stephen Hemminger, stable, David Marchand

When using function versioning and building with Link Time Optimization,
the compiler does not see the __asm__ annotation of symbols and
therefore thinks there are two versions of the same symbol.

The fix is to use compiler symver attribute on the function which
was added in GCC 10. Keep the older method for backward compatibility
with older compilers.

Bugzilla ID: 1949
Fixes: e30e194c4d06 ("eal: rework function versioning macros")
Cc: stable@dpdk.org

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
---
 lib/eal/common/eal_export.h | 46 +++++++++++++++++++++++++++----------
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/lib/eal/common/eal_export.h b/lib/eal/common/eal_export.h
index 7e47d34064..1318e6278d 100644
--- a/lib/eal/common/eal_export.h
+++ b/lib/eal/common/eal_export.h
@@ -30,39 +30,61 @@
  * new functionality, behavior, etc.  When that occurs, it is desirable to
  * allow for backwards compatibility for a time with older binaries that are
  * dynamically linked to the dpdk.
+ *
+ * RTE_VERSION_SYMBOL
+ * Create a symbol version table entry binding symbol <name>@DPDK_<ver> to the internal
+ * function name <name>_v<ver>.
+ *
+ * RTE_VERSION_EXPERIMENTAL_SYMBOL similar to RTE_VERSION_SYMBOL but for experimental API symbols.
+ * This is mainly used for keeping compatibility for symbols that get promoted to stable ABI.
+ *
+ * RTE_DEFAULT_SYMBOL
+ * Create a symbol version entry instructing the linker to bind references to
+ * symbol <name> to the internal symbol <name>_v<ver>.
  */
 
 #ifdef RTE_BUILD_SHARED_LIB
 
-/*
- * Create a symbol version table entry binding symbol <name>@DPDK_<ver> to the internal
- * function name <name>_v<ver>.
- */
+/* Prefer the compiler method of versioning which uses attributes */
+#if  __has_attribute(symver)
+
+#define RTE_VERSION_SYMBOL(ver, type, name, args) VERSIONING_WARN	\
+	__attribute__((__symver__(RTE_STR(name) "@DPDK_" RTE_STR(ver)))) \
+	type name ## _v ## ver args;					\
+	type name ## _v ## ver args
+
+#define RTE_VERSION_EXPERIMENTAL_SYMBOL(type, name, args) VERSIONING_WARN \
+	__attribute__((__symver__(RTE_STR(name) "@EXPERIMENTAL")))	\
+	type name ## _exp args;						\
+	type name ## _exp args
+
+#define RTE_DEFAULT_SYMBOL(ver, type, name, args) VERSIONING_WARN	\
+	__attribute__((__symver__(RTE_STR(name) "@@DPDK_" RTE_STR(ver)))) \
+	type name ## _v ## ver args;					\
+	type name ## _v ## ver args
+#else /* !__has_attribute(symver) */
+
+/* Use asm tag to create symbol table entry */
 #define RTE_VERSION_SYMBOL(ver, type, name, args) VERSIONING_WARN \
 __asm__(".symver " RTE_STR(name) "_v" RTE_STR(ver) ", " RTE_STR(name) "@DPDK_" RTE_STR(ver)); \
 __rte_used type name ## _v ## ver args; \
 type name ## _v ## ver args
 
-/*
- * Similar to RTE_VERSION_SYMBOL but for experimental API symbols.
- * This is mainly used for keeping compatibility for symbols that get promoted to stable ABI.
- */
 #define RTE_VERSION_EXPERIMENTAL_SYMBOL(type, name, args) VERSIONING_WARN \
 __asm__(".symver " RTE_STR(name) "_exp, " RTE_STR(name) "@EXPERIMENTAL") \
 __rte_used type name ## _exp args; \
 type name ## _exp args
 
-/*
- * Create a symbol version entry instructing the linker to bind references to
- * symbol <name> to the internal symbol <name>_v<ver>.
- */
 #define RTE_DEFAULT_SYMBOL(ver, type, name, args) VERSIONING_WARN \
 __asm__(".symver " RTE_STR(name) "_v" RTE_STR(ver) ", " RTE_STR(name) "@@DPDK_" RTE_STR(ver)); \
 __rte_used type name ## _v ## ver args; \
 type name ## _v ## ver args
 
+#endif /* __has_attribute(symver) */
+
 #else /* !RTE_BUILD_SHARED_LIB */
 
+/* static library does not have versioned symbols */
 #define RTE_VERSION_SYMBOL(ver, type, name, args) VERSIONING_WARN \
 type name ## _v ## ver args; \
 type name ## _v ## ver args
-- 
2.53.0


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] eal: fix function versioning with LTO
  2026-06-02 22:57 [PATCH] eal: fix function versioning with LTO Stephen Hemminger
@ 2026-06-03 10:01 ` David Marchand
  2026-06-03 15:24   ` Stephen Hemminger
  2026-06-03 15:53   ` Stephen Hemminger
  0 siblings, 2 replies; 5+ messages in thread
From: David Marchand @ 2026-06-03 10:01 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, stable, Thomas Monjalon

Hello,

On Wed, 3 Jun 2026 at 00:57, Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> When using function versioning and building with Link Time Optimization,
> the compiler does not see the __asm__ annotation of symbols and
> therefore thinks there are two versions of the same symbol.
>
> The fix is to use compiler symver attribute on the function which
> was added in GCC 10. Keep the older method for backward compatibility
> with older compilers.
>
> Bugzilla ID: 1949
> Fixes: e30e194c4d06 ("eal: rework function versioning macros")

We never used the symver stuff, so it seems unlikely the issue was
introduced with this rework.

The fact that clang does not support this attribute is a concern.


> Cc: stable@dpdk.org

Why do we need to backport?

LTO is kind of experimental, so it seems good enough to reply "not
expected to work in older LTS" if someone reported an issue.

And in practice, no LTS release call the versioning macros, since a
LTS drops all compatibility.

> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>

I would like to reproduce, but I can't build main with LTO.
What patches did you apply locally to avoid warnings on the hash library?


-- 
David Marchand


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] eal: fix function versioning with LTO
  2026-06-03 10:01 ` David Marchand
@ 2026-06-03 15:24   ` Stephen Hemminger
  2026-06-03 15:53   ` Stephen Hemminger
  1 sibling, 0 replies; 5+ messages in thread
From: Stephen Hemminger @ 2026-06-03 15:24 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, stable, Thomas Monjalon

On Wed, 3 Jun 2026 12:01:48 +0200
David Marchand <david.marchand@redhat.com> wrote:

> Hello,
> 
> On Wed, 3 Jun 2026 at 00:57, Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> >
> > When using function versioning and building with Link Time Optimization,
> > the compiler does not see the __asm__ annotation of symbols and
> > therefore thinks there are two versions of the same symbol.
> >
> > The fix is to use compiler symver attribute on the function which
> > was added in GCC 10. Keep the older method for backward compatibility
> > with older compilers.
> >
> > Bugzilla ID: 1949
> > Fixes: e30e194c4d06 ("eal: rework function versioning macros")  
> 
> We never used the symver stuff, so it seems unlikely the issue was
> introduced with this rework.
> 
> The fact that clang does not support this attribute is a concern.
> 
> 
> > Cc: stable@dpdk.org  
> 
> Why do we need to backport?
> 
> LTO is kind of experimental, so it seems good enough to reply "not
> expected to work in older LTS" if someone reported an issue.
> 
> And in practice, no LTS release call the versioning macros, since a
> LTS drops all compatibility.
> 
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>  
> 
> I would like to reproduce, but I can't build main with LTO.
> What patches did you apply locally to avoid warnings on the hash library?
I get no warnings from current main with GCC 15

I was doing test build of net-next with this patch:
https://patchwork.dpdk.org/project/dpdk/patch/20260529000748.275863-1-stephen@networkplumber.org/

The LTO build is done by:
 $ meson setup build-lto -Db_lto=true

The result was:
cc  -o lib/librte_ethdev.so.26.2 lib/librte_ethdev.so.26.2.p/ethdev_ethdev_driver.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_private.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_profile.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_trace_points.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_class_eth.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_ethdev.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_ethdev_cman.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_ethdev_telemetry.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_flow.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_mtr.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_tm.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_telemetry.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_common.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_8079.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_8472.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_8636.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_linux_ethtool.c.o -flto=auto -Wl,--as-needed -Wl,--no-undefined -Wl,-O1 -shared -fPIC -Wl,-soname,librte_ethdev.so.26 -Wl,--no-as-needed -Wl,--undefined-version -pthread -Wl,--start-group -lm -ldl -lnuma -lfdt '-Wl,-rpath,$ORIGIN/' lib/librte_eal.so.26.2 lib/librte_kvargs.so.26.2 lib/librte_log.so.26.2 lib/librte_telemetry.so.26.2 lib/librte_argparse.so.26.2 lib/librte_net.so.26.2 lib/librte_mbuf.so.26.2 lib/librte_mempool.so.26.2 lib/librte_ring.so.26.2 lib/librte_meter.so.26.2 -Wl,--version-script=/home/shemminger/DPDK/lto/build-lto/lib/ethdev_exports.map /usr/lib/x86_64-linux-gnu/libbsd.so /usr/lib/x86_64-linux-gnu/libarchive.so -Wl,--end-group
/tmp/cc3RQyqL.s: Assembler messages:
/tmp

Fed the result into Claude, and it said "yeah, I see the same problem on
other projects, the answer is ...". With a little searching found an example
in Gentoo https://github.com/InBetweenNames/gentooLTO/pull/458

With this change symbol versioning with LTO works on both GCC >= 10 and Clang.
Clang LTO doesn't have the attribute, but it also doesn't have the same LTO issue.


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] eal: fix function versioning with LTO
  2026-06-03 10:01 ` David Marchand
  2026-06-03 15:24   ` Stephen Hemminger
@ 2026-06-03 15:53   ` Stephen Hemminger
  2026-06-04  7:50     ` David Marchand
  1 sibling, 1 reply; 5+ messages in thread
From: Stephen Hemminger @ 2026-06-03 15:53 UTC (permalink / raw)
  To: David Marchand; +Cc: dev, stable, Thomas Monjalon

On Wed, 3 Jun 2026 12:01:48 +0200
David Marchand <david.marchand@redhat.com> wrote:

> Hello,
> 
> On Wed, 3 Jun 2026 at 00:57, Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> >
> > When using function versioning and building with Link Time Optimization,
> > the compiler does not see the __asm__ annotation of symbols and
> > therefore thinks there are two versions of the same symbol.
> >
> > The fix is to use compiler symver attribute on the function which
> > was added in GCC 10. Keep the older method for backward compatibility
> > with older compilers.
> >
> > Bugzilla ID: 1949
> > Fixes: e30e194c4d06 ("eal: rework function versioning macros")  
> 
> We never used the symver stuff, so it seems unlikely the issue was
> introduced with this rework.
> 
> The fact that clang does not support this attribute is a concern.

Clang doesn't have this problem. It works as is.

> > Cc: stable@dpdk.org  
> 
> Why do we need to backport?

Well LTO has worked for a long time, it is not experimental just
not commonly done since it takes so long to build.

We were doing it years ago at MSFT.

> 
> LTO is kind of experimental, so it seems good enough to reply "not
> expected to work in older LTS" if someone reported an issue.
> 
> And in practice, no LTS release call the versioning macros, since a
> LTS drops all compatibility.
> 
> > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>  
> 
> I would like to reproduce, but I can't build main with LTO.
> What patches did you apply locally to avoid warnings on the hash library?
I use Debian testing and GCC 15 but shows up on older versions as well
I get no warnings building main

 $ git am ~/Downloads/v2-ethdev-add-buffer-size-parameter-to-rte_eth_dev_get_name_by_port.patch
 $ meson setup build-lto -Db_lto=true
 $ ninja -C build-lto
ninja: Entering directory `build-lto'
[620/3781] Linking target lib/librte_ethdev.so.26.2
FAILED: [code=1] lib/librte_ethdev.so.26.2 
cc  -o lib/librte_ethdev.so.26.2 lib/librte_ethdev.so.26.2.p/ethdev_ethdev_driver.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_private.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_profile.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_trace_points.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_class_eth.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_ethdev.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_ethdev_cman.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_ethdev_telemetry.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_flow.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_mtr.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_tm.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_telemetry.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_common.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_8079.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_8472.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_8636.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_linux_ethtool.c.o -flto=auto -Wl,--as-needed -Wl,--no-undefined -Wl,-O1 -shared -fPIC -Wl,-soname,librte_ethdev.so.26 -Wl,--no-as-needed -Wl,--undefined-version -pthread -Wl,--start-group -lm -ldl -lnuma -lfdt '-Wl,-rpath,$ORIGIN/' lib/librte_eal.so.26.2 lib/librte_kvargs.so.26.2 lib/librte_log.so.26.2 lib/librte_telemetry.so.26.2 lib/librte_argparse.so.26.2 lib/librte_net.so.26.2 lib/librte_mbuf.so.26.2 lib/librte_mempool.so.26.2 lib/librte_ring.so.26.2 lib/librte_meter.so.26.2 -Wl,--version-script=/home/shemminger/DPDK/lto/build-lto/lib/ethdev_exports.map /usr/lib/x86_64-linux-gnu/libbsd.so /usr/lib/x86_64-linux-gnu/libarchive.so -Wl,--end-group
/tmp/cc3RQyqL.s: Assembler messages:
/tmp/cc3RQyqL.s: Error: invalid attempt to declare external version name as default in symbol `rte_eth_dev_get_name_by_port@@DPDK_27'
make: *** [/tmp/ccVzgiZ2.mk:2: /tmp/ccTlGfA9.ltrans0.ltrans.o] Error 1
make: *** Waiting for unfinished jobs....
lto-wrapper: fatal error: make returned 2 exit status
compilation terminated.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] eal: fix function versioning with LTO
  2026-06-03 15:53   ` Stephen Hemminger
@ 2026-06-04  7:50     ` David Marchand
  0 siblings, 0 replies; 5+ messages in thread
From: David Marchand @ 2026-06-04  7:50 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev, stable, Thomas Monjalon

On Wed, 3 Jun 2026 at 17:56, Stephen Hemminger
<stephen@networkplumber.org> wrote:
>
> On Wed, 3 Jun 2026 12:01:48 +0200
> David Marchand <david.marchand@redhat.com> wrote:
>
> > Hello,
> >
> > On Wed, 3 Jun 2026 at 00:57, Stephen Hemminger
> > <stephen@networkplumber.org> wrote:
> > >
> > > When using function versioning and building with Link Time Optimization,
> > > the compiler does not see the __asm__ annotation of symbols and
> > > therefore thinks there are two versions of the same symbol.
> > >
> > > The fix is to use compiler symver attribute on the function which
> > > was added in GCC 10. Keep the older method for backward compatibility
> > > with older compilers.
> > >
> > > Bugzilla ID: 1949
> > > Fixes: e30e194c4d06 ("eal: rework function versioning macros")
> >
> > We never used the symver stuff, so it seems unlikely the issue was
> > introduced with this rework.
> >
> > The fact that clang does not support this attribute is a concern.
>
> Clang doesn't have this problem. It works as is.

The Fixes: tag is wrong regardless.
The issue is probably present since introduction of the versioning
macros, or introduction of LTO in DPDK (not sure which came first).


> > > Cc: stable@dpdk.org
> >
> > Why do we need to backport?
>
> Well LTO has worked for a long time, it is not experimental just
> not commonly done since it takes so long to build.
>
> We were doing it years ago at MSFT.

Well, sorry, but every time I enable LTO, I end up with some warnings somewhere.
I don't think I am doing stuff really exotic though.

Looking at bugzilla, we had various fixes for LTO over the years.
We still have one open bz btw: https://bugs.dpdk.org/show_bug.cgi?id=1709

Hence my feeling this feature is not something used by many people around.
And without a CI, we will keep on having to fix bugs/issues.


> > LTO is kind of experimental, so it seems good enough to reply "not
> > expected to work in older LTS" if someone reported an issue.
> >
> > And in practice, no LTS release call the versioning macros, since a
> > LTS drops all compatibility.

Just to be clear, we don't need fixing the macros in LTS: every time
we prepare a LTS rc0, we drop any kind of symbol compat.


> >
> > > Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> >
> > I would like to reproduce, but I can't build main with LTO.
> > What patches did you apply locally to avoid warnings on the hash library?
> I use Debian testing and GCC 15 but shows up on older versions as well
> I get no warnings building main

Building from scratch, I do avoid the warnings I hit yesterday.

The fix looks correct, my problem is with the form.
Fixes: tags accuracy is important.
And I prefer we stick to "It is not broken, don't fix it".


Thanks.


>
>  $ git am ~/Downloads/v2-ethdev-add-buffer-size-parameter-to-rte_eth_dev_get_name_by_port.patch
>  $ meson setup build-lto -Db_lto=true
>  $ ninja -C build-lto
> ninja: Entering directory `build-lto'
> [620/3781] Linking target lib/librte_ethdev.so.26.2
> FAILED: [code=1] lib/librte_ethdev.so.26.2
> cc  -o lib/librte_ethdev.so.26.2 lib/librte_ethdev.so.26.2.p/ethdev_ethdev_driver.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_private.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_profile.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_trace_points.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_class_eth.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_ethdev.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_ethdev_cman.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_ethdev_telemetry.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_flow.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_mtr.c.o lib/librte_ethdev.so.26.2.p/ethdev_rte_tm.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_telemetry.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_common.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_8079.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_8472.c.o lib/librte_ethdev.so.26.2.p/ethdev_sff_8636.c.o lib/librte_ethdev.so.26.2.p/ethdev_ethdev_linux_ethtool.c.o -flto=auto -Wl,--as-needed -Wl,--no-undefined -Wl,-O1 -shared -fPIC -Wl,-soname,librte_ethdev.so.26 -Wl,--no-as-needed -Wl,--undefined-version -pthread -Wl,--start-group -lm -ldl -lnuma -lfdt '-Wl,-rpath,$ORIGIN/' lib/librte_eal.so.26.2 lib/librte_kvargs.so.26.2 lib/librte_log.so.26.2 lib/librte_telemetry.so.26.2 lib/librte_argparse.so.26.2 lib/librte_net.so.26.2 lib/librte_mbuf.so.26.2 lib/librte_mempool.so.26.2 lib/librte_ring.so.26.2 lib/librte_meter.so.26.2 -Wl,--version-script=/home/shemminger/DPDK/lto/build-lto/lib/ethdev_exports.map /usr/lib/x86_64-linux-gnu/libbsd.so /usr/lib/x86_64-linux-gnu/libarchive.so -Wl,--end-group
> /tmp/cc3RQyqL.s: Assembler messages:
> /tmp/cc3RQyqL.s: Error: invalid attempt to declare external version name as default in symbol `rte_eth_dev_get_name_by_port@@DPDK_27'
> make: *** [/tmp/ccVzgiZ2.mk:2: /tmp/ccTlGfA9.ltrans0.ltrans.o] Error 1
> make: *** Waiting for unfinished jobs....
> lto-wrapper: fatal error: make returned 2 exit status
> compilation terminated.
>


-- 
David Marchand


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-06-04  7:50 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-02 22:57 [PATCH] eal: fix function versioning with LTO Stephen Hemminger
2026-06-03 10:01 ` David Marchand
2026-06-03 15:24   ` Stephen Hemminger
2026-06-03 15:53   ` Stephen Hemminger
2026-06-04  7:50     ` David Marchand

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