diff --git a/net/ucx/Makefile b/net/ucx/Makefile index e1b35a6a76ec..a0aa09488d6b 100644 --- a/net/ucx/Makefile +++ b/net/ucx/Makefile @@ -1,71 +1,71 @@ PORTNAME= ucx -DISTVERSION= 1.20.1 +DISTVERSION= 1.22.0 PORTREVISION= 4 CATEGORIES= net MASTER_SITES= https://github.com/openucx/ucx/releases/download/v${DISTVERSION}/ MAINTAINER= rikka.goering@outlook.de COMMENT= Unified Communication X framework (UCX) WWW= https://openucx.org/ LICENSE= BSD3CLAUSE LICENSE_FILE= ${WRKSRC}/LICENSE ONLY_FOR_ARCHS= aarch64 amd64 powerpc64le ONLY_FOR_ARCHS_REASON= uses arch-specific CPU backends; armv7 is not supported upstream and does not build on FreeBSD BUILD_DEPENDS= bash:shells/bash \ ${LOCALBASE}/share/aclocal/ax_c_float_words_bigendian.m4:devel/autoconf-archive USES= autoreconf dos2unix gmake libtool pkgconfig USE_LDCONFIG= yes GNU_CONFIGURE= yes CONFIGURE_SHELL= ${LOCALBASE}/bin/bash CONFIGURE_ARGS= --disable-doxygen-doc \ --enable-compiler-opt=0 \ --enable-gtest \ --enable-mt \ --with-go=no CONFIGURE_ENV= GIT=/usr/bin/false INSTALL_TARGET= install-strip TEST_ENV+= LD_LIBRARY_PATH=${STAGEDIR}${PREFIX}/lib TESTING_UNSAFE= yes LDFLAGS+= -lexecinfo -lprocstat -lutil PORTDOCS= * PORTEXAMPLES= * OPTIONS_DEFINE= DOCS EXAMPLES FUSE IBVERBS IODEMO PERFTEST UMAD OPTIONS_DEFAULT= FUSE IODEMO PERFTEST OPTIONS_SUB= yes IBVERBS_DESC= Enable InfiniBand/RDMA (verbs) transport IODEMO_DESC= Install io_demo test application PERFTEST_DESC= Install ucx_perftest benchmarks UMAD_DESC= Build/install perftest MAD plugin (umad) FUSE_LIB_DEPENDS= libfuse3.so:filesystems/fusefs-libs3 FUSE_CONFIGURE_ON= --with-fuse3=${LOCALBASE} FUSE_CONFIGURE_OFF= --with-fuse3=no IBVERBS_CONFIGURE_ON= --with-verbs=${LOCALBASE} IBVERBS_CONFIGURE_OFF= --with-verbs=no UMAD_IMPLIES= IBVERBS PERFTEST UMAD_CONFIGURE_ON= --with-mad=${LOCALBASE} UMAD_CONFIGURE_OFF= --with-mad=no post-patch: ${REINPLACE_CMD} 's|^examplesdir = $$(pkgdatadir)/examples$$|examplesdir = ${EXAMPLESDIR}|' \ ${WRKSRC}/examples/Makefile.am post-install: ${MV} ${STAGEDIR}${ETCDIR}/ucx.conf ${STAGEDIR}${ETCDIR}/ucx.conf.sample do-test: cd ${WRKSRC}/test/gtest && \ ${SETENV} ${TEST_ENV} ${MAKE_CMD} && \ ${SETENV} ${TEST_ENV} ./gtest --gtest_filter=-malloc_hook*:sysv/*:test_rcache*:test_rcache_pfn*:test_vfs_sock*:test_datatype.hlist_for_each_extract_if:tcp/test_uct_pending.pending_fairness*:tcp/test_uct_peer_failure.purge_failed_peer*:tcp/test_uct_pending.pending_purge*:tcp/test_uct_iface.is_reachable*:tcp/test_uct_perf*:tcp/test_uct_loopback*:tcp/test_uct_tcp.listener_flood_connect_and_send_large*:tcp/test_uct_tcp.listener_flood_connect_and_send_small*:tcp/test_uct_tcp.check_addr_len*:shm*/*:mm_tcp/*:ib_shm/*:ud_tcp/*:all/*:*/test_ucp_loopback*:tcp/test_ucp_perf*:*/test_ucp_proto_mock_self.rkey_ptr*:test_config.test_config_file:test_config.test_config_file_parse_files:signal/*:*/test_async.many_timers*:*/test_ucp_peer_failure_keepalive*:self/test_ucp_wakeup.signal*:tcp/test_ucp_wakeup.signal*:tcp/test_proto_reset.am_eager_multi_bcopy*:tcp/test_uct_sockaddr.err_handle*:tcp/test_ucp_sockaddr_protocols_diff_net_devices*:tcp/test_ucp_sockaddr_iface_activate*:*/test_ucp_atomic*:*/test_ucp_mmap*:*/test_ucp_tag_match_rndv_align*:*/test_ucp_tag_probe*:tcp/test_ucp_sockaddr.*close_during_rndv*:tcp/test_ucp_sockaddr_protocols_err*:*test_ucp_wireup_1sided.stress_connect*:*/test_event_set.ucs_event_set_trig_modes* .include diff --git a/net/ucx/distinfo b/net/ucx/distinfo index a2d38f6413d8..b5412b0f4f40 100644 --- a/net/ucx/distinfo +++ b/net/ucx/distinfo @@ -1,3 +1,3 @@ -TIMESTAMP = 1781120416 -SHA256 (ucx-1.20.1.tar.gz) = 545c419a7b5e04643cb8bff5a19b3b5071a8f8f0605f1e8efb36f8f3d7bfb9d3 -SIZE (ucx-1.20.1.tar.gz) = 3505964 +TIMESTAMP = 1788913800 +SHA256 (ucx-1.22.0.tar.gz) = 258941cddd14ca60d38c0d31b9b09ec1052c901086841011a498da8b55a3cb24 +SIZE (ucx-1.22.0.tar.gz) = 3689879 diff --git a/net/ucx/files/patch-Makefile.am b/net/ucx/files/patch-Makefile.am index 8993d3b04bd6..0bf24b316414 100644 --- a/net/ucx/files/patch-Makefile.am +++ b/net/ucx/files/patch-Makefile.am @@ -1,13 +1,13 @@ ---- Makefile.am.orig 2026-02-05 12:41:56 UTC +--- Makefile.am.orig 2026-09-09 00:55:51 UTC +++ Makefile.am -@@ -59,8 +59,10 @@ SUBDIRS += \ +@@ -55,8 +55,10 @@ SUBDIRS += \ cmake \ config +if BUILD_GTEST if HAVE_GTEST SUBDIRS += test/gtest +endif endif if HAVE_MPICC diff --git a/net/ucx/files/patch-config_m4_ucm.m4 b/net/ucx/files/patch-config_m4_ucm.m4 deleted file mode 100644 index 7ba238108c02..000000000000 --- a/net/ucx/files/patch-config_m4_ucm.m4 +++ /dev/null @@ -1,33 +0,0 @@ ---- config/m4/ucm.m4.orig 2026-02-04 09:52:46 UTC -+++ config/m4/ucm.m4 -@@ -15,11 +15,18 @@ AC_ARG_WITH([allocator], - [], - [with_allocator=ptmalloc286]) - -+AC_CHECK_FUNCS([brk sbrk], [], [], [#include ]) -+ -+HAVE_UCM_PTMALLOC286=no -+ - case ${with_allocator} in - ptmalloc286) - AC_MSG_NOTICE(Memory allocator is ptmalloc-2.8.6 version) -- AC_DEFINE([HAVE_UCM_PTMALLOC286], 1, [Use ptmalloc-2.8.6 version]) -- HAVE_UCM_PTMALLOC286=yes -+ AS_IF([test "x$ac_cv_func_brk" = "xyes" && test "x$ac_cv_func_sbrk" = "xyes"], -+ [AC_DEFINE([HAVE_UCM_PTMALLOC286], 1, [Use ptmalloc-2.8.6 version]) -+ HAVE_UCM_PTMALLOC286=yes], -+ [AC_MSG_WARN([brk()/sbrk() not available; disabling ptmalloc286 allocator]) -+ HAVE_UCM_PTMALLOC286=no]) - ;; - *) - AC_MSG_ERROR(Cannot continue. Unsupported memory allocator name -@@ -83,6 +90,9 @@ AS_IF([test "x$mmap_hooks_happy" = "xyes"], - AS_IF([test "x$mmap_hooks_happy" = "xyes"], - AS_IF([test "x$ipc_hooks_happy" = "xyes" -o "x$shm_hooks_happy" = "xyes"], - [bistro_hooks_happy=yes])) -+ -+AS_IF([test "x$ac_cv_func_brk" != "xyes" -o "x$ac_cv_func_sbrk" != "xyes"], -+ [bistro_hooks_happy=no]) - - AS_IF([test "x$bistro_hooks_happy" = "xyes"], - [AC_DEFINE([UCM_BISTRO_HOOKS], [1], [Enable BISTRO hooks])], diff --git a/net/ucx/files/patch-configure.ac b/net/ucx/files/patch-configure.ac index 80c52b4ff672..731a3955d42a 100644 --- a/net/ucx/files/patch-configure.ac +++ b/net/ucx/files/patch-configure.ac @@ -1,106 +1,42 @@ ---- configure.ac.orig 2026-06-12 20:50:26 UTC +--- configure.ac.orig 2026-09-09 00:44:04 UTC +++ configure.ac -@@ -14,8 +14,6 @@ define([ucx_ver_extra], ) # Extra version string. Em - define([ucx_ver_patch], 1) # Patch version. Increased for a bugfix release. - define([ucx_ver_extra], ) # Extra version string. Empty for a general release. - --define([ts], esyscmd([sh -c "date +%Y%m%d%H%M%S"])) -- - # This is the API version (see libtool library versioning) - # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html - # current:rev:age -@@ -31,14 +29,20 @@ AC_CONFIG_HEADERS([config.h]) - AC_USE_SYSTEM_EXTENSIONS - AC_CONFIG_HEADERS([config.h]) - --AC_CHECK_PROG(GITBIN, git, yes) --AS_IF([test x"${GITBIN}" = x"yes"], -- [# remove preceding "refs/heads/" (11 characters) for symbolic ref -- AC_SUBST(SCM_BRANCH, esyscmd([sh -c 'git symbolic-ref --quiet HEAD | sed "s/^.\{11\}//"'])) -- AC_SUBST(SCM_VERSION, esyscmd([sh -c 'git rev-parse --short=7 HEAD']))], -- [AC_SUBST(SCM_BRANCH, "") -- AC_SUBST(SCM_VERSION, "0000000")]) -+AC_PATH_PROG([GIT], [git], [:]) - -+SCM_BRANCH="" -+SCM_VERSION="0000000" -+ -+AS_IF([test -d "${srcdir}/.git" && test "x$GIT" != "x:" && \ -+ $GIT -C "${srcdir}" rev-parse --is-inside-work-tree >/dev/null 2>&1], [ -+ SCM_BRANCH=`$GIT -C "${srcdir}" symbolic-ref --quiet HEAD 2>/dev/null | sed 's,^refs/heads/,,'` -+ SCM_VERSION=`$GIT -C "${srcdir}" rev-parse --short=7 HEAD 2>/dev/null` -+]) -+ -+AC_SUBST([SCM_BRANCH]) -+AC_SUBST([SCM_VERSION]) -+ - AH_TOP([ - #ifndef UCX_CONFIG_H - #define UCX_CONFIG_H -@@ -85,9 +89,44 @@ AC_FUNC_STRERROR_R +@@ -122,7 +122,38 @@ AC_FUNC_STRERROR_R AC_C_RESTRICT AC_FUNC_STRERROR_R -AC_PATH_TOOL([PKG_CONFIG], [pkg-config], [pkg-config]) +PKG_PROG_PKG_CONFIG - ++ +dnl Float word order can differ from integer endianness on some ABIs. -+ dnl Prefer Autoconf's macro if available; otherwise fall back to autoconf-archive. -+ m4_ifdef([AC_C_FLOAT_WORDS_BIGENDIAN], -+ [AC_C_FLOAT_WORDS_BIGENDIAN], -+ [m4_ifdef([AX_C_FLOAT_WORDS_BIGENDIAN], -+ [AX_C_FLOAT_WORDS_BIGENDIAN], -+ [AC_MSG_ERROR([need AC_C_FLOAT_WORDS_BIGENDIAN or AX_C_FLOAT_WORDS_BIGENDIAN])])]) - ++dnl Prefer Autoconf's macro if available; otherwise fall back to autoconf-archive. ++m4_ifdef([AC_C_FLOAT_WORDS_BIGENDIAN], ++ [AC_C_FLOAT_WORDS_BIGENDIAN], ++ [m4_ifdef([AX_C_FLOAT_WORDS_BIGENDIAN], ++ [AX_C_FLOAT_WORDS_BIGENDIAN], ++ [AC_MSG_ERROR([need AC_C_FLOAT_WORDS_BIGENDIAN or AX_C_FLOAT_WORDS_BIGENDIAN])])]) ++ +AC_CHECK_HEADERS([sys/eventfd.h sys/timerfd.h]) +AC_CHECK_HEADERS([netinet/in.h arpa/inet.h]) + -+AC_CHECK_FUNCS([brk sbrk]) -+ ++dnl brk()/sbrk() detection itself is performed by config/m4/ucm.m4. ++dnl Keep a common feature define for FreeBSD UCM compatibility code. +AS_IF([test "x$ac_cv_func_brk" = "xyes" && test "x$ac_cv_func_sbrk" = "xyes"], + [have_brk_sbrk=yes], + [have_brk_sbrk=no]) + -+have_ucm_malloc_hooks=no -+case "$host_os" in -+ linux*) have_ucm_malloc_hooks=yes ;; -+ *) have_ucm_malloc_hooks=no ;; -+esac -+AM_CONDITIONAL([HAVE_UCM_MALLOC_HOOKS], [test "x$have_ucm_malloc_hooks" = xyes]) ++AM_CONDITIONAL([HAVE_BRK_SBRK], ++ [test "x$have_brk_sbrk" = "xyes"]) + -+AM_CONDITIONAL([HAVE_BRK_SBRK], [test "x$have_brk_sbrk" = "xyes"]) +AS_IF([test "x$have_brk_sbrk" = "xyes"], + [AC_DEFINE([HAVE_BRK_SBRK], [1], -+ [Define if both brk() and sbrk() are available])], -+ []) ++ [Define if both brk() and sbrk() are available])]) + +case "$host_os" in + freebsd*) build_gtest=no ;; + *) build_gtest=yes ;; +esac -+AM_CONDITIONAL([BUILD_GTEST], [test "x$build_gtest" = xyes]) -+ - # - # Define SHARED_LIB preprocessor macro when building a shared library - # -@@ -255,6 +294,20 @@ AS_IF([test "x$with_docs_only" = xyes], - m4_include([test/apps/iodemo/configure.m4]) - m4_include([test/apps/uct_info/configure.m4]) - -+AS_IF([test "x$with_docs_only" != xyes], [ -+ have_gtest=yes -+], [ -+ have_gtest=no -+]) -+ -+AM_CONDITIONAL([HAVE_GTEST], [test "x$have_gtest" = "xyes"]) -+ -+GTEST_CPPFLAGS="${GTEST_CFLAGS}" -+GTEST_CXXFLAGS="${GTEST_CFLAGS}" -+GTEST_LDFLAGS="" -+AC_SUBST([GTEST_CPPFLAGS]) -+AC_SUBST([GTEST_CXXFLAGS]) -+AC_SUBST([GTEST_LDFLAGS]) ++AM_CONDITIONAL([BUILD_GTEST], ++ [test "x$build_gtest" = xyes]) - # - # Disable checking user parameters + AS_IF([test "x$enable_module_deepbind" = xyes], + [AC_CHECK_DECLS([RTLD_DEEPBIND], diff --git a/net/ucx/files/patch-src_ucm_mmap_install.c b/net/ucx/files/patch-src_ucm_mmap_install.c deleted file mode 100644 index 33a4ea90b28f..000000000000 --- a/net/ucx/files/patch-src_ucm_mmap_install.c +++ /dev/null @@ -1,55 +0,0 @@ ---- src/ucm/mmap/install.c.orig 2026-02-04 09:52:46 UTC -+++ src/ucm/mmap/install.c -@@ -86,8 +86,10 @@ static ucm_mmap_func_t ucm_mmap_funcs[] = { - #endif - { UCM_MMAP_RELOC_ENTRY(shmat), UCM_EVENT_SHMAT, UCM_EVENT_NONE}, - { UCM_MMAP_RELOC_ENTRY(shmdt), UCM_EVENT_SHMDT, UCM_EVENT_SHMAT}, -+#ifdef HAVE_BRK_SBRK - { UCM_MMAP_RELOC_ENTRY(sbrk), UCM_EVENT_SBRK, UCM_EVENT_NONE}, - { UCM_MMAP_RELOC_ENTRY(brk), UCM_EVENT_BRK, UCM_EVENT_NONE}, -+#endif - { UCM_MMAP_RELOC_ENTRY(madvise), UCM_EVENT_MADVISE, UCM_EVENT_NONE}, - { {NULL, NULL, NULL}, UCM_EVENT_NONE} - }; -@@ -135,6 +137,7 @@ static void ucm_mmap_event_test_callback(ucm_event_typ - } - } - -+#ifdef HAVE_BRK_SBRK - /* Call brk() and check return value, to avoid compile error of unused result */ - static void ucm_brk_checked(void *addr) - { -@@ -143,6 +146,7 @@ static void ucm_brk_checked(void *addr) - ucm_diag("brk(addr=%p) failed: %m", addr); - } - } -+#endif - - /* Fire events with pre/post action. The problem is in call sequence: we - * can't just fire single event - most of the system calls require set of -@@ -199,6 +203,7 @@ ucm_fire_mmap_events_internal(int events, ucm_mmap_tes - } - - if (exclusive && !RUNNING_ON_VALGRIND) { -+#ifdef HAVE_BRK_SBRK - sbrk_size = ucm_get_page_size(); - if (events & (UCM_EVENT_BRK|UCM_EVENT_VM_MAPPED|UCM_EVENT_VM_UNMAPPED)) { - p = ucm_get_current_brk(); -@@ -213,14 +218,17 @@ ucm_fire_mmap_events_internal(int events, ucm_mmap_tes - UCM_FIRE_EVENT(events, UCM_EVENT_SBRK|UCM_EVENT_VM_UNMAPPED, - data, (void)sbrk(-sbrk_size)); - } -+#endif - } else { - /* To avoid side effects on other threads and valgrind heap corruption, - * pass invalid parameters. We assume that if the natives events are - * delivered, it means VM_MAPPED/UNMAPPED would be delivered as well. - */ -+#ifdef HAVE_BRK_SBRK - if (events & UCM_EVENT_BRK) { - UCM_FIRE_EVENT(events, UCM_EVENT_BRK, data, ucm_brk_checked(NULL)); - } -+#endif - } - - if (events & (UCM_EVENT_MADVISE|UCM_EVENT_VM_UNMAPPED)) { diff --git a/net/ucx/files/patch-src_ucm_util_replace.c b/net/ucx/files/patch-src_ucm_util_replace.c index c14023c8fe4b..cc52f68e68ce 100644 --- a/net/ucx/files/patch-src_ucm_util_replace.c +++ b/net/ucx/files/patch-src_ucm_util_replace.c @@ -1,68 +1,16 @@ ---- src/ucm/util/replace.c.orig 2026-02-04 09:52:46 UTC +--- src/ucm/util/replace.c.orig 2026-09-09 00:53:37 UTC +++ src/ucm/util/replace.c -@@ -55,8 +55,10 @@ UCM_DEFINE_REPLACE_FUNC(shmdt, int, -1, co - #endif - UCM_DEFINE_REPLACE_FUNC(shmat, void*, MAP_FAILED, int, const void*, int) - UCM_DEFINE_REPLACE_FUNC(shmdt, int, -1, const void*) -+#ifdef HAVE_BRK_SBRK - UCM_DEFINE_REPLACE_FUNC(sbrk, void*, MAP_FAILED, intptr_t) - UCM_DEFINE_REPLACE_FUNC(brk, int, -1, void*) -+#endif - UCM_DEFINE_REPLACE_FUNC(madvise, int, -1, void*, size_t, int) - - UCM_DEFINE_SELECT_FUNC(mmap, void*, SYS_mmap, void*, size_t, int, int, int, -@@ -122,6 +124,7 @@ int ucm_orig_shmdt(const void *shmaddr) - - #endif - -+#ifdef HAVE_BRK_SBRK - _UCM_DEFINE_DLSYM_FUNC(brk, ucm_orig_dlsym_brk, ucm_override_brk, int, void*) - - int ucm_orig_brk(void *addr) -@@ -156,7 +159,32 @@ void *ucm_orig_sbrk(intptr_t increment) - (void*)-1 : prev; - } - } -+#else -+int ucm_orig_brk(void *addr) -+{ -+ (void)addr; -+ errno = ENOSYS; -+ return -1; -+} - -+void *ucm_orig_sbrk(intptr_t increment) -+{ -+ (void)increment; -+ errno = ENOSYS; -+ return MAP_FAILED; -+} -+ -+int ucm_override_brk(void *addr) -+{ -+ return ucm_orig_brk(addr); -+} -+ -+void *ucm_override_sbrk(intptr_t increment) -+{ -+ return ucm_orig_sbrk(increment); -+} -+#endif -+ - #else /* UCM_BISTRO_HOOKS */ - - UCM_DEFINE_DLSYM_FUNC(brk, int, void*) -@@ -168,9 +196,13 @@ void *ucm_get_current_brk() +@@ -176,9 +176,13 @@ void *ucm_get_current_brk() void *ucm_get_current_brk() { -+#ifdef HAVE_BRK_SBRK ++#if HAVE_BRK #if HAVE___CURBRK return __curbrk; #else return ucm_brk_syscall(0); +#endif +#else + return NULL; #endif } diff --git a/net/ucx/files/patch-src_ucm_util_sys.c b/net/ucx/files/patch-src_ucm_util_sys.c index d09fb998b3f3..9d8fea20b16e 100644 --- a/net/ucx/files/patch-src_ucm_util_sys.c +++ b/net/ucx/files/patch-src_ucm_util_sys.c @@ -1,161 +1,150 @@ ---- src/ucm/util/sys.c.orig 2026-02-04 09:52:46 UTC +--- src/ucm/util/sys.c.orig 2026-09-09 00:55:51 UTC +++ src/ucm/util/sys.c @@ -14,6 +14,13 @@ # include "config.h" #endif +#if defined(__FreeBSD__) +#include +#include +#include +#include +#endif + #include #include #include @@ -21,10 +28,17 @@ #include #include #include +#ifdef HAVE_LINUX_MMAN_H #include +#endif #include #include +#ifdef __linux__ #include +#elif defined(__FreeBSD__) +#include +#include +#endif #include #include #include @@ -34,6 +48,24 @@ #define UCM_PROC_SELF_MAPS "/proc/self/maps" +#if !defined(__linux__) +#include +#include + +void *ucm_orig_mremap(void *old_address, size_t old_size, size_t new_size, + int flags, void *new_address) +{ + (void)old_address; + (void)old_size; + (void)new_size; + (void)flags; + (void)new_address; + + errno = ENOSYS; + return MAP_FAILED; +} +#endif + ucm_global_config_t ucm_global_opts = { .log_level = UCS_LOG_LEVEL_WARN, .enable_events = 1, @@ -136,7 +168,22 @@ void *ucm_sys_realloc(void *ptr, size_t size) return ptr; } +#if defined(__linux__) newptr = ucm_orig_mremap(oldptr, oldsize, sys_size, MREMAP_MAYMOVE, NULL); +#else + /* FreeBSD: no Linux mremap/MREMAP_MAYMOVE. Fallback: allocate+copy+unmap. + * If upper layers can tolerate "not supported", you can instead: + * errno = ENOTSUP; return MAP_FAILED; + */ + newptr = mmap(NULL, sys_size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (newptr != MAP_FAILED) { + size_t copy_sz = (oldsize < sys_size) ? oldsize : sys_size; + memcpy(newptr, oldptr, copy_sz); + munmap(oldptr, oldsize); + } +#endif + if (newptr == MAP_FAILED) { ucm_error("mremap(oldptr=%p oldsize=%zu, newsize=%zu) failed: %m", oldptr, oldsize, sys_size); @@ -148,6 +195,35 @@ void ucm_parse_proc_self_maps(ucm_proc_maps_cb_t cb, v void ucm_parse_proc_self_maps(ucm_proc_maps_cb_t cb, void *arg) { +#if defined(__FreeBSD__) + struct kinfo_vmentry *vmmap; + int count, i, prot; + char *path; + char empty_path[] = ""; + + vmmap = kinfo_getvmmap(getpid(), &count); + if (vmmap == NULL) { + ucm_warn("kinfo_getvmmap() failed: %m"); + return; + } + + for (i = 0; i < count; i++) { + prot = 0; + if (vmmap[i].kve_protection & KVME_PROT_READ) prot |= PROT_READ; + if (vmmap[i].kve_protection & KVME_PROT_WRITE) prot |= PROT_WRITE; + if (vmmap[i].kve_protection & KVME_PROT_EXEC) prot |= PROT_EXEC; + + path = (vmmap[i].kve_path[0] != '\0') ? vmmap[i].kve_path + : empty_path; + if (cb(arg, (void *)vmmap[i].kve_start, + vmmap[i].kve_end - vmmap[i].kve_start, + prot, path)) { + break; + } + } + + free(vmmap); +#else static char *buffer = MAP_FAILED; static size_t buffer_size = 32768; static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; @@ -263,6 +339,7 @@ out: out: pthread_mutex_unlock(&lock); +#endif } typedef struct { -@@ -377,15 +454,31 @@ void *ucm_brk_syscall(void *addr) - - void *ucm_brk_syscall(void *addr) - { -+#if defined(__linux__) - /* Return type is equivalent to full pointer size */ - UCS_STATIC_ASSERT(sizeof(syscall(0)) == sizeof(void*)); -- - return (void*)syscall(SYS_brk, addr); -+#else -+ (void)addr; -+ errno = ENOSYS; -+ return NULL; -+#endif +@@ -389,9 +466,21 @@ void *ucm_brk_syscall(void *addr) + #endif } -pid_t ucm_get_tid() +pid_t ucm_get_tid(void) { - return syscall(SYS_gettid); +#if defined(__linux__) + return (pid_t)syscall(SYS_gettid); +#elif defined(__FreeBSD__) + long tid; ++ + if (thr_self(&tid) == 0) { + return (pid_t)tid; + } -+ /* fallback */ ++ + return (pid_t)getpid(); +#else + return (pid_t)getpid(); +#endif } void UCS_F_CTOR ucm_init() diff --git a/net/ucx/files/patch-src_ucp_core_ucp__ep.c b/net/ucx/files/patch-src_ucp_core_ucp__ep.c index de942fa55c93..1437b85ffaaf 100644 --- a/net/ucx/files/patch-src_ucp_core_ucp__ep.c +++ b/net/ucx/files/patch-src_ucp_core_ucp__ep.c @@ -1,28 +1,28 @@ ---- src/ucp/core/ucp_ep.c.orig 2026-07-01 23:04:16 UTC +--- src/ucp/core/ucp_ep.c.orig 2026-09-09 02:32:02 UTC +++ src/ucp/core/ucp_ep.c -@@ -3181,11 +3181,25 @@ void ucp_ep_config_lane_info_str(ucp_worker_h worker, +@@ -3499,11 +3499,25 @@ void ucp_ep_config_lane_info_str(ucp_worker_h worker, } dst_md_index = key->lanes[lane].dst_md_index; +#ifdef __FreeBSD__ + if (key->dst_md_cmpts != NULL) { + cmpt_index = ucp_ep_config_get_dst_md_cmpt(key, dst_md_index); + ucs_string_buffer_appendf( + strbuf, "md[%d]/%s/sysdev[%d] seg %zu", dst_md_index, + context->tl_cmpts[cmpt_index].attr.name, + key->lanes[lane].dst_sys_dev, key->lanes[lane].seg_size); + } else { + ucs_string_buffer_appendf( + strbuf, "md[%d]/sysdev[%d] seg %zu", dst_md_index, + key->lanes[lane].dst_sys_dev, key->lanes[lane].seg_size); + } +#else cmpt_index = ucp_ep_config_get_dst_md_cmpt(key, dst_md_index); ucs_string_buffer_appendf( strbuf, "md[%d]/%s/sysdev[%d] seg %zu", dst_md_index, context->tl_cmpts[cmpt_index].attr.name, key->lanes[lane].dst_sys_dev, key->lanes[lane].seg_size); +#endif prio = ucp_ep_config_get_multi_lane_prio(key->rma_bw_lanes, lane); if (prio != -1) { diff --git a/net/ucx/files/patch-src_ucp_core_ucp__worker.c b/net/ucx/files/patch-src_ucp_core_ucp__worker.c index 671c3fa16573..da3ba04e02e6 100644 --- a/net/ucx/files/patch-src_ucp_core_ucp__worker.c +++ b/net/ucx/files/patch-src_ucp_core_ucp__worker.c @@ -1,184 +1,184 @@ ---- src/ucp/core/ucp_worker.c.orig 2026-02-05 12:41:56 UTC +--- src/ucp/core/ucp_worker.c.orig 2026-09-09 02:32:02 UTC +++ src/ucp/core/ucp_worker.c @@ -9,6 +9,8 @@ # include "config.h" #endif +#include + #include "ucp_am.h" #include "ucp_ep_vfs.h" #include "ucp_worker.h" -@@ -35,9 +37,18 @@ +@@ -36,9 +38,18 @@ #include #include #include +#if defined(HAVE_SYS_EVENTFD_H) #include -#include +#endif +#if defined(HAVE_SYS_TIMERFD_H) #include +#endif +#if defined(__linux__) +#include +#endif +#if defined(__FreeBSD__) +#include +#endif #include -@@ -290,7 +301,10 @@ static ucs_status_t ucp_worker_wakeup_init(ucp_worker_ +@@ -291,7 +302,10 @@ static ucs_status_t ucp_worker_wakeup_init(ucp_worker_ worker->event_fd = -1; worker->event_set = NULL; worker->eventfd = -1; - worker->uct_events = 0; +#if defined(__FreeBSD__) + worker->eventfd_write = -1; +#endif + worker->uct_events = 0; status = UCS_OK; goto out; } -@@ -320,6 +334,19 @@ static ucs_status_t ucp_worker_wakeup_init(ucp_worker_ +@@ -321,6 +335,19 @@ static ucs_status_t ucp_worker_wakeup_init(ucp_worker_ worker->flags |= UCP_WORKER_FLAG_EDGE_TRIGGERED; } +#if defined(__FreeBSD__) + { + int pipefd[2]; + if (pipe2(pipefd, O_CLOEXEC | O_NONBLOCK) < 0) { + ucs_error("Failed to create wakeup pipe: %m"); + status = UCS_ERR_IO_ERROR; + goto err_cleanup_event_set; + } + worker->eventfd = pipefd[0]; /* read end: monitored by kqueue */ + worker->eventfd_write = pipefd[1]; /* write end: used to signal */ + } + ucp_worker_wakeup_ctl_fd(worker, UCP_WORKER_EPFD_OP_ADD, worker->eventfd); +#elif defined(HAVE_SYS_EVENTFD_H) worker->eventfd = eventfd(0, EFD_CLOEXEC | EFD_NONBLOCK); if (worker->eventfd == -1) { ucs_error("Failed to create event fd: %m"); -@@ -328,6 +355,13 @@ static ucs_status_t ucp_worker_wakeup_init(ucp_worker_ +@@ -329,6 +356,13 @@ static ucs_status_t ucp_worker_wakeup_init(ucp_worker_ } ucp_worker_wakeup_ctl_fd(worker, UCP_WORKER_EPFD_OP_ADD, worker->eventfd); +#else + /* No eventfd(). */ + worker->eventfd = -1; +#if defined(__FreeBSD__) + worker->eventfd_write = -1; +#endif +#endif worker->uct_events = 0; -@@ -371,6 +405,12 @@ static void ucp_worker_wakeup_cleanup(ucp_worker_h wor +@@ -372,6 +406,12 @@ static void ucp_worker_wakeup_cleanup(ucp_worker_h wor } if (worker->eventfd != -1) { close(worker->eventfd); +#if defined(__FreeBSD__) + if (worker->eventfd_write != -1) { + close(worker->eventfd_write); + worker->eventfd_write = -1; + } +#endif } } -@@ -423,12 +463,24 @@ static ucs_status_t ucp_worker_wakeup_signal_fd(ucp_wo +@@ -424,12 +464,24 @@ static ucs_status_t ucp_worker_wakeup_signal_fd(ucp_wo static ucs_status_t ucp_worker_wakeup_signal_fd(ucp_worker_h worker) { uint64_t dummy = 1; + int write_fd; int ret; - ucs_trace_func("worker=%p fd=%d", worker, worker->eventfd); +#if defined(__FreeBSD__) + write_fd = worker->eventfd_write; +#else + write_fd = worker->eventfd; +#endif + ucs_trace_func("worker=%p fd=%d", worker, write_fd); + + if (write_fd == -1) { + + return UCS_OK; + } + do { - ret = write(worker->eventfd, &dummy, sizeof(dummy)); + ret = write(write_fd, &dummy, sizeof(dummy)); if (ret == sizeof(dummy)) { return UCS_OK; } else if (ret == -1) { -@@ -3375,7 +3427,7 @@ void ucp_worker_print_info(ucp_worker_h worker, FILE * +@@ -3501,7 +3553,7 @@ void ucp_worker_print_info(ucp_worker_h worker, FILE * UCP_WORKER_THREAD_CS_EXIT_CONDITIONAL(worker); } -static UCS_F_ALWAYS_INLINE void +static UCS_F_ALWAYS_INLINE ucs_status_t ucp_worker_keepalive_timerfd_init(ucp_worker_h worker) { ucs_time_t ka_interval = worker->context->config.ext.keepalive_interval; -@@ -3385,14 +3437,18 @@ ucp_worker_keepalive_timerfd_init(ucp_worker_h worker) +@@ -3511,14 +3563,18 @@ ucp_worker_keepalive_timerfd_init(ucp_worker_h worker) if (!(worker->context->config.features & UCP_FEATURE_WAKEUP) || (worker->keepalive.timerfd >= 0)) { - return; + return UCS_OK; } +/* timerfd_* are Linux-only */ +#if !defined(HAVE_SYS_TIMERFD_H) + worker->keepalive.timerfd = -1; + return UCS_OK; +#else worker->keepalive.timerfd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK); if (worker->keepalive.timerfd < 0) { - ucs_warn("worker %p: failed to create keepalive timer fd: %m", - worker); - return; + ucs_error("timerfd_create() failed: %m"); + return UCS_ERR_IO_ERROR; } ucs_assert(ka_interval > 0); -@@ -3412,10 +3468,11 @@ ucp_worker_keepalive_timerfd_init(ucp_worker_h worker) +@@ -3538,10 +3594,11 @@ ucp_worker_keepalive_timerfd_init(ucp_worker_h worker) ucp_worker_wakeup_ctl_fd(worker, UCP_WORKER_EPFD_OP_ADD, worker->keepalive.timerfd); - return; + return UCS_OK; err_close_timerfd: close(worker->keepalive.timerfd); +#endif } static UCS_F_ALWAYS_INLINE void -@@ -3571,6 +3628,7 @@ void ucp_worker_keepalive_add_ep(ucp_ep_h ep) +@@ -3704,6 +3761,7 @@ void ucp_worker_keepalive_add_ep(ucp_ep_h ep) void ucp_worker_keepalive_add_ep(ucp_ep_h ep) { ucp_worker_h worker = ep->worker; + ucs_status_t status; if (ucp_ep_config(ep)->key.keepalive_lane == UCP_NULL_LANE) { ucs_trace("ep %p flags 0x%x cfg_index %d err_mode %d: keepalive lane" -@@ -3579,7 +3637,12 @@ void ucp_worker_keepalive_add_ep(ucp_ep_h ep) +@@ -3712,7 +3770,12 @@ void ucp_worker_keepalive_add_ep(ucp_ep_h ep) return; } - ucp_worker_keepalive_timerfd_init(worker); + status = ucp_worker_keepalive_timerfd_init(worker); + if ((status != UCS_OK) && (status != UCS_ERR_UNSUPPORTED)) { + ucs_warn("worker %p: failed to initialize keepalive timerfd: %s", + worker, ucs_status_string(status)); + } + ucs_trace("ep %p flags 0x%x: set keepalive lane to %u", ep, ep->flags, ucp_ep_config(ep)->key.keepalive_lane); uct_worker_progress_register_safe(worker->uct, diff --git a/net/ucx/files/patch-src_ucp_core_ucp__worker.h b/net/ucx/files/patch-src_ucp_core_ucp__worker.h index 3a91f11aef42..b4fec1b28364 100644 --- a/net/ucx/files/patch-src_ucp_core_ucp__worker.h +++ b/net/ucx/files/patch-src_ucp_core_ucp__worker.h @@ -1,13 +1,13 @@ ---- src/ucp/core/ucp_worker.h.orig 2026-02-05 12:41:56 UTC +--- src/ucp/core/ucp_worker.h.orig 2026-09-09 02:32:02 UTC +++ src/ucp/core/ucp_worker.h -@@ -319,6 +319,10 @@ typedef struct ucp_worker { +@@ -323,6 +323,10 @@ typedef struct ucp_worker { int event_fd; /* Allocated (on-demand) event fd for wakeup */ ucs_sys_event_set_t *event_set; /* Allocated UCS event set for wakeup */ int eventfd; /* Event fd to support signal() calls */ +#if defined(__FreeBSD__) + int eventfd_write; /* Write end of wakeup pipe (FreeBSD only). + * eventfd holds the read end. */ +#endif unsigned uct_events; /* UCT arm events */ ucs_list_link_t arm_ifaces; /* List of interfaces to arm */ diff --git a/net/ucx/files/patch-src_ucs_arch_aarch64_cpu.h b/net/ucx/files/patch-src_ucs_arch_aarch64_cpu.h deleted file mode 100644 index 74a17feb2179..000000000000 --- a/net/ucx/files/patch-src_ucs_arch_aarch64_cpu.h +++ /dev/null @@ -1,10 +0,0 @@ ---- src/ucs/arch/aarch64/cpu.h.orig 2026-02-17 21:08:28 UTC -+++ src/ucs/arch/aarch64/cpu.h -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - #include diff --git a/net/ucx/files/patch-src_ucs_config_parser.c b/net/ucx/files/patch-src_ucs_config_parser.c index 8ab9c6cda94d..09246725ab89 100644 --- a/net/ucx/files/patch-src_ucs_config_parser.c +++ b/net/ucx/files/patch-src_ucs_config_parser.c @@ -1,54 +1,54 @@ ---- src/ucs/config/parser.c.orig 2026-02-05 12:41:56 UTC +--- src/ucs/config/parser.c.orig 2026-09-09 02:32:02 UTC +++ src/ucs/config/parser.c -@@ -25,6 +25,7 @@ - #include +@@ -27,6 +27,7 @@ #include #include + #include +#include /* width of titles in docstring */ -@@ -693,6 +694,8 @@ int ucs_config_sscanf_signo(const char *buf, void *des +@@ -697,6 +698,8 @@ int ucs_config_sscanf_signo(const char *buf, void *des int ucs_config_sscanf_signo(const char *buf, void *dest, const void *arg) { char *endptr; + const char *name; + const char *name_nosig; int signo; signo = strtol(buf, &endptr, 10); -@@ -701,11 +704,31 @@ int ucs_config_sscanf_signo(const char *buf, void *des +@@ -705,11 +708,31 @@ int ucs_config_sscanf_signo(const char *buf, void *des return 1; } - if (!strncmp(buf, "SIG", 3)) { - buf += 3; + name = buf; + if (!strncasecmp(name, "SIG", 3)) { + name_nosig = name + 3; + } else { + name_nosig = name; } - return ucs_config_sscanf_enum(buf, dest, ucs_signal_names); +#if defined(__FreeBSD__) + for (signo = 1; signo < NSIG; ++signo) { + if ((sys_signame[signo] != NULL) && + !strcasecmp(name_nosig, sys_signame[signo])) { + *(int*)dest = signo; + return 1; + } + } +#endif + + if (ucs_config_sscanf_enum(name_nosig, dest, ucs_signal_names)) { + return 1; + } + if (name_nosig != name) { + return ucs_config_sscanf_enum(name, dest, ucs_signal_names); + } + + return 0; } int ucs_config_sprintf_signo(char *buf, size_t max, diff --git a/net/ucx/files/patch-src_ucs_datastruct_string__buffer.c b/net/ucx/files/patch-src_ucs_datastruct_string__buffer.c index e69c65333301..ad15550c35de 100644 --- a/net/ucx/files/patch-src_ucs_datastruct_string__buffer.c +++ b/net/ucx/files/patch-src_ucs_datastruct_string__buffer.c @@ -1,18 +1,18 @@ ---- src/ucs/datastruct/string_buffer.c.orig 2026-05-17 17:31:16 UTC +--- src/ucs/datastruct/string_buffer.c.orig 2026-09-09 02:36:31 UTC +++ src/ucs/datastruct/string_buffer.c -@@ -141,8 +141,13 @@ void ucs_string_buffer_append_iovec(ucs_string_buffer_ +@@ -151,8 +151,13 @@ void ucs_string_buffer_append_iovec(ucs_string_buffer_ size_t iov_index; for (iov_index = 0; iov_index < iovcnt; ++iov_index) { - ucs_string_buffer_appendf(strb, "%p,%zu|", iov[iov_index].iov_base, - iov[iov_index].iov_len); + if (iov[iov_index].iov_base == NULL) { + ucs_string_buffer_appendf(strb, "(nil),%zu|", + iov[iov_index].iov_len); + } else { + ucs_string_buffer_appendf(strb, "%p,%zu|", iov[iov_index].iov_base, + iov[iov_index].iov_len); + } } ucs_string_buffer_rtrim(strb, "|"); } diff --git a/net/ucx/files/patch-src_ucs_debug_debug.c b/net/ucx/files/patch-src_ucs_debug_debug.c deleted file mode 100644 index 01aebbd3f7e3..000000000000 --- a/net/ucx/files/patch-src_ucs_debug_debug.c +++ /dev/null @@ -1,11 +0,0 @@ ---- src/ucs/debug/debug.c.orig 2026-01-12 18:10:14 UTC -+++ src/ucs/debug/debug.c -@@ -24,6 +24,8 @@ - #include - #include - #include -+#include -+#include - #ifdef HAVE_DETAILED_BACKTRACE - # include - #endif /* HAVE_DETAILED_BACKTRACE */ diff --git a/net/ucx/files/patch-src_ucs_debug_log.c b/net/ucx/files/patch-src_ucs_debug_log.c deleted file mode 100644 index ab60cc2bdfe6..000000000000 --- a/net/ucx/files/patch-src_ucs_debug_log.c +++ /dev/null @@ -1,14 +0,0 @@ ---- src/ucs/debug/log.c.orig 2026-02-04 09:52:46 UTC -+++ src/ucs/debug/log.c -@@ -78,7 +78,11 @@ static int __thread ucs_log_current_indent = 0; - static unsigned ucs_log_handlers_count = 0; - static int ucs_log_initialized = 0; - static int __thread ucs_log_current_indent = 0; -+#if defined(__FreeBSD__) -+static char ucs_log_hostname[UCS_HOST_NAME_MAX] = {0}; -+#else - static char ucs_log_hostname[HOST_NAME_MAX] = {0}; -+#endif - static int ucs_log_pid = 0; - static FILE *ucs_log_file = NULL; - static char *ucs_log_file_base_name = NULL; diff --git a/net/ucx/files/patch-src_ucs_sys_compiler.h b/net/ucx/files/patch-src_ucs_sys_compiler.h deleted file mode 100644 index 9fe706c4c951..000000000000 --- a/net/ucx/files/patch-src_ucs_sys_compiler.h +++ /dev/null @@ -1,17 +0,0 @@ ---- src/ucs/sys/compiler.h.orig 2026-02-04 09:52:46 UTC -+++ src/ucs/sys/compiler.h -@@ -32,7 +32,13 @@ - - /* A function which should not be optimized */ - #if defined(HAVE_ATTRIBUTE_NOOPTIMIZE) && (HAVE_ATTRIBUTE_NOOPTIMIZE == 1) --#define UCS_F_NOOPTIMIZE __attribute__((optimize("O0"))) -+#if defined(__clang__) -+# define UCS_F_NOOPTIMIZE __attribute__((optnone)) -+#elif defined(__GNUC__) -+# define UCS_F_NOOPTIMIZE __attribute__((optimize("O0"))) -+#else -+# define UCS_F_NOOPTIMIZE -+#endif - #else - #define UCS_F_NOOPTIMIZE - #endif diff --git a/net/ucx/files/patch-src_ucs_sys_netlink.c b/net/ucx/files/patch-src_ucs_sys_netlink.c index a1a451b6e205..deb0898adc63 100644 --- a/net/ucx/files/patch-src_ucs_sys_netlink.c +++ b/net/ucx/files/patch-src_ucs_sys_netlink.c @@ -1,92 +1,92 @@ ---- src/ucs/sys/netlink.c.orig 2026-05-06 13:47:14 UTC +--- src/ucs/sys/netlink.c.orig 2026-09-09 14:48:02 UTC +++ src/ucs/sys/netlink.c @@ -8,6 +8,8 @@ #include "config.h" #endif +#if defined(__linux__) + #include "netlink.h" #include -@@ -347,3 +349,80 @@ int ucs_netlink_is_best_route(int if_index, const stru +@@ -384,3 +386,80 @@ int ucs_netlink_is_best_route(int if_index, const stru return (ucs_netlink_max_netmask_len(sa_remote) == netmask_len); } +#else + +#include "netlink.h" + +#include + +#include +#include +#include +#include + +ucs_status_t +ucs_netlink_send_request(int protocol, unsigned short nlmsg_type, + unsigned short nlmsg_flags, + const void *protocol_header, size_t header_length, + ucs_netlink_parse_cb_t parse_cb, void *arg) +{ + (void)protocol; + (void)nlmsg_type; + (void)nlmsg_flags; + (void)protocol_header; + (void)header_length; + (void)parse_cb; + (void)arg; + return UCS_ERR_UNSUPPORTED; +} + +int +ucs_netlink_route_exists(int if_index, const struct sockaddr *sa_remote, + int *netmask_len_p) +{ + char if_name[IF_NAMESIZE]; + struct ifreq ifr; + struct sockaddr_in local_addr, netmask; + in_addr_t local_ip, mask, remote_ip; + + if (sa_remote->sa_family != AF_INET) { + return 0; /* IPv6 not yet handled */ + } + + if (if_indextoname(if_index, if_name) == NULL) { + return 0; + } + + memset(&ifr, 0, sizeof(ifr)); + if (ucs_netif_ioctl(if_name, SIOCGIFADDR, &ifr) != UCS_OK) { + return 0; + } + memcpy(&local_addr, &ifr.ifr_addr, sizeof(local_addr)); + + memset(&ifr, 0, sizeof(ifr)); + if (ucs_netif_ioctl(if_name, SIOCGIFNETMASK, &ifr) != UCS_OK) { + return 0; + } + memcpy(&netmask, &ifr.ifr_addr, sizeof(netmask)); + + local_ip = local_addr.sin_addr.s_addr; + mask = netmask.sin_addr.s_addr; + remote_ip = ((const struct sockaddr_in *)sa_remote)->sin_addr.s_addr; + + if (netmask_len_p != NULL) { + *netmask_len_p = __builtin_popcount(ntohl(mask)); + } + + /* Remote is reachable if it is in the same subnet as the local interface */ + return (remote_ip & mask) == (local_ip & mask); +} + +int +ucs_netlink_is_best_route(int if_index, const struct sockaddr *sa_remote) +{ + int netmask_len; + + return ucs_netlink_route_exists(if_index, sa_remote, &netmask_len); +} + +#endif diff --git a/net/ucx/files/patch-src_ucs_sys_sock.c b/net/ucx/files/patch-src_ucs_sys_sock.c index 541411d97e83..3dfec75b51f4 100644 --- a/net/ucx/files/patch-src_ucs_sys_sock.c +++ b/net/ucx/files/patch-src_ucs_sys_sock.c @@ -1,30 +1,30 @@ ---- src/ucs/sys/sock.c.orig 2026-05-06 13:47:14 UTC +--- src/ucs/sys/sock.c.orig 2026-09-09 14:48:02 UTC +++ src/ucs/sys/sock.c @@ -20,7 +20,10 @@ #include #include +#include #include +#include +#include #include #include #include -@@ -517,6 +520,16 @@ int ucs_socket_max_conn() +@@ -524,6 +527,16 @@ int ucs_socket_max_conn() int ucs_socket_max_conn() { static long somaxconn_val = 0; + +#if defined(__FreeBSD__) + if (!somaxconn_val) { + int val; + size_t len = sizeof(val); + if (sysctlbyname("kern.ipc.somaxconn", &val, &len, NULL, 0) == 0) { + somaxconn_val = val; + } + } +#endif if (somaxconn_val || (ucs_read_file_number(&somaxconn_val, 1, diff --git a/net/ucx/files/patch-src_ucs_sys_sys.c b/net/ucx/files/patch-src_ucs_sys_sys.c index 0e8f1cf6cef2..87eed1335220 100644 --- a/net/ucx/files/patch-src_ucs_sys_sys.c +++ b/net/ucx/files/patch-src_ucs_sys_sys.c @@ -1,354 +1,442 @@ ---- src/ucs/sys/sys.c.orig 2026-05-06 13:47:14 UTC +--- src/ucs/sys/sys.c.orig 2026-09-12 01:59:18 UTC +++ src/ucs/sys/sys.c -@@ -23,16 +23,28 @@ +@@ -23,16 +23,29 @@ #include #include +#include #include #include #include #include #include #include +#include #include +#include #include #include #include +#include +#if defined(__FreeBSD__) +#include +#include +#include +#include +#include +#include ++#include +#endif #ifdef HAVE_SYS_THR_H #include #endif -@@ -94,7 +106,7 @@ const char *ucs_get_host_name() +@@ -94,7 +107,7 @@ const char *ucs_get_host_name() const char *ucs_get_host_name() { - static char hostname[HOST_NAME_MAX] = {0}; + static char hostname[UCS_HOST_NAME_MAX] = {0}; if (*hostname == 0) { gethostname(hostname, sizeof(hostname)); -@@ -181,6 +193,46 @@ static uint64_t ucs_get_mac_address() +@@ -209,6 +222,46 @@ static uint64_t ucs_get_mac_address() static uint64_t ucs_get_mac_address() { static uint64_t mac_address = 0; +#if defined(__FreeBSD__) + struct ifaddrs *ifap = NULL, *ifa; + + if (mac_address != 0) { + return mac_address; + } + + if (getifaddrs(&ifap) != 0) { + ucs_error("getifaddrs() failed: %m"); + return 0; + } + + for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + const struct sockaddr *sa = ifa->ifa_addr; + const struct sockaddr_dl *sdl; + const unsigned char *lladdr; + + if ((ifa->ifa_flags & IFF_LOOPBACK) || (sa == NULL)) { + continue; + } + if (sa->sa_family != AF_LINK) { + continue; + } + + sdl = (const struct sockaddr_dl *)sa; + if (sdl->sdl_alen < 6) { + continue; + } + + lladdr = (const unsigned char *)LLADDR(sdl); + mac_address = 0; + memcpy(&mac_address, lladdr, 6); + break; + } + + freeifaddrs(ifap); + + ucs_trace("MAC address is 0x%012"PRIX64, mac_address); + return mac_address; +#else struct ifreq ifr, *it, *end; struct ifconf ifc; char buf[1024]; -@@ -228,6 +280,7 @@ static uint64_t ucs_get_mac_address() +@@ -256,6 +309,7 @@ static uint64_t ucs_get_mac_address() } return mac_address; +#endif } static uint64_t __sumup_host_name(unsigned prime_index) -@@ -671,6 +724,21 @@ size_t ucs_get_memfree_size() +@@ -699,6 +753,22 @@ size_t ucs_get_memfree_size() { ssize_t mem_free; +#if defined(__FreeBSD__) + unsigned long v_free_count; + unsigned long pagesize; + size_t len; + + len = sizeof(v_free_count); + if (sysctlbyname("vm.stats.vm.v_free_count", &v_free_count, &len, + NULL, 0) == 0) { + len = sizeof(pagesize); + if (sysctlbyname("hw.pagesize", &pagesize, &len, NULL, 0) == 0) { + return v_free_count * pagesize; + } + } ++ + return UCS_DEFAULT_MEM_FREE; +#else - mem_free = ucs_get_meminfo_entry("MemFree"); + mem_free = ucs_get_meminfo_entry("MemFree", 1); if (mem_free == -1) { mem_free = UCS_DEFAULT_MEM_FREE; -@@ -679,12 +747,16 @@ size_t ucs_get_memfree_size() +@@ -707,12 +777,16 @@ size_t ucs_get_memfree_size() } return mem_free; +#endif } ssize_t ucs_get_huge_page_size() { static ssize_t huge_page_size = 0; +#if defined(__FreeBSD__) + return -1; +#else /* Cache the huge page size value */ if (huge_page_size == 0) { - huge_page_size = ucs_get_meminfo_entry("Hugepagesize"); -@@ -696,6 +768,7 @@ ssize_t ucs_get_huge_page_size() + huge_page_size = ucs_get_meminfo_entry("Hugepagesize", 1); +@@ -724,6 +798,7 @@ ssize_t ucs_get_huge_page_size() } return huge_page_size; +#endif } - size_t ucs_get_phys_mem_size() -@@ -751,6 +824,10 @@ static void ucs_sysv_shmget_error_check_ENOSPC(size_t + static ssize_t ucs_get_huge_pages_count() +@@ -777,6 +852,17 @@ size_t ucs_get_shmmax() + #define UCS_PROC_SYS_SHMMAX_FILE "/proc/sys/kernel/shmmax" + size_t ucs_get_shmmax() + { ++#if defined(__FreeBSD__) ++ unsigned long shmmax; ++ size_t len = sizeof(shmmax); ++ ++ if (sysctlbyname("kern.ipc.shmmax", &shmmax, &len, NULL, 0) != 0) { ++ ucs_warn("failed to read kern.ipc.shmmax: %m"); ++ return 0; ++ } ++ ++ return (size_t)shmmax; ++#else + ucs_status_t status; + long size; + +@@ -787,12 +873,17 @@ size_t ucs_get_shmmax() + } + + return size; ++#endif + } + + static void ucs_sysv_shmget_error_check_ENOSPC(size_t alloc_size, const struct shminfo *ipc_info, char *buf, size_t max) { +#if defined(__FreeBSD__) + (void)alloc_size; (void)ipc_info; (void)buf; (void)max; + return; +#else unsigned long new_used_ids; unsigned long new_shm_tot; struct shm_info shm_info; -@@ -782,6 +859,7 @@ static void ucs_sysv_shmget_error_check_ENOSPC(size_t +@@ -824,6 +915,7 @@ static void ucs_sysv_shmget_error_check_ENOSPC(size_t " limit in /proc/sys/kernel/shmall (=%lu)", new_shm_tot, ipc_info->shmall); } +#endif } ucs_status_t ucs_sys_get_proc_cap(uint32_t *effective) -@@ -842,6 +920,14 @@ static void ucs_sysv_shmget_format_error(size_t alloc_ +@@ -884,6 +976,14 @@ static void ucs_sysv_shmget_format_error(size_t alloc_ const char *alloc_name, int sys_errno, char *buf, size_t max) { +#if defined(__FreeBSD__) + /* FreeBSD does not have Linux shmctl(IPC_INFO/SHM_INFO) or struct shminfo. */ + snprintf(buf, max, + "shmget(size=%zu flags=0x%x) for %s failed: %s, please check shared " + "memory limits by 'sysctl kern.ipc' / 'sysctl hw.pagesize' / 'ipcs -a'", + alloc_size, flags, alloc_name, strerror(sys_errno)); + return; +#else struct shminfo ipc_info; char *p, *endp, *errp; int ret; -@@ -879,6 +965,7 @@ static void ucs_sysv_shmget_format_error(size_t alloc_ +@@ -921,6 +1021,7 @@ static void ucs_sysv_shmget_format_error(size_t alloc_ if (p == errp) { snprintf(p, endp - p, ", please check shared memory limits by 'ipcs -l'"); } +#endif } ucs_status_t ucs_sysv_alloc(size_t *size, size_t max_size, void **address_p, -@@ -1272,11 +1359,44 @@ void *ucs_sys_realloc(void *old_ptr, size_t old_length +@@ -1315,11 +1416,44 @@ void *ucs_sys_realloc(void *old_ptr, size_t old_length { void *ptr; +#if defined(__FreeBSD__) + size_t copy_length; + new_length = ucs_align_up_pow2(new_length, ucs_get_page_size()); if (old_ptr == NULL) { + ptr = mmap(NULL, new_length, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) { + ucs_log_fatal_error("mmap(NULL, %zu, READ|WRITE, PRIVATE|ANON) failed: %m", + new_length); + return NULL; + } + return ptr; + } + + old_length = ucs_align_up_pow2(old_length, ucs_get_page_size()); + ptr = mmap(NULL, new_length, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, -1, 0); + if (ptr == MAP_FAILED) { + ucs_log_fatal_error("mmap(NULL, %zu, READ|WRITE, PRIVATE|ANON) failed: %m", + new_length); + return NULL; + } + + copy_length = ucs_min(old_length, new_length); + memcpy(ptr, old_ptr, copy_length); + + if (munmap(old_ptr, old_length) != 0) { + ucs_log_fatal_error("munmap(%p, %zu) failed: %m", old_ptr, old_length); + } + + return ptr; +#elif defined(__linux__) + new_length = ucs_align_up_pow2(new_length, ucs_get_page_size()); + if (old_ptr == NULL) { /* Note: Must pass the 0 offset as "long", otherwise it will be * partially undefined when converted to syscall arguments */ - ptr = (void*)syscall(__NR_mmap, NULL, new_length, PROT_READ|PROT_WRITE, + ptr = (void*)syscall(SYS_mmap, NULL, new_length, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0ul); if (ptr == MAP_FAILED) { ucs_log_fatal_error("mmap(NULL, %zu, READ|WRITE, PRIVATE|ANON) failed: %m", -@@ -1285,7 +1405,7 @@ void *ucs_sys_realloc(void *old_ptr, size_t old_length +@@ -1328,7 +1462,7 @@ void *ucs_sys_realloc(void *old_ptr, size_t old_length } } else { old_length = ucs_align_up_pow2(old_length, ucs_get_page_size()); - ptr = (void*)syscall(__NR_mremap, old_ptr, old_length, new_length, + ptr = (void*)syscall(SYS_mremap, old_ptr, old_length, new_length, MREMAP_MAYMOVE); if (ptr == MAP_FAILED) { ucs_log_fatal_error("mremap(%p, %zu, %zu, MAYMOVE) failed: %m", -@@ -1295,6 +1415,13 @@ void *ucs_sys_realloc(void *old_ptr, size_t old_length +@@ -1338,6 +1472,13 @@ void *ucs_sys_realloc(void *old_ptr, size_t old_length } return ptr; +#else +(void)old_ptr; + (void)old_length; + (void)new_length; + ucs_log_fatal_error("ucs_sys_realloc() is not implemented on this platform"); + return NULL; +#endif } void ucs_sys_free(void *ptr, size_t length) -@@ -1302,11 +1429,19 @@ void ucs_sys_free(void *ptr, size_t length) +@@ -1345,11 +1486,19 @@ void ucs_sys_free(void *ptr, size_t length) int ret; if (ptr != NULL) { +#if defined(__FreeBSD__) length = ucs_align_up_pow2(length, ucs_get_page_size()); - ret = syscall(__NR_munmap, ptr, length); + ret = munmap(ptr, length); if (ret) { ucs_log_fatal_error("munmap(%p, %zu) failed: %m", ptr, length); } +#else + length = ucs_align_up_pow2(length, ucs_get_page_size()); + ret = syscall(SYS_munmap, ptr, length); + if (ret) { + ucs_log_fatal_error("munmap(%p, %zu) failed: %m", ptr, length); + } +#endif } } -@@ -1376,12 +1511,32 @@ ucs_status_t ucs_sys_pthread_getaffinity(ucs_sys_cpuse +@@ -1419,12 +1568,32 @@ ucs_status_t ucs_sys_pthread_getaffinity(ucs_sys_cpuse ucs_status_t ucs_sys_pthread_getaffinity(ucs_sys_cpuset_t *cpuset) { +#if defined(__FreeBSD__) + long tid; + int ret; + +#ifdef HAVE_SYS_THR_H + thr_self(&tid); +#else + /* Fallback: best-effort use process id */ + tid = (long)getpid(); +#endif + + ret = cpuset_getaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, tid, + sizeof(*cpuset), cpuset); + if (ret != 0) { + ucs_error("cpuset_getaffinity(TID=%ld) failed: %m", tid); + return UCS_ERR_INVALID_PARAM; + } + return UCS_OK; +#else if (pthread_getaffinity_np(pthread_self(), sizeof(*cpuset), cpuset)) { ucs_error("pthread_getaffinity_np() failed: %m"); return UCS_ERR_INVALID_PARAM; } return UCS_OK; +#endif } void ucs_sys_cpuset_copy(ucs_cpu_set_t *dst, const ucs_sys_cpuset_t *src) -@@ -1435,6 +1590,10 @@ ucs_status_t ucs_sys_get_boot_id(uint64_t *high, uint6 +@@ -1494,6 +1663,10 @@ ucs_status_t ucs_sys_get_boot_id(uint64_t *high, uint6 static ucs_init_once_t init_once = UCS_INIT_ONCE_INITIALIZER; static ucs_status_t status = UCS_ERR_IO_ERROR; +#if defined(__FreeBSD__) + struct timeval boottime; + size_t len; +#else char bootid_str[256]; ssize_t size; uint32_t v1; -@@ -1444,8 +1603,17 @@ ucs_status_t ucs_sys_get_boot_id(uint64_t *high, uint6 +@@ -1503,8 +1676,17 @@ ucs_status_t ucs_sys_get_boot_id(uint64_t *high, uint6 uint8_t v5[6]; int res; int i; +#endif UCS_INIT_ONCE(&init_once) { +#if defined(__FreeBSD__) + len = sizeof(boottime); + if (sysctlbyname("kern.boottime", &boottime, &len, NULL, 0) == 0) { + boot_id.high = (uint64_t)boottime.tv_sec; + boot_id.low = (uint64_t)boottime.tv_usec; + status = UCS_OK; + } +#else size = ucs_read_file_str(bootid_str, sizeof(bootid_str), 1, "%s", UCS_PROCESS_BOOTID_FILE); if (size <= 0) { -@@ -1465,6 +1633,7 @@ ucs_status_t ucs_sys_get_boot_id(uint64_t *high, uint6 +@@ -1524,6 +1706,7 @@ ucs_status_t ucs_sys_get_boot_id(uint64_t *high, uint6 boot_id.high |= (uint64_t)v5[i] << (16 + (i * 8)); } } +#endif } if (status == UCS_OK) { -@@ -1542,7 +1711,8 @@ ucs_status_t ucs_pthread_create(pthread_t *thread_id_p +@@ -1601,7 +1784,8 @@ ucs_status_t ucs_pthread_create(pthread_t *thread_id_p ret = pthread_create(&thread_id, NULL, start_routine, arg); if (ret != 0) { - ucs_error("pthread_create() failed: %m"); + ucs_error("pthread_create(start_routine=%p arg=%p) failed: %s (%d)", + start_routine, arg, strerror(ret), ret); return UCS_ERR_IO_ERROR; } +@@ -1630,6 +1814,52 @@ unsigned long ucs_sys_get_proc_create_time(pid_t pid) + + unsigned long ucs_sys_get_proc_create_time(pid_t pid) + { ++#if defined(__FreeBSD__) ++ struct kinfo_proc kp; ++ struct timeval boottime; ++ uint64_t proc_usec, boot_usec, start_usec; ++ size_t len; ++ int mib[4]; ++ ++ /* ++ * FreeBSD exposes process creation time through struct kinfo_proc. ++ * Preserve the API semantics of returning time since system boot. ++ */ ++ mib[0] = CTL_KERN; ++ mib[1] = KERN_PROC; ++ mib[2] = KERN_PROC_PID; ++ mib[3] = pid; ++ ++ memset(&kp, 0, sizeof(kp)); ++ len = sizeof(kp); ++ ++ if (sysctl(mib, 4, &kp, &len, NULL, 0) < 0) { ++ ucs_debug("failed to get information for pid %d: %m", pid); ++ return 0ul; ++ } ++ ++ if ((len == 0) || (kp.ki_pid != pid)) { ++ return 0ul; ++ } ++ ++ len = sizeof(boottime); ++ if (sysctlbyname("kern.boottime", &boottime, &len, NULL, 0) < 0) { ++ ucs_debug("failed to get system boot time: %m"); ++ return 0ul; ++ } ++ ++ proc_usec = ((uint64_t)kp.ki_start.tv_sec * UCS_MBYTE) + ++ kp.ki_start.tv_usec; ++ boot_usec = ((uint64_t)boottime.tv_sec * UCS_MBYTE) + ++ boottime.tv_usec; ++ ++ if (proc_usec <= boot_usec) { ++ return 0ul; ++ } ++ ++ start_usec = proc_usec - boot_usec; ++ return (unsigned long)start_usec; ++#else + char stat[1024]; + char *start_str; + ssize_t size; +@@ -1658,6 +1888,7 @@ err: + ucs_debug("failed to scan "UCS_PROCCESS_STAT_FMT, pid); + err: + return 0ul; ++#endif + } + + ucs_status_t ucs_sys_get_effective_memlock_rlimit(size_t *rlimit_value) diff --git a/net/ucx/files/patch-src_ucs_sys_sys.h b/net/ucx/files/patch-src_ucs_sys_sys.h deleted file mode 100644 index 4ba632e48ca5..000000000000 --- a/net/ucx/files/patch-src_ucs_sys_sys.h +++ /dev/null @@ -1,26 +0,0 @@ ---- src/ucs/sys/sys.h.orig 2026-02-05 12:41:56 UTC -+++ src/ucs/sys/sys.h -@@ -50,6 +50,8 @@ - #include - #include - #include -+#include -+#include - - - #include -@@ -61,6 +63,14 @@ typedef cpuset_t ucs_sys_cpuset_t; - typedef cpuset_t ucs_sys_cpuset_t; - #else - #error "Port me" -+#endif -+ -+#ifndef UCS_HOST_NAME_MAX -+# ifdef _POSIX_HOST_NAME_MAX -+# define UCS_HOST_NAME_MAX _POSIX_HOST_NAME_MAX -+# else -+# define UCS_HOST_NAME_MAX 256 -+# endif - #endif - - #define UCS_SYS_FS_SYSTEM_PATH "/sys/devices/system" diff --git a/net/ucx/files/patch-src_ucs_type_float8.h b/net/ucx/files/patch-src_ucs_type_float8.h index cf2e88796c29..0b1ac7a22503 100644 --- a/net/ucx/files/patch-src_ucs_type_float8.h +++ b/net/ucx/files/patch-src_ucs_type_float8.h @@ -1,174 +1,189 @@ ---- src/ucs/type/float8.h.orig 2026-02-04 09:52:46 UTC +--- src/ucs/type/float8.h.orig 2026-09-09 14:58:32 UTC +++ src/ucs/type/float8.h -@@ -3,12 +3,63 @@ - * - * See file LICENSE for terms. - */ -- +@@ -7,31 +7,60 @@ #ifndef UCS_TYPE_FLOAT_H #define UCS_TYPE_FLOAT_H +-#ifdef HAVE_IEEE754_H -#include +#include +#include - -+/* IEEE754 double layout helpers without bitfields. ++ ++/* ++ * IEEE754 double layout helpers without relying on implementation-defined ++ * C bitfield layout. + */ +static inline void +ucs_double_to_words(double d, uint32_t *hi, uint32_t *lo) +{ + uint32_t w[2]; ++ + memcpy(w, &d, sizeof(w)); +#if defined(FLOAT_WORDS_BIGENDIAN) + *hi = w[0]; + *lo = w[1]; -+#else + #else +-/* Portable fallback for systems without (non-glibc, e.g. musl, FreeBSD libc) */ +-union ieee754_double { + *hi = w[1]; + *lo = w[0]; +#endif +} + +static inline double +ucs_words_to_double(uint32_t hi, uint32_t lo) +{ + uint32_t w[2]; -+ double d; + double d; +- struct { +-#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +- unsigned int negative:1; +- unsigned int exponent:11; +- unsigned int mantissa0:20; +- unsigned int mantissa1:32; +-#elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +- unsigned int mantissa1:32; +- unsigned int mantissa0:20; +- unsigned int exponent:11; +- unsigned int negative:1; ++ +#if defined(FLOAT_WORDS_BIGENDIAN) + w[0] = hi; + w[1] = lo; -+#else + #else +-# error "Unsupported byte order" + w[0] = lo; + w[1] = hi; -+#endif + #endif +- } ieee; +-}; +-#define IEEE754_DOUBLE_BIAS 0x3ff +-#endif + + memcpy(&d, w, sizeof(d)); + return d; +} + -+static inline uint32_t ucs_ieee_double_sign(uint32_t hi) -+{ -+ return hi >> 31; -+} -+ -+static inline uint32_t ucs_ieee_double_exp(uint32_t hi) ++static inline uint32_t ++ucs_ieee_double_exp(uint32_t hi) +{ + return (hi >> 20) & 0x7ffu; +} + -+static inline uint32_t ucs_ieee_double_mant_hi20(uint32_t hi) ++static inline uint32_t ++ucs_ieee_double_mant_hi20(uint32_t hi) +{ + return hi & 0x000fffffu; +} + -+#ifndef IEEE754_DOUBLE_BIAS -+# define IEEE754_DOUBLE_BIAS 1023 -+#endif ++#define IEEE754_DOUBLE_BIAS 1023 + #include #include #include -@@ -18,7 +69,6 @@ typedef uint8_t ucs_fp8_t; +@@ -41,7 +70,6 @@ typedef uint8_t ucs_fp8_t; typedef uint8_t ucs_fp8_t; - /** * Bits number in the exponent part of a packed floating-point number */ -@@ -103,24 +153,31 @@ static UCS_F_ALWAYS_INLINE ucs_fp8_t ucs_fp8_pack(doub +@@ -126,24 +154,31 @@ static UCS_F_ALWAYS_INLINE ucs_fp8_t ucs_fp8_pack(doub static UCS_F_ALWAYS_INLINE ucs_fp8_t ucs_fp8_pack(double value, uint64_t min, uint64_t max) { - union ieee754_double ieee_value = {0}; + uint32_t hi, lo; + uint32_t exp; + uint32_t mant0; uint8_t exponent; int8_t min_exponent, max_exponent; - ieee_value.d = value; min_exponent = ucs_ilog2(min); max_exponent = ucs_ilog2(max); - if (ucs_unlikely(ieee_value.ieee.exponent == _UCS_FP8_IEEE_NAN_EXPONENT)) { + ucs_double_to_words(value, &hi, &lo); + exp = ucs_ieee_double_exp(hi); + mant0 = ucs_ieee_double_mant_hi20(hi); + + if (ucs_unlikely(exp == _UCS_FP8_IEEE_NAN_EXPONENT)) { /* NaN maps to a special value for NaN */ exponent = _UCS_FP8_NAN; - } else if (ucs_unlikely(ieee_value.ieee.exponent > + } else if (ucs_unlikely(exp > (max_exponent + _UCS_FP8_EXPONENT_OFFSET))) { /* A number beyond the max supported is capped */ exponent = max_exponent - min_exponent; - ieee_value.ieee.mantissa0 = 0; - ieee_value.ieee.mantissa1 = 0; - } else if (ucs_unlikely(ieee_value.ieee.exponent <= + /* zero mantissa in-place */ + mant0 = 0; + lo = 0; + hi = (hi & 0xfff00000u); /* keep sign+exp, clear mantissa hi20 */ + } else if (ucs_unlikely(exp <= min_exponent + _UCS_FP8_EXPONENT_OFFSET)) { if (ucs_unlikely(value == 0)) { /* 0 maps to a special value for 0 */ -@@ -128,15 +185,16 @@ static UCS_F_ALWAYS_INLINE ucs_fp8_t ucs_fp8_pack(doub +@@ -151,15 +186,16 @@ static UCS_F_ALWAYS_INLINE ucs_fp8_t ucs_fp8_pack(doub } else { /* A number below the min supported is rounded up */ exponent = 1; - ieee_value.ieee.mantissa0 = 0; - ieee_value.ieee.mantissa1 = 0; + mant0 = 0; + lo = 0; + hi = (hi & 0xfff00000u); } } else { - exponent = ieee_value.ieee.exponent - _UCS_FP8_EXPONENT_OFFSET - + exponent = exp - _UCS_FP8_EXPONENT_OFFSET - min_exponent; } - return exponent | ((ieee_value.ieee.mantissa0 >> _UCS_FP_MANTISSA_OFFSET) + return exponent | ((mant0 >> _UCS_FP_MANTISSA_OFFSET) << _UCS_FP8_EXPONENT_BITS); } -@@ -154,23 +212,28 @@ ucs_fp8_unpack(ucs_fp8_t value, uint64_t min, uint64_t +@@ -177,23 +213,28 @@ ucs_fp8_unpack(ucs_fp8_t value, uint64_t min, uint64_t static UCS_F_ALWAYS_INLINE double ucs_fp8_unpack(ucs_fp8_t value, uint64_t min, uint64_t max) { - union ieee754_double ieee_value = {0}; + uint32_t hi = 0, lo = 0; + uint32_t exp; + uint32_t mant0; uint8_t exponent = value & _UCS_FP8_EXPONENT_MASK; - ieee_value.ieee.negative = 0; + (void)max; + if (ucs_unlikely(exponent == 0)) { - ieee_value.ieee.exponent = 0; + exp = 0; } else if (ucs_unlikely(exponent == _UCS_FP8_NAN)) { - ieee_value.ieee.exponent = _UCS_FP8_IEEE_NAN_EXPONENT; + exp = _UCS_FP8_IEEE_NAN_EXPONENT; } else { - ieee_value.ieee.exponent = exponent + _UCS_FP8_EXPONENT_OFFSET + + exp = exponent + _UCS_FP8_EXPONENT_OFFSET + ucs_ilog2(min); } - ieee_value.ieee.mantissa0 = value >> _UCS_FP8_EXPONENT_BITS; - ieee_value.ieee.mantissa0 = ieee_value.ieee.mantissa0 - << _UCS_FP_MANTISSA_OFFSET; + mant0 = (uint32_t)(value >> _UCS_FP8_EXPONENT_BITS); + mant0 = (mant0 << _UCS_FP_MANTISSA_OFFSET) & 0x000fffffu; - return ieee_value.d; + hi = ((exp & 0x7ffu) << 20) | (mant0 & 0x000fffffu); + lo = 0; + + return ucs_words_to_double(hi, lo); } diff --git a/net/ucx/files/patch-src_uct_base_uct__iface.c b/net/ucx/files/patch-src_uct_base_uct__iface.c index 9f17767fbd5f..01320cc86b56 100644 --- a/net/ucx/files/patch-src_uct_base_uct__iface.c +++ b/net/ucx/files/patch-src_uct_base_uct__iface.c @@ -1,22 +1,22 @@ ---- src/uct/base/uct_iface.c.orig 2026-06-18 20:00:16 UTC +--- src/uct/base/uct_iface.c.orig 2026-09-09 16:00:25 UTC +++ src/uct/base/uct_iface.c -@@ -1025,6 +1025,11 @@ int uct_iface_local_is_reachable(uct_iface_local_addr_ +@@ -1053,6 +1053,11 @@ int uct_iface_local_is_reachable(uct_iface_local_addr_ ucs_sys_namespace_type_t sys_ns_type, const uct_iface_is_reachable_params_t *params) { +#ifdef __FreeBSD__ + /* On FreeBSD, local processes sharing loopback or IPC mechanisms + * are always mutually reachable. */ + return 1; +#else uct_iface_local_addr_ns_t my_addr = {}; uct_iface_get_local_address(&my_addr, sys_ns_type); -@@ -1054,6 +1059,7 @@ int uct_iface_local_is_reachable(uct_iface_local_addr_ +@@ -1080,6 +1085,7 @@ int uct_iface_local_is_reachable(uct_iface_local_addr_ return 0; } return 1; +#endif } void uct_iface_mpool_config_copy(ucs_mpool_params_t *mp_params, diff --git a/net/ucx/files/patch-src_uct_ib_base_ib__device.c b/net/ucx/files/patch-src_uct_ib_base_ib__device.c deleted file mode 100644 index 7916113cbb69..000000000000 --- a/net/ucx/files/patch-src_uct_ib_base_ib__device.c +++ /dev/null @@ -1,17 +0,0 @@ ---- src/uct/ib/base/ib_device.c.orig 2026-03-02 11:31:24 UTC -+++ src/uct/ib/base/ib_device.c -@@ -30,6 +30,14 @@ - #include - #endif - -+#ifndef s6_addr32 -+# if defined(__FreeBSD__) -+# define s6_addr32 __u6_addr.__u6_addr32 -+# elif defined(__linux__) -+# define s6_addr32 u6_addr.u6_addr32 -+# endif -+#endif -+ - #define UCT_IB_DEVICE_LOOPBACK_NDEV_INDEX_INVALID 0 - - diff --git a/net/ucx/files/patch-src_uct_ib_base_ib__device.h b/net/ucx/files/patch-src_uct_ib_base_ib__device.h index 9ee4b5440b29..c2603c53f56a 100644 --- a/net/ucx/files/patch-src_uct_ib_base_ib__device.h +++ b/net/ucx/files/patch-src_uct_ib_base_ib__device.h @@ -1,18 +1,18 @@ ---- src/uct/ib/base/ib_device.h.orig 2026-02-05 12:41:56 UTC +--- src/uct/ib/base/ib_device.h.orig 2026-09-09 16:00:25 UTC +++ src/uct/ib/base/ib_device.h -@@ -20,8 +20,13 @@ +@@ -21,8 +21,13 @@ #include #include -#include - +#if defined(__linux__) +# include +# include +#else +# include +# include +#endif #define UCT_IB_QPN_ORDER 24 /* How many bits can be an IB QP number */ #define UCT_IB_UIDX_SHIFT 8 /* BE uidx shift */ diff --git a/net/ucx/files/patch-src_uct_ib_ud_base_ud__iface.c b/net/ucx/files/patch-src_uct_ib_ud_base_ud__iface.c index b0ed4172a351..41dd3989c61d 100644 --- a/net/ucx/files/patch-src_uct_ib_ud_base_ud__iface.c +++ b/net/ucx/files/patch-src_uct_ib_ud_base_ud__iface.c @@ -1,17 +1,17 @@ ---- src/uct/ib/ud/base/ud_iface.c.orig 2026-02-05 12:41:56 UTC +--- src/uct/ib/ud/base/ud_iface.c.orig 2026-09-09 16:00:25 UTC +++ src/uct/ib/ud/base/ud_iface.c -@@ -1113,7 +1113,13 @@ union ibv_gid* uct_ud_grh_get_dgid(struct ibv_grh *grh +@@ -1112,7 +1112,13 @@ union ibv_gid* uct_ud_grh_get_dgid(struct ibv_grh *grh size_t i; /* Make sure that daddr in IPv4 resides in the last 4 bytes in GRH */ - UCS_STATIC_ASSERT((UCT_IB_GRH_LEN - (20 + offsetof(struct iphdr, daddr))) == + UCS_STATIC_ASSERT((UCT_IB_GRH_LEN - (20 + offsetof( +#if defined(__linux__) + struct iphdr, daddr +#else + struct ip, ip_dst +#endif + ))) == UCS_IPV4_ADDR_LEN); /* Make sure that dgid resides in the last 16 bytes in GRH */ diff --git a/net/ucx/files/patch-src_uct_sm_mm_base_mm__iface.c b/net/ucx/files/patch-src_uct_sm_mm_base_mm__iface.c index 000376248199..f9d9fe9984e9 100644 --- a/net/ucx/files/patch-src_uct_sm_mm_base_mm__iface.c +++ b/net/ucx/files/patch-src_uct_sm_mm_base_mm__iface.c @@ -1,87 +1,110 @@ ---- src/uct/sm/mm/base/mm_iface.c.orig 2026-03-14 22:02:10 UTC +--- src/uct/sm/mm/base/mm_iface.c.orig 2026-09-14 16:39:41 UTC +++ src/uct/sm/mm/base/mm_iface.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include /* Maximal number of events to clear from the signaling pipe in single call */ -@@ -681,6 +684,10 @@ static ucs_status_t uct_mm_iface_create_signal_fd(uct_ +@@ -143,10 +146,18 @@ uct_mm_iface_is_reachable_v2(const uct_iface_h tl_ifac + return 0; + } + +- return uct_sm_iface_is_reachable(tl_iface, params) && +- uct_mm_md_mapper_ops(md)->is_reachable(md, iface_addr->fifo_seg_id, +- iface_addr + 1) && +- uct_iface_scope_is_reachable(tl_iface, params); ++ if (!uct_sm_iface_is_reachable(tl_iface, params)) { ++ return 0; ++ } ++ ++ if (!uct_mm_md_mapper_ops(md)->is_reachable(md, iface_addr->fifo_seg_id, ++ iface_addr + 1)) { ++ uct_iface_fill_info_str_buf(params, ++ "shared memory segment is not reachable"); ++ return 0; ++ } ++ ++ return uct_iface_scope_is_reachable(tl_iface, params); + } + + void uct_mm_iface_release_desc(uct_recv_desc_t *self, void *desc) +@@ -680,6 +691,10 @@ static ucs_status_t uct_mm_iface_create_signal_fd(uct_ ucs_status_t status; socklen_t addrlen; struct sockaddr_un bind_addr; +#if defined(__FreeBSD__) + const char *tmpdir; + int path_len; +#endif int ret; /* Create a UNIX domain socket to send and receive wakeup signal from remote processes */ -@@ -700,10 +707,33 @@ static ucs_status_t uct_mm_iface_create_signal_fd(uct_ +@@ -699,10 +714,33 @@ static ucs_status_t uct_mm_iface_create_signal_fd(uct_ /* Bind the signal socket to automatic address */ bind_addr.sun_family = AF_UNIX; memset(bind_addr.sun_path, 0, sizeof(bind_addr.sun_path)); +#if defined(__FreeBSD__) + tmpdir = ucs_get_tmpdir(); + path_len = snprintf(bind_addr.sun_path, sizeof(bind_addr.sun_path), + "%s/ucx_mm.%ld.%p", + tmpdir, (long)getpid(), (void*)iface); + if ((path_len < 0) || ((size_t)path_len >= sizeof(bind_addr.sun_path))) { + ucs_error("Failed to generate unix domain socket path"); + status = UCS_ERR_IO_ERROR; + goto err_close; + } + + unlink(bind_addr.sun_path); + + addrlen = offsetof(struct sockaddr_un, sun_path) + path_len + 1; + ret = bind(iface->signal_fd, (struct sockaddr*)&bind_addr, addrlen); +#else + /* Linux autobind behavior */ ret = bind(iface->signal_fd, (struct sockaddr*)&bind_addr, sizeof(sa_family_t)); +#endif if (ret < 0) { ucs_error("Failed to auto-bind unix domain socket: %m"); status = UCS_ERR_IO_ERROR; +#if defined(__FreeBSD__) + if (bind_addr.sun_path[0] != '\0') { + unlink(bind_addr.sun_path); + } +#endif goto err_close; } -@@ -718,6 +748,11 @@ static ucs_status_t uct_mm_iface_create_signal_fd(uct_ +@@ -717,6 +755,11 @@ static ucs_status_t uct_mm_iface_create_signal_fd(uct_ if (ret < 0) { ucs_error("Failed to retrieve unix domain socket address: %m"); status = UCS_ERR_IO_ERROR; +#if defined(__FreeBSD__) + if (bind_addr.sun_path[0] != '\0') { + unlink(bind_addr.sun_path); + } +#endif goto err_close; } -@@ -904,6 +939,17 @@ static UCS_CLASS_CLEANUP_FUNC(uct_mm_iface_t) +@@ -903,6 +946,17 @@ static UCS_CLASS_CLEANUP_FUNC(uct_mm_iface_t) ucs_mpool_put(self->last_recv_desc); ucs_mpool_cleanup(&self->recv_desc_mp, 1); + +#if defined(__FreeBSD__) + { + const struct sockaddr_un *sun = + (const struct sockaddr_un *)ucs_unaligned_ptr(&self->recv_fifo_ctl->signal_sockaddr); + if ((self->recv_fifo_ctl->signal_addrlen > offsetof(struct sockaddr_un, sun_path)) && + (sun->sun_path[0] != '\0')) { + unlink(sun->sun_path); + } + } +#endif close(self->signal_fd); uct_iface_mem_free(&self->recv_fifo_mem); ucs_arbiter_cleanup(&self->arbiter); diff --git a/net/ucx/files/patch-src_uct_sm_mm_posix_mm__posix.c b/net/ucx/files/patch-src_uct_sm_mm_posix_mm__posix.c new file mode 100644 index 000000000000..a6678226f53c --- /dev/null +++ b/net/ucx/files/patch-src_uct_sm_mm_posix_mm__posix.c @@ -0,0 +1,118 @@ +--- src/uct/sm/mm/posix/mm_posix.c.orig 2026-09-11 19:04:33 UTC ++++ src/uct/sm/mm/posix/mm_posix.c +@@ -49,6 +49,11 @@ + #define UCT_POSIX_SHM_OPEN_DIR "/dev/shm" /* directory path for shm_open() */ + #define UCT_POSIX_FILE_FMT "/ucx_shm_posix_%"PRIx64 + #define UCT_POSIX_PROCFS_FILE_FMT "/proc/%d/fd/%d" /* file pattern for procfs mode */ ++#if defined(__FreeBSD__) ++#define UCT_POSIX_USE_PROC_LINK_DEFAULT "n" ++#else ++#define UCT_POSIX_USE_PROC_LINK_DEFAULT "y" ++#endif + + + typedef struct uct_posix_md_config { +@@ -82,7 +87,7 @@ static ucs_config_field_t uct_posix_md_config_table[] + ucs_offsetof(uct_posix_md_config_t, shm_min_size), + UCS_CONFIG_TYPE_MEMUNITS}, + +- {"USE_PROC_LINK", "y", ++ {"USE_PROC_LINK", UCT_POSIX_USE_PROC_LINK_DEFAULT, + "Use /proc//fd/ to share posix file.\n" + " y - Use /proc//fd/ to share posix file.\n" + " n - Use original file path to share posix file.\n", +@@ -135,18 +140,30 @@ uct_posix_md_query(uct_md_h tl_md, uct_md_attr_v2_t *m + struct statvfs shm_statvfs; + size_t shm_size; + +- if (statvfs(posix_config->dir, &shm_statvfs) < 0) { +- ucs_error("could not stat shared memory device %s (%m)", +- posix_config->dir); +- return UCS_ERR_NO_DEVICE; ++#if defined(__FreeBSD__) ++ if (uct_posix_use_shm_open(posix_config)) { ++ /* ++ * FreeBSD POSIX shared memory objects are kernel VM objects and ++ * are not backed by the filesystem mounted at /dev/shm. ++ * The actual allocation path checks whether the requested size ++ * can be backed. ++ */ ++ shm_size = SIZE_MAX; ++ } else ++#endif ++ { ++ if (statvfs(posix_config->dir, &shm_statvfs) < 0) { ++ ucs_error("could not stat shared memory device %s (%m)", ++ posix_config->dir); ++ return UCS_ERR_NO_DEVICE; ++ } ++ shm_size = shm_statvfs.f_bsize * shm_statvfs.f_bavail; ++ if (shm_size < posix_config->shm_min_size) { ++ ucs_debug("md alloc disabled: only %zu bytes left in shm", shm_size); ++ shm_size = 0; ++ } + } + +- shm_size = shm_statvfs.f_bsize * shm_statvfs.f_bavail; +- if (shm_size < posix_config->shm_min_size) { +- ucs_debug("md alloc disabled: only %zu bytes left in shm", shm_size); +- shm_size = 0; +- } +- + uct_mm_md_query(&md->super, md_attr, shm_size); + + md_attr->rkey_packed_size = sizeof(uct_posix_packed_rkey_t) + +@@ -200,6 +217,13 @@ static ucs_status_t uct_posix_test_mem(int shm_fd, siz + size_to_write = ucs_min(remaining, chunk_size); + single_write = write(shm_fd, buf, size_to_write); + ++ if (single_write == 0) { ++ ucs_error("write returned zero before completing shared memory " ++ "allocation"); ++ status = UCS_ERR_IO_ERROR; ++ goto out_free_buf; ++ } ++ + if (single_write < 0) { + switch(errno) { + case ENOSPC: +@@ -551,13 +575,33 @@ uct_posix_mem_alloc(uct_md_h tl_md, size_t *length_p, + goto err_free_seg; + } + +- /* Check if the location of the backing file has enough memory for the +- * needed size by trying to write there before calling mmap */ +- status = uct_posix_test_mem(fd, seg->length); +- if (status != UCS_OK) { +- goto err_close; ++ /* ++ * Size/test the backing object before mmap. ++ * ++ * On FreeBSD, POSIX shared memory objects created by shm_open() are ++ * kernel VM objects rather than files in /dev/shm. write() does not ++ * provide the filesystem-space probing semantics used here and may ++ * return zero without making progress. Size the object explicitly ++ * with ftruncate() instead. ++ */ ++#if defined(__FreeBSD__) ++ if (seg->seg_id & UCT_POSIX_SEG_FLAG_SHM_OPEN) { ++ if (ftruncate(fd, seg->length) < 0) { ++ ucs_error("ftruncate(fd=%d, length=%zu) failed: %m", ++ fd, seg->length); ++ status = UCS_ERR_SHMEM_SEGMENT; ++ goto err_close; ++ } ++ } else ++#endif ++ { ++ /* Check if the location of the backing file has enough memory for the ++ * needed size by trying to write there before calling mmap */ ++ status = uct_posix_test_mem(fd, seg->length); ++ if (status != UCS_OK) { ++ goto err_close; ++ } + } +- + /* If using procfs link instead of mmid, remove the original file and update + * seg->seg_id */ + if (posix_config->use_proc_link) { diff --git a/net/ucx/files/patch-src_uct_sm_scopy_cma_configure.m4 b/net/ucx/files/patch-src_uct_sm_scopy_cma_configure.m4 new file mode 100644 index 000000000000..c8828d366893 --- /dev/null +++ b/net/ucx/files/patch-src_uct_sm_scopy_cma_configure.m4 @@ -0,0 +1,15 @@ +--- src/uct/sm/scopy/cma/configure.m4.orig 2026-09-14 16:35:41 UTC ++++ src/uct/sm/scopy/cma/configure.m4 +@@ -21,6 +21,12 @@ AS_IF([test "x$enable_cma" != xno], + ] + ) + ++AS_IF([test "x$cma_happy" != xno], ++ [AC_DEFINE([HAVE_CMA], [1], ++ [Define to 1 if CMA transport is available])], ++ [AC_DEFINE([HAVE_CMA], [0], ++ [Define to 0 if CMA transport is unavailable])]) ++ + AM_CONDITIONAL([HAVE_CMA], [test "x$cma_happy" != xno]) + AC_CONFIG_FILES([src/uct/sm/scopy/cma/Makefile + src/uct/sm/scopy/cma/ucx-cma.pc]) diff --git a/net/ucx/files/patch-src_uct_tcp_tcp__base.c b/net/ucx/files/patch-src_uct_tcp_tcp__base.c index 624ca2c1c428..87159aaf4f50 100644 --- a/net/ucx/files/patch-src_uct_tcp_tcp__base.c +++ b/net/ucx/files/patch-src_uct_tcp_tcp__base.c @@ -1,15 +1,29 @@ ---- src/uct/tcp/tcp_base.c.orig 2026-02-04 09:52:46 UTC +--- src/uct/tcp/tcp_base.c.orig 2026-09-13 01:26:42 UTC +++ src/uct/tcp/tcp_base.c -@@ -15,8 +15,12 @@ ucs_status_t ucs_tcp_base_set_syn_cnt(int fd, int tcp_ +@@ -17,9 +17,15 @@ ucs_status_t ucs_tcp_base_set_syn_cnt(int fd, int tcp_ ucs_status_t ucs_tcp_base_set_syn_cnt(int fd, int tcp_syn_cnt) { if (tcp_syn_cnt != UCS_ULUNITS_AUTO) { -+#if defined(__linux__) - ucs_socket_setopt(fd, IPPROTO_TCP, TCP_SYNCNT, (const void*)&tcp_syn_cnt, - sizeof(int)); ++#ifdef TCP_SYNCNT + return ucs_socket_setopt(fd, IPPROTO_TCP, TCP_SYNCNT, + (const void*)&tcp_syn_cnt, + sizeof(tcp_syn_cnt)); +#else + (void)fd; ++ (void)tcp_syn_cnt; ++ return UCS_OK; +#endif } - /* return UCS_OK anyway since setting TCP_SYNCNT is done on best effort */ + return UCS_OK; +@@ -54,7 +60,8 @@ ucs_status_t ucs_tcp_base_set_user_timeout(int fd, ucs + (const void*)&user_timeout_ms, + sizeof(user_timeout_ms)); + #else +- ucs_error("TCP_USER_TIMEOUT is not supported"); +- return UCS_ERR_UNSUPPORTED; ++ (void)fd; ++ (void)user_timeout; ++ return UCS_OK; + #endif + } diff --git a/net/ucx/files/patch-src_uct_tcp_tcp__iface.c b/net/ucx/files/patch-src_uct_tcp_tcp__iface.c index 09bb8fee678c..d20608ac9d7f 100644 --- a/net/ucx/files/patch-src_uct_tcp_tcp__iface.c +++ b/net/ucx/files/patch-src_uct_tcp_tcp__iface.c @@ -1,258 +1,258 @@ ---- src/uct/tcp/tcp_iface.c.orig 2026-07-24 21:46:07 UTC +--- src/uct/tcp/tcp_iface.c.orig 2026-09-09 16:04:04 UTC +++ src/uct/tcp/tcp_iface.c @@ -20,6 +20,10 @@ #include #include #include +#if defined(__FreeBSD__) +#include +#include +#endif #define UCT_TCP_IFACE_NETDEV_DIR "/sys/class/net" -@@ -195,6 +199,41 @@ uct_tcp_iface_get_address(uct_iface_h tl_iface, uct_if +@@ -197,6 +201,41 @@ uct_tcp_iface_get_address(uct_iface_h tl_iface, uct_if return UCS_OK; } +#if defined(__FreeBSD__) +static int uct_tcp_iface_has_route(const struct sockaddr *addr) +{ + struct sockaddr_storage addr_copy; + socklen_t addrlen; + int fd, ret; + + memcpy(&addr_copy, addr, sizeof(addr_copy)); + + if (addr->sa_family == AF_INET6) { + addrlen = sizeof(struct sockaddr_in6); + if (((struct sockaddr_in6*)&addr_copy)->sin6_port == 0) { + /* UDP connect() cannot target port 0; use a placeholder port + * since only route existence is being checked, not + * connectivity to a specific port. */ + ((struct sockaddr_in6*)&addr_copy)->sin6_port = htons(1); + } + } else { + addrlen = sizeof(struct sockaddr_in); + if (((struct sockaddr_in*)&addr_copy)->sin_port == 0) { + ((struct sockaddr_in*)&addr_copy)->sin_port = htons(1); + } + } + + fd = socket(addr->sa_family, SOCK_DGRAM, 0); + if (fd < 0) { + return 1; /* assume reachable if socket creation fails */ + } + + ret = connect(fd, (struct sockaddr*)&addr_copy, addrlen); + close(fd); + return (ret == 0); +} +#endif + static int uct_tcp_iface_is_reachable_v2(const uct_iface_h tl_iface, const uct_iface_is_reachable_params_t *params) -@@ -207,6 +246,9 @@ uct_tcp_iface_is_reachable_v2(const uct_iface_h tl_ifa +@@ -209,6 +248,9 @@ uct_tcp_iface_is_reachable_v2(const uct_iface_h tl_ifa char remote_addr_str[UCS_SOCKADDR_STRING_LEN]; unsigned ndev_index; ucs_status_t status; +#if defined(__FreeBSD__) + int is_best_route; +#endif if (!uct_iface_is_reachable_params_valid( params, UCT_IFACE_IS_REACHABLE_FIELD_DEVICE_ADDR)) { -@@ -264,8 +306,13 @@ uct_tcp_iface_is_reachable_v2(const uct_iface_h tl_ifa +@@ -266,8 +308,13 @@ uct_tcp_iface_is_reachable_v2(const uct_iface_h tl_ifa return 0; } - if (!ucs_netlink_is_best_route(ndev_index, - (const struct sockaddr*)&remote_addr)) { +#if defined(__FreeBSD__) + is_best_route = uct_tcp_iface_has_route((const struct sockaddr*)&remote_addr); +#else + int is_best_route = ucs_netlink_is_best_route(ndev_index, + (const struct sockaddr*)&remote_addr); +#endif + if (!is_best_route) { uct_iface_fill_info_str_buf( params, "no route to %s", ucs_sockaddr_str((const struct sockaddr *)&remote_addr, -@@ -284,6 +331,11 @@ uct_tcp_iface_get_sysfs_path(const char *dev_name, cha +@@ -286,6 +333,11 @@ uct_tcp_iface_get_sysfs_path(const char *dev_name, cha static const char * uct_tcp_iface_get_sysfs_path(const char *dev_name, char *path_buffer) { +#if defined(__FreeBSD__) + (void)dev_name; + (void)path_buffer; + return NULL; +#else const char *sysfs_path = NULL; ucs_status_t status; char *lowest_path_buf; -@@ -310,6 +362,7 @@ out: +@@ -312,6 +364,7 @@ out: ucs_free(lowest_path_buf); out: return sysfs_path; +#endif } static ucs_status_t uct_tcp_iface_query(uct_iface_h tl_iface, -@@ -422,7 +475,16 @@ static void uct_tcp_iface_handle_events(void *callback +@@ -424,7 +477,16 @@ static void uct_tcp_iface_handle_events(void *callback unsigned *count = (unsigned*)arg; uct_tcp_ep_t *ep = (uct_tcp_ep_t*)callback_data; +#if defined(__FreeBSD__) + /* kqueue may deliver a queued event for an ep that was closed and + * removed from the event set between the kevent() call and this + * callback. Treat it as a no-op rather than aborting. */ + if (ep->conn_state == UCT_TCP_EP_CONN_STATE_CLOSED) { + return; + } +#else ucs_assertv(ep->conn_state != UCT_TCP_EP_CONN_STATE_CLOSED, "ep=%p", ep); +#endif if (events & UCS_EVENT_SET_EVREAD) { *count += uct_tcp_ep_cm_state[ep->conn_state].rx_progress(ep); -@@ -943,6 +1005,10 @@ static int uct_tcp_is_bridge(const char *if_name) +@@ -950,6 +1012,10 @@ static int uct_tcp_is_bridge(const char *if_name) static int uct_tcp_is_bridge(const char *if_name) { +#if defined(__FreeBSD__) + (void)if_name; + return 0; +#else char *path; int ret; struct stat st; -@@ -962,6 +1028,7 @@ out: +@@ -969,6 +1035,7 @@ out: ucs_free(path); out: return ret; +#endif } ucs_status_t uct_tcp_query_devices(uct_md_h md, -@@ -971,7 +1038,11 @@ ucs_status_t uct_tcp_query_devices(uct_md_h md, +@@ -978,7 +1045,11 @@ ucs_status_t uct_tcp_query_devices(uct_md_h md, uct_tcp_md_t *tcp_md = ucs_derived_of(md, uct_tcp_md_t); const unsigned sys_device_priority = 10; uct_tl_device_resource_t *devices, *tmp; - struct dirent **entries, **entry; +#if defined(__FreeBSD__) + struct if_nameindex *ifn, *it; +#else + struct dirent **entries, **entry; +#endif unsigned num_devices; int is_active, i, n; ucs_status_t status; -@@ -979,21 +1050,77 @@ ucs_status_t uct_tcp_query_devices(uct_md_h md, +@@ -986,21 +1057,77 @@ ucs_status_t uct_tcp_query_devices(uct_md_h md, char *path_buffer; ucs_sys_device_t sys_dev; +#if defined(__FreeBSD__) + ifn = if_nameindex(); + if (ifn == NULL) { + ucs_error("if_nameindex() failed: %m"); + status = UCS_ERR_IO_ERROR; + goto out; + } +#else n = scandir(UCT_TCP_IFACE_NETDEV_DIR, &entries, NULL, alphasort); if (n == -1) { ucs_error("scandir(%s) failed: %m", UCT_TCP_IFACE_NETDEV_DIR); status = UCS_ERR_IO_ERROR; goto out; } +#endif devices = NULL; num_devices = 0; +#if defined(__FreeBSD__) + path_buffer = NULL; + status = UCS_OK; +#else status = ucs_string_alloc_path_buffer(&path_buffer, "path_buffer"); if (status != UCS_OK) { - goto out; + goto out_release; } +#endif +#if defined(__FreeBSD__) + for (it = ifn; it->if_name != NULL; ++it) { + is_active = 0; + for (i = 0; i < tcp_md->config.af_prio_count; i++) { + if (ucs_netif_is_active(it->if_name, + tcp_md->config.af_prio_list[i])) { + is_active = 1; + break; + } + } + + if (!is_active) { + continue; + } + + if (!tcp_md->config.bridge_enable && + uct_tcp_is_bridge(it->if_name)) { + ucs_debug("filtered out bridge device %s", it->if_name); + continue; + } + + tmp = ucs_realloc(devices, sizeof(*devices) * (num_devices + 1), + "tcp devices"); + if (tmp == NULL) { + ucs_free(devices); + status = UCS_ERR_NO_MEMORY; + goto out_release; + } + devices = tmp; + + sysfs_path = uct_tcp_iface_get_sysfs_path(it->if_name, path_buffer); + sys_dev = ucs_topo_get_sysfs_dev(it->if_name, sysfs_path, + sys_device_priority); + + ucs_snprintf_zero(devices[num_devices].name, + sizeof(devices[num_devices].name), "%s", + it->if_name); + devices[num_devices].type = UCT_DEVICE_TYPE_NET; + devices[num_devices].sys_device = sys_dev; + ++num_devices; + } +#else ucs_carray_for_each(entry, entries, n) { /* According to the sysfs(5) manual page, all of entries * has to be a symbolic link representing one of the real -@@ -1045,18 +1172,28 @@ ucs_status_t uct_tcp_query_devices(uct_md_h md, +@@ -1052,18 +1179,28 @@ ucs_status_t uct_tcp_query_devices(uct_md_h md, devices[num_devices].sys_device = sys_dev; ++num_devices; } +#endif *num_devices_p = num_devices; *devices_p = devices; status = UCS_OK; out_release: +#if defined(__FreeBSD__) + if (ifn != NULL) { + if_freenameindex(ifn); + } + if (path_buffer != NULL) { + ucs_free(path_buffer); + } +#else ucs_carray_for_each(entry, entries, n) { free(*entry); } free(entries); ucs_free(path_buffer); +#endif out: return status; } diff --git a/net/ucx/files/patch-test_apps_iodemo_io__demo.cc b/net/ucx/files/patch-test_apps_iodemo_io__demo.cc index 26e653cc28f4..4e9a33b70e45 100644 --- a/net/ucx/files/patch-test_apps_iodemo_io__demo.cc +++ b/net/ucx/files/patch-test_apps_iodemo_io__demo.cc @@ -1,23 +1,23 @@ ---- test/apps/iodemo/io_demo.cc.orig 2026-02-04 09:52:46 UTC +--- test/apps/iodemo/io_demo.cc.orig 2026-09-09 16:04:04 UTC +++ test/apps/iodemo/io_demo.cc -@@ -18,6 +18,7 @@ +@@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include -@@ -2999,8 +3000,10 @@ static int do_client(options_t& test_opts) +@@ -3032,8 +3033,10 @@ static int do_client(options_t& test_opts) LOG << "random seed: " << test_opts.random_seed; // randomize servers to optimize startup - std::random_shuffle(test_opts.servers.begin(), test_opts.servers.end(), - IoDemoRandom::urand); + { + std::mt19937 rng(static_cast(test_opts.random_seed)); + std::shuffle(test_opts.servers.begin(), test_opts.servers.end(), rng); + } UcxLog vlog(LOG_PREFIX, test_opts.verbose); vlog << "List of servers:"; diff --git a/net/ucx/files/patch-test_gtest_common_test.cc b/net/ucx/files/patch-test_gtest_common_test.cc index 8137143df0f5..a860f3e748a9 100644 --- a/net/ucx/files/patch-test_gtest_common_test.cc +++ b/net/ucx/files/patch-test_gtest_common_test.cc @@ -1,19 +1,19 @@ ---- test/gtest/common/test.cc.orig 2026-05-07 20:53:46 UTC +--- test/gtest/common/test.cc.orig 2026-09-09 16:04:04 UTC +++ test/gtest/common/test.cc -@@ -481,14 +481,15 @@ static void clear_dontcopy_regions_vma_cb(ucs_sys_vma_ +@@ -557,14 +557,15 @@ static void clear_dontcopy_regions_vma_cb(ucs_sys_vma_ static void clear_dontcopy_regions_vma_cb(ucs_sys_vma_info_t *info, void *ctx) { int ret; - if (info->flags & UCS_SYS_VMA_FLAG_DONTCOPY) { +#ifdef __linux__ ret = madvise((void*)info->start, info->end - info->start, MADV_DOFORK); if (ret != 0) { UCS_TEST_MESSAGE << "madvise(DOFORK) failed, errno: " << errno << std::hex << " 0x" << info->start << "-0x" << info->end; } +#endif } } diff --git a/net/ucx/files/patch-test_gtest_common_test__helpers.cc b/net/ucx/files/patch-test_gtest_common_test__helpers.cc index 76f9a5f7f136..55f76e1f9f30 100644 --- a/net/ucx/files/patch-test_gtest_common_test__helpers.cc +++ b/net/ucx/files/patch-test_gtest_common_test__helpers.cc @@ -1,25 +1,144 @@ ---- test/gtest/common/test_helpers.cc.orig 2026-05-06 13:47:14 UTC +--- test/gtest/common/test_helpers.cc.orig 2026-09-09 16:59:33 UTC +++ test/gtest/common/test_helpers.cc -@@ -13,6 +13,11 @@ - #include +@@ -14,8 +14,18 @@ #include -+#include + #include +#include +#include -+#include -+ - #include + #include ++#if defined(__FreeBSD__) ++#include ++#include ++#include ++#include ++#include ++#endif ++ extern "C" { -@@ -513,7 +518,9 @@ out_close: + // On some platforms users have to declare environ explicitly + extern char** environ; +@@ -504,7 +514,7 @@ std::vector read_dir(const std::string &p + + dir = opendir(path.c_str()); + if (dir == NULL) { +- goto out_close; ++ return result; } - out_close: -- closedir(dir); -+ if (dir != NULL) { -+ closedir(dir); -+ } + for (entry = readdir(dir); entry != NULL; entry = readdir(dir)) { +@@ -513,7 +523,6 @@ std::vector read_dir(const std::string &p + } + } + +-out_close: + closedir(dir); return result; } +@@ -521,6 +530,42 @@ std::set get_open_fds() + std::set get_open_fds() + { + std::set fds; ++ ++#if defined(__FreeBSD__) ++ struct procstat *procstat; ++ struct kinfo_proc *procs; ++ struct filestat_list *files; ++ struct filestat *fst; ++ unsigned int count; ++ ++ procstat = procstat_open_sysctl(); ++ if (procstat == NULL) { ++ ucs_fatal("procstat_open_sysctl() failed"); ++ } ++ ++ procs = procstat_getprocs(procstat, KERN_PROC_PID, getpid(), &count); ++ if ((procs == NULL) || (count == 0)) { ++ procstat_close(procstat); ++ ucs_fatal("procstat_getprocs() failed"); ++ } ++ ++ files = procstat_getfiles(procstat, &procs[0], 0); ++ if (files == NULL) { ++ procstat_freeprocs(procstat, procs); ++ procstat_close(procstat); ++ ucs_fatal("procstat_getfiles() failed"); ++ } ++ ++ STAILQ_FOREACH(fst, files, next) { ++ if (fst->fs_fd >= 0) { ++ fds.insert(fst->fs_fd); ++ } ++ } ++ ++ procstat_freefiles(procstat, files); ++ procstat_freeprocs(procstat, procs); ++ procstat_close(procstat); ++#else + DIR *dir = opendir("/proc/self/fd"); + if (dir == NULL) { + ucs_fatal("failed to open /proc/self/fd"); +@@ -542,11 +587,54 @@ std::set get_open_fds() + } + } + closedir(dir); ++#endif ++ + return fds; + } + + std::string readlink_proc_fd(int fd) + { ++#if defined(__FreeBSD__) ++ struct procstat *procstat; ++ struct kinfo_proc *procs; ++ struct filestat_list *files; ++ struct filestat *fst; ++ unsigned int count; ++ std::string result(""); ++ ++ procstat = procstat_open_sysctl(); ++ if (procstat == NULL) { ++ return ""; ++ } ++ ++ procs = procstat_getprocs(procstat, KERN_PROC_PID, getpid(), &count); ++ if ((procs == NULL) || (count == 0)) { ++ procstat_close(procstat); ++ return ""; ++ } ++ ++ files = procstat_getfiles(procstat, &procs[0], 0); ++ if (files == NULL) { ++ procstat_freeprocs(procstat, procs); ++ procstat_close(procstat); ++ return ""; ++ } ++ ++ STAILQ_FOREACH(fst, files, next) { ++ if (fst->fs_fd == fd) { ++ if ((fst->fs_path != NULL) && (fst->fs_path[0] != '\0')) { ++ result = fst->fs_path; ++ } ++ break; ++ } ++ } ++ ++ procstat_freefiles(procstat, files); ++ procstat_freeprocs(procstat, procs); ++ procstat_close(procstat); ++ ++ return result; ++#else + char path[64], link[PATH_MAX]; + const size_t max_len = sizeof(link) - 1; + +@@ -559,6 +647,7 @@ std::string readlink_proc_fd(int fd) + + link[len] = '\0'; + return std::string(link); ++#endif + } + static std::map get_all_rdmacm_net_devices() diff --git a/net/ucx/files/patch-test_gtest_common_test__helpers.h b/net/ucx/files/patch-test_gtest_common_test__helpers.h index 1dc0916147ab..41eea0e57624 100644 --- a/net/ucx/files/patch-test_gtest_common_test__helpers.h +++ b/net/ucx/files/patch-test_gtest_common_test__helpers.h @@ -1,10 +1,10 @@ ---- test/gtest/common/test_helpers.h.orig 2026-06-10 22:15:23 UTC +--- test/gtest/common/test_helpers.h.orig 2026-09-09 16:06:37 UTC +++ test/gtest/common/test_helpers.h -@@ -34,6 +34,7 @@ +@@ -36,6 +36,7 @@ #include #include #include +#include #ifndef UINT16_MAX diff --git a/net/ucx/files/patch-test_gtest_ucp_test__ucp__am.cc b/net/ucx/files/patch-test_gtest_ucp_test__ucp__am.cc index 6ab2ff1fcc8a..30589bb8a622 100644 --- a/net/ucx/files/patch-test_gtest_ucp_test__ucp__am.cc +++ b/net/ucx/files/patch-test_gtest_ucp_test__ucp__am.cc @@ -1,13 +1,13 @@ ---- test/gtest/ucp/test_ucp_am.cc.orig 2026-06-17 18:31:13 UTC +--- test/gtest/ucp/test_ucp_am.cc.orig 2026-09-09 16:06:37 UTC +++ test/gtest/ucp/test_ucp_am.cc -@@ -124,7 +124,9 @@ ucs_status_t test_ucp_am::am_handler(test_ucp_am *me, +@@ -129,7 +129,9 @@ ucs_status_t test_ucp_am::am_handler(test_ucp_am *me, std::vector cmp(length, (char)length); std::vector databuf(length, 'r'); - memcpy(&databuf[0], data, length); + if (length > 0) { + memcpy(&databuf[0], data, length); + } EXPECT_EQ(cmp, databuf); diff --git a/net/ucx/files/patch-test_gtest_ucp_test__ucp__proto__mock.cc b/net/ucx/files/patch-test_gtest_ucp_test__ucp__proto__mock.cc new file mode 100644 index 000000000000..b85b1230bca0 --- /dev/null +++ b/net/ucx/files/patch-test_gtest_ucp_test__ucp__proto__mock.cc @@ -0,0 +1,18 @@ +--- test/gtest/ucp/test_ucp_proto_mock.cc.orig 2026-09-14 16:35:57 UTC ++++ test/gtest/ucp/test_ucp_proto_mock.cc +@@ -1186,6 +1186,7 @@ UCP_INSTANTIATE_TEST_CASE_TLS(test_ucp_proto_mock_rcx_ + + UCP_INSTANTIATE_TEST_CASE_TLS(test_ucp_proto_mock_rcx_numa, rcx, "rc_x") + ++#if HAVE_CMA + class test_ucp_proto_mock_cma : public test_ucp_proto_mock { + public: + test_ucp_proto_mock_cma() +@@ -1214,6 +1215,7 @@ UCP_INSTANTIATE_TEST_CASE_TLS(test_ucp_proto_mock_cma, + } + + UCP_INSTANTIATE_TEST_CASE_TLS(test_ucp_proto_mock_cma, mm_cma, "posix,cma") ++#endif + + class test_ucp_proto_mock_tcp : public test_ucp_proto_mock { + public: diff --git a/net/ucx/files/patch-test_gtest_ucs_test__async.cc b/net/ucx/files/patch-test_gtest_ucs_test__async.cc index e10d275c44d2..fcef45b0879e 100644 --- a/net/ucx/files/patch-test_gtest_ucs_test__async.cc +++ b/net/ucx/files/patch-test_gtest_ucs_test__async.cc @@ -1,11 +1,11 @@ ---- test/gtest/ucs/test_async.cc.orig 2026-06-08 19:48:30 UTC +--- test/gtest/ucs/test_async.cc.orig 2026-09-09 16:06:37 UTC +++ test/gtest/ucs/test_async.cc -@@ -544,7 +544,7 @@ UCS_TEST_P(test_async, many_timers) { +@@ -545,7 +545,7 @@ UCS_TEST_P(test_async, many_timers) { const int max_timers = ucs_max(10, 250 / ucs::test_time_multiplier()); std::vector timers; - timers.reserve(max_timers); + timers.resize(max_timers); for (int count = 0; count < max_iters; ++count) { for (int count2 = 0; count2 < max_timers; ++count2) { diff --git a/net/ucx/files/patch-test_gtest_ucs_test__config.cc b/net/ucx/files/patch-test_gtest_ucs_test__config.cc index e421a5b37e21..2afe04220521 100644 --- a/net/ucx/files/patch-test_gtest_ucs_test__config.cc +++ b/net/ucx/files/patch-test_gtest_ucs_test__config.cc @@ -1,62 +1,62 @@ ---- test/gtest/ucs/test_config.cc.orig 2026-02-05 12:41:56 UTC +--- test/gtest/ucs/test_config.cc.orig 2026-09-09 16:06:37 UTC +++ test/gtest/ucs/test_config.cc -@@ -365,22 +365,18 @@ class test_config : public ucs::test { (protected) +@@ -372,22 +372,18 @@ class test_config : public ucs::test { (protected) std::string dump(ucs_config_print_flags_t flags, const char *filter = nullptr) const { - char *dump_data = nullptr; + char *dump_data = nullptr; size_t dump_size; - char line_buf[1024]; std::string res; FILE *file = open_memstream(&dump_data, &dump_size); ucs_config_parser_print_opts(file, "", &m_opts, car_opts_table, nullptr, UCS_DEFAULT_ENV_PREFIX, flags, filter); - fseek(file, 0, SEEK_SET); - - while (fgets(line_buf, sizeof(line_buf), file)) { - res += line_buf; - } - fclose(file); + if (dump_data != nullptr) { + res = std::string(dump_data, dump_size); + } free(dump_data); return res; } -@@ -432,12 +428,19 @@ class test_config : public ucs::test { (protected) +@@ -439,12 +435,19 @@ class test_config : public ucs::test { (protected) ucs_config_parser_print_opts(file, "", *opts, car_opts_table, prefix, UCS_DEFAULT_ENV_PREFIX, (ucs_config_print_flags_t)flags, nullptr); - + fclose(file); /* Sanity check - all lines begin with UCS_ */ unsigned num_lines = 0; - fseek(file, 0, SEEK_SET); - while (fgets(line_buf, sizeof(line_buf), file)) { - if (line_buf[0] == '\n') { + char *pos = dump_data; + char *end = dump_data + dump_size; + while (pos < end) { + char *nl = (char*)memchr(pos, '\n', end - pos); + size_t len = nl ? (size_t)(nl - pos) : (size_t)(end - pos); + if (len >= sizeof(line_buf)) len = sizeof(line_buf) - 1; + memcpy(line_buf, pos, len); + line_buf[len] = '\0'; + pos = nl ? nl + 1 : end; + if (line_buf[0] == '\n'|| line_buf[0] == '\0') { continue; } -@@ -465,7 +468,7 @@ class test_config : public ucs::test { (protected) +@@ -472,7 +475,7 @@ class test_config : public ucs::test { (protected) size_t cnt = 0; for (size_t i = 2 + strlen("alias of: ") + 1; - line_buf[i] != '\n'; i++) { + line_buf[i] != '\n' && line_buf[i] != '\0'; i++) { alias[cnt++] = line_buf[i]; } } diff --git a/net/ucx/files/patch-test_gtest_uct_test__md.cc b/net/ucx/files/patch-test_gtest_uct_test__md.cc index 9401c6fea420..675be4f56f44 100644 --- a/net/ucx/files/patch-test_gtest_uct_test__md.cc +++ b/net/ucx/files/patch-test_gtest_uct_test__md.cc @@ -1,10 +1,10 @@ ---- test/gtest/uct/test_md.cc.orig 2026-05-07 22:05:14 UTC +--- test/gtest/uct/test_md.cc.orig 2026-09-09 16:06:37 UTC +++ test/gtest/uct/test_md.cc -@@ -21,6 +21,7 @@ extern "C" { +@@ -25,6 +25,7 @@ extern "C" { #include #endif } +#include #include #include #include diff --git a/net/ucx/files/patch-test_gtest_uct_test__mm.cc b/net/ucx/files/patch-test_gtest_uct_test__mm.cc new file mode 100644 index 000000000000..46dda4503598 --- /dev/null +++ b/net/ucx/files/patch-test_gtest_uct_test__mm.cc @@ -0,0 +1,17 @@ +--- test/gtest/uct/test_mm.cc.orig 2026-09-13 20:27:27 UTC ++++ test/gtest/uct/test_mm.cc +@@ -147,12 +147,12 @@ class test_uct_mm : public uct_test { (public) + size_t iface_addr_len = uct_mm_md_mapper_call(md(m_e1), iface_addr_length); + std::vector iface_addr(iface_addr_len); + +- status = uct_mm_md_mapper_call(md(m_e1), iface_addr_pack, &iface_addr[0]); ++ status = uct_mm_md_mapper_call(md(m_e1), iface_addr_pack, iface_addr.data()); + ASSERT_UCS_OK(status); + + uct_mm_remote_seg_t rseg; + status = uct_mm_md_mapper_call(md(m_e2), mem_attach, seg->seg_id, size, +- &iface_addr[0], &rseg); ++ iface_addr.data(), &rseg); + ASSERT_UCS_OK(status); + + test_attach_ptr(ptr, rseg.address, 0xdeadbeef11111);