Adding OSv support. Based on Linux/FreeBSD EAL, but calling OSv kernel APIs to access devices, allocate contiguous memory, etc.
Signed-off-by: Takuya ASADA <syuu at cloudius-systems.com> --- config/{common_linuxapp => common_osvapp} | 24 +- ...xapp-gcc => defconfig_x86_64-native-osvapp-gcc} | 2 +- lib/librte_eal/Makefile | 2 + Makefile => lib/librte_eal/osvapp/Makefile | 5 +- lib/librte_eal/osvapp/capstan/Capstanfile | 5 + lib/librte_eal/osvapp/capstan/GET | 22 ++ lib/librte_eal/osvapp/eal/Makefile | 115 ++++++++ lib/librte_eal/{linuxapp => osvapp}/eal/eal.c | 123 +------- .../{linuxapp => osvapp}/eal/eal_alarm.c | 0 .../{linuxapp => osvapp}/eal/eal_debug.c | 0 lib/librte_eal/osvapp/eal/eal_hugepage_info.cc | 63 +++++ .../{bsdapp => osvapp}/eal/eal_interrupts.c | 0 .../eal/eal_lcore.c => osvapp/eal/eal_lcore.cc} | 53 ++-- lib/librte_eal/{bsdapp => osvapp}/eal/eal_log.c | 0 lib/librte_eal/osvapp/eal/eal_memory.cc | 148 ++++++++++ lib/librte_eal/osvapp/eal/eal_pci.cc | 311 +++++++++++++++++++++ .../{linuxapp => osvapp}/eal/eal_thread.c | 0 lib/librte_eal/osvapp/eal/eal_timer.c | 130 +++++++++ .../eal/include/exec-env/rte_interrupts.h | 0 .../{bsdapp => osvapp}/eal/rte_eal_version.map | 11 +- mk/exec-env/{linuxapp => osvapp}/rte.app.mk | 0 mk/exec-env/{linuxapp => osvapp}/rte.vars.mk | 6 +- 22 files changed, 847 insertions(+), 173 deletions(-) copy config/{common_linuxapp => common_osvapp} (96%) copy config/{defconfig_x86_64-native-linuxapp-gcc => defconfig_x86_64-native-osvapp-gcc} (98%) copy Makefile => lib/librte_eal/osvapp/Makefile (93%) create mode 100644 lib/librte_eal/osvapp/capstan/Capstanfile create mode 100755 lib/librte_eal/osvapp/capstan/GET create mode 100644 lib/librte_eal/osvapp/eal/Makefile copy lib/librte_eal/{linuxapp => osvapp}/eal/eal.c (87%) copy lib/librte_eal/{linuxapp => osvapp}/eal/eal_alarm.c (100%) copy lib/librte_eal/{linuxapp => osvapp}/eal/eal_debug.c (100%) create mode 100644 lib/librte_eal/osvapp/eal/eal_hugepage_info.cc copy lib/librte_eal/{bsdapp => osvapp}/eal/eal_interrupts.c (100%) copy lib/librte_eal/{bsdapp/eal/eal_lcore.c => osvapp/eal/eal_lcore.cc} (80%) copy lib/librte_eal/{bsdapp => osvapp}/eal/eal_log.c (100%) create mode 100644 lib/librte_eal/osvapp/eal/eal_memory.cc create mode 100644 lib/librte_eal/osvapp/eal/eal_pci.cc copy lib/librte_eal/{linuxapp => osvapp}/eal/eal_thread.c (100%) create mode 100644 lib/librte_eal/osvapp/eal/eal_timer.c copy lib/librte_eal/{bsdapp => osvapp}/eal/include/exec-env/rte_interrupts.h (100%) copy lib/librte_eal/{bsdapp => osvapp}/eal/rte_eal_version.map (92%) copy mk/exec-env/{linuxapp => osvapp}/rte.app.mk (100%) copy mk/exec-env/{linuxapp => osvapp}/rte.vars.mk (95%) diff --git a/config/common_linuxapp b/config/common_osvapp similarity index 96% copy from config/common_linuxapp copy to config/common_osvapp index 09a58ac..ce973fe 100644 --- a/config/common_linuxapp +++ b/config/common_osvapp @@ -35,8 +35,8 @@ # # CONFIG_RTE_EXEC_ENV can be linuxapp, bsdapp # -CONFIG_RTE_EXEC_ENV="linuxapp" -CONFIG_RTE_EXEC_ENV_LINUXAPP=y +CONFIG_RTE_EXEC_ENV="osvapp" +CONFIG_RTE_EXEC_ENV_OSVAPP=y ## ## machine can define specific variables or action for a specific board @@ -89,7 +89,7 @@ CONFIG_RTE_LIBNAME="intel_dpdk" # CONFIG_RTE_LIBRTE_EAL=y CONFIG_RTE_MAX_LCORE=128 -CONFIG_RTE_MAX_NUMA_NODES=8 +CONFIG_RTE_MAX_NUMA_NODES=1 CONFIG_RTE_MAX_MEMSEG=256 CONFIG_RTE_MAX_MEMZONE=2560 CONFIG_RTE_MAX_TAILQ=32 @@ -98,8 +98,8 @@ CONFIG_RTE_LOG_HISTORY=256 CONFIG_RTE_LIBEAL_USE_HPET=n CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n -CONFIG_RTE_EAL_IGB_UIO=y -CONFIG_RTE_EAL_VFIO=y +CONFIG_RTE_EAL_IGB_UIO=n +CONFIG_RTE_EAL_VFIO=n # # Special configurations in PCI Config Space for high performance @@ -111,7 +111,13 @@ CONFIG_RTE_PCI_MAX_READ_REQUEST_SIZE=0 # # Compile Environment Abstraction Layer for linux # -CONFIG_RTE_LIBRTE_EAL_LINUXAPP=y +CONFIG_RTE_LIBRTE_EAL_OSVAPP=y + +# +# Compile OSv specific parameters +# +CONFIG_RTE_CONTIGUOUS_CHUNK_SIZE=32M +CONFIG_RTE_DEFAULT_NUM_CHUNKS=4 # # Compile Environment Abstraction Layer to support hotplug @@ -403,7 +409,7 @@ CONFIG_RTE_LIBRTE_PIPELINE=y # # Compile librte_kni # -CONFIG_RTE_LIBRTE_KNI=y +CONFIG_RTE_LIBRTE_KNI=n CONFIG_RTE_KNI_PREEMPT_DEFAULT=y CONFIG_RTE_KNI_KO_DEBUG=n CONFIG_RTE_KNI_VHOST=n @@ -414,12 +420,10 @@ CONFIG_RTE_KNI_VHOST_DEBUG_TX=n # # Compile vhost library -# fuse-devel is needed to run vhost-cuse. +# fuse-devel is needed to run vhost. # fuse-devel enables user space char driver development -# vhost-user is turned on by default. # CONFIG_RTE_LIBRTE_VHOST=n -CONFIG_RTE_LIBRTE_VHOST_USER=y CONFIG_RTE_LIBRTE_VHOST_DEBUG=n # diff --git a/config/defconfig_x86_64-native-linuxapp-gcc b/config/defconfig_x86_64-native-osvapp-gcc similarity index 98% copy from config/defconfig_x86_64-native-linuxapp-gcc copy to config/defconfig_x86_64-native-osvapp-gcc index 60baf5b..2134270 100644 --- a/config/defconfig_x86_64-native-linuxapp-gcc +++ b/config/defconfig_x86_64-native-osvapp-gcc @@ -30,7 +30,7 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # -#include "common_linuxapp" +#include "common_osvapp" CONFIG_RTE_MACHINE="native" diff --git a/lib/librte_eal/Makefile b/lib/librte_eal/Makefile index 69003cf..c555587 100644 --- a/lib/librte_eal/Makefile +++ b/lib/librte_eal/Makefile @@ -35,5 +35,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += common DIRS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += linuxapp DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += common DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += bsdapp +DIRS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += common +DIRS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += osvapp include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/Makefile b/lib/librte_eal/osvapp/Makefile similarity index 93% copy from Makefile copy to lib/librte_eal/osvapp/Makefile index f4b807e..15badb3 100644 --- a/Makefile +++ b/lib/librte_eal/osvapp/Makefile @@ -29,5 +29,8 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.error Error please compile using GNU Make (gmake) +include $(RTE_SDK)/mk/rte.vars.mk +DIRS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal + +include $(RTE_SDK)/mk/rte.subdir.mk diff --git a/lib/librte_eal/osvapp/capstan/Capstanfile b/lib/librte_eal/osvapp/capstan/Capstanfile new file mode 100644 index 0000000..c03480d --- /dev/null +++ b/lib/librte_eal/osvapp/capstan/Capstanfile @@ -0,0 +1,5 @@ +base: cloudius/osv-base + +cmdline: /test -c 1 -n 1 --no-shconf + +build: ./GET diff --git a/lib/librte_eal/osvapp/capstan/GET b/lib/librte_eal/osvapp/capstan/GET new file mode 100755 index 0000000..891fab6 --- /dev/null +++ b/lib/librte_eal/osvapp/capstan/GET @@ -0,0 +1,22 @@ +#!/bin/sh -e + +export RTE_SDK=`readlink -f ../../../..` +export RTE_TARGET=x86_64-native-osvapp-gcc +OSV_SDK=`readlink -f osv` +OSV_VER=v0.18 + +if [ ! -e $OSV_SDK ]; then + git clone -b $OSV_VER --depth 1 https://github.com/cloudius-systems/osv +fi +cd $RTE_SDK +make install T=$RTE_TARGET OSV_SDK=$OSV_SDK +(cd examples/cmdline; make) +(cd examples/helloworld; make) +(cd examples/ip_fragmentation; make) +(cd examples/l2fwd; make) +(cd examples/l3fwd; make) +cd - +mkdir -p ROOTFS +find $RTE_SDK/x86_64-native-osvapp-gcc/app/ -executable -readable -type f -exec cp -v {} ROOTFS/ \; +find $RTE_SDK/examples/*/build/app -executable -readable -type f -exec cp -v {} ROOTFS/ \; +find $RTE_SDK/x86_64-native-osvapp-gcc/lib/ -name "*.so*" -exec cp -av {} ROOTFS/ \; diff --git a/lib/librte_eal/osvapp/eal/Makefile b/lib/librte_eal/osvapp/eal/Makefile new file mode 100644 index 0000000..571e04c --- /dev/null +++ b/lib/librte_eal/osvapp/eal/Makefile @@ -0,0 +1,115 @@ +# BSD LICENSE +# +# Copyright(c) 2010-2014 Intel Corporation. All rights reserved. +# All rights reserved. +# +# 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. +# * Neither the name of Intel Corporation nor the names of its +# contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "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 COPYRIGHT +# OWNER OR CONTRIBUTORS 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. + +include $(RTE_SDK)/mk/rte.vars.mk + +LIB = librte_eal.a + +EXPORT_MAP := rte_eal_version.map + +LIBABIVER := 1 + +VPATH += $(RTE_SDK)/lib/librte_eal/common + +INC_FLAGS := -I$(SRCDIR)/include +INC_FLAGS += -I$(RTE_SDK)/lib/librte_eal/common +INC_FLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include +INC_FLAGS += -I$(RTE_SDK)/lib/librte_ring +INC_FLAGS += -I$(RTE_SDK)/lib/librte_mempool +INC_FLAGS += -I$(RTE_SDK)/lib/librte_malloc +INC_FLAGS += -I$(RTE_SDK)/lib/librte_ether +INC_FLAGS += -I$(RTE_SDK)/lib/librte_pmd_ring +INC_FLAGS += -I$(RTE_SDK)/lib/librte_pmd_pcap +INC_FLAGS += -I$(RTE_SDK)/lib/librte_pmd_af_packet +INC_FLAGS += -I$(RTE_SDK)/lib/librte_pmd_xenvirt +INC_FLAGS += -I$(OSV_SDK) +INC_FLAGS += -I$(OSV_SDK)/arch/x64 +INC_FLAGS += -I$(OSV_SDK)/arch/common +INC_FLAGS += -I$(OSV_SDK)/include + +CFLAGS += $(INC_FLAGS) $(WERROR_FLAGS) -O3 +CXXFLAGS += $(INC_FLAGS) -std=gnu++11 -O3 + +# specific to osvapp exec-env +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) := eal.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_hugepage_info.cc +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_memory.cc +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_thread.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_log.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_pci.cc +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_debug.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_lcore.cc +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_timer.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_interrupts.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_alarm.c + +# from common dir +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_memzone.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_log.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_launch.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_pci.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_memory.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_tailqs.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_errno.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_cpuflags.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_string_fns.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_hexdump.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_devargs.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_dev.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_options.c +SRCS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += eal_common_thread.c + +CFLAGS_eal.o := -D_GNU_SOURCE +CFLAGS_eal_lcore.o := -D_GNU_SOURCE +CFLAGS_eal_thread.o := -D_GNU_SOURCE +CFLAGS_eal_log.o := -D_GNU_SOURCE +CFLAGS_eal_common_log.o := -D_GNU_SOURCE +CFLAGS_eal_hugepage_info.o := -D_GNU_SOURCE +CFLAGS_eal_pci.o := -D_GNU_SOURCE +CFLAGS_eal_common_whitelist.o := -D_GNU_SOURCE +CFLAGS_eal_common_options.o := -D_GNU_SOURCE +CFLAGS_eal_common_thread.o := -D_GNU_SOURCE + +# workaround for a gcc bug with noreturn attribute +# http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12603 +ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y) +CFLAGS_eal_thread.o += -Wno-return-type +endif + +INC := rte_interrupts.h + +SYMLINK-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP)-include/exec-env := \ + $(addprefix include/exec-env/,$(INC)) + +DEPDIRS-$(CONFIG_RTE_LIBRTE_EAL_OSVAPP) += lib/librte_eal/common + +include $(RTE_SDK)/mk/rte.lib.mk + diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/osvapp/eal/eal.c similarity index 87% copy from lib/librte_eal/linuxapp/eal/eal.c copy to lib/librte_eal/osvapp/eal/eal.c index bd770cf..b6e2143 100644 --- a/lib/librte_eal/linuxapp/eal/eal.c +++ b/lib/librte_eal/osvapp/eal/eal.c @@ -50,9 +50,7 @@ #include <errno.h> #include <sys/mman.h> #include <sys/queue.h> -#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) #include <sys/io.h> -#endif #include <rte_common.h> #include <rte_debug.h> @@ -351,14 +349,9 @@ eal_usage(const char *prgname) printf("\nUsage: %s ", prgname); eal_common_usage(); printf("EAL Linux options:\n" - " -d LIB.so Add driver (can be used multiple times)\n" - " --"OPT_SOCKET_MEM" Memory to allocate on sockets (comma separated values)\n" - " --"OPT_HUGE_DIR" Directory where hugetlbfs is mounted\n" - " --"OPT_FILE_PREFIX" Prefix for hugepage filenames\n" - " --"OPT_BASE_VIRTADDR" Base virtual address\n" - " --"OPT_CREATE_UIO_DEV" Create /dev/uioX (usually done by hotplug)\n" - " --"OPT_VFIO_INTR" Interrupt mode for VFIO (legacy|msi|msix)\n" - " --"OPT_XEN_DOM0" Support running on Xen dom0 without hugetlbfs\n" + " -d LIB.so : add driver (can be used multiple times)\n" + " --"OPT_SOCKET_MEM" : memory to allocate on specific\n" + " sockets (use comma separated values)\n" "\n"); /* Allow the application to print its usage message too if hook is set */ if ( rte_application_usage_hook ) { @@ -444,10 +437,8 @@ eal_parse_base_virtaddr(const char *arg) return -1; /* make sure we don't exceed 32-bit boundary on 32-bit target */ -#ifndef RTE_ARCH_64 if (addr >= UINTPTR_MAX) return -1; -#endif /* align the addr on 16M boundary, 16MB is the minimum huge page * size on IBM Power architecture. If the addr is aligned to 16MB, @@ -459,28 +450,6 @@ eal_parse_base_virtaddr(const char *arg) return 0; } -static int -eal_parse_vfio_intr(const char *mode) -{ - unsigned i; - static struct { - const char *name; - enum rte_intr_mode value; - } map[] = { - { "legacy", RTE_INTR_MODE_LEGACY }, - { "msi", RTE_INTR_MODE_MSI }, - { "msix", RTE_INTR_MODE_MSIX }, - }; - - for (i = 0; i < RTE_DIM(map); i++) { - if (!strcmp(mode, map[i].name)) { - internal_config.vfio_intr_mode = map[i].value; - return 0; - } - } - return -1; -} - static inline size_t eal_get_hugepage_mem_size(void) { @@ -552,26 +521,6 @@ eal_parse_args(int argc, char **argv) TAILQ_INSERT_TAIL(&solib_list, solib, next); break; - /* long options */ - case OPT_XEN_DOM0_NUM: -#ifdef RTE_LIBRTE_XEN_DOM0 - internal_config.xen_dom0_support = 1; -#else - RTE_LOG(ERR, EAL, "Can't support DPDK app " - "running on Dom0, please configure" - " RTE_LIBRTE_XEN_DOM0=y\n"); - return -1; -#endif - break; - - case OPT_HUGE_DIR_NUM: - internal_config.hugepage_dir = optarg; - break; - - case OPT_FILE_PREFIX_NUM: - internal_config.hugefile_prefix = optarg; - break; - case OPT_SOCKET_MEM_NUM: if (eal_parse_socket_mem(optarg) < 0) { RTE_LOG(ERR, EAL, "invalid parameters for --" @@ -590,19 +539,6 @@ eal_parse_args(int argc, char **argv) } break; - case OPT_VFIO_INTR_NUM: - if (eal_parse_vfio_intr(optarg) < 0) { - RTE_LOG(ERR, EAL, "invalid parameters for --" - OPT_VFIO_INTR "\n"); - eal_usage(prgname); - return -1; - } - break; - - case OPT_CREATE_UIO_DEV_NUM: - internal_config.create_uio_dev = 1; - break; - default: if (opt < OPT_LONG_MIN_NUM && isprint(opt)) { RTE_LOG(ERR, EAL, "Option %c is not supported " @@ -630,14 +566,6 @@ eal_parse_args(int argc, char **argv) return -1; } - /* --xen-dom0 doesn't make sense with --socket-mem */ - if (internal_config.xen_dom0_support && internal_config.force_sockets == 1) { - RTE_LOG(ERR, EAL, "Options --"OPT_SOCKET_MEM" cannot be specified " - "together with --"OPT_XEN_DOM0"\n"); - eal_usage(prgname); - return -1; - } - if (optind >= 0) argv[optind-1] = prgname; ret = optind-1; @@ -686,13 +614,7 @@ rte_eal_mcfg_complete(void) int rte_eal_iopl_init(void) { -#if defined(RTE_ARCH_X86_64) || defined(RTE_ARCH_I686) - if (iopl(3) != 0) - return -1; return 0; -#else - return -1; -#endif } /* Launch threads, called at application init(). */ @@ -729,7 +651,6 @@ rte_eal_init(int argc, char **argv) if (internal_config.no_hugetlbfs == 0 && internal_config.process_type != RTE_PROC_SECONDARY && - internal_config.xen_dom0_support == 0 && eal_hugepage_info_init() < 0) rte_panic("Cannot get hugepage information\n"); @@ -758,11 +679,6 @@ rte_eal_init(int argc, char **argv) if (rte_eal_pci_init() < 0) rte_panic("Cannot init PCI\n"); -#ifdef RTE_LIBRTE_IVSHMEM - if (rte_eal_ivshmem_init() < 0) - rte_panic("Cannot init IVSHMEM\n"); -#endif - if (rte_eal_memory_init() < 0) rte_panic("Cannot init memory\n"); @@ -775,11 +691,6 @@ rte_eal_init(int argc, char **argv) if (rte_eal_tailqs_init() < 0) rte_panic("Cannot init tail queues for objects\n"); -#ifdef RTE_LIBRTE_IVSHMEM - if (rte_eal_ivshmem_obj_init() < 0) - rte_panic("Cannot init IVSHMEM objects\n"); -#endif - if (rte_eal_log_init(logid, internal_config.syslog_facility) < 0) rte_panic("Cannot init logs\n"); @@ -865,31 +776,3 @@ int rte_eal_has_hugepages(void) { return ! internal_config.no_hugetlbfs; } - -int -rte_eal_check_module(const char *module_name) -{ - char mod_name[30]; /* Any module names can be longer than 30 bytes? */ - int ret = 0; - int n; - - if (NULL == module_name) - return -1; - - FILE *fd = fopen("/proc/modules", "r"); - if (NULL == fd) { - RTE_LOG(ERR, EAL, "Open /proc/modules failed!" - " error %i (%s)\n", errno, strerror(errno)); - return -1; - } - while (!feof(fd)) { - n = fscanf(fd, "%29s %*[^\n]", mod_name); - if ((n == 1) && !strcmp(mod_name, module_name)) { - ret = 1; - break; - } - } - fclose(fd); - - return ret; -} diff --git a/lib/librte_eal/linuxapp/eal/eal_alarm.c b/lib/librte_eal/osvapp/eal/eal_alarm.c similarity index 100% copy from lib/librte_eal/linuxapp/eal/eal_alarm.c copy to lib/librte_eal/osvapp/eal/eal_alarm.c diff --git a/lib/librte_eal/linuxapp/eal/eal_debug.c b/lib/librte_eal/osvapp/eal/eal_debug.c similarity index 100% copy from lib/librte_eal/linuxapp/eal/eal_debug.c copy to lib/librte_eal/osvapp/eal/eal_debug.c diff --git a/lib/librte_eal/osvapp/eal/eal_hugepage_info.cc b/lib/librte_eal/osvapp/eal/eal_hugepage_info.cc new file mode 100644 index 0000000..779e992 --- /dev/null +++ b/lib/librte_eal/osvapp/eal/eal_hugepage_info.cc @@ -0,0 +1,63 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * 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. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + */ + +#include <rte_log.h> +#include <rte_common.h> +#include "eal_internal_cfg.h" +#include "eal_hugepages.h" + +#define CONTIGUOUS_CHUNK_SIZE RTE_STR(RTE_CONTIGUOUS_CHUNK_SIZE) + +static inline size_t +get_contiguous_chunk_size(void) +{ + return rte_str_to_size(CONTIGUOUS_CHUNK_SIZE); +} + +int +eal_hugepage_info_init(void) +{ + struct hugepage_info *hpi = &internal_config.hugepage_info[0]; + + internal_config.num_hugepage_sizes = 1; + /* size of contiguous chunk size for eal_memory.cc */ + hpi->hugepage_sz = get_contiguous_chunk_size(); + /* this will ignored */ + hpi->hugedir = "/"; + /* only used when -m is not specified */ + hpi->num_pages[0] = RTE_DEFAULT_NUM_CHUNKS; + /* this will ignored */ + hpi->lock_descriptor = -1; + + return 0; +} diff --git a/lib/librte_eal/bsdapp/eal/eal_interrupts.c b/lib/librte_eal/osvapp/eal/eal_interrupts.c similarity index 100% copy from lib/librte_eal/bsdapp/eal/eal_interrupts.c copy to lib/librte_eal/osvapp/eal/eal_interrupts.c diff --git a/lib/librte_eal/bsdapp/eal/eal_lcore.c b/lib/librte_eal/osvapp/eal/eal_lcore.cc similarity index 80% copy from lib/librte_eal/bsdapp/eal/eal_lcore.c copy to lib/librte_eal/osvapp/eal/eal_lcore.cc index 162fb4f..5ff10e7 100644 --- a/lib/librte_eal/bsdapp/eal/eal_lcore.c +++ b/lib/librte_eal/osvapp/eal/eal_lcore.cc @@ -31,38 +31,35 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <unistd.h> -#include <sys/sysctl.h> - #include <rte_log.h> #include <rte_eal.h> #include <rte_lcore.h> #include <rte_common.h> #include <rte_debug.h> +#include <osv/sched.hh> + #include "eal_private.h" #include "eal_thread.h" -/* No topology information available on FreeBSD including NUMA info */ -#define cpu_core_id(X) 0 -#define cpu_socket_id(X) 0 - static int -get_ncpus(void) +cpu_detected(unsigned lcore_id) { - int mib[2] = {CTL_HW, HW_NCPU}; - int ncpu; - size_t len = sizeof(ncpu); + return lcore_id < sched::cpus.size() ? 1 : 0; +} - sysctl(mib, 2, &ncpu, &len, NULL, 0); - RTE_LOG(INFO, EAL, "Sysctl reports %d cpus\n", ncpu); - return ncpu; +unsigned +eal_cpu_socket_id(unsigned lcore_id) +{ + return 0; +} + +static unsigned +cpu_core_id(unsigned lcore_id) +{ + return lcore_id; } -/* - * fill the cpu_info structure with as much info as we can get. - * code is similar to linux version, but sadly available info is less. - */ int rte_eal_cpu_init(void) { @@ -71,7 +68,6 @@ rte_eal_cpu_init(void) unsigned lcore_id; unsigned count = 0; - const unsigned ncpus = get_ncpus(); /* * Parse the maximum set of logical cores, detect the subset of running * ones and enable them by default. @@ -80,7 +76,8 @@ rte_eal_cpu_init(void) /* init cpuset for per lcore config */ CPU_ZERO(&lcore_config[lcore_id].cpuset); - lcore_config[lcore_id].detected = (lcore_id < ncpus); + /* in 1:1 mapping, record related cpu detected state */ + lcore_config[lcore_id].detected = cpu_detected(lcore_id); if (lcore_config[lcore_id].detected == 0) { config->lcore_role[lcore_id] = ROLE_OFF; continue; @@ -92,7 +89,7 @@ rte_eal_cpu_init(void) /* By default, each detected core is enabled */ config->lcore_role[lcore_id] = ROLE_RTE; lcore_config[lcore_id].core_id = cpu_core_id(lcore_id); - lcore_config[lcore_id].socket_id = cpu_socket_id(lcore_id); + lcore_config[lcore_id].socket_id = eal_cpu_socket_id(lcore_id); if (lcore_config[lcore_id].socket_id >= RTE_MAX_NUMA_NODES) #ifdef RTE_EAL_ALLOW_INV_SOCKET_ID lcore_config[lcore_id].socket_id = 0; @@ -101,9 +98,11 @@ rte_eal_cpu_init(void) "RTE_MAX_NUMA_NODES (%d)\n", lcore_config[lcore_id].socket_id, RTE_MAX_NUMA_NODES); #endif - RTE_LOG(DEBUG, EAL, "Detected lcore %u\n", - lcore_id); - count++; + RTE_LOG(DEBUG, EAL, "Detected lcore %u as core %u on socket %u\n", + lcore_id, + lcore_config[lcore_id].core_id, + lcore_config[lcore_id].socket_id); + count ++; } /* Set the count of enabled logical cores of the EAL configuration */ config->lcore_count = count; @@ -113,9 +112,3 @@ rte_eal_cpu_init(void) return 0; } - -unsigned -eal_cpu_socket_id(__rte_unused unsigned cpu_id) -{ - return cpu_socket_id(cpu_id); -} diff --git a/lib/librte_eal/bsdapp/eal/eal_log.c b/lib/librte_eal/osvapp/eal/eal_log.c similarity index 100% copy from lib/librte_eal/bsdapp/eal/eal_log.c copy to lib/librte_eal/osvapp/eal/eal_log.c diff --git a/lib/librte_eal/osvapp/eal/eal_memory.cc b/lib/librte_eal/osvapp/eal/eal_memory.cc new file mode 100644 index 0000000..fa4a49d --- /dev/null +++ b/lib/librte_eal/osvapp/eal/eal_memory.cc @@ -0,0 +1,148 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * 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. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + */ +#include <sys/mman.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/sysctl.h> +#include <inttypes.h> +#include <fcntl.h> + +#include <rte_eal.h> +#include <rte_eal_memconfig.h> +#include <rte_log.h> +#include <rte_string_fns.h> +#include "eal_private.h" +#include "eal_internal_cfg.h" +#include "eal_filesystem.h" + +#include <osv/contiguous_alloc.hh> +#include <osv/virt_to_phys.hh> +#include <assert.h> +#include <osv/types.h> +#include <osv/mmu-defs.hh> + +/* + * Get physical address of any mapped virtual address in the current process. + */ +phys_addr_t +rte_mem_virt2phy(const void *virtaddr) +{ + /* XXX not implemented. This function is only used by + * rte_mempool_virt2phy() when hugepages are disabled. */ + (void)virtaddr; + return RTE_BAD_PHYS_ADDR; +} + +static int +rte_eal_hugepage_init(void) +{ + struct rte_mem_config *mcfg; + uint64_t total_mem = 0; + void *addr; + unsigned i, j, seg_idx = 0; + + /* get pointer to global configuration */ + mcfg = rte_eal_get_configuration()->mem_config; + + /* for debug purposes, hugetlbfs can be disabled */ + if (internal_config.no_hugetlbfs) { + addr = malloc(internal_config.memory); + mcfg->memseg[0].phys_addr = (phys_addr_t)(uintptr_t)addr; + mcfg->memseg[0].addr = addr; + mcfg->memseg[0].len = internal_config.memory; + mcfg->memseg[0].socket_id = 0; + return 0; + } + + /* allocate all contiguous chunks */ + for (i = 0; i < internal_config.num_hugepage_sizes; i ++){ + struct hugepage_info *hpi; + size_t alloc_size = 0; + + hpi = &internal_config.hugepage_info[i]; + hpi->num_pages[0] = 0; + for (j = 0; ; j++) { + struct rte_memseg *seg; + uint64_t physaddr; + + addr = memory::alloc_phys_contiguous_aligned(hpi->hugepage_sz, mmu::huge_page_size); + seg = &mcfg->memseg[seg_idx++]; + seg->addr = addr; + seg->phys_addr = mmu::virt_to_phys(addr); + seg->hugepage_sz = hpi->hugepage_sz; + seg->len = hpi->hugepage_sz; + seg->nchannel = mcfg->nchannel; + seg->nrank = mcfg->nrank; + seg->socket_id = 0; + total_mem += hpi->hugepage_sz; + hpi->num_pages[0]++; + RTE_LOG(INFO, EAL, "Mapped memory segment %u @ %p: physaddr:0x%" + PRIx64", len %zu\n", + 0, seg->addr, seg->phys_addr, seg->len); + if (total_mem >= internal_config.memory || + seg_idx >= RTE_MAX_MEMSEG) + break; + } + } + return 0; +} + +static int +rte_eal_memdevice_init(void) +{ + struct rte_config *config; + + if (rte_eal_process_type() == RTE_PROC_SECONDARY) + return 0; + + config = rte_eal_get_configuration(); + config->mem_config->nchannel = internal_config.force_nchannel; + config->mem_config->nrank = internal_config.force_nrank; + + return 0; +} + +/* init memory subsystem */ +int +rte_eal_memory_init(void) +{ + RTE_LOG(INFO, EAL, "Setting up memory...\n"); + const int retval = rte_eal_hugepage_init(); + if (retval < 0) + return -1; + + if (internal_config.no_shconf == 0 && rte_eal_memdevice_init() < 0) + return -1; + + return 0; +} diff --git a/lib/librte_eal/osvapp/eal/eal_pci.cc b/lib/librte_eal/osvapp/eal/eal_pci.cc new file mode 100644 index 0000000..e0495e6 --- /dev/null +++ b/lib/librte_eal/osvapp/eal/eal_pci.cc @@ -0,0 +1,311 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * All rights reserved. + * + * 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. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + */ + +#include <ctype.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <unistd.h> +#include <inttypes.h> +#include <stdarg.h> +#include <errno.h> +#include <limits.h> + +#include <rte_interrupts.h> +#include <rte_log.h> +#include <rte_pci.h> +#include <rte_common.h> +#include <rte_launch.h> +#include <rte_memory.h> +#include <rte_memzone.h> +#include <rte_eal.h> +#include <rte_eal_memconfig.h> +#include <rte_per_lcore.h> +#include <rte_lcore.h> +#include <rte_malloc.h> +#include <rte_string_fns.h> +#include <rte_debug.h> +#include <rte_devargs.h> + +#include "rte_pci_dev_ids.h" +#include "eal_filesystem.h" +#include "eal_private.h" + +#include <drivers/device.hh> +#include <drivers/pci-device.hh> + +/** + * @file + * PCI probing under linux + * + * This code is used to simulate a PCI probe by parsing information in + * sysfs. Moreover, when a registered driver matches a device, the + * kernel driver currently using it is unloaded and replaced by + * igb_uio module, which is a very minimal userland driver for Intel + * network card, only providing access to PCI BAR to applications, and + * enabling bus master. + */ + +struct uio_map { + void *addr; + uint64_t offset; + uint64_t size; + uint64_t phaddr; +}; + +/* + * For multi-process we need to reproduce all PCI mappings in secondary + * processes, so save them in a tailq. + */ +struct uio_resource { + TAILQ_ENTRY(uio_resource) next; + + struct rte_pci_addr pci_addr; + char path[PATH_MAX]; + size_t nb_maps; + struct uio_map maps[PCI_MAX_RESOURCE]; +}; + +TAILQ_HEAD(uio_res_list, uio_resource); + +static struct uio_res_list *uio_res_list = NULL; + +static struct rte_tailq_elem rte_pci_tailq = { + NULL, + { NULL, NULL, }, + "PCI_RESOURCE_LIST", +}; +EAL_REGISTER_TAILQ(rte_pci_tailq) + +/* unbind kernel driver for this device */ +static int +pci_unbind_kernel_driver(struct rte_pci_device *dev __rte_unused) +{ + RTE_LOG(ERR, EAL, "RTE_PCI_DRV_FORCE_UNBIND flag is not implemented " + "for OSv\n"); + return -ENOTSUP; +} + +/* Scan one pci entry, and fill the devices list from it. */ +static int +pci_scan_one(hw::hw_device* dev) +{ + u8 bus, device, func; + auto pci_dev = static_cast<pci::device*>(dev); + auto rte_dev = new rte_pci_device(); + + /* get bus id, device id, function no */ + pci_dev->get_bdf(bus, device, func); + rte_dev->addr.domain = 0; + rte_dev->addr.bus = bus; + rte_dev->addr.devid = device; + rte_dev->addr.function = func; + + /* get vendor id */ + rte_dev->id.vendor_id = pci_dev->get_vendor_id(); + + /* get device id */ + rte_dev->id.device_id = pci_dev->get_device_id(); + + /* get subsystem_vendor id */ + rte_dev->id.subsystem_vendor_id = pci_dev->get_subsystem_vid(); + + /* get subsystem_device id */ + rte_dev->id.subsystem_device_id = pci_dev->get_subsystem_id(); + + /* TODO: get max_vfs */ + rte_dev->max_vfs = 0; + + /* OSv has no NUMA support (yet) */ + rte_dev->numa_node = -1; + + /* Disable interrupt */ + rte_dev->intr_handle.fd = -1; + rte_dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN; + + for (int i = 0; ; i++) { + auto bar = pci_dev->get_bar(i+1); + if (bar == nullptr) { + RTE_LOG(DEBUG, EAL, " bar%d not available\n", i); + break; + } + if (bar->is_mmio()) { + rte_dev->mem_resource[i].len = bar->get_size(); + rte_dev->mem_resource[i].phys_addr = bar->get_addr64(); + bar->map(); + rte_dev->mem_resource[i].addr = const_cast<void *>(bar->get_mmio()); + } else { + rte_dev->mem_resource[i].len = bar->get_size(); + rte_dev->mem_resource[i].phys_addr = 0; + rte_dev->mem_resource[i].addr = reinterpret_cast<void *>(bar->get_addr_lo()); + } + } + + /* device is valid, add in list (sorted) */ + if (TAILQ_EMPTY(&pci_device_list)) { + TAILQ_INSERT_TAIL(&pci_device_list, rte_dev, next); + } + else { + struct rte_pci_device *dev2 = NULL; + int ret; + + TAILQ_FOREACH(dev2, &pci_device_list, next) { + ret = rte_eal_compare_pci_addr(&rte_dev->addr, &dev2->addr); + if (ret > 0) + continue; + else if (ret < 0) { + TAILQ_INSERT_BEFORE(dev2, rte_dev, next); + return 1; + } else { /* already registered */ + /* update pt_driver */ + dev2->pt_driver = rte_dev->pt_driver; + dev2->max_vfs = rte_dev->max_vfs; + memmove(dev2->mem_resource, + rte_dev->mem_resource, + sizeof(rte_dev->mem_resource)); + delete rte_dev; + return 0; + } + } + TAILQ_INSERT_TAIL(&pci_device_list, rte_dev, next); + } + + return 1; +} + +/* + * Scan the content of the PCI bus, and add the devices in the devices + * list. Call pci_scan_one() for each pci entry found. + */ +static int +pci_scan(void) +{ + unsigned dev_count = 0; + int err = 0; + + auto dm = hw::device_manager::instance(); + dm->for_each_device([&dev_count, &err] (hw::hw_device* dev) { + int ret = pci_scan_one(dev); + if (ret < 0) { + err++; + } else { + dev_count += ret; + } + }); + + if (err) + return -1; + + RTE_LOG(ERR, EAL, "PCI scan found %u devices\n", dev_count); + return 0; +} + +/* + * If vendor/device ID match, call the devinit() function of the + * driver. + */ +int +rte_eal_pci_probe_one_driver(struct rte_pci_driver *dr, struct rte_pci_device *dev) +{ + struct rte_pci_id *id_table; + int ret; + + for (id_table = dr->id_table ; id_table->vendor_id != 0; id_table++) { + + /* check if device's identifiers match the driver's ones */ + if (id_table->vendor_id != dev->id.vendor_id && + id_table->vendor_id != PCI_ANY_ID) + continue; + if (id_table->device_id != dev->id.device_id && + id_table->device_id != PCI_ANY_ID) + continue; + if (id_table->subsystem_vendor_id != dev->id.subsystem_vendor_id && + id_table->subsystem_vendor_id != PCI_ANY_ID) + continue; + if (id_table->subsystem_device_id != dev->id.subsystem_device_id && + id_table->subsystem_device_id != PCI_ANY_ID) + continue; + + struct rte_pci_addr *loc = &dev->addr; + + RTE_LOG(DEBUG, EAL, "PCI device " PCI_PRI_FMT " on NUMA socket %i\n", + loc->domain, loc->bus, loc->devid, loc->function, + dev->numa_node); + + RTE_LOG(DEBUG, EAL, " probe driver: %x:%x %s\n", dev->id.vendor_id, + dev->id.device_id, dr->name); + + /* no initialization when blacklisted, return without error */ + if (dev->devargs != NULL && + dev->devargs->type == RTE_DEVTYPE_BLACKLISTED_PCI) { + + RTE_LOG(DEBUG, EAL, " Device is blacklisted, not initializing\n"); + return 0; + } + + if (dr->drv_flags & RTE_PCI_DRV_FORCE_UNBIND && + rte_eal_process_type() == RTE_PROC_PRIMARY) { + /* unbind current driver */ + if (pci_unbind_kernel_driver(dev) < 0) + return -1; + } + + /* reference driver structure */ + dev->driver = dr; + + /* call the driver devinit() function */ + return dr->devinit(dr, dev); + } + /* return positive value if driver is not found */ + return 1; +} + +/* Init the PCI EAL subsystem */ +int +rte_eal_pci_init(void) +{ + TAILQ_INIT(&pci_driver_list); + TAILQ_INIT(&pci_device_list); + uio_res_list = RTE_TAILQ_CAST(rte_pci_tailq.head, uio_res_list); + + /* for debug purposes, PCI can be disabled */ + if (internal_config.no_pci) + return 0; + + if (pci_scan() < 0) { + RTE_LOG(ERR, EAL, "%s(): Cannot scan PCI bus\n", __func__); + return -1; + } + return 0; +} diff --git a/lib/librte_eal/linuxapp/eal/eal_thread.c b/lib/librte_eal/osvapp/eal/eal_thread.c similarity index 100% copy from lib/librte_eal/linuxapp/eal/eal_thread.c copy to lib/librte_eal/osvapp/eal/eal_thread.c diff --git a/lib/librte_eal/osvapp/eal/eal_timer.c b/lib/librte_eal/osvapp/eal/eal_timer.c new file mode 100644 index 0000000..86bdd84 --- /dev/null +++ b/lib/librte_eal/osvapp/eal/eal_timer.c @@ -0,0 +1,130 @@ +/*- + * BSD LICENSE + * + * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. + * Copyright(c) 2012-2013 6WIND S.A. + * All rights reserved. + * + * 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. + * * Neither the name of Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "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 COPYRIGHT + * OWNER OR CONTRIBUTORS 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. + */ + +#include <string.h> +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <inttypes.h> +#include <errno.h> + +#include <rte_common.h> +#include <rte_log.h> +#include <rte_cycles.h> +#include <rte_memory.h> +#include <rte_memzone.h> +#include <rte_eal.h> +#include <rte_debug.h> + +#include "eal_private.h" +#include "eal_internal_cfg.h" + +#ifdef RTE_LIBEAL_USE_HPET +#error "HPET is not supported in OSv" +#endif + +enum timer_source eal_timer_source = EAL_TIMER_TSC; + +/* The frequency of the RDTSC timer resolution */ +static uint64_t eal_tsc_resolution_hz = 0; + +void +rte_delay_us(unsigned us) +{ + const uint64_t start = rte_get_timer_cycles(); + const uint64_t ticks = (uint64_t)us * rte_get_timer_hz() / 1E6; + while ((rte_get_timer_cycles() - start) < ticks) + rte_pause(); +} + +uint64_t +rte_get_tsc_hz(void) +{ + return eal_tsc_resolution_hz; +} + +static int +set_tsc_freq_from_clock(void) +{ +#define NS_PER_SEC 1E9 + + struct timespec sleeptime; + sleeptime.tv_sec = 0; + sleeptime.tv_nsec = 5E8; /* 1/2 second */ + + struct timespec t_start, t_end; + + if (clock_gettime(CLOCK_MONOTONIC, &t_start) == 0) { + uint64_t ns, end, start = rte_rdtsc(); + nanosleep(&sleeptime,NULL); + clock_gettime(CLOCK_MONOTONIC_RAW, &t_end); + end = rte_rdtsc(); + ns = ((t_end.tv_sec - t_start.tv_sec) * NS_PER_SEC); + ns += (t_end.tv_nsec - t_start.tv_nsec); + + double secs = (double)ns/NS_PER_SEC; + eal_tsc_resolution_hz = (uint64_t)((end - start)/secs); + return 0; + } + return -1; +} + +static void +set_tsc_freq_fallback(void) +{ + RTE_LOG(WARNING, EAL, "WARNING: clock_gettime cannot use " + "CLOCK_MONOTONIC_RAW and HPET is not available" + " - clock timings may be less accurate.\n"); + /* assume that the sleep(1) will sleep for 1 second */ + uint64_t start = rte_rdtsc(); + sleep(1); + eal_tsc_resolution_hz = rte_rdtsc() - start; +} + +static void +set_tsc_freq(void) +{ + if (set_tsc_freq_from_clock() < 0) + set_tsc_freq_fallback(); + + RTE_LOG(INFO, EAL, "TSC frequency is ~%" PRIu64 " KHz\n", + eal_tsc_resolution_hz/1000); +} + +int +rte_eal_timer_init(void) +{ + set_tsc_freq(); + return 0; +} diff --git a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_interrupts.h b/lib/librte_eal/osvapp/eal/include/exec-env/rte_interrupts.h similarity index 100% copy from lib/librte_eal/bsdapp/eal/include/exec-env/rte_interrupts.h copy to lib/librte_eal/osvapp/eal/include/exec-env/rte_interrupts.h diff --git a/lib/librte_eal/bsdapp/eal/rte_eal_version.map b/lib/librte_eal/osvapp/eal/rte_eal_version.map similarity index 92% copy from lib/librte_eal/bsdapp/eal/rte_eal_version.map copy to lib/librte_eal/osvapp/eal/rte_eal_version.map index 67b6a6c..ebb584a 100644 --- a/lib/librte_eal/bsdapp/eal/rte_eal_version.map +++ b/lib/librte_eal/osvapp/eal/rte_eal_version.map @@ -31,24 +31,26 @@ DPDK_2.0 { rte_eal_get_physmem_layout; rte_eal_get_physmem_size; rte_eal_has_hugepages; - rte_eal_hpet_init; rte_eal_init; rte_eal_iopl_init; rte_eal_lcore_role; rte_eal_mp_remote_launch; rte_eal_mp_wait_lcore; + rte_eal_parse_devargs_str; + rte_eal_pci_close_one; rte_eal_pci_dump; rte_eal_pci_probe; + rte_eal_pci_probe_one; rte_eal_pci_register; rte_eal_pci_unregister; rte_eal_process_type; rte_eal_remote_launch; rte_eal_tailq_lookup; rte_eal_tailq_register; + rte_eal_vdev_init; + rte_eal_vdev_uninit; rte_eal_wait_lcore; rte_exit; - rte_get_hpet_cycles; - rte_get_hpet_hz; rte_get_tsc_hz; rte_hexdump; rte_intr_callback_register; @@ -86,9 +88,6 @@ DPDK_2.0 { rte_thread_get_affinity; rte_thread_set_affinity; rte_vlog; - rte_xen_dom0_memory_attach; - rte_xen_dom0_memory_init; - test_mp_secondary; local: *; }; diff --git a/mk/exec-env/linuxapp/rte.app.mk b/mk/exec-env/osvapp/rte.app.mk similarity index 100% copy from mk/exec-env/linuxapp/rte.app.mk copy to mk/exec-env/osvapp/rte.app.mk diff --git a/mk/exec-env/linuxapp/rte.vars.mk b/mk/exec-env/osvapp/rte.vars.mk similarity index 95% copy from mk/exec-env/linuxapp/rte.vars.mk copy to mk/exec-env/osvapp/rte.vars.mk index e5af318..db0f115 100644 --- a/mk/exec-env/linuxapp/rte.vars.mk +++ b/mk/exec-env/osvapp/rte.vars.mk @@ -39,11 +39,7 @@ # # examples for RTE_EXEC_ENV: linuxapp, bsdapp # -ifeq ($(RTE_BUILD_SHARED_LIB),y) -EXECENV_CFLAGS = -pthread -fPIC -else -EXECENV_CFLAGS = -pthread -endif +EXECENV_CFLAGS = -pthread -fPIC -shared # Workaround lack of DT_NEEDED entry EXECENV_LDFLAGS = --no-as-needed -- 2.1.0