diff --git a/.github/workflows/freebsd-ci.yml b/.github/workflows/freebsd-ci.yml new file mode 100644 index 000000000..e097b9ed6 --- /dev/null +++ b/.github/workflows/freebsd-ci.yml @@ -0,0 +1,34 @@ +name: FreeBSD Build + +on: + push: + branches: [ "freebsd" ] + pull_request: + branches: [ "freebsd" ] + +jobs: + build-freebsd: + # vmactions runs a QEMU VM inside an Ubuntu runner, so runs-on MUST be ubuntu-latest + runs-on: ubuntu-latest + name: Build rdma-core on FreeBSD + + steps: + # Step 1: Check out your rdma-core repository into the Ubuntu host runner + - name: Checkout Code + uses: actions/checkout@v4 + + # Step 2: Fire up the FreeBSD VM and execute the build steps + - name: Build in FreeBSD VM + uses: vmactions/freebsd-vm@v1 + with: + release: "15.1" + usesh: true # Use standard sh rather than tcsh (default shell on FreeBSD) + + # The 'prepare' section runs inside the VM before copying files, + # ideal for installing system package dependencies. + prepare: | + uname -a + pkg install -y gcc cmake ninja python3 bash libepoll-shim pkgconf lang/cython + + run: | + bash build-freebsd.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 06862ae58..16d00e8c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -564,13 +564,15 @@ else() set(NL_LIBRARIES "") RDMA_DoFixup(0 "netlink/attr.h") RDMA_DoFixup(0 "netlink/msg.h") - RDMA_DoFixup(0 "netlink/netlink.h") RDMA_DoFixup(0 "netlink/object-api.h") RDMA_DoFixup(0 "netlink/route/link.h") RDMA_DoFixup(0 "netlink/route/link/vlan.h") RDMA_DoFixup(0 "netlink/route/neighbour.h") - RDMA_DoFixup(0 "netlink/route/route.h") RDMA_DoFixup(0 "netlink/route/rtnl.h") + if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + RDMA_DoFixup(0 "netlink/netlink.h") + RDMA_DoFixup(0 "netlink/route/route.h") + endif() endif() # Older stuff blows up if these headers are included together @@ -793,6 +795,9 @@ add_subdirectory(util/tests) add_subdirectory(Documentation) add_subdirectory(kernel-boot) add_subdirectory(kernel-headers) +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + add_subdirectory(freebsd-headers) +endif() # Libraries add_subdirectory(libibumad) add_subdirectory(libibumad/man) diff --git a/README-FreeBSD.txt b/README-FreeBSD.txt new file mode 100644 index 000000000..b85674c8f --- /dev/null +++ b/README-FreeBSD.txt @@ -0,0 +1,26 @@ +The port just compiles. + +FreeBSD version should be main or stable/15, after the tdestroy(3) and +strdupa()/strndupa() additions. + +You need to install the following packages: +cmake-core +ninja +gcc +python3 +pyXXX-cython3 +pyXXX-docutils +bash +libepoll-shim +pkgconf + +1. All fake constants for (rt)netlink that are added in + freebsd-headers/linux point to the usage areas that need porting. +2. sysfs accesses must be replaced by sysctl. + Similarly, there should be use of /proc that needs to be ported. +3. I have no idea if the FreeBSD verbs/drivers ABI is compatible with + the Linux provided by kernel-headers/*. +4. Tests for the compilation environment properties done in CMakeLists.txt + are performed before the freebsd-headers get chance to populate build + environment. As such, some tests provide invalid results, e.g. + the co-existence of netinet/in.h and linux/in*.h. diff --git a/build-freebsd.sh b/build-freebsd.sh new file mode 100755 index 000000000..a8389cde8 --- /dev/null +++ b/build-freebsd.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +set -e + +LOCALBASE=$(/sbin/sysctl -n user.localbase) +CMAKE=${LOCALBASE}/bin/cmake +NINJA=${LOCALBASE}/bin/ninja +PYTHON=${LOCALBASE}/bin/python3 +GCC=${LOCALBASE}/bin/gcc +GXX=${LOCALBASE}/bin/g++ + +SRCDIR=$(dirname $0) +BUILDDIR=${SRCDIR}/build + +mkdir -p ${BUILDDIR} + +cd ${BUILDDIR} + +${CMAKE} -DIN_PLACE=1 -GNinja -DENABLE_RESOLVE_NEIGH=0 -DIOCTL_MODE=write \ + -DPYTHON_EXECUTABLE=${PYTHON} \ + -DCMAKE_C_COMPILER=${GCC} -DCMAKE_CXX_COMPILER=${GXX} \ + ${EXTRA_CMAKE_FLAGS:-} .. +${NINJA} -k 0 diff --git a/buildlib/FindLDSymVer.cmake b/buildlib/FindLDSymVer.cmake index d4065d922..154170053 100644 --- a/buildlib/FindLDSymVer.cmake +++ b/buildlib/FindLDSymVer.cmake @@ -3,12 +3,20 @@ # find_package helper to detect symbol version support in the compiler and # linker. If supported then LDSYMVER_MODE will be set to GNU +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set(GLOBAL_SYMBOLS_BIN " + environ; + __progname; + ") +endif() + # Basic sample GNU style map file file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/test.map" " IBVERBS_1.0 { global: ibv_get_device_list; - local: *; + ${GLOBAL_SYMBOLS_BIN} + local: *; }; IBVERBS_1.1 { diff --git a/buildlib/config.h.in b/buildlib/config.h.in index 0a7769e64..32c3acd27 100644 --- a/buildlib/config.h.in +++ b/buildlib/config.h.in @@ -13,7 +13,11 @@ // FIXME: Remove this, The cmake version hard-requires new style CLOEXEC support #define STREAM_CLOEXEC "e" +#if defined __linux__ #define RDMA_CDEV_DIR "/dev/infiniband" +#elif defined __FreeBSD__ +#define RDMA_CDEV_DIR "/dev" +#endif #define IBV_CONFIG_DIR "@CONFIG_DIR@" #define RS_CONF_DIR "@CMAKE_INSTALL_FULL_SYSCONFDIR@/rdma/rsocket" diff --git a/buildlib/make_abi_structs.py b/buildlib/make_abi_structs.py index 0817735eb..05b3d63c1 100644 --- a/buildlib/make_abi_structs.py +++ b/buildlib/make_abi_structs.py @@ -19,10 +19,33 @@ import re; import functools; import sys; +import os; -def in_struct(ln,FO,nesting=0): +sysname=sys.argv[3] + +def cpre_sysname(): + mapping = {"Linux": "__linux__", "FreeBSD": "__FreeBSD__"} + try: + return mapping[sysname] + except KeyError: + raise NotImplementedError(sysname) + +def in_struct(ln,FO,nesting=0,wait_for_endif=False,skip=False): """Copy a top level structure over to the #define output, keeping track of nested structures.""" + if wait_for_endif: + g = re.match(r"#endif", ln) + if g != None: + return functools.partial(in_struct,nesting=nesting,wait_for_endif=False,skip=False) + g = re.match(r"#ifdef\s+(\S+)",ln) + if g != None: + ifdefsym = g.group(1) + if ifdefsym == cpre_sysname(): + return functools.partial(in_struct,nesting=nesting,wait_for_endif=True,skip=False) + return functools.partial(in_struct,nesting=nesting,wait_for_endif=True,skip=True) + if skip: + return functools.partial(in_struct,nesting=nesting,wait_for_endif=wait_for_endif,skip=skip) + if nesting == 0: if re.match(r"(}.*);",ln): FO.write(ln[:-1] + "\n\n"); @@ -31,11 +54,11 @@ def in_struct(ln,FO,nesting=0): FO.write(ln + " \\\n"); if ln == "struct {" or ln == "union {": - return functools.partial(in_struct,nesting=nesting+1); + return functools.partial(in_struct,nesting=nesting+1,wait_for_endif=wait_for_endif,skip=skip); if re.match(r"}.*;",ln): - return functools.partial(in_struct,nesting=nesting-1); - return functools.partial(in_struct,nesting=nesting); + return functools.partial(in_struct,nesting=nesting-1,wait_for_endif=wait_for_endif,skip=skip); + return functools.partial(in_struct,nesting=nesting,wait_for_endif=wait_for_endif,skip=skip); def find_struct(ln,FO): """Look for the start of a top level structure""" diff --git a/buildlib/rdma_functions.cmake b/buildlib/rdma_functions.cmake index 6e0c7d2e8..097f27e18 100644 --- a/buildlib/rdma_functions.cmake +++ b/buildlib/rdma_functions.cmake @@ -57,7 +57,7 @@ function(rdma_create_symlink LINK_CONTENT DEST) # Newer versions of cmake can use "${CMAKE_COMMAND}" "-E" "create_symlink" # however it is broken weirdly on older versions. - execute_process(COMMAND "ln" "-Tsf" + execute_process(COMMAND "ln" "-sf" "${LINK_CONTENT}" "${DEST}" RESULT_VARIABLE retcode) if(NOT "${retcode}" STREQUAL "0") message(FATAL_ERROR "Failed to create symlink in ${DEST}") diff --git a/freebsd-headers/CMakeLists.txt b/freebsd-headers/CMakeLists.txt new file mode 100644 index 000000000..1ff7c5fa2 --- /dev/null +++ b/freebsd-headers/CMakeLists.txt @@ -0,0 +1,31 @@ +publish_internal_headers("" + alloca.h + errno.h + limits.h + string.h + ) + +publish_internal_headers(netinet + netinet/in.h + netinet/tcp.h + ) + +publish_internal_headers(sys + sys/mman.h + sys/sendfile.h + sys/shm.h + sys/socket.h + sys/sysmacros.h + ) + +publish_internal_headers(linux + linux/if_ether.h + linux/in.h + linux/in6.h + linux/ioctl.h + linux/ip.h + linux/netlink.h + linux/rtnetlink.h + linux/socket.h + linux/types.h + ) diff --git a/freebsd-headers/alloca.h b/freebsd-headers/alloca.h new file mode 100644 index 000000000..69ddd74b3 --- /dev/null +++ b/freebsd-headers/alloca.h @@ -0,0 +1,6 @@ +#ifndef __FREEBSD_ALLOCA_H__ +#define __FREEBSD_ALLOCA_H__ + +/* empty */ + +#endif diff --git a/freebsd-headers/errno.h b/freebsd-headers/errno.h new file mode 100644 index 000000000..dfe0307e5 --- /dev/null +++ b/freebsd-headers/errno.h @@ -0,0 +1,10 @@ +#ifndef __FREEBSD_ERRNO_H__ +#define __FREEBSD_ERRNO_H__ + +#include_next +#define ENODATA 100000 +#define EBADE 100001 +#define EREMOTEIO 100002 +#define ENONET 100003 + +#endif diff --git a/freebsd-headers/limits.h b/freebsd-headers/limits.h new file mode 100644 index 000000000..f86942d9f --- /dev/null +++ b/freebsd-headers/limits.h @@ -0,0 +1,10 @@ +#ifndef __FREEBSD_LIMITS_H__ +#define __FREEBSD_LIMITS_H__ + +#include + +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX MAXHOSTNAMELEN +#endif + +#endif diff --git a/freebsd-headers/linux/if_ether.h b/freebsd-headers/linux/if_ether.h new file mode 100644 index 000000000..8cba917af --- /dev/null +++ b/freebsd-headers/linux/if_ether.h @@ -0,0 +1,4 @@ +#include + +#define ETH_ALEN ETHER_ADDR_LEN + diff --git a/freebsd-headers/linux/in.h b/freebsd-headers/linux/in.h new file mode 100644 index 000000000..b31116082 --- /dev/null +++ b/freebsd-headers/linux/in.h @@ -0,0 +1,4 @@ +#ifndef __FREEBSD_LINUX_IN_H__ +#define __FREEBSD_LINUX_IN_H__ + +#endif diff --git a/freebsd-headers/linux/in6.h b/freebsd-headers/linux/in6.h new file mode 100644 index 000000000..4a466b64b --- /dev/null +++ b/freebsd-headers/linux/in6.h @@ -0,0 +1,25 @@ +#ifndef __FREEBSD_LINUX_IN6_H__ +#define __FREEBSD_LINUX_IN6_H__ + +#include +#include + +struct linux_in6_addr { + union { + __u8 __u6_addr8[16]; + __be16 __u6_addr16[8]; + __be32 __u6_addr32[4]; + } __in6_u; +}; + +#undef s6_addr +#define s6_addr __in6_u.__u6_addr8 +#undef s6_addr16 +#define s6_addr16 __in6_u.__u6_addr16 +#undef s6_addr32 +#define s6_addr32 __in6_u.__u6_addr32 + +#define in6_addr linux_in6_addr +#define in6_u __in6_u + +#endif diff --git a/freebsd-headers/linux/ioctl.h b/freebsd-headers/linux/ioctl.h new file mode 100644 index 000000000..6ec92cf73 --- /dev/null +++ b/freebsd-headers/linux/ioctl.h @@ -0,0 +1 @@ +#include diff --git a/freebsd-headers/linux/ip.h b/freebsd-headers/linux/ip.h new file mode 100644 index 000000000..24de2e12c --- /dev/null +++ b/freebsd-headers/linux/ip.h @@ -0,0 +1,31 @@ +#ifndef __FREEBSD_LINUX_IP_H__ +#define __FREEBSD_LINUX_IP_H__ + +#include +#include +#include + +struct iphdr { +#if BYTE_ORDER == LITTLE_ENDIAN + __u8 ihl:4, + version:4; +#endif +#if BYTE_ORDER == BIG_ENDIAN + __u8 version:4, + ihl:4; +#endif + __u8 tos; + __be16 tot_len; + __be16 id; + __be16 frag_off; + __u8 ttl; + __u8 protocol; + __sum16 check; + __struct_group(/* no tag */, addrs, /* no attrs */, + __be32 saddr; + __be32 daddr; + ); + /*The options start here. */ +}; + +#endif diff --git a/freebsd-headers/linux/netlink.h b/freebsd-headers/linux/netlink.h new file mode 100644 index 000000000..256a194a2 --- /dev/null +++ b/freebsd-headers/linux/netlink.h @@ -0,0 +1,7 @@ +#ifndef __FREEBSD_LINUX_NETLINK_H +#define __FREEBSD_LINUX_NETLINK_H + +#include +#define NETLINK_RDMA 1000000 + +#endif diff --git a/freebsd-headers/linux/rtnetlink.h b/freebsd-headers/linux/rtnetlink.h new file mode 100644 index 000000000..1e456bb9d --- /dev/null +++ b/freebsd-headers/linux/rtnetlink.h @@ -0,0 +1,7 @@ +#ifndef __FREEBSD_LINUX_RTNETLINK_H__ +#define __FREEBSD_LINUX_RTNETLINK_H__ + +#include +#include + +#endif diff --git a/freebsd-headers/linux/socket.h b/freebsd-headers/linux/socket.h new file mode 100644 index 000000000..651d20c4b --- /dev/null +++ b/freebsd-headers/linux/socket.h @@ -0,0 +1,4 @@ +#ifndef __FREEBSD_LINUX_SOCKET_H__ +#define __FREEBSD_LINUX_SOCKET_H__ + +#endif diff --git a/freebsd-headers/linux/stddef.h b/freebsd-headers/linux/stddef.h new file mode 100644 index 000000000..95113a836 --- /dev/null +++ b/freebsd-headers/linux/stddef.h @@ -0,0 +1,27 @@ +#ifndef __FREEBSD_LINUX_STDDEF_H__ +#define __FREEBSD_LINUX_STDDEF_H__ + +#ifndef __cplusplus +#define __struct_group_tag(TAG) TAG +#else +#define __struct_group_tag(TAG) +#endif + +#define __struct_group(TAG, NAME, ATTRS, MEMBERS...) \ + union { \ + struct { MEMBERS } ATTRS; \ + struct __struct_group_tag(TAG) { MEMBERS } ATTRS NAME; \ + } ATTRS + +#ifdef __cplusplus +#define __DECLARE_FLEX_ARRAY(T, member) \ + T member[0] +#else +#define __DECLARE_FLEX_ARRAY(TYPE, NAME) \ + struct { \ + struct { } __empty_ ## NAME; \ + TYPE NAME[]; \ + } +#endif + +#endif diff --git a/freebsd-headers/linux/types.h b/freebsd-headers/linux/types.h new file mode 100644 index 000000000..e3924c553 --- /dev/null +++ b/freebsd-headers/linux/types.h @@ -0,0 +1,68 @@ +/*- + * Copyright (c) 2010 Isilon Systems, Inc. + * Copyright (c) 2010 iX Systems, Inc. + * Copyright (c) 2010 Panasas, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice unmodified, this list of conditions, and the following + * disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef _INFINIBAND_TYPES_H_ +#define _INFINIBAND_TYPES_H_ + +#include +#include + +//#define __bitwise __attribute__((bitwise)) +#define __bitwise + +typedef int8_t s8; +typedef uint8_t u8; +typedef int8_t __s8; +typedef uint8_t __u8; + +typedef int16_t s16; +typedef uint16_t u16; +typedef int16_t __s16; +typedef uint16_t __u16; +typedef __u16 __bitwise __sum16; + +typedef int32_t s32; +typedef uint32_t u32; +typedef int32_t __s32; +typedef uint32_t __u32; + +typedef int64_t s64; +typedef uint64_t u64; +typedef int64_t __s64; +typedef uint64_t __u64; + +typedef uint16_t __le16; +typedef uint16_t __be16; +typedef uint32_t __le32; +typedef uint32_t __be32; +typedef uint64_t __le64; +typedef uint64_t __be64; + +typedef uint64_t __aligned_u64; +typedef uint64_t __aligned_le64; + +#endif /* _INFINIBAND_TYPES_H_ */ diff --git a/freebsd-headers/netinet/in.h b/freebsd-headers/netinet/in.h new file mode 100644 index 000000000..0b0aec6b4 --- /dev/null +++ b/freebsd-headers/netinet/in.h @@ -0,0 +1,14 @@ +#ifndef __FREEBSD_NETINET_IN_H__ +#define __FREEBSD_NETINET_IN_H__ + +#include_next + +#undef IN6_IS_ADDR_V4MAPPED +#define IN6_IS_ADDR_V4MAPPED(a) \ + (__extension__ \ + ({ const struct in6_addr *__a = (const struct in6_addr *) (a); \ + __a->__in6_u.__u6_addr32[0] == 0 \ + && __a->__in6_u.__u6_addr32[1] == 0 \ + && __a->__in6_u.__u6_addr32[2] == htonl (0xffff); })) + +#endif diff --git a/freebsd-headers/netinet/tcp.h b/freebsd-headers/netinet/tcp.h new file mode 100644 index 000000000..f751f0488 --- /dev/null +++ b/freebsd-headers/netinet/tcp.h @@ -0,0 +1,10 @@ +#ifndef __FREEBSD_NETINET_TCP_H__ +#define __FREEBSD_NETINET_TCP_H__ + +#include_next +#include_next + +#define TCP_CLOSE TCPS_CLOSED +#define TCP_ESTABLISHED TCPS_ESTABLISHED + +#endif diff --git a/freebsd-headers/string.h b/freebsd-headers/string.h new file mode 100644 index 000000000..5226a805f --- /dev/null +++ b/freebsd-headers/string.h @@ -0,0 +1,35 @@ +#ifndef __FREEBSD_STRING_H__ +#define __FREEBSD_STRING_H__ + +#include_next + +#ifndef strdupa +#define strdupa(_Str) (__extension__({ \ + const char *_Str1; \ + size_t _Len; \ + char *_Copy; \ + \ + _Str1 = (_Str); \ + _Len = strlen(_Str1) + 1; \ + _Copy = (char *)__builtin_alloca(_Len); \ + memcpy(_Copy, _Str1, _Len); \ + _Copy; \ +})) +#endif + +#ifndef strndupa +#define strndupa(_Str, _Maxlen) (__extension__({ \ + const char *_Str1; \ + char *_Copy; \ + size_t _Len; \ + \ + _Str1 = (_Str); \ + _Len = strnlen((_Str1), (_Maxlen)); \ + _Copy = __builtin_alloca(_Len + 1); \ + (void)memcpy(_Copy, _Str1, _Len); \ + _Copy[_Len] = '\0'; \ + _Copy; \ +})) +#endif + +#endif diff --git a/freebsd-headers/sys/mman.h b/freebsd-headers/sys/mman.h new file mode 100644 index 000000000..601d21952 --- /dev/null +++ b/freebsd-headers/sys/mman.h @@ -0,0 +1,16 @@ +#ifndef __FREEBSD_SYS_MMAN_H__ +#define __FREEBSD_SYS_MMAN_H__ + +#include_next + +/* use minherit(2) as needed */ +#define MADV_DOFORK 0x10000001 +#define MADV_DONTFORK 0x10000002 + +#define MAP_LOCKED 0 /* XXXKIB implement ? */ +#define MAP_HUGETLB 0 +#define MAP_POPULATE 0 +#define MAP_NORESERVE 0 +#define MAP_GROWSDOWN 0 + +#endif diff --git a/freebsd-headers/sys/sendfile.h b/freebsd-headers/sys/sendfile.h new file mode 100644 index 000000000..ea1836b15 --- /dev/null +++ b/freebsd-headers/sys/sendfile.h @@ -0,0 +1,8 @@ +#ifndef __FREEBSD_SYS_SENDFILE_H__ +#define __FREEBSD_SYS_SENDFILE_H__ + +#include +#include +#include + +#endif diff --git a/freebsd-headers/sys/shm.h b/freebsd-headers/sys/shm.h new file mode 100644 index 000000000..4b3783f17 --- /dev/null +++ b/freebsd-headers/sys/shm.h @@ -0,0 +1,8 @@ +#ifndef __FREEBSD_SYS_SHM_H__ +#define __FREEBSD_SYS_SHM_H__ + +#include_next + +#define SHM_HUGETLB 0 + +#endif diff --git a/freebsd-headers/sys/socket.h b/freebsd-headers/sys/socket.h new file mode 100644 index 000000000..e644a0c2d --- /dev/null +++ b/freebsd-headers/sys/socket.h @@ -0,0 +1,7 @@ +#ifndef __FREEBSD_SYS_SOCKET_H__ +#define __FREEBSD_SYS_SOCKET_H__ + +#include_next +#define AF_LLC 1000000 + +#endif diff --git a/freebsd-headers/sys/sysmacros.h b/freebsd-headers/sys/sysmacros.h new file mode 100644 index 000000000..c30bcd62f --- /dev/null +++ b/freebsd-headers/sys/sysmacros.h @@ -0,0 +1,6 @@ +#ifndef __FREEBSD_SYS_SYSMACROS_H__ +#define __FREEBSD_SYS_SYSMACROS_H__ + +#include + +#endif diff --git a/infiniband-diags/ibaddr.c b/infiniband-diags/ibaddr.c index c26492c09..af64ce410 100644 --- a/infiniband-diags/ibaddr.c +++ b/infiniband-diags/ibaddr.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include diff --git a/infiniband-diags/ibdiag_common.c b/infiniband-diags/ibdiag_common.c index 69b39480f..77687c1a5 100644 --- a/infiniband-diags/ibdiag_common.c +++ b/infiniband-diags/ibdiag_common.c @@ -55,6 +55,7 @@ #include #include #include +#include #include #include diff --git a/infiniband-diags/saquery.c b/infiniband-diags/saquery.c index 3d8c6ce08..70c99b73e 100644 --- a/infiniband-diags/saquery.c +++ b/infiniband-diags/saquery.c @@ -44,6 +44,7 @@ #include #include #include +#include #define _GNU_SOURCE diff --git a/kernel-headers/CMakeLists.txt b/kernel-headers/CMakeLists.txt index cd9c08cad..bcaee7b5d 100644 --- a/kernel-headers/CMakeLists.txt +++ b/kernel-headers/CMakeLists.txt @@ -51,7 +51,7 @@ function(rdma_kernel_provider_abi) set(HDRS ${HDRS} ${OHDR}) add_custom_command( OUTPUT "${OHDR}" - COMMAND "${PYTHON_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/buildlib/make_abi_structs.py" "${IHDR}" "${OHDR}" + COMMAND "${PYTHON_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/buildlib/make_abi_structs.py" "${IHDR}" "${OHDR}" "${CMAKE_SYSTEM_NAME}" MAIN_DEPENDENCY "${IHDR}" DEPENDS "${PROJECT_SOURCE_DIR}/buildlib/make_abi_structs.py" WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" diff --git a/kernel-headers/rdma/mlx5-abi.h b/kernel-headers/rdma/mlx5-abi.h index 8a6ad6c68..904205a5b 100644 --- a/kernel-headers/rdma/mlx5-abi.h +++ b/kernel-headers/rdma/mlx5-abi.h @@ -287,6 +287,7 @@ enum mlx5_ib_create_cq_flags { }; struct mlx5_ib_create_cq { +#ifdef __linux__ __aligned_u64 buf_addr; __aligned_u64 db_addr; __u32 cqe_size; @@ -296,6 +297,18 @@ struct mlx5_ib_create_cq { __u16 uar_page_index; __u16 reserved0; __u32 reserved1; +#endif +#ifdef __FreeBSD__ + __u64 buf_addr; + __u64 db_addr; + __u32 cqe_size; + __u16 flags; + __u16 uar_page_index; + __u8 cqe_comp_en; + __u8 cqe_comp_res_format; + __u16 reserved0; + __u32 reserved1; +#endif }; struct mlx5_ib_create_cq_resp { diff --git a/libibmad/mad.h b/libibmad/mad.h index 99d3a5a06..8b527df3b 100644 --- a/libibmad/mad.h +++ b/libibmad/mad.h @@ -1714,6 +1714,7 @@ extern int ibdebug; /* Misc. macros: */ /** align value \a l to \a size (ceil) */ +#undef ALIGN #define ALIGN(l, size) (((l) + ((size) - 1)) / (size) * (size)) /** printf style warning MACRO, includes name of function and pid */ diff --git a/libibmad/portid.c b/libibmad/portid.c index ea02ca9ae..b4572b228 100644 --- a/libibmad/portid.c +++ b/libibmad/portid.c @@ -35,6 +35,7 @@ #include #include #include +#include #include diff --git a/libibmad/resolve.c b/libibmad/resolve.c index 2c397eb1a..cbdf75272 100644 --- a/libibmad/resolve.c +++ b/libibmad/resolve.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/libibumad/tests/umad_sa_mcm_rereg_test.c b/libibumad/tests/umad_sa_mcm_rereg_test.c index 4330d9f14..64283509f 100644 --- a/libibumad/tests/umad_sa_mcm_rereg_test.c +++ b/libibumad/tests/umad_sa_mcm_rereg_test.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include diff --git a/libibverbs/CMakeLists.txt b/libibverbs/CMakeLists.txt index eaf25a1ae..e04e77f4f 100644 --- a/libibverbs/CMakeLists.txt +++ b/libibverbs/CMakeLists.txt @@ -20,6 +20,14 @@ publish_internal_headers(infiniband configure_file("libibverbs.map.in" "${CMAKE_CURRENT_BINARY_DIR}/libibverbs.map" @ONLY) +if (CMAKE_SYSTEM_NAME STREQUAL "Linux") + set(SYSDEP_SOURCES init-sysfs.c sysfs-sysfs.c) +endif() + +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set(SYSDEP_SOURCES init-sysctl.c sysfs-sysctl.c) +endif() + rdma_library(ibverbs "${CMAKE_CURRENT_BINARY_DIR}/libibverbs.map" # See Documentation/versioning.md 1 1.18.${PACKAGE_VERSION} @@ -56,8 +64,8 @@ rdma_library(ibverbs "${CMAKE_CURRENT_BINARY_DIR}/libibverbs.map" memory.c neigh.c static_driver.c - sysfs.c verbs.c + ${SYSDEP_SOURCES} ) target_link_libraries(ibverbs LINK_PRIVATE ${NL_LIBRARIES} diff --git a/libibverbs/cmd_ioctl.h b/libibverbs/cmd_ioctl.h index 95fa7207c..b1e6446be 100644 --- a/libibverbs/cmd_ioctl.h +++ b/libibverbs/cmd_ioctl.h @@ -146,7 +146,7 @@ unsigned int __ioctl_final_num_attrs(unsigned int num_attrs, /* * C99 does not permit an initializer for VLAs, so this function does the init - * instead. It is called in the wonky way so that DELCARE_COMMAND_BUFFER can + * instead. It is called in the wonky way so that DECLARE_COMMAND_BUFFER can * still be a 'variable', and we so we don't require C11 mode. */ static inline int _ioctl_init_cmdb(struct ibv_command_buffer *cmd, diff --git a/libibverbs/examples/devinfo.c b/libibverbs/examples/devinfo.c index 1892ccd50..df561b60b 100644 --- a/libibverbs/examples/devinfo.c +++ b/libibverbs/examples/devinfo.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include diff --git a/libibverbs/examples/xsrq_pingpong.c b/libibverbs/examples/xsrq_pingpong.c index c0dc0b2e1..ab89fd75b 100644 --- a/libibverbs/examples/xsrq_pingpong.c +++ b/libibverbs/examples/xsrq_pingpong.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include diff --git a/libibverbs/ibverbs.h b/libibverbs/ibverbs.h index 33f83a7b9..2bb7b671d 100644 --- a/libibverbs/ibverbs.h +++ b/libibverbs/ibverbs.h @@ -90,6 +90,7 @@ static inline const struct verbs_context_ops *get_ops(struct ibv_context *ctx) enum ibv_node_type decode_knode_type(unsigned int knode_type); int find_sysfs_devs_nl(struct list_head *tmp_sysfs_dev_list); +int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list); int try_access_device(const struct verbs_sysfs_dev *sysfs_dev); diff --git a/libibverbs/init-sysctl.c b/libibverbs/init-sysctl.c new file mode 100644 index 000000000..8916914e5 --- /dev/null +++ b/libibverbs/init-sysctl.c @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. + * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "driver.h" +#include "ibverbs.h" +#include + +int setup_sysfs_uverbs(int uv_dirfd, const char *uverbs, + struct verbs_sysfs_dev *sysfs_dev) +{ + return 0; +} + +int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list) +{ + char class_path[IBV_SYSFS_PATH_MAX]; + char uverbs_path[IBV_SYSFS_PATH_MAX]; + struct verbs_sysfs_dev *sysfs_dev = NULL; + const char *sysfs_path; + char value[32]; + int i, ret; + + ret = 0; + sysfs_path = ibv_get_sysfs_path(); + + snprintf(class_path, sizeof class_path, "%s/class/infiniband_verbs", + sysfs_path); + + for (i = 0; i < 256; i++) { + if (sysfs_dev == NULL) { + sysfs_dev = calloc(1, sizeof *sysfs_dev); + if (sysfs_dev == NULL) { + ret = ENOMEM; + goto out; + } + } else { + memset(sysfs_dev, 0, sizeof(*sysfs_dev)); + } + + snprintf(sysfs_dev->sysfs_name, sizeof(sysfs_dev->sysfs_name), + "uverbs%d", i); + + snprintf(uverbs_path, sizeof(uverbs_path), + "%s/%s", class_path, sysfs_dev->sysfs_name); + + if (ibv_read_sysfs_file(uverbs_path, "ibdev", + sysfs_dev->ibdev_name, sizeof(sysfs_dev->ibdev_name)) < 0) + continue; + + if (!check_snprintf(sysfs_dev->ibdev_path, + sizeof(sysfs_dev->ibdev_path), "%s/class/infiniband/%s", + ibv_get_sysfs_path(), sysfs_dev->ibdev_name)) + continue; + + if (ibv_read_sysfs_file(uverbs_path, "abi_version", + value, sizeof(value)) > 0) + sysfs_dev->abi_ver = strtol(value, NULL, 10); + + if (ibv_read_sysfs_file(sysfs_dev->ibdev_path, "node_type", + value, sizeof(value)) > 0) { + sysfs_dev->node_type = + decode_knode_type(strtoul(value, NULL, 10)); + } else { + sysfs_dev->node_type = IBV_NODE_UNKNOWN; + } + // XXXKIB sysfs_dev->sysfs_cdev = XXX; + sysfs_dev->ibdev_idx = -1; + + list_add(tmp_sysfs_dev_list, &sysfs_dev->entry); + sysfs_dev = NULL; + } + + out: + if (sysfs_dev != NULL) + free(sysfs_dev); + + return ret; +} diff --git a/libibverbs/init-sysfs.c b/libibverbs/init-sysfs.c new file mode 100644 index 000000000..0ab1a0fca --- /dev/null +++ b/libibverbs/init-sysfs.c @@ -0,0 +1,175 @@ +/* + * Copyright (c) 2004, 2005 Topspin Communications. All rights reserved. + * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include "driver.h" +#include "ibverbs.h" +#include + +int setup_sysfs_uverbs(int uv_dirfd, const char *uverbs, + struct verbs_sysfs_dev *sysfs_dev) +{ + unsigned int major; + unsigned int minor; + struct stat buf; + char value[32]; + + if (!check_snprintf(sysfs_dev->sysfs_name, + sizeof(sysfs_dev->sysfs_name), "%s", uverbs)) + return -1; + + if (stat(sysfs_dev->ibdev_path, &buf)) + return -1; + sysfs_dev->time_created = buf.st_mtim; + + if (ibv_read_sysfs_file_at(uv_dirfd, "dev", value, + sizeof(value)) < 0) + return -1; + if (sscanf(value, "%u:%u", &major, &minor) != 2) + return -1; + sysfs_dev->sysfs_cdev = makedev(major, minor); + + if (ibv_read_sysfs_file_at(uv_dirfd, "abi_version", value, + sizeof(value)) > 0) + sysfs_dev->abi_ver = strtoul(value, NULL, 10); + + return 0; +} + +static int setup_sysfs_dev(int dirfd, const char *uverbs, + struct list_head *tmp_sysfs_dev_list) +{ + struct verbs_sysfs_dev *sysfs_dev = NULL; + char value[32]; + int uv_dirfd; + + sysfs_dev = calloc(1, sizeof(*sysfs_dev)); + if (!sysfs_dev) + return ENOMEM; + + sysfs_dev->ibdev_idx = -1; + + uv_dirfd = openat(dirfd, uverbs, O_RDONLY | O_DIRECTORY | O_CLOEXEC); + if (uv_dirfd == -1) + goto err_alloc; + + if (ibv_read_sysfs_file_at(uv_dirfd, "ibdev", sysfs_dev->ibdev_name, + sizeof(sysfs_dev->ibdev_name)) < 0) + goto err_fd; + + if (!check_snprintf( + sysfs_dev->ibdev_path, sizeof(sysfs_dev->ibdev_path), + "%s/class/infiniband/%s", ibv_get_sysfs_path(), + sysfs_dev->ibdev_name)) + goto err_fd; + + if (setup_sysfs_uverbs(uv_dirfd, uverbs, sysfs_dev)) + goto err_fd; + + if (ibv_read_ibdev_sysfs_file(value, sizeof(value), sysfs_dev, + "node_type") <= 0) + sysfs_dev->node_type = IBV_NODE_UNKNOWN; + else + sysfs_dev->node_type = + decode_knode_type(strtoul(value, NULL, 10)); + + if (try_access_device(sysfs_dev)) + goto err_fd; + + close(uv_dirfd); + list_add(tmp_sysfs_dev_list, &sysfs_dev->entry); + return 0; + +err_fd: + close(uv_dirfd); +err_alloc: + free(sysfs_dev); + return 0; +} + +int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list) +{ + struct verbs_sysfs_dev *dev, *dev_tmp; + char class_path[IBV_SYSFS_PATH_MAX]; + DIR *class_dir; + struct dirent *dent; + int ret = 0; + + if (!check_snprintf(class_path, sizeof(class_path), + "%s/class/infiniband_verbs", ibv_get_sysfs_path())) + return ENOMEM; + + class_dir = opendir(class_path); + if (!class_dir) + return ENOSYS; + + while ((dent = readdir(class_dir))) { + if (dent->d_name[0] == '.') + continue; + + ret = setup_sysfs_dev(dirfd(class_dir), dent->d_name, + tmp_sysfs_dev_list); + if (ret) + break; + } + closedir(class_dir); + + if (ret) { + list_for_each_safe (tmp_sysfs_dev_list, dev, dev_tmp, entry) { + list_del(&dev->entry); + free(dev); + } + } + return ret; +} diff --git a/libibverbs/init.c b/libibverbs/init.c index 5f3d11e2d..fe271e95f 100644 --- a/libibverbs/init.c +++ b/libibverbs/init.c @@ -120,123 +120,6 @@ enum ibv_node_type decode_knode_type(unsigned int knode_type) return IBV_NODE_UNKNOWN; } -int setup_sysfs_uverbs(int uv_dirfd, const char *uverbs, - struct verbs_sysfs_dev *sysfs_dev) -{ - unsigned int major; - unsigned int minor; - struct stat buf; - char value[32]; - - if (!check_snprintf(sysfs_dev->sysfs_name, - sizeof(sysfs_dev->sysfs_name), "%s", uverbs)) - return -1; - - if (stat(sysfs_dev->ibdev_path, &buf)) - return -1; - sysfs_dev->time_created = buf.st_mtim; - - if (ibv_read_sysfs_file_at(uv_dirfd, "dev", value, - sizeof(value)) < 0) - return -1; - if (sscanf(value, "%u:%u", &major, &minor) != 2) - return -1; - sysfs_dev->sysfs_cdev = makedev(major, minor); - - if (ibv_read_sysfs_file_at(uv_dirfd, "abi_version", value, - sizeof(value)) > 0) - sysfs_dev->abi_ver = strtoul(value, NULL, 10); - - return 0; -} - -static int setup_sysfs_dev(int dirfd, const char *uverbs, - struct list_head *tmp_sysfs_dev_list) -{ - struct verbs_sysfs_dev *sysfs_dev = NULL; - char value[32]; - int uv_dirfd; - - sysfs_dev = calloc(1, sizeof(*sysfs_dev)); - if (!sysfs_dev) - return ENOMEM; - - sysfs_dev->ibdev_idx = -1; - - uv_dirfd = openat(dirfd, uverbs, O_RDONLY | O_DIRECTORY | O_CLOEXEC); - if (uv_dirfd == -1) - goto err_alloc; - - if (ibv_read_sysfs_file_at(uv_dirfd, "ibdev", sysfs_dev->ibdev_name, - sizeof(sysfs_dev->ibdev_name)) < 0) - goto err_fd; - - if (!check_snprintf( - sysfs_dev->ibdev_path, sizeof(sysfs_dev->ibdev_path), - "%s/class/infiniband/%s", ibv_get_sysfs_path(), - sysfs_dev->ibdev_name)) - goto err_fd; - - if (setup_sysfs_uverbs(uv_dirfd, uverbs, sysfs_dev)) - goto err_fd; - - if (ibv_read_ibdev_sysfs_file(value, sizeof(value), sysfs_dev, - "node_type") <= 0) - sysfs_dev->node_type = IBV_NODE_UNKNOWN; - else - sysfs_dev->node_type = - decode_knode_type(strtoul(value, NULL, 10)); - - if (try_access_device(sysfs_dev)) - goto err_fd; - - close(uv_dirfd); - list_add(tmp_sysfs_dev_list, &sysfs_dev->entry); - return 0; - -err_fd: - close(uv_dirfd); -err_alloc: - free(sysfs_dev); - return 0; -} - -static int find_sysfs_devs(struct list_head *tmp_sysfs_dev_list) -{ - struct verbs_sysfs_dev *dev, *dev_tmp; - char class_path[IBV_SYSFS_PATH_MAX]; - DIR *class_dir; - struct dirent *dent; - int ret = 0; - - if (!check_snprintf(class_path, sizeof(class_path), - "%s/class/infiniband_verbs", ibv_get_sysfs_path())) - return ENOMEM; - - class_dir = opendir(class_path); - if (!class_dir) - return ENOSYS; - - while ((dent = readdir(class_dir))) { - if (dent->d_name[0] == '.') - continue; - - ret = setup_sysfs_dev(dirfd(class_dir), dent->d_name, - tmp_sysfs_dev_list); - if (ret) - break; - } - closedir(class_dir); - - if (ret) { - list_for_each_safe (tmp_sysfs_dev_list, dev, dev_tmp, entry) { - list_del(&dev->entry); - free(dev); - } - } - return ret; -} - void verbs_register_driver(const struct verbs_device_ops *ops) { struct ibv_driver *driver; diff --git a/libibverbs/memory.c b/libibverbs/memory.c index c9821e664..d0c2f128f 100644 --- a/libibverbs/memory.c +++ b/libibverbs/memory.c @@ -605,7 +605,16 @@ static int do_madvise(void *addr, size_t length, int advice, int ret; void *p; +#if !defined INHERIT_COPY ret = madvise(addr, length, advice); +#else + if (advice == MADV_DOFORK || advice == MADV_DONTFORK) { + ret = minherit(addr, length, advice == MADV_DOFORK ? + INHERIT_COPY : INHERIT_NONE); + } else { + ret = madvise(addr, length, advice); + } +#endif if (!ret || advice == MADV_DONTFORK) return ret; @@ -614,8 +623,12 @@ static int do_madvise(void *addr, size_t length, int advice, /* if MADV_DOFORK failed we will try to remove VM_DONTCOPY * flag from each page */ +#if !defined INHERIT_COPY for (p = addr; p < addr + length; p += range_page_size) madvise(p, range_page_size, MADV_DOFORK); +#else + minherit(addr, length, INHERIT_COPY); +#endif } return 0; diff --git a/libibverbs/neigh.c b/libibverbs/neigh.c index 7eed95f14..464b8b8f0 100644 --- a/libibverbs/neigh.c +++ b/libibverbs/neigh.c @@ -9,6 +9,7 @@ #include #include +#include #if HAVE_WORKING_IF_H #include #endif diff --git a/libibverbs/sysfs-sysctl.c b/libibverbs/sysfs-sysctl.c new file mode 100644 index 000000000..83ab5c086 --- /dev/null +++ b/libibverbs/sysfs-sysctl.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2006 Cisco Systems, Inc. All rights reserved. + * + * This software is available to you under a choice of one of two + * licenses. You may choose to be licensed under the terms of the GNU + * General Public License (GPL) Version 2, available from the file + * COPYING in the main directory of this source tree, or the + * OpenIB.org BSD license below: + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above + * copyright notice, this list of conditions and the following + * disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#define _GNU_SOURCE +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ibverbs.h" + +static const char *sysfs_path; + +const char *ibv_get_sysfs_path(void) +{ + const char *env = NULL; + static const char slash_sys[] = "/sys"; + + if (sysfs_path) + return sysfs_path; + + /* + * Only follow use path passed in through the calling user's + * environment if we're not running SUID. + */ + if (getuid() == geteuid()) + env = getenv("SYSFS_PATH"); + + if (env) { + int len; + char *dup; + + sysfs_path = dup = strndup(env, IBV_SYSFS_PATH_MAX); + if (dup == NULL) { + sysfs_path = slash_sys; + } else { + len = strlen(dup); + while (len > 0 && dup[len - 1] == '/') { + --len; + dup[len] = '\0'; + } + } + } else + sysfs_path = slash_sys; + + return sysfs_path; +} + +static int sysctl_verbose = -1; + +int ibv_read_sysfs_file(const char *dir, const char *file, + char *buf, size_t size) +{ + char *path, *s, *r; + int ret; + size_t len; + + if (sysctl_verbose == -1) + sysctl_verbose = getenv("IBVERBS_SYSCTL_VERBOSE") != NULL; + + if (asprintf(&path, "%s/%s", dir, file) < 0) + return -1; + + if (sysctl_verbose) + fprintf(stderr, "sysctl \"%s\": ", path); + for (s = &path[0]; *s != '\0'; s++) + if (*s == '/') + *s = '.'; + + len = size; + ret = sysctlbyname(&path[1], buf, &len, NULL, 0); + if (sysctl_verbose) { + if (ret == -1) { + fprintf(stderr, "error %d (%s)\n", errno, + strerror(errno)); + } else { + r = alloca(len + 1); + memcpy(r, buf, len); + r[len] = '\0'; + fprintf(stderr, "%s\n", r); + } + } + free(path); + + if (ret == -1) + return -1; + + if (len > 0 && buf[len - 1] == '\n') + buf[--len] = '\0'; + + return len; +} + +int ibv_read_ibdev_sysfs_file(char *buf, size_t size, + struct verbs_sysfs_dev *sysfs_dev, + const char *fnfmt, ...) +{ + char comp[IBV_SYSFS_PATH_MAX]; + va_list ap; + + va_start(ap, fnfmt); + vsnprintf(comp, sizeof(comp), fnfmt, ap); + va_end(ap); + + if (strcmp(comp, "device/modalias") == 0) { + char path_device[IBV_SYSFS_PATH_MAX]; + char value[64]; + unsigned vendor; + unsigned devid; + + snprintf(path_device, sizeof(path_device), "%s/%s/%s/device", + ibv_get_sysfs_path(), "class/infiniband_verbs", + sysfs_dev->sysfs_name); + if (ibv_read_sysfs_file(path_device, "vendor", value, + sizeof(value)) < 0) + return -1; + vendor = strtoul(value, NULL, 0); + if (ibv_read_sysfs_file(path_device, "device", value, + sizeof(value)) < 0) + return -1; + devid = strtoul(value, NULL, 0); + snprintf(buf, size, "pci:v%08Xd%08Xsv", vendor, devid); + return 1; + } + + return -1; +} diff --git a/libibverbs/sysfs.c b/libibverbs/sysfs-sysfs.c similarity index 100% rename from libibverbs/sysfs.c rename to libibverbs/sysfs-sysfs.c diff --git a/libibverbs/verbs.c b/libibverbs/verbs.c index bb5233b53..61a8129e8 100644 --- a/libibverbs/verbs.c +++ b/libibverbs/verbs.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include diff --git a/librdmacm/CMakeLists.txt b/librdmacm/CMakeLists.txt index e30626cd2..5d679d321 100644 --- a/librdmacm/CMakeLists.txt +++ b/librdmacm/CMakeLists.txt @@ -49,3 +49,9 @@ if (ENABLE_STATIC) endif() endif() rdma_pkg_config("rdmacm" "${REQUIRES}libibverbs" "${CMAKE_THREAD_LIBS_INIT}") + +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + find_package(epoll-shim REQUIRED) + target_link_libraries(rdmacm PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rspreload PRIVATE epoll-shim::epoll-shim) +endif() diff --git a/librdmacm/examples/CMakeLists.txt b/librdmacm/examples/CMakeLists.txt index ed119466f..6f0a7ad1e 100644 --- a/librdmacm/examples/CMakeLists.txt +++ b/librdmacm/examples/CMakeLists.txt @@ -42,3 +42,27 @@ target_link_libraries(udaddy LINK_PRIVATE rdmacm rdmacm_tools) rdma_executable(udpong udpong.c) target_link_libraries(udpong LINK_PRIVATE rdmacm rdmacm_tools) + +if (CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + find_package(epoll-shim REQUIRED) + target_include_directories(rdmacm_tools PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rdmacm_tools PRIVATE epoll-shim::epoll-shim) + target_include_directories(cmtime PRIVATE epoll-shim::epoll-shim) + target_link_libraries(cmtime PRIVATE epoll-shim::epoll-shim) + target_include_directories(mckey PRIVATE epoll-shim::epoll-shim) + target_link_libraries(mckey PRIVATE epoll-shim::epoll-shim) + target_include_directories(rcopy PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rcopy PRIVATE epoll-shim::epoll-shim) + target_include_directories(riostream PRIVATE epoll-shim::epoll-shim) + target_link_libraries(riostream PRIVATE epoll-shim::epoll-shim) + target_include_directories(rping PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rping PRIVATE epoll-shim::epoll-shim) + target_include_directories(rstream PRIVATE epoll-shim::epoll-shim) + target_link_libraries(rstream PRIVATE epoll-shim::epoll-shim) + target_include_directories(ucmatose PRIVATE epoll-shim::epoll-shim) + target_link_libraries(ucmatose PRIVATE epoll-shim::epoll-shim) + target_include_directories(udaddy PRIVATE epoll-shim::epoll-shim) + target_link_libraries(udaddy PRIVATE epoll-shim::epoll-shim) + target_include_directories(udpong PRIVATE epoll-shim::epoll-shim) + target_link_libraries(udpong PRIVATE epoll-shim::epoll-shim) +endif() diff --git a/librdmacm/preload.c b/librdmacm/preload.c index f46e80f3a..b8d84157d 100644 --- a/librdmacm/preload.c +++ b/librdmacm/preload.c @@ -33,6 +33,11 @@ #define _GNU_SOURCE #include +#ifdef __FreeBSD__ +#define EPOLL_SHIM_DISABLE_WRAPPER_MACROS +#include +#endif + #include #include #include @@ -69,6 +74,8 @@ ssize_t sendfile64(int out_fd, int in_fd, off64_t *offset64, size_t count); #endif #endif +struct sf_hdtr; + struct socket_calls { int (*socket)(int domain, int type, int protocol); int (*bind)(int socket, const struct sockaddr *addr, socklen_t addrlen); @@ -103,9 +110,14 @@ struct socket_calls { #endif int (*dup)(int oldfd); int (*dup2)(int oldfd, int newfd); +#if defined __linux__ ssize_t (*sendfile)(int out_fd, int in_fd, off_t *offset, size_t count); #if RDMA_PRELOAD_WRAP_LFS64 ssize_t (*sendfile64)(int out_fd, int in_fd, off64_t *offset64, size_t count); +#endif +#elif defined __FreeBSD__ + int (*sendfile)(int in_fd, int out_fd, off_t offset, size_t count, + struct sf_hdtr *hdtr, off_t *sbytes, int flags); #endif int (*fxstat)(int ver, int fd, struct stat *buf); }; @@ -160,6 +172,13 @@ static void free_config(void) free(config); } +#ifdef __FreeBSD__ +#include + +static char program_invocation_short_name_buf[256]; +static char *program_invocation_short_name; +#endif + /* * Config file format: * # Starting '#' indicates comment @@ -391,18 +410,8 @@ static void getenv_options(void) fork_support = atoi(var); } -static void init_preload(void) +static void init_preload_act(void) { - static int init; - - /* Quick check without lock */ - if (init) - return; - - pthread_mutex_lock(&mut); - if (init) - goto out; - real.socket = dlsym(RTLD_NEXT, "socket"); real.bind = dlsym(RTLD_NEXT, "bind"); real.listen = dlsym(RTLD_NEXT, "listen"); @@ -464,9 +473,18 @@ static void init_preload(void) getenv_options(); scan_config(); - init = 1; -out: - pthread_mutex_unlock(&mut); +#ifdef __FreeBSD__ + strlcpy(program_invocation_short_name_buf, getprogname(), + sizeof(program_invocation_short_name_buf)); + program_invocation_short_name = basename(program_invocation_short_name_buf); +#endif +} + +static void init_preload(void) +{ + static pthread_once_t init_preload_ctrl = PTHREAD_ONCE_INIT; + + pthread_once(&init_preload_ctrl, init_preload_act); } /* @@ -1159,8 +1177,12 @@ int fcntl(int socket, int cmd, ... /* arg */) case F_GETFD: case F_GETFL: case F_GETOWN: +#ifdef F_GETSIG case F_GETSIG: +#endif +#ifdef F_GETLEASE case F_GETLEASE: +#endif ret = (fd_get(socket, &fd) == fd_rsocket) ? rfcntl(fd, cmd) : real.fcntl(fd, cmd); break; @@ -1169,9 +1191,15 @@ int fcntl(int socket, int cmd, ... /* arg */) case F_SETFD: case F_SETFL: case F_SETOWN: +#ifdef F_SETSIG case F_SETSIG: +#endif +#ifdef F_SETLEASE case F_SETLEASE: +#endif +#ifdef F_NOTIFY case F_NOTIFY: +#endif lparam = va_arg(args, long); ret = (fd_get(socket, &fd) == fd_rsocket) ? rfcntl(fd, cmd, lparam) : real.fcntl(fd, cmd, lparam); @@ -1291,6 +1319,49 @@ int dup2(int oldfd, int newfd) return newfd; } +#if defined __FreeBSD__ +int sendfile(int in_fd, int out_fd, off_t offset, size_t count, + struct sf_hdtr *hdtr, off_t *sbytes, int flags) +{ + void *file_addr; + struct stat st; + int fd; + size_t map_len; + ssize_t ret; + uintptr_t file_addr_a; + + if (fd_get(out_fd, &fd) != fd_rsocket) { + return real.sendfile(in_fd, out_fd, offset, count, hdtr, + sbytes, flags); + } + if (hdtr != NULL || flags != 0) { + errno = EOPNOTSUPP; + return -1; + } + if (count == 0) { + if (fstat(in_fd, &st) == -1) + return -1; + if (offset > st.st_size) + count = 0; + else + count = st.st_size - offset; + } + map_len = round_page((offset & PAGE_MASK) + count); + file_addr = mmap(NULL, map_len, PROT_READ, 0, in_fd, + trunc_page(offset)); + if (file_addr == MAP_FAILED) + return -1; + file_addr_a = (uintptr_t)file_addr; + file_addr_a += offset & PAGE_MASK; /* GCC extension */ + ret = rwrite(fd, (void *)file_addr_a, count); + munmap(file_addr, map_len); + if (ret < 0) + return -1; + if (sbytes != NULL) + *sbytes = ret; + return 0; +} +#elif defined __linux__ ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) { void *file_addr; @@ -1310,6 +1381,9 @@ ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) munmap(file_addr, count); return ret; } +#else +#error "Port me" +#endif #if RDMA_PRELOAD_WRAP_LFS64 ssize_t sendfile64(int out_fd, int in_fd, off64_t *offset64, size_t count) diff --git a/providers/mlx5/qp.c b/providers/mlx5/qp.c index b28273c83..4e72327b1 100644 --- a/providers/mlx5/qp.c +++ b/providers/mlx5/qp.c @@ -492,6 +492,7 @@ static inline int copy_eth_inline_headers(struct ibv_qp *ibqp, return 0; } +#undef ALIGN #define ALIGN(x, log_a) ((((x) + (1 << (log_a)) - 1)) & ~((1 << (log_a)) - 1)) static inline __be16 get_klm_octo(int nentries) diff --git a/providers/rxe/rxe.c b/providers/rxe/rxe.c index 62615e65e..314f6739f 100644 --- a/providers/rxe/rxe.c +++ b/providers/rxe/rxe.c @@ -1738,7 +1738,7 @@ static inline int rdma_gid2ip(sockaddr_union_t *out, union ibv_gid *gid) } else { memset(&out->_sockaddr_in6, 0, sizeof(out->_sockaddr_in6)); out->_sockaddr_in6.sin6_family = AF_INET6; - memcpy(&out->_sockaddr_in6.sin6_addr.s6_addr, gid->raw, 16); + memcpy(&out->_sockaddr_in6.sin6_addr, gid->raw, 16); } return 0; } diff --git a/providers/rxe/rxe.h b/providers/rxe/rxe.h index 6da22b89f..241b866ea 100644 --- a/providers/rxe/rxe.h +++ b/providers/rxe/rxe.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include "rxe-abi.h" diff --git a/providers/vmw_pvrdma/pvrdma.h b/providers/vmw_pvrdma/pvrdma.h index bb6ba729d..9c08dc8c4 100644 --- a/providers/vmw_pvrdma/pvrdma.h +++ b/providers/vmw_pvrdma/pvrdma.h @@ -54,6 +54,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/pyverbs/providers/mlx5/dr_action.pyx b/pyverbs/providers/mlx5/dr_action.pyx index 373c0e890..d60f9758b 100644 --- a/pyverbs/providers/mlx5/dr_action.pyx +++ b/pyverbs/providers/mlx5/dr_action.pyx @@ -9,7 +9,7 @@ from pyverbs.providers.mlx5.mlx5_enums import mlx5dv_dr_action_dest_type from pyverbs.pyverbs_error import PyverbsError from pyverbs.base cimport close_weakrefs from libc.stdlib cimport calloc, free -from libc.stdint cimport uint32_t, uint8_t +from libc.stdint cimport uint64_t, uint32_t, uint8_t from libc.string cimport memcpy import weakref import struct @@ -18,6 +18,8 @@ import errno be64toh = lambda num: struct.unpack('Q'.encode(), struct.pack('!8s'.encode(), num))[0] ACTION_SIZE = 8 +cdef extern from "": + ctypedef uint64_t __be64 cdef class DrAction(PyverbsCM): def __init__(self): @@ -111,7 +113,7 @@ cdef class DrActionModify(DrAction): """ super().__init__() action_buf_size = len(actions) * ACTION_SIZE - cdef unsigned long long *buf = calloc(1, action_buf_size) + cdef __be64 *buf = <__be64 *>calloc(1, action_buf_size) if buf == NULL: raise MemoryError('Failed to allocate memory', errno)