Building on armel and other old 32 bit architectures has undefined references to __atomic_store_8
Hi, I'm not sure if armel and others are still a valid target you care about. Anyway building fio 3.41 for Debian on armel failed with:
/usr/bin/ld: backend.o: in function `log_inflight':
./backend.c:945:(.text+0x159c): undefined reference to `__atomic_store_8'
/usr/bin/ld: ./backend.c:949:(.text+0x15d4): undefined reference to `__atomic_store_8'
/usr/bin/ld: backend.o: in function `invalidate_inflight':
./backend.c:986:(.text+0x1704): undefined reference to `__atomic_store_8'
gcc -Wl,-z,defs -Wl,-z,relro -Wl,-z,now -Wl,-z,defs -Wl,-z,relro -Wl,-z,now -rdynamic -o t/fio-verify-state t/verify-state.o t/log.o crc/crc32c.o crc/crc32c-intel.o crc/crc32c-arm64.o t/debug.o -lnuma -libverbs -lnl-3 -lnl-route-3 -libverbs -lnl-3 -lnl-route-3 -lz -lm -lnfs -lgnutls -laio -lpthread -ldl -lnbd -laio -libverbs -lrdmacm
/usr/bin/ld: verify.o: in function `get_all_io_list':
./verify.c:1680:(.text+0x5464): undefined reference to `__atomic_load_8'
/usr/bin/ld: ./verify.c:1683:(.text+0x548c): undefined reference to `__atomic_load_8'
collect2: error: ld returned 1 exit status
As far as I understood the issue gcc emits code using libatomic functions, but misses to link it properly, which is solved by passing on -latomic explicitly. For Debian I worked around that in the Debian build itself[1]. Since Debian plans to remove armel soon, I'm also not sure how worthwhile that is. But maybe some porters want to keep that alive as well.
[1] https://salsa.debian.org/debian/fio/-/commit/9b6c398072b51e179318cbb953ee5a0550356012
Hello @hoexter:
Curious... Has fio always emitted __atomic_store_8 references on armel and friends? I guess as fio has used more recent C atomics functionality we've grown a dependency that doesn't exist on other more popular platforms. I guess the "technically correct" thing to is a configure time probe like https://gitlab.haskell.org/ghc/ghc/-/commit/774fc4d63f920d4f8057450c3d50a483b025a536 ?
@sitsofe I'm probably not qualified to give you a reliable answer, but based on what I've read this seems to be related to the transitioning of time_t to 64bit data types.
@hoexter thanks for the hint. In fio it looks like the problem was triggered because code was recently added that does an atomic operation (e.g. atomic_store_release() in https://github.com/axboe/fio/blob/80d72cb05a6c54ea1b256dcd69e3e4fdc9294f4f/backend.c#L945 ) on a 64 bit value. When a platform doesn't natively support atomic operations on a particular value GCC falls back to using libatomic to emulate things, which then has to be linked in. The reason you're hearing about it in relation to time is because that is a common case where atomics were being done on the old 32 bit time values but now the value has changed to 64 bits making atomic emulation necessary on certain platforms. Apparently some platforms don't even have 32 bit atomics (see https://gcc.gnu.org/legacy-ml/gcc-help/2019-06/msg00068.html )...
@hoexter does the following patch help?
diff --git a/configure b/configure
index 3209e225..f03c66b3 100755
--- a/configure
+++ b/configure
@@ -661,6 +661,31 @@ if ! compile_prog "" "" "C11 atomics"; then
fi
+##########################################
+# 64 bit atomics support
+atomic_64="no"
+cat > $TMPC << EOF
+#include <stdatomic.h>
+#include <stdint.h>
+
+int main(void)
+{
+ _Atomic uint64_t v;
+ atomic_store_explicit(&v, 1, memory_order_release);
+ return 0;
+}
+EOF
+if compile_prog "" "" "64 bit atomics"; then
+ atomic_64="yes"
+elif compile_prog "" "-latomic" "64 bit atomics require libatomic"; then
+ LIBS="-latomic $LIBS"
+ atomic_64="yes"
+else
+ fatal "64 bit atomics not supported"
+fi
+print_config "64 bit atomics" "$atomic_64"
+
+
##########################################
# check for wordsize
wordsize="0"
@sitsofe thank you, lgtm. Did a successful test build on armel.
./configure --disable-native --prefix=/usr --enable-libnbd
Operating system Linux
CPU arm
Big endian no
Compiler gcc
Cross compile no
Static build no
64 bit atomics yes
Wordsize 32
-> -latomic is passed on to gcc.
This patch also fixed it on big-endian powerpc-*-linux-gnu 32bit.