add FreeBSD support

Changes to allow compilation and use on FreeBSD. Includes:
* contigmem and nic_uio driver for FreeBSD
* new EAL instance
* new "bsdapp" compilation target
* various compilation fixes due to differences between linux and freebsd

Signed-off-by: Bruce Richardson <bruce.richardson@intel.com>
This commit is contained in:
Bruce Richardson 2014-02-10 11:49:10 +00:00 committed by David Marchand
parent e9d48c0072
commit 764bf26873
55 changed files with 5157 additions and 123 deletions

45
GNUmakefile Normal file
View File

@ -0,0 +1,45 @@
# 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.
#
# Head Makefile for compiling rte SDK
#
RTE_SDK := $(CURDIR)
export RTE_SDK
#
# directory list
#
ROOTDIRS-y := scripts lib app
include $(RTE_SDK)/mk/rte.sdkroot.mk

View File

@ -29,17 +29,5 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Head Makefile for compiling rte SDK
#
.error Error please compile using GNU Make (gmake)
RTE_SDK := $(CURDIR)
export RTE_SDK
#
# directory list
#
ROOTDIRS-y := scripts lib app
include $(RTE_SDK)/mk/rte.sdkroot.mk

View File

@ -41,7 +41,11 @@
#include <unistd.h>
#include <inttypes.h>
#ifndef __linux__
#ifndef __FreeBSD__
#include <net/socket.h>
#else
#include <sys/socket.h>
#endif
#endif
#include <netinet/in.h>

View File

@ -39,8 +39,10 @@
#include <netinet/in.h>
#include <termios.h>
#ifndef __linux__
#ifndef __FreeBSD__
#include <net/socket.h>
#endif
#endif
#include <inttypes.h>
#include <errno.h>
#include <sys/queue.h>

View File

@ -36,6 +36,14 @@
#ifndef RTE_EXEC_ENV_BAREMETAL
#ifdef RTE_EXEC_ENV_BSDAPP
#define self "curproc"
#define exe "file"
#else
#define self "self"
#define exe "exe"
#endif
/*
* launches a second copy of the test process using the given argv parameters,
* which should include argv[0] as the process name. To identify in the
@ -61,7 +69,7 @@ process_dup(const char *const argv[], int numargs, const char *env_value)
/* close all open file descriptors, check /proc/self/fd to only
* call close on open fds. Exclude fds 0, 1 and 2*/
for (fd = getdtablesize(); fd > 2; fd-- ) {
rte_snprintf(path, sizeof(path), "/proc/self/fd/%d", fd);
rte_snprintf(path, sizeof(path), "/proc/" exe "/fd/%d", fd);
if (access(path, F_OK) == 0)
close(fd);
}
@ -73,7 +81,7 @@ process_dup(const char *const argv[], int numargs, const char *env_value)
/* set the environment variable */
if (setenv(RECURSIVE_ENV_VAR, env_value, 1) != 0)
rte_panic("Cannot export environment variable\n");
if (execv("/proc/self/exe", argv_cpy) < 0)
if (execv("/proc/" self "/" exe, argv_cpy) < 0)
rte_panic("Cannot exec\n");
}
/* parent process does a wait */

View File

@ -37,7 +37,11 @@
#include <netinet/in.h>
#ifndef __linux__
#ifndef __FreeBSD__
#include <net/socket.h>
#else
#include <sys/socket.h>
#endif
#endif
#include <rte_string_fns.h>
@ -56,13 +60,17 @@
(((x & 0xFF) << 8) | ((x & 0xFF00) >> 8))
/* create IPv6 address, swapping bytes where needed */
#ifndef s6_addr16
# define s6_addr16 __u6_addr.__u6_addr16
#endif
#define IP6(a,b,c,d,e,f,g,h) .ipv6 = \
{.s6_addr16 = \
{U16_SWAP(a),U16_SWAP(b),U16_SWAP(c),U16_SWAP(d),\
U16_SWAP(e),U16_SWAP(f),U16_SWAP(g),U16_SWAP(h)}}
/** these are defined in netinet/in.h but not present in linux headers */
#ifdef __linux__
#ifndef NIPQUAD
#define NIPQUAD_FMT "%u.%u.%u.%u"
#define NIPQUAD(addr) \
(unsigned)((unsigned char *)&addr)[0], \
@ -88,6 +96,7 @@
(unsigned)((addr).s6_addr[13]), \
(unsigned)((addr).s6_addr[14]), \
(unsigned)((addr).s6_addr[15])
#endif

View File

@ -47,6 +47,7 @@
#include <dirent.h>
#include <sys/wait.h>
#include <sys/file.h>
#include <limits.h>
#include <rte_debug.h>
#include <rte_string_fns.h>
@ -217,6 +218,7 @@ process_hugefiles(const char * prefix, enum hugepage_action action)
return result;
}
#ifdef RTE_EXEC_ENV_LINUXAPP
/*
* count the number of "node*" files in /sys/devices/system/node/
*/
@ -246,6 +248,7 @@ get_number_of_sockets(void)
closedir(dir);
return result;
}
#endif
static char*
get_current_prefix(char * prefix, int size)
@ -293,12 +296,17 @@ static int
test_whitelist_flag(void)
{
unsigned i;
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD target doesn't support prefixes at this point */
const char * prefix = "";
#else
char prefix[PATH_MAX], tmp[PATH_MAX];
if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
printf("Error - unable to get current prefix!\n");
return -1;
}
rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
#endif
const char *wlinval[][11] = {
{prgname, prefix, mp_flag, "-n", "1", "-c", "1",
@ -381,12 +389,17 @@ test_whitelist_flag(void)
static int
test_invalid_b_flag(void)
{
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD target doesn't support prefixes at this point */
const char * prefix = "";
#else
char prefix[PATH_MAX], tmp[PATH_MAX];
if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
printf("Error - unable to get current prefix!\n");
return -1;
}
rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
#endif
const char *blinval[][9] = {
{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-b", "error"},
@ -422,12 +435,17 @@ test_invalid_b_flag(void)
static int
test_invalid_r_flag(void)
{
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD target doesn't support prefixes at this point */
const char * prefix = "";
#else
char prefix[PATH_MAX], tmp[PATH_MAX];
if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
printf("Error - unable to get current prefix!\n");
return -1;
}
rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
#endif
const char *rinval[][9] = {
{prgname, prefix, mp_flag, "-n", "1", "-c", "1", "-r", "error"},
@ -461,12 +479,17 @@ test_invalid_r_flag(void)
static int
test_missing_c_flag(void)
{
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD target doesn't support prefixes at this point */
const char * prefix = "";
#else
char prefix[PATH_MAX], tmp[PATH_MAX];
if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
printf("Error - unable to get current prefix!\n");
return -1;
}
rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
#endif
/* -c flag but no coremask value */
const char *argv1[] = { prgname, prefix, mp_flag, "-n", "3", "-c"};
@ -499,12 +522,17 @@ test_missing_c_flag(void)
static int
test_missing_n_flag(void)
{
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD target doesn't support prefixes at this point */
const char * prefix = "";
#else
char prefix[PATH_MAX], tmp[PATH_MAX];
if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
printf("Error - unable to get current prefix!\n");
return -1;
}
rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
#endif
/* -n flag but no value */
const char *argv1[] = { prgname, prefix, no_huge, no_shconf, "-c", "1", "-n"};
@ -538,6 +566,10 @@ static int
test_no_hpet_flag(void)
{
char prefix[PATH_MAX], tmp[PATH_MAX];
#ifdef RTE_EXEC_ENV_BSDAPP
return 0;
#endif
if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
printf("Error - unable to get current prefix!\n");
return -1;
@ -567,26 +599,25 @@ test_no_hpet_flag(void)
static int
test_no_huge_flag(void)
{
char prefix[PATH_MAX], tmp[PATH_MAX];
if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
printf("Error - unable to get current prefix!\n");
return -1;
}
rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD target doesn't support prefixes at this point, and we also need to
* run another primary process here */
const char * prefix = no_shconf;
#else
const char * prefix = "--file-prefix=nohuge";
#endif
/* With --no-huge */
const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
"--file-prefix=nohuge"};
const char *argv1[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2"};
/* With --no-huge and -m */
const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", "-m", "2",
"--file-prefix=nohuge"};
const char *argv2[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2", "-m", "2"};
/* With --no-huge and --socket-mem */
const char *argv3[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
"--socket-mem=2", "--file-prefix=nohuge"};
"--socket-mem=2"};
/* With --no-huge, -m and --socket-mem */
const char *argv4[] = {prgname, prefix, no_huge, "-c", "1", "-n", "2",
"-m", "2", "--socket-mem=2", "--file-prefix=nohuge"};
"-m", "2", "--socket-mem=2"};
if (launch_proc(argv1) != 0) {
printf("Error - process did not run ok with --no-huge flag\n");
return -1;
@ -595,6 +626,11 @@ test_no_huge_flag(void)
printf("Error - process run ok with --no-huge and -m flags\n");
return -1;
}
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD target does not support NUMA, hence no --socket-mem tests */
return 0;
#endif
if (launch_proc(argv3) == 0) {
printf("Error - process run ok with --no-huge and --socket-mem "
"flags\n");
@ -611,12 +647,17 @@ test_no_huge_flag(void)
static int
test_misc_flags(void)
{
char hugepath[PATH_MAX] = {0};
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD target doesn't support prefixes at this point */
const char * prefix = "";
const char * nosh_prefix = "";
#else
char prefix[PATH_MAX], tmp[PATH_MAX];
const char * nosh_prefix = "--file-prefix=noshconf";
FILE * hugedir_handle = NULL;
char line[PATH_MAX] = {0};
char hugepath[PATH_MAX] = {0};
char prefix[PATH_MAX], tmp[PATH_MAX];
unsigned i, isempty = 1;
if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
printf("Error - unable to get current prefix!\n");
return -1;
@ -654,6 +695,7 @@ test_misc_flags(void)
printf("No mounted hugepage dir found!\n");
return -1;
}
#endif
/* check that some general flags don't prevent things from working.
@ -676,7 +718,11 @@ test_misc_flags(void)
const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
/* With no-sh-conf */
const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
"--no-shconf", "--file-prefix=noshconf" };
no_shconf, nosh_prefix };
#ifdef RTE_EXEC_ENV_BSDAPP
return 0;
#endif
/* With --huge-dir */
const char *argv7[] = {prgname, "-c", "1", "-n", "2", "-m", "2",
"--file-prefix=hugedir", "--huge-dir", hugepath};
@ -719,6 +765,9 @@ test_misc_flags(void)
printf("Error - process did not run ok with --no-shconf flag\n");
return -1;
}
#ifdef RTE_EXEC_ENV_BSDAPP
return 0;
#endif
if (launch_proc(argv7) != 0) {
printf("Error - process did not run ok with --huge-dir flag\n");
return -1;
@ -752,6 +801,10 @@ test_file_prefix(void)
* 7. check that only memtest2 hugefiles are present in the hugedir
*/
#ifdef RTE_EXEC_ENV_BSDAPP
return 0;
#endif
/* this should fail unless the test itself is run with "memtest" prefix */
const char *argv0[] = {prgname, mp_flag, "-c", "1", "-n", "2", "-m", "2",
"--file-prefix=" memtest };
@ -852,13 +905,17 @@ test_file_prefix(void)
static int
test_memory_flags(void)
{
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD target doesn't support prefixes at this point */
const char * prefix = "";
#else
char prefix[PATH_MAX], tmp[PATH_MAX];
if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
printf("Error - unable to get current prefix!\n");
return -1;
}
rte_snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
#endif
/* valid -m flag */
const char *argv0[] = {prgname, "-c", "10", "-n", "2",
"--file-prefix=" memtest, "-m", "2"};
@ -899,7 +956,12 @@ test_memory_flags(void)
* extra 2 megs on socket that doesn't exist on current system */
char invalid_socket_mem[SOCKET_MEM_STRLEN];
char buf[SOCKET_MEM_STRLEN]; /* to avoid copying string onto itself */
#ifdef RTE_EXEC_ENV_BSDAPP
int i, num_sockets = 1;
#else
int i, num_sockets = get_number_of_sockets();
#endif
if (num_sockets <= 0 || num_sockets > RTE_MAX_NUMA_NODES) {
printf("Error - cannot get number of sockets!\n");
@ -944,10 +1006,15 @@ test_memory_flags(void)
"--file-prefix=" memtest, valid_socket_mem};
if (launch_proc(argv0) != 0) {
printf("Error - process failed with valid -m flag!\n");
printf("Error - secondary process failed with valid -m flag !\n");
return -1;
}
#ifdef RTE_EXEC_ENV_BSDAPP
/* no other tests are applicable to BSD */
return 0;
#endif
if (launch_proc(argv1) != 0) {
printf("Error - secondary process failed with valid -m flag !\n");
return -1;

View File

@ -53,6 +53,11 @@ test_parse_sysfs_value(void)
unsigned valid_number;
unsigned long retval = 0;
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD doesn't have /proc/pid/fd */
return 0;
#endif
printf("Testing function eal_parse_sysfs_value()\n");
/* get a temporary filename to use for all tests - create temp file handle and then

View File

@ -49,7 +49,12 @@ test_errno(void)
{
const char *rte_retval;
const char *libc_retval;
#ifdef RTE_EXEC_ENV_BSDAPP
/* BSD has a colon in the string, unlike linux */
const char unknown_code_result[] = "Unknown error: %d";
#else
const char unknown_code_result[] = "Unknown error %d";
#endif
char expected_libc_retval[sizeof(unknown_code_result)+3];
/* use a small selection of standard errors for testing */

View File

@ -53,6 +53,7 @@
#include <sys/wait.h>
#include <libgen.h>
#include <dirent.h>
#include <limits.h>
#include <rte_common.h>
#include <rte_memory.h>

View File

@ -0,0 +1,297 @@
# 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.
#
#
# define executive environment
#
# CONFIG_RTE_EXEC_ENV can be linuxapp, baremetal, bsdapp
#
CONFIG_RTE_EXEC_ENV="bsdapp"
CONFIG_RTE_EXEC_ENV_BSDAPP=y
#
# machine can define specific variables or action for a specific board
# RTE_MACHINE can be:
# default nothing specific
# native current machine
# atm Intel® Atom™ microarchitecture
# nhm Intel® microarchitecture code name Nehalem
# wsm Intel® microarchitecture code name Westmere
# snb Intel® microarchitecture code name Sandy Bridge
# ivb Intel® microarchitecture code name Ivy Bridge
#
# Note: if your compiler does not support the relevant -march options,
# it will be compiled with whatever latest processor the compiler supports!
#
CONFIG_RTE_MACHINE="native"
#
# define the architecture we compile for.
# CONFIG_RTE_ARCH can be i686, x86_64, x86_64_32
#
CONFIG_RTE_ARCH="x86_64"
CONFIG_RTE_ARCH_X86_64=y
#
# The compiler we use.
# Can be gcc or icc.
#
CONFIG_RTE_TOOLCHAIN="gcc"
CONFIG_RTE_TOOLCHAIN_GCC=y
#
# Use intrinsics or assembly code for key routines
#
CONFIG_RTE_FORCE_INTRINSICS=n
#
# Compile to share library
#
CONFIG_RTE_LIBNAME=intel_dpdk
CONFIG_RTE_BUILD_SHARED_LIB=n
#
# Combine to one single library
#
CONFIG_RTE_BUILD_COMBINE_LIBS=n
#
# Compile Environment Abstraction Layer
#
CONFIG_RTE_LIBRTE_EAL=y
CONFIG_RTE_MAX_LCORE=64
CONFIG_RTE_MAX_NUMA_NODES=8
CONFIG_RTE_MAX_MEMSEG=256
CONFIG_RTE_MAX_MEMZONE=2560
CONFIG_RTE_MAX_TAILQ=32
CONFIG_RTE_LOG_LEVEL=8
CONFIG_RTE_LOG_HISTORY=256
CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
CONFIG_RTE_EAL_ALWAYS_PANIC_ON_ERROR=n
#
# FreeBSD contiguous memory driver settings
#
CONFIG_RTE_CONTIGMEM_MAX_NUM_BUFS=64
CONFIG_RTE_CONTIGMEM_DEFAULT_NUM_BUFS=2
CONFIG_RTE_CONTIGMEM_DEFAULT_BUF_SIZE=1024*1024*1024
#
# Compile Environment Abstraction Layer for BSD
#
CONFIG_RTE_LIBRTE_EAL_BSDAPP=y
#
# Compile Environment Abstraction Layer for linux
#
CONFIG_RTE_LIBRTE_EAL_LINUXAPP=n
#
# Compile Environment Abstraction Layer for Bare metal
#
CONFIG_RTE_LIBRTE_EAL_BAREMETAL=n
#
# Compile Environment Abstraction Layer to support Vmware TSC map
#
CONFIG_RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT=y
#
# Compile generic ethernet library
#
CONFIG_RTE_LIBRTE_ETHER=y
CONFIG_RTE_LIBRTE_ETHDEV_DEBUG=n
CONFIG_RTE_MAX_ETHPORTS=32
CONFIG_RTE_LIBRTE_IEEE1588=n
CONFIG_RTE_ETHDEV_QUEUE_STAT_CNTRS=16
#
# Compile burst-oriented IGB & EM PMD drivers
#
CONFIG_RTE_LIBRTE_EM_PMD=y
CONFIG_RTE_LIBRTE_IGB_PMD=y
CONFIG_RTE_LIBRTE_E1000_DEBUG_INIT=n
CONFIG_RTE_LIBRTE_E1000_DEBUG_RX=n
CONFIG_RTE_LIBRTE_E1000_DEBUG_TX=n
CONFIG_RTE_LIBRTE_E1000_DEBUG_TX_FREE=n
CONFIG_RTE_LIBRTE_E1000_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_E1000_PF_DISABLE_STRIP_CRC=n
#
# Compile burst-oriented IXGBE PMD driver
#
CONFIG_RTE_LIBRTE_IXGBE_PMD=y
CONFIG_RTE_LIBRTE_IXGBE_DEBUG_INIT=n
CONFIG_RTE_LIBRTE_IXGBE_DEBUG_RX=n
CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX=n
CONFIG_RTE_LIBRTE_IXGBE_DEBUG_TX_FREE=n
CONFIG_RTE_LIBRTE_IXGBE_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_IXGBE_PF_DISABLE_STRIP_CRC=n
CONFIG_RTE_LIBRTE_IXGBE_RX_ALLOW_BULK_ALLOC=y
CONFIG_RTE_LIBRTE_IXGBE_ALLOW_UNSUPPORTED_SFP=n
#
# Compile burst-oriented VIRTIO PMD driver
#
CONFIG_RTE_LIBRTE_VIRTIO_PMD=n
CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_INIT=n
CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_RX=n
CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_TX=n
CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DRIVER=n
CONFIG_RTE_LIBRTE_VIRTIO_DEBUG_DUMP=n
#
# Compile example software rings based PMD
#
CONFIG_RTE_LIBRTE_PMD_RING=y
CONFIG_RTE_PMD_RING_MAX_RX_RINGS=16
CONFIG_RTE_PMD_RING_MAX_TX_RINGS=16
#
# Compile software PMD backed by PCAP files
#
CONFIG_RTE_LIBRTE_PMD_PCAP=y
#
# Do prefetch of packet data within PMD driver receive function
#
CONFIG_RTE_PMD_PACKET_PREFETCH=y
#
# Compile librte_ring
#
CONFIG_RTE_LIBRTE_RING=y
CONFIG_RTE_LIBRTE_RING_DEBUG=n
CONFIG_RTE_RING_SPLIT_PROD_CONS=n
#
# Compile librte_mempool
#
CONFIG_RTE_LIBRTE_MEMPOOL=y
CONFIG_RTE_MEMPOOL_CACHE_MAX_SIZE=512
CONFIG_RTE_LIBRTE_MEMPOOL_DEBUG=n
#
# Compile librte_mbuf
#
CONFIG_RTE_LIBRTE_MBUF=y
CONFIG_RTE_LIBRTE_MBUF_DEBUG=n
CONFIG_RTE_MBUF_SCATTER_GATHER=y
CONFIG_RTE_MBUF_REFCNT_ATOMIC=y
CONFIG_RTE_PKTMBUF_HEADROOM=128
#
# Compile librte_timer
#
CONFIG_RTE_LIBRTE_TIMER=y
CONFIG_RTE_LIBRTE_TIMER_DEBUG=n
#
# Compile librte_malloc
#
CONFIG_RTE_LIBRTE_MALLOC=y
CONFIG_RTE_LIBRTE_MALLOC_DEBUG=n
CONFIG_RTE_MALLOC_MEMZONE_SIZE=11M
#
# Compile librte_cmdline
#
CONFIG_RTE_LIBRTE_CMDLINE=y
CONFIG_RTE_LIBRTE_CMDLINE_DEBUG=n
#
# Compile librte_hash
#
CONFIG_RTE_LIBRTE_HASH=y
CONFIG_RTE_LIBRTE_HASH_DEBUG=n
#
# Compile librte_lpm
#
CONFIG_RTE_LIBRTE_LPM=y
CONFIG_RTE_LIBRTE_LPM_DEBUG=n
#
# Compile librte_power
#
CONFIG_RTE_LIBRTE_POWER=n
CONFIG_RTE_LIBRTE_POWER_DEBUG=n
CONFIG_RTE_MAX_LCORE_FREQS=64
#
# Compile librte_net
#
CONFIG_RTE_LIBRTE_NET=y
#
# Compile librte_meter
#
CONFIG_RTE_LIBRTE_METER=y
#
# Compile librte_sched
#
CONFIG_RTE_LIBRTE_SCHED=y
CONFIG_RTE_SCHED_RED=n
CONFIG_RTE_SCHED_COLLECT_STATS=n
CONFIG_RTE_SCHED_SUBPORT_TC_OV=n
CONFIG_RTE_SCHED_PORT_N_GRINDERS=8
#
# Compile the test application
# Compile librte_kni
#
CONFIG_RTE_LIBRTE_KNI=n
CONFIG_RTE_LIBRTE_KNI_DEBUG=n
CONFIG_RTE_KNI_KO_DEBUG=n
CONFIG_RTE_KNI_VHOST=n
CONFIG_RTE_KNI_VHOST_MAX_CACHE_SIZE=1024
CONFIG_RTE_KNI_VHOST_VNET_HDR_EN=n
CONFIG_RTE_KNI_VHOST_DEBUG_RX=n
CONFIG_RTE_KNI_VHOST_DEBUG_TX=n
#
# Enable warning directives
#
CONFIG_RTE_INSECURE_FUNCTION_WARNING=n
#
# Compile the test application
#
CONFIG_RTE_APP_TEST=y
#
# Compile the PMD test application
#
CONFIG_RTE_TEST_PMD=y
CONFIG_RTE_TEST_PMD_RECORD_CORE_CYCLES=n
CONFIG_RTE_TEST_PMD_RECORD_BURST_STATS=n

View File

@ -67,7 +67,11 @@
#include <netinet/in.h>
#include <termios.h>
#ifndef __linux__
#include <net/socket.h>
#ifdef __FreeBSD__
#include <sys/socket.h>
#else
#include <net/socket.h>
#endif
#endif
#include <cmdline_rdline.h>

View File

@ -49,7 +49,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_vt100.c
SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_socket.c
SRCS-$(CONFIG_RTE_LIBRTE_CMDLINE) += cmdline_parse_portlist.c
CFLAGS_cmdline.o := -D_GNU_SOURCE
CFLAGS += -D_GNU_SOURCE
# install includes
INCS := cmdline.h cmdline_parse.h cmdline_parse_num.h cmdline_parse_ipaddr.h

View File

@ -87,7 +87,11 @@
#include <errno.h>
#include <netinet/in.h>
#ifndef __linux__
#ifndef __FreeBSD__
#include <net/socket.h>
#else
#include <sys/socket.h>
#endif
#endif
#include <rte_string_fns.h>

View File

@ -65,10 +65,6 @@
#include <string.h>
#include <errno.h>
#include <stdarg.h>
#include <netinet/in.h>
#ifndef __linux__
#include <net/socket.h>
#endif
#include <rte_string_fns.h>
#include "cmdline_parse.h"

View File

@ -33,6 +33,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
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_BAREMETAL) += baremetal
DIRS-$(CONFIG_RTE_LIBRTE_EAL_BAREMETAL) += common

View File

@ -0,0 +1,38 @@
# 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
DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal
DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += contigmem
DIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += nic_uio
include $(RTE_SDK)/mk/rte.subdir.mk

View File

@ -0,0 +1,36 @@
# 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.
#
KMOD= contigmem
SRCS= contigmem.c device_if.h bus_if.h
.include <bsd.kmod.mk>

View File

@ -0,0 +1,52 @@
# 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
#
# module name and path
#
MODULE = contigmem
#
# CFLAGS
#
MODULE_CFLAGS += -I$(SRCDIR)
MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
MODULE_CFLAGS += -Winline -Wall -Werror
MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
#
# all source are stored in SRCS-y
#
SRCS-y := contigmem.c
include $(RTE_SDK)/mk/rte.bsdmodule.mk

View File

@ -0,0 +1,233 @@
/*-
* 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/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/bio.h>
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/proc.h>
#include <sys/rwlock.h>
#include <sys/systm.h>
#include <sys/sysctl.h>
#include <machine/bus.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
static int contigmem_load(void);
static int contigmem_unload(void);
static int contigmem_physaddr(SYSCTL_HANDLER_ARGS);
static d_mmap_t contigmem_mmap;
static d_mmap_single_t contigmem_mmap_single;
static d_open_t contigmem_open;
static int contigmem_num_buffers = RTE_CONTIGMEM_DEFAULT_NUM_BUFS;
static int contigmem_buffer_size = RTE_CONTIGMEM_DEFAULT_BUF_SIZE;
static eventhandler_tag contigmem_eh_tag;
static void *contigmem_buffers[RTE_CONTIGMEM_MAX_NUM_BUFS];
static struct cdev *contigmem_cdev = NULL;
TUNABLE_INT("hw.contigmem.num_buffers", &contigmem_num_buffers);
TUNABLE_INT("hw.contigmem.buffer_size", &contigmem_buffer_size);
static SYSCTL_NODE(_hw, OID_AUTO, contigmem, CTLFLAG_RD, 0, "contigmem");
SYSCTL_INT(_hw_contigmem, OID_AUTO, num_buffers, CTLFLAG_RD,
&contigmem_num_buffers, 0, "Number of contigmem buffers allocated");
SYSCTL_INT(_hw_contigmem, OID_AUTO, buffer_size, CTLFLAG_RD,
&contigmem_buffer_size, 0, "Size of each contiguous buffer");
static SYSCTL_NODE(_hw_contigmem, OID_AUTO, physaddr, CTLFLAG_RD, 0,
"physaddr");
MALLOC_DEFINE(M_CONTIGMEM, "contigmem", "contigmem(4) allocations");
static int contigmem_modevent(module_t mod, int type, void *arg)
{
int error = 0;
switch (type) {
case MOD_LOAD:
error = contigmem_load();
break;
case MOD_UNLOAD:
error = contigmem_unload();
break;
default:
break;
}
return (error);
}
moduledata_t contigmem_mod = {
"contigmem",
(modeventhand_t)contigmem_modevent,
0
};
DECLARE_MODULE(contigmem, contigmem_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
MODULE_VERSION(contigmem, 1);
static struct cdevsw contigmem_ops = {
.d_name = "contigmem",
.d_version = D_VERSION,
.d_mmap = contigmem_mmap,
.d_mmap_single = contigmem_mmap_single,
.d_open = contigmem_open,
};
static int
contigmem_load()
{
char index_string[8], description[32];
int i;
if (contigmem_num_buffers > RTE_CONTIGMEM_MAX_NUM_BUFS) {
printf("%d buffers requested is greater than %d allowed\n",
contigmem_num_buffers, RTE_CONTIGMEM_MAX_NUM_BUFS);
return (EINVAL);
}
if (contigmem_buffer_size < PAGE_SIZE ||
(contigmem_buffer_size & (contigmem_buffer_size - 1)) != 0) {
printf("buffer size 0x%x is not greater than PAGE_SIZE and "
"power of two\n", contigmem_buffer_size);
return (EINVAL);
}
for (i = 0; i < contigmem_num_buffers; i++) {
contigmem_buffers[i] =
contigmalloc(contigmem_buffer_size, M_CONTIGMEM, M_ZERO, 0,
BUS_SPACE_MAXADDR, contigmem_buffer_size, 0);
if (contigmem_buffers[i] == NULL) {
printf("contigmalloc failed for buffer %d\n", i);
return (ENOMEM);
}
printf("%2u: virt=%p phys=%p\n", i, contigmem_buffers[i],
(void *)pmap_kextract((vm_offset_t)contigmem_buffers[i]));
snprintf(index_string, sizeof(index_string), "%d", i);
snprintf(description, sizeof(description),
"phys addr for buffer %d", i);
SYSCTL_ADD_PROC(NULL,
&SYSCTL_NODE_CHILDREN(_hw_contigmem, physaddr), OID_AUTO,
index_string, CTLTYPE_U64 | CTLFLAG_RD,
(void *)(uintptr_t)i, 0, contigmem_physaddr, "LU",
description);
}
contigmem_cdev = make_dev_credf(0, &contigmem_ops, 0, NULL, UID_ROOT,
GID_WHEEL, 0600, "contigmem");
return (0);
}
static int
contigmem_unload()
{
int i;
if (contigmem_cdev != NULL)
destroy_dev(contigmem_cdev);
if (contigmem_eh_tag != NULL)
EVENTHANDLER_DEREGISTER(process_exit, contigmem_eh_tag);
for (i = 0; i < contigmem_num_buffers; i++)
if (contigmem_buffers[i] != NULL)
contigfree(contigmem_buffers[i], contigmem_buffer_size,
M_CONTIGMEM);
return (0);
}
static int
contigmem_physaddr(SYSCTL_HANDLER_ARGS)
{
uint64_t physaddr;
int index = (int)(uintptr_t)arg1;
physaddr = (uint64_t)vtophys(contigmem_buffers[index]);
return (sysctl_handle_64(oidp, &physaddr, 0, req));
}
static int
contigmem_open(struct cdev *cdev, int fflags, int devtype,
struct thread *td)
{
return (0);
}
static int
contigmem_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
int prot, vm_memattr_t *memattr)
{
*paddr = offset;
return (0);
}
static int
contigmem_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size,
struct vm_object **obj, int nprot)
{
/*
* The buffer index is encoded in the offset. Divide the offset by
* PAGE_SIZE to get the index of the buffer requested by the user
* app.
*/
if ((*offset/PAGE_SIZE) >= contigmem_num_buffers)
return (EINVAL);
*offset = (vm_ooffset_t)vtophys(contigmem_buffers[*offset/PAGE_SIZE]);
*obj = vm_pager_allocate(OBJT_DEVICE, cdev, size, nprot, *offset,
curthread->td_ucred);
return (0);
}

View File

@ -0,0 +1,94 @@
# 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
VPATH += $(RTE_SDK)/lib/librte_eal/common
CFLAGS += -I$(SRCDIR)/include
CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
CFLAGS += -I$(RTE_SDK)/lib/librte_ring
CFLAGS += -I$(RTE_SDK)/lib/librte_mempool
CFLAGS += -I$(RTE_SDK)/lib/librte_malloc
CFLAGS += -I$(RTE_SDK)/lib/librte_ether
CFLAGS += -I$(RTE_SDK)/lib/librte_pmd_ring
CFLAGS += -I$(RTE_SDK)/lib/librte_pmd_pcap
CFLAGS += $(WERROR_FLAGS) -O3
# specific to linuxapp exec-env
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) := eal.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_memory.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_hugepage_info.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_thread.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_log.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_pci.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_debug.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_lcore.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_timer.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_interrupts.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_alarm.c
# from common dir
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_memzone.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_log.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_launch.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_pci.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_memory.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_tailqs.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_errno.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_cpuflags.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_hexdump.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_whitelist.c
SRCS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += eal_common_nonpci_devs.c
CFLAGS_eal.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
# 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
CFLAGS_eal_hpet.o += -Wno-return-type
endif
INC := rte_per_lcore.h rte_lcore.h rte_interrupts.h rte_kni_common.h
SYMLINK-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP)-include/exec-env := \
$(addprefix include/exec-env/,$(INC))
DEPDIRS-$(CONFIG_RTE_LIBRTE_EAL_BSDAPP) += lib/librte_eal/common
include $(RTE_SDK)/mk/rte.lib.mk

View File

@ -0,0 +1,904 @@
/*-
* 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 <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <unistd.h>
#include <pthread.h>
#include <syslog.h>
#include <getopt.h>
#include <sys/file.h>
#include <stddef.h>
#include <errno.h>
#include <limits.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/queue.h>
#include <rte_common.h>
#include <rte_debug.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_eal_memconfig.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_log.h>
#include <rte_random.h>
#include <rte_cycles.h>
#include <rte_string_fns.h>
#include <rte_cpuflags.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_common.h>
#include <rte_version.h>
#include <rte_atomic.h>
#include <malloc_heap.h>
#include <rte_eth_ring.h>
#include "eal_private.h"
#include "eal_thread.h"
#include "eal_internal_cfg.h"
#include "eal_filesystem.h"
#include "eal_hugepages.h"
#define OPT_HUGE_DIR "huge-dir"
#define OPT_PROC_TYPE "proc-type"
#define OPT_NO_SHCONF "no-shconf"
#define OPT_NO_HPET "no-hpet"
#define OPT_VMWARE_TSC_MAP "vmware-tsc-map"
#define OPT_NO_PCI "no-pci"
#define OPT_NO_HUGE "no-huge"
#define OPT_FILE_PREFIX "file-prefix"
#define OPT_SOCKET_MEM "socket-mem"
#define OPT_USE_DEVICE "use-device"
#define OPT_SYSLOG "syslog"
#define RTE_EAL_BLACKLIST_SIZE 0x100
#define MEMSIZE_IF_NO_HUGE_PAGE (64ULL * 1024ULL * 1024ULL)
#define SOCKET_MEM_STRLEN (RTE_MAX_NUMA_NODES * 10)
#define HIGHEST_RPL 3
#define BITS_PER_HEX 4
#define GET_BLACKLIST_FIELD(in, fd, lim, dlm) \
{ \
unsigned long val; \
char *end; \
errno = 0; \
val = strtoul((in), &end, 16); \
if (errno != 0 || end[0] != (dlm) || val > (lim)) \
return (-EINVAL); \
(fd) = (typeof (fd))val; \
(in) = end + 1; \
}
/* Allow the application to print its usage message too if set */
static rte_usage_hook_t rte_application_usage_hook = NULL;
/* early configuration structure, when memory config is not mmapped */
static struct rte_mem_config early_mem_config;
/* define fd variable here, because file needs to be kept open for the
* duration of the program, as we hold a write lock on it in the primary proc */
static int mem_cfg_fd = -1;
static struct flock wr_lock = {
.l_type = F_WRLCK,
.l_whence = SEEK_SET,
.l_start = offsetof(struct rte_mem_config, memseg),
.l_len = sizeof(early_mem_config.memseg),
};
/* Address of global and public configuration */
static struct rte_config rte_config = {
.mem_config = &early_mem_config,
};
static struct rte_pci_addr eal_dev_blacklist[RTE_EAL_BLACKLIST_SIZE];
/* internal configuration (per-core) */
struct lcore_config lcore_config[RTE_MAX_LCORE];
/* internal configuration */
struct internal_config internal_config;
/* used by rte_rdtsc() */
int rte_cycles_vmware_tsc_map;
/* Return a pointer to the configuration structure */
struct rte_config *
rte_eal_get_configuration(void)
{
return &rte_config;
}
/* parse a sysfs (or other) file containing one integer value */
int
eal_parse_sysfs_value(const char *filename, unsigned long *val)
{
FILE *f;
char buf[BUFSIZ];
char *end = NULL;
if ((f = fopen(filename, "r")) == NULL) {
RTE_LOG(ERR, EAL, "%s(): cannot open sysfs value %s\n",
__func__, filename);
return -1;
}
if (fgets(buf, sizeof(buf), f) == NULL) {
RTE_LOG(ERR, EAL, "%s(): cannot read sysfs value %s\n",
__func__, filename);
fclose(f);
return -1;
}
*val = strtoul(buf, &end, 0);
if ((buf[0] == '\0') || (end == NULL) || (*end != '\n')) {
RTE_LOG(ERR, EAL, "%s(): cannot parse sysfs value %s\n",
__func__, filename);
fclose(f);
return -1;
}
fclose(f);
return 0;
}
/* create memory configuration in shared/mmap memory. Take out
* a write lock on the memsegs, so we can auto-detect primary/secondary.
* This means we never close the file while running (auto-close on exit).
* We also don't lock the whole file, so that in future we can use read-locks
* on other parts, e.g. memzones, to detect if there are running secondary
* processes. */
static void
rte_eal_config_create(void)
{
void *rte_mem_cfg_addr;
int retval;
const char *pathname = eal_runtime_config_path();
if (internal_config.no_shconf)
return;
if (mem_cfg_fd < 0){
mem_cfg_fd = open(pathname, O_RDWR | O_CREAT, 0660);
if (mem_cfg_fd < 0)
rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
}
retval = ftruncate(mem_cfg_fd, sizeof(*rte_config.mem_config));
if (retval < 0){
close(mem_cfg_fd);
rte_panic("Cannot resize '%s' for rte_mem_config\n", pathname);
}
retval = fcntl(mem_cfg_fd, F_SETLK, &wr_lock);
if (retval < 0){
close(mem_cfg_fd);
rte_exit(EXIT_FAILURE, "Cannot create lock on '%s'. Is another primary "
"process running?\n", pathname);
}
rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
if (rte_mem_cfg_addr == MAP_FAILED){
rte_panic("Cannot mmap memory for rte_config\n");
}
memcpy(rte_mem_cfg_addr, &early_mem_config, sizeof(early_mem_config));
rte_config.mem_config = (struct rte_mem_config *) rte_mem_cfg_addr;
}
/* attach to an existing shared memory config */
static void
rte_eal_config_attach(void)
{
void *rte_mem_cfg_addr;
const char *pathname = eal_runtime_config_path();
if (internal_config.no_shconf)
return;
if (mem_cfg_fd < 0){
mem_cfg_fd = open(pathname, O_RDWR);
if (mem_cfg_fd < 0)
rte_panic("Cannot open '%s' for rte_mem_config\n", pathname);
}
rte_mem_cfg_addr = mmap(NULL, sizeof(*rte_config.mem_config),
PROT_READ | PROT_WRITE, MAP_SHARED, mem_cfg_fd, 0);
close(mem_cfg_fd);
if (rte_mem_cfg_addr == MAP_FAILED)
rte_panic("Cannot mmap memory for rte_config\n");
rte_config.mem_config = (struct rte_mem_config *) rte_mem_cfg_addr;
}
/* Detect if we are a primary or a secondary process */
static enum rte_proc_type_t
eal_proc_type_detect(void)
{
enum rte_proc_type_t ptype = RTE_PROC_PRIMARY;
const char *pathname = eal_runtime_config_path();
/* if we can open the file but not get a write-lock we are a secondary
* process. NOTE: if we get a file handle back, we keep that open
* and don't close it to prevent a race condition between multiple opens */
if (((mem_cfg_fd = open(pathname, O_RDWR)) >= 0) &&
(fcntl(mem_cfg_fd, F_SETLK, &wr_lock) < 0))
ptype = RTE_PROC_SECONDARY;
RTE_LOG(INFO, EAL, "Auto-detected process type: %s\n",
ptype == RTE_PROC_PRIMARY ? "PRIMARY" : "SECONDARY");
return ptype;
}
/* Sets up rte_config structure with the pointer to shared memory config.*/
static void
rte_config_init(void)
{
/* set the magic in configuration structure */
rte_config.magic = RTE_MAGIC;
rte_config.process_type = (internal_config.process_type == RTE_PROC_AUTO) ?
eal_proc_type_detect() : /* for auto, detect the type */
internal_config.process_type; /* otherwise use what's already set */
switch (rte_config.process_type){
case RTE_PROC_PRIMARY:
rte_eal_config_create();
break;
case RTE_PROC_SECONDARY:
rte_eal_config_attach();
rte_eal_mcfg_wait_complete(rte_config.mem_config);
break;
case RTE_PROC_AUTO:
case RTE_PROC_INVALID:
rte_panic("Invalid process type\n");
}
}
/* display usage */
static void
eal_usage(const char *prgname)
{
printf("\nUsage: %s -c COREMASK -n NUM [-m NB] [-r NUM] [-b <domain:bus:devid.func>]"
"[--proc-type primary|secondary|auto] \n\n"
"EAL options:\n"
" -c COREMASK : A hexadecimal bitmask of cores to run on\n"
" -n NUM : Number of memory channels\n"
" -v : Display version information on startup\n"
" -b <domain:bus:devid.func>: to prevent EAL from using specified "
"PCI device\n"
" (multiple -b options are allowed)\n"
" -m MB : memory to allocate\n"
" -r NUM : force number of memory ranks (don't detect)\n"
" --"OPT_PROC_TYPE" : type of this process\n"
" --"OPT_USE_DEVICE": use the specified ethernet device(s) only. "
"Use comma-separate <[domain:]bus:devid.func> values.\n"
" [NOTE: Cannot be used with -b option]\n"
" --"OPT_VMWARE_TSC_MAP": use VMware TSC map instead of "
"native RDTSC\n"
"\nEAL options for DEBUG use only:\n"
" --"OPT_NO_HUGE" : use malloc instead of hugetlbfs\n"
" --"OPT_NO_PCI" : disable pci\n"
" --"OPT_NO_SHCONF": no shared config (mmap'd files)\n"
"\n",
prgname);
/* Allow the application to print its usage message too if hook is set */
if ( rte_application_usage_hook ) {
printf("===== Application Usage =====\n\n");
rte_application_usage_hook(prgname);
}
}
/* Set a per-application usage message */
rte_usage_hook_t
rte_set_application_usage_hook( rte_usage_hook_t usage_func )
{
rte_usage_hook_t old_func;
/* Will be NULL on the first call to denote the last usage routine. */
old_func = rte_application_usage_hook;
rte_application_usage_hook = usage_func;
return old_func;
}
/*
* Parse the coremask given as argument (hexadecimal string) and fill
* the global configuration (core role and core count) with the parsed
* value.
*/
static int xdigit2val(unsigned char c)
{
int val;
if(isdigit(c))
val = c - '0';
else if(isupper(c))
val = c - 'A' + 10;
else
val = c - 'a' + 10;
return val;
}
static int
eal_parse_coremask(const char *coremask)
{
struct rte_config *cfg = rte_eal_get_configuration();
int i, j, idx = 0 ;
unsigned count = 0;
char c;
int val;
if (coremask == NULL)
return -1;
/* Remove all blank characters ahead and after .
* Remove 0x/0X if exists.
*/
while (isblank(*coremask))
coremask++;
if (coremask[0] == '0' && ((coremask[1] == 'x')
|| (coremask[1] == 'X')) )
coremask += 2;
i = strnlen(coremask, sysconf(_SC_ARG_MAX));
while ((i > 0) && isblank(coremask[i - 1]))
i--;
if (i == 0)
return -1;
for (i = i - 1; i >= 0 && idx < RTE_MAX_LCORE; i--) {
c = coremask[i];
if (isxdigit(c) == 0) {
/* invalid characters */
return (-1);
}
val = xdigit2val(c);
for(j = 0; j < BITS_PER_HEX && idx < RTE_MAX_LCORE; j++, idx++) {
if((1 << j) & val) {
cfg->lcore_role[idx] = ROLE_RTE;
if(count == 0)
cfg->master_lcore = idx;
count++;
} else {
cfg->lcore_role[idx] = ROLE_OFF;
}
}
}
for(; i >= 0; i--)
if(coremask[i] != '0')
return -1;
for(; idx < RTE_MAX_LCORE; idx++)
cfg->lcore_role[idx] = ROLE_OFF;
if(count == 0)
return -1;
return 0;
}
static int
eal_parse_syslog(const char *facility)
{
int i;
static struct {
const char *name;
int value;
} map[] = {
{ "auth", LOG_AUTH },
{ "cron", LOG_CRON },
{ "daemon", LOG_DAEMON },
{ "ftp", LOG_FTP },
{ "kern", LOG_KERN },
{ "lpr", LOG_LPR },
{ "mail", LOG_MAIL },
{ "news", LOG_NEWS },
{ "syslog", LOG_SYSLOG },
{ "user", LOG_USER },
{ "uucp", LOG_UUCP },
{ "local0", LOG_LOCAL0 },
{ "local1", LOG_LOCAL1 },
{ "local2", LOG_LOCAL2 },
{ "local3", LOG_LOCAL3 },
{ "local4", LOG_LOCAL4 },
{ "local5", LOG_LOCAL5 },
{ "local6", LOG_LOCAL6 },
{ "local7", LOG_LOCAL7 },
{ NULL, 0 }
};
for (i = 0; map[i].name; i++) {
if (!strcmp(facility, map[i].name)) {
internal_config.syslog_facility = map[i].value;
return 0;
}
}
return -1;
}
static inline size_t
eal_get_hugepage_mem_size(void)
{
uint64_t size = 0;
unsigned i, j;
for (i = 0; i < internal_config.num_hugepage_sizes; i++) {
struct hugepage_info *hpi = &internal_config.hugepage_info[i];
if (hpi->hugedir != NULL) {
for (j = 0; j < RTE_MAX_NUMA_NODES; j++) {
size += hpi->hugepage_sz * hpi->num_pages[j];
}
}
}
return (size < SIZE_MAX) ? (size_t)(size) : SIZE_MAX;
}
static enum rte_proc_type_t
eal_parse_proc_type(const char *arg)
{
if (strncasecmp(arg, "primary", sizeof("primary")) == 0)
return RTE_PROC_PRIMARY;
if (strncasecmp(arg, "secondary", sizeof("secondary")) == 0)
return RTE_PROC_SECONDARY;
if (strncasecmp(arg, "auto", sizeof("auto")) == 0)
return RTE_PROC_AUTO;
return RTE_PROC_INVALID;
}
static ssize_t
eal_parse_blacklist_opt(const char *optarg, size_t idx)
{
if (idx >= sizeof (eal_dev_blacklist) / sizeof (eal_dev_blacklist[0])) {
RTE_LOG(ERR, EAL, "%s - too many devices to blacklist...\n", optarg);
return (-EINVAL);
} else if (eal_parse_pci_DomBDF(optarg, eal_dev_blacklist + idx) < 0 &&
eal_parse_pci_BDF(optarg, eal_dev_blacklist + idx) < 0) {
RTE_LOG(ERR, EAL, "%s - invalid device to blacklist...\n", optarg);
return (-EINVAL);
}
idx += 1;
return (idx);
}
/* Parse the argument given in the command line of the application */
static int
eal_parse_args(int argc, char **argv)
{
int opt, ret, i;
char **argvopt;
int option_index;
int coremask_ok = 0;
ssize_t blacklist_index = 0;
char *prgname = argv[0];
static struct option lgopts[] = {
{OPT_NO_HUGE, 0, 0, 0},
{OPT_NO_PCI, 0, 0, 0},
{OPT_NO_HPET, 0, 0, 0},
{OPT_VMWARE_TSC_MAP, 0, 0, 0},
{OPT_HUGE_DIR, 1, 0, 0},
{OPT_NO_SHCONF, 0, 0, 0},
{OPT_PROC_TYPE, 1, 0, 0},
{OPT_FILE_PREFIX, 1, 0, 0},
{OPT_SOCKET_MEM, 1, 0, 0},
{OPT_USE_DEVICE, 1, 0, 0},
{OPT_SYSLOG, 1, NULL, 0},
{0, 0, 0, 0}
};
argvopt = argv;
internal_config.memory = 0;
internal_config.force_nrank = 0;
internal_config.force_nchannel = 0;
internal_config.hugefile_prefix = HUGEFILE_PREFIX_DEFAULT;
internal_config.hugepage_dir = NULL;
internal_config.force_sockets = 0;
internal_config.syslog_facility = LOG_DAEMON;
#ifdef RTE_LIBEAL_USE_HPET
internal_config.no_hpet = 0;
#else
internal_config.no_hpet = 1;
#endif
/* zero out the NUMA config */
for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
internal_config.socket_mem[i] = 0;
/* zero out hugedir descriptors */
for (i = 0; i < MAX_HUGEPAGE_SIZES; i++)
internal_config.hugepage_info[i].lock_descriptor = 0;
internal_config.vmware_tsc_map = 0;
while ((opt = getopt_long(argc, argvopt, "b:c:m:n:r:v",
lgopts, &option_index)) != EOF) {
switch (opt) {
/* blacklist */
case 'b':
if ((blacklist_index = eal_parse_blacklist_opt(optarg,
blacklist_index)) < 0) {
eal_usage(prgname);
return (-1);
}
break;
/* coremask */
case 'c':
if (eal_parse_coremask(optarg) < 0) {
RTE_LOG(ERR, EAL, "invalid coremask\n");
eal_usage(prgname);
return -1;
}
coremask_ok = 1;
break;
/* size of memory */
case 'm':
internal_config.memory = atoi(optarg);
internal_config.memory *= 1024ULL;
internal_config.memory *= 1024ULL;
break;
/* force number of channels */
case 'n':
internal_config.force_nchannel = atoi(optarg);
if (internal_config.force_nchannel == 0 ||
internal_config.force_nchannel > 4) {
RTE_LOG(ERR, EAL, "invalid channel number\n");
eal_usage(prgname);
return -1;
}
break;
/* force number of ranks */
case 'r':
internal_config.force_nrank = atoi(optarg);
if (internal_config.force_nrank == 0 ||
internal_config.force_nrank > 16) {
RTE_LOG(ERR, EAL, "invalid rank number\n");
eal_usage(prgname);
return -1;
}
break;
case 'v':
/* since message is explicitly requested by user, we
* write message at highest log level so it can always be seen
* even if info or warning messages are disabled */
RTE_LOG(CRIT, EAL, "RTE Version: '%s'\n", rte_version());
break;
/* long options */
case 0:
if (!strcmp(lgopts[option_index].name, OPT_NO_HUGE)) {
internal_config.no_hugetlbfs = 1;
}
else if (!strcmp(lgopts[option_index].name, OPT_NO_PCI)) {
internal_config.no_pci = 1;
}
else if (!strcmp(lgopts[option_index].name, OPT_NO_HPET)) {
internal_config.no_hpet = 1;
}
else if (!strcmp(lgopts[option_index].name, OPT_VMWARE_TSC_MAP)) {
internal_config.vmware_tsc_map = 1;
}
else if (!strcmp(lgopts[option_index].name, OPT_NO_SHCONF)) {
internal_config.no_shconf = 1;
}
else if (!strcmp(lgopts[option_index].name, OPT_HUGE_DIR)) {
RTE_LOG(ERR, EAL, "Option "OPT_HUGE_DIR" is not supported on"
"FreeBSD\n");
return -1;
}
else if (!strcmp(lgopts[option_index].name, OPT_PROC_TYPE)) {
internal_config.process_type = eal_parse_proc_type(optarg);
}
else if (!strcmp(lgopts[option_index].name, OPT_FILE_PREFIX)) {
RTE_LOG(ERR, EAL, "Option "OPT_FILE_PREFIX" is not supported on"
"FreeBSD\n");
return -1;
}
else if (!strcmp(lgopts[option_index].name, OPT_SOCKET_MEM)) {
RTE_LOG(ERR, EAL, "Option "OPT_SOCKET_MEM" is not supported on"
"FreeBSD\n");
return -1;
}
else if (!strcmp(lgopts[option_index].name, OPT_USE_DEVICE)) {
eal_dev_whitelist_add_entry(optarg);
}
else if (!strcmp(lgopts[option_index].name, OPT_SYSLOG)) {
if (eal_parse_syslog(optarg) < 0) {
RTE_LOG(ERR, EAL, "invalid parameters for --"
OPT_SYSLOG "\n");
eal_usage(prgname);
return -1;
}
}
break;
default:
eal_usage(prgname);
return -1;
}
}
/* sanity checks */
if (!coremask_ok) {
RTE_LOG(ERR, EAL, "coremask not specified\n");
eal_usage(prgname);
return -1;
}
if (internal_config.process_type == RTE_PROC_AUTO){
internal_config.process_type = eal_proc_type_detect();
}
if (internal_config.process_type == RTE_PROC_INVALID){
RTE_LOG(ERR, EAL, "Invalid process type specified\n");
eal_usage(prgname);
return -1;
}
if (internal_config.process_type == RTE_PROC_PRIMARY &&
internal_config.force_nchannel == 0) {
RTE_LOG(ERR, EAL, "Number of memory channels (-n) not specified\n");
eal_usage(prgname);
return -1;
}
if (index(internal_config.hugefile_prefix,'%') != NULL){
RTE_LOG(ERR, EAL, "Invalid char, '%%', in '"OPT_FILE_PREFIX"' option\n");
eal_usage(prgname);
return -1;
}
if (internal_config.memory > 0 && internal_config.force_sockets == 1) {
RTE_LOG(ERR, EAL, "Options -m and --socket-mem cannot be specified "
"at the same time\n");
eal_usage(prgname);
return -1;
}
/* --no-huge doesn't make sense with either -m or --socket-mem */
if (internal_config.no_hugetlbfs &&
(internal_config.memory > 0 ||
internal_config.force_sockets == 1)) {
RTE_LOG(ERR, EAL, "Options -m or --socket-mem cannot be specified "
"together with --no-huge!\n");
eal_usage(prgname);
return -1;
}
/* if no blacklist, parse a whitelist */
if (blacklist_index > 0) {
if (eal_dev_whitelist_exists()) {
RTE_LOG(ERR, EAL, "Error: blacklist [-b] and whitelist "
"[--use-device] options cannot be used at the same time\n");
eal_usage(prgname);
return -1;
}
rte_eal_pci_set_blacklist(eal_dev_blacklist, blacklist_index);
} else {
if (eal_dev_whitelist_exists() && eal_dev_whitelist_parse() < 0) {
RTE_LOG(ERR,EAL, "Error parsing whitelist[--use-device] options\n");
return -1;
}
}
if (optind >= 0)
argv[optind-1] = prgname;
/* if no memory amounts were requested, this will result in 0 and
* will be overriden later, right after eal_hugepage_info_init() */
for (i = 0; i < RTE_MAX_NUMA_NODES; i++)
internal_config.memory += internal_config.socket_mem[i];
ret = optind-1;
optind = 0; /* reset getopt lib */
return ret;
}
static void
eal_check_mem_on_local_socket(void)
{
const struct rte_memseg *ms;
int i, socket_id;
socket_id = rte_lcore_to_socket_id(rte_config.master_lcore);
ms = rte_eal_get_physmem_layout();
for (i = 0; i < RTE_MAX_MEMSEG; i++)
if (ms[i].socket_id == socket_id &&
ms[i].len > 0)
return;
RTE_LOG(WARNING, EAL, "WARNING: Master core has no "
"memory on local socket!\n");
}
static int
sync_func(__attribute__((unused)) void *arg)
{
return 0;
}
inline static void
rte_eal_mcfg_complete(void)
{
/* ALL shared mem_config related INIT DONE */
if (rte_config.process_type == RTE_PROC_PRIMARY)
rte_config.mem_config->magic = RTE_MAGIC;
}
/* Abstraction for port I/0 privilage */
static int
rte_eal_iopl_init(void)
{
int fd = -1;
fd = open("/dev/io", O_RDWR);
if (fd < 0)
return -1;
return 0;
}
/* Launch threads, called at application init(). */
int
rte_eal_init(int argc, char **argv)
{
int i, fctret, ret;
pthread_t thread_id;
static rte_atomic32_t run_once = RTE_ATOMIC32_INIT(0);
if (!rte_atomic32_test_and_set(&run_once))
return -1;
thread_id = pthread_self();
if (rte_eal_log_early_init() < 0)
rte_panic("Cannot init early logs\n");
fctret = eal_parse_args(argc, argv);
if (fctret < 0)
exit(1);
if (internal_config.no_hugetlbfs == 0 &&
internal_config.process_type != RTE_PROC_SECONDARY &&
eal_hugepage_info_init() < 0)
rte_panic("Cannot get hugepage information\n");
if (internal_config.memory == 0 && internal_config.force_sockets == 0) {
if (internal_config.no_hugetlbfs)
internal_config.memory = MEMSIZE_IF_NO_HUGE_PAGE;
else
internal_config.memory = eal_get_hugepage_mem_size();
}
if (internal_config.vmware_tsc_map == 1) {
#ifdef RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT
rte_cycles_vmware_tsc_map = 1;
RTE_LOG (DEBUG, EAL, "Using VMWARE TSC MAP, "
"you must have monitor_control.pseudo_perfctr = TRUE\n");
#else
RTE_LOG (WARNING, EAL, "Ignoring --vmware-tsc-map because "
"RTE_LIBRTE_EAL_VMWARE_TSC_MAP_SUPPORT is not set\n");
#endif
}
rte_srand(rte_rdtsc());
rte_config_init();
if (rte_eal_iopl_init() == 0)
rte_config.flags |= EAL_FLG_HIGH_IOPL;
if (rte_eal_cpu_init() < 0)
rte_panic("Cannot detect lcores\n");
if (rte_eal_memory_init() < 0)
rte_panic("Cannot init memory\n");
if (rte_eal_memzone_init() < 0)
rte_panic("Cannot init memzone\n");
if (rte_eal_tailqs_init() < 0)
rte_panic("Cannot init tail queues for objects\n");
/* if (rte_eal_log_init(argv[0], internal_config.syslog_facility) < 0)
rte_panic("Cannot init logs\n");*/
if (rte_eal_alarm_init() < 0)
rte_panic("Cannot init interrupt-handling thread\n");
if (rte_eal_intr_init() < 0)
rte_panic("Cannot init interrupt-handling thread\n");
if (rte_eal_timer_init() < 0)
rte_panic("Cannot init HPET or TSC timers\n");
if (rte_eal_pci_init() < 0)
rte_panic("Cannot init PCI\n");
RTE_LOG(DEBUG, EAL, "Master core %u is ready (tid=%p)\n",
rte_config.master_lcore, thread_id);
eal_check_mem_on_local_socket();
rte_eal_mcfg_complete();
if (rte_eal_non_pci_ethdev_init() < 0)
rte_panic("Cannot init non-PCI eth_devs\n");
RTE_LCORE_FOREACH_SLAVE(i) {
/*
* create communication pipes between master thread
* and children
*/
if (pipe(lcore_config[i].pipe_master2slave) < 0)
rte_panic("Cannot create pipe\n");
if (pipe(lcore_config[i].pipe_slave2master) < 0)
rte_panic("Cannot create pipe\n");
lcore_config[i].state = WAIT;
/* create a thread for each lcore */
ret = pthread_create(&lcore_config[i].thread_id, NULL,
eal_thread_loop, NULL);
if (ret != 0)
rte_panic("Cannot create thread\n");
}
eal_thread_init_master(rte_config.master_lcore);
/*
* Launch a dummy function on all slave lcores, so that master lcore
* knows they are all ready when this function returns.
*/
rte_eal_mp_remote_launch(sync_func, NULL, SKIP_MASTER);
rte_eal_mp_wait_lcore();
return fctret;
}
/* get core role */
enum rte_lcore_role_t
rte_eal_lcore_role(unsigned lcore_id)
{
return (rte_config.lcore_role[lcore_id]);
}
enum rte_proc_type_t
rte_eal_process_type(void)
{
return (rte_config.process_type);
}

View File

@ -0,0 +1,60 @@
/*-
* 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 <stdlib.h>
#include <errno.h>
#include <rte_alarm.h>
#include <rte_common.h>
#include "eal_private.h"
int
rte_eal_alarm_init(void)
{
return 0;
}
int
rte_eal_alarm_set(uint64_t us __rte_unused,
rte_eal_alarm_callback cb_fn __rte_unused,
void *cb_arg __rte_unused)
{
return -ENOTSUP;
}
int
rte_eal_alarm_cancel(rte_eal_alarm_callback cb_fn __rte_unused,
void *cb_arg __rte_unused)
{
return -ENOTSUP;
}

View File

@ -0,0 +1,113 @@
/*-
* 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 <execinfo.h>
#include <stdarg.h>
#include <signal.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_common.h>
#define BACKTRACE_SIZE 256
/* dump the stack of the calling core */
void rte_dump_stack(void)
{
void *func[BACKTRACE_SIZE];
char **symb = NULL;
int size;
size = backtrace(func, BACKTRACE_SIZE);
symb = backtrace_symbols(func, size);
while (size > 0) {
rte_log(RTE_LOG_ERR, RTE_LOGTYPE_EAL,
"%d: [%s]\n", size, symb[size - 1]);
size --;
}
}
/* not implemented in this environment */
void rte_dump_registers(void)
{
return;
}
/* call abort(), it will generate a coredump if enabled */
void __rte_panic(const char *funcname, const char *format, ...)
{
va_list ap;
/* disable history */
rte_log_set_history(0);
rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
va_start(ap, format);
rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
va_end(ap);
rte_dump_stack();
rte_dump_registers();
abort();
}
/*
* Like rte_panic this terminates the application. However, no traceback is
* provided and no core-dump is generated.
*/
void
rte_exit(int exit_code, const char *format, ...)
{
va_list ap;
/* disable history */
rte_log_set_history(0);
if (exit_code != 0)
RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n"
" Cause: ", exit_code);
va_start(ap, format);
rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
va_end(ap);
#ifndef RTE_EAL_ALWAYS_PANIC_ON_ERROR
exit(exit_code);
#else
rte_dump_stack();
rte_dump_registers();
abort();
#endif
}

View File

@ -0,0 +1,133 @@
/*-
* 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/types.h>
#include <sys/sysctl.h>
#include <sys/mman.h>
#include <string.h>
#include <rte_log.h>
#include <fcntl.h>
#include "eal_hugepages.h"
#include "eal_internal_cfg.h"
#include "eal_filesystem.h"
#define CONTIGMEM_DEV "/dev/contigmem"
/*
* Uses mmap to create a shared memory area for storage of data
* Used in this file to store the hugepage file map on disk
*/
static void *
create_shared_memory(const char *filename, const size_t mem_size)
{
void *retval;
int fd = open(filename, O_CREAT | O_RDWR, 0666);
if (fd < 0)
return NULL;
if (ftruncate(fd, mem_size) < 0) {
close(fd);
return NULL;
}
retval = mmap(NULL, mem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
close(fd);
return retval;
}
/*
* No hugepage support on freebsd, but we dummy it, using contigmem driver
*/
int
eal_hugepage_info_init(void)
{
size_t sysctl_size;
int buffer_size, num_buffers, fd, error;
/* re-use the linux "internal config" structure for our memory data */
struct hugepage_info *hpi = &internal_config.hugepage_info[0];
struct hugepage_info *tmp_hpi;
sysctl_size = sizeof(num_buffers);
error = sysctlbyname("hw.contigmem.num_buffers", &num_buffers,
&sysctl_size, NULL, 0);
if (error != 0) {
RTE_LOG(ERR, EAL, "could not read sysctl hw.contigmem.num_buffers");
return -1;
}
sysctl_size = sizeof(buffer_size);
error = sysctlbyname("hw.contigmem.buffer_size", &buffer_size,
&sysctl_size, NULL, 0);
if (error != 0) {
RTE_LOG(ERR, EAL, "could not read sysctl hw.contigmem.buffer_size");
return -1;
}
fd = open(CONTIGMEM_DEV, O_RDWR);
if (fd < 0) {
RTE_LOG(ERR, EAL, "could not open "CONTIGMEM_DEV"\n");
return -1;
}
if (buffer_size >= 1<<30)
RTE_LOG(INFO, EAL, "Contigmem driver has %d buffers, each of size %dGB\n",
num_buffers, buffer_size>>30);
else if (buffer_size >= 1<<20)
RTE_LOG(INFO, EAL, "Contigmem driver has %d buffers, each of size %dMB\n",
num_buffers, buffer_size>>20);
else
RTE_LOG(INFO, EAL, "Contigmem driver has %d buffers, each of size %dKB\n",
num_buffers, buffer_size>>10);
internal_config.num_hugepage_sizes = 1;
hpi->hugedir = CONTIGMEM_DEV;
hpi->hugepage_sz = buffer_size;
hpi->num_pages[0] = num_buffers;
hpi->lock_descriptor = fd;
tmp_hpi = create_shared_memory(eal_hugepage_info_path(),
sizeof(struct hugepage_info));
if (tmp_hpi == NULL ) {
RTE_LOG(ERR, EAL, "Failed to create shared memory!\n");
return -1;
}
memcpy(tmp_hpi, hpi, sizeof(struct hugepage_info));
if ( munmap(tmp_hpi, sizeof(struct hugepage_info)) < 0) {
RTE_LOG(ERR, EAL, "Failed to unmap shared memory!\n");
return -1;
}
return 0;
}

View File

@ -0,0 +1,71 @@
/*-
* 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_common.h>
#include <rte_interrupts.h>
#include "eal_private.h"
int
rte_intr_callback_register(struct rte_intr_handle *intr_handle __rte_unused,
rte_intr_callback_fn cb __rte_unused,
void *cb_arg __rte_unused)
{
return -ENOTSUP;
}
int
rte_intr_callback_unregister(struct rte_intr_handle *intr_handle __rte_unused,
rte_intr_callback_fn cb_fn __rte_unused,
void *cb_arg __rte_unused)
{
return -ENOTSUP;
}
int
rte_intr_enable(struct rte_intr_handle *intr_handle __rte_unused)
{
return -ENOTSUP;
}
int
rte_intr_disable(struct rte_intr_handle *intr_handle __rte_unused)
{
return -ENOTSUP;
}
int
rte_eal_intr_init(void)
{
return 0;
}

View File

@ -0,0 +1,102 @@
/*-
* 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 <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 "eal_private.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)
{
int mib[2] = {CTL_HW, HW_NCPU};
int ncpu;
size_t len = sizeof(ncpu);
sysctl(mib, 2, &ncpu, &len, NULL, 0);
RTE_LOG(INFO, EAL, "Sysctl reports %d cpus\n", ncpu);
return ncpu;
}
/*
* 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)
{
/* pointer to global configuration */
struct rte_config *config = rte_eal_get_configuration();
unsigned lcore_id;
unsigned count = 0;
const unsigned ncpus = get_ncpus();
/* disable lcores that were not detected */
RTE_LCORE_FOREACH(lcore_id) {
lcore_config[lcore_id].detected = (lcore_id < ncpus);
if (lcore_config[lcore_id].detected == 0) {
RTE_LOG(DEBUG, EAL, "Skip lcore %u (not detected)\n", lcore_id);
config->lcore_role[lcore_id] = ROLE_OFF;
continue;
}
count++;
lcore_config[lcore_id].core_id = cpu_core_id(lcore_id);
lcore_config[lcore_id].socket_id = 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;
#else
rte_panic("Socket ID (%u) is greater than "
"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);
}
config->lcore_count = count;
return 0;
}

View File

@ -0,0 +1,57 @@
/*-
* 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 <stdio.h>
#include <rte_common.h>
#include <rte_log.h>
#include <eal_private.h>
/*
* set the log to default function, called during eal init process,
* once memzones are available.
*/
int
rte_eal_log_init(const char *id __rte_unused, int facility __rte_unused)
{
if (rte_eal_common_log_init(stderr) < 0)
return -1;
return 0;
}
int
rte_eal_log_early_init(void)
{
rte_openlog_stream(stderr);
return 0;
}

View File

@ -0,0 +1,212 @@
/*-
* 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"
#define PAGE_SIZE (sysconf(_SC_PAGESIZE))
static int
rte_eal_contigmem_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;
}
/* map all hugepages and sort them */
for (i = 0; i < internal_config.num_hugepage_sizes; i ++){
struct hugepage_info *hpi;
hpi = &internal_config.hugepage_info[i];
for (j = 0; j < hpi->num_pages[0]; j++) {
struct rte_memseg *seg;
uint64_t physaddr;
int error;
size_t sysctl_size = sizeof(physaddr);
char physaddr_str[64];
addr = mmap(NULL, hpi->hugepage_sz, PROT_READ|PROT_WRITE,
MAP_SHARED, hpi->lock_descriptor, j * PAGE_SIZE);
if (addr == MAP_FAILED) {
RTE_LOG(ERR, EAL, "Failed to mmap buffer %u from %s\n",
j, hpi->hugedir);
return -1;
}
rte_snprintf(physaddr_str, sizeof(physaddr_str), "hw.contigmem"
".physaddr.%d", j);
error = sysctlbyname(physaddr_str, &physaddr, &sysctl_size,
NULL, 0);
if (error < 0) {
RTE_LOG(ERR, EAL, "Failed to get physical addr for buffer %u "
"from %s\n", j, hpi->hugedir);
return -1;
}
seg = &mcfg->memseg[seg_idx++];
seg->addr = addr;
seg->phys_addr = physaddr;
seg->hugepage_sz = hpi->hugepage_sz;
seg->len = hpi->hugepage_sz;
seg->nchannel = mcfg->nchannel;
seg->nrank = mcfg->nrank;
seg->socket_id = 0;
RTE_LOG(INFO, EAL, "Mapped memory segment %u @ %p: physaddr:0x%"
PRIx64", len %zu\n",
seg_idx, addr, physaddr, hpi->hugepage_sz);
if (total_mem >= internal_config.memory ||
seg_idx >= RTE_MAX_MEMSEG)
break;
}
}
return 0;
}
static int
rte_eal_contigmem_attach(void)
{
const struct hugepage_info *hpi;
int fd_hugepage_info, fd_hugepage = -1;
unsigned i = 0;
struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
/* Obtain a file descriptor for hugepage_info */
fd_hugepage_info = open(eal_hugepage_info_path(), O_RDONLY);
if (fd_hugepage_info < 0) {
RTE_LOG(ERR, EAL, "Could not open %s\n", eal_hugepage_info_path());
return -1;
}
/* Map the shared hugepage_info into the process address spaces */
hpi = mmap(NULL, sizeof(struct hugepage_info), PROT_READ, MAP_PRIVATE,
fd_hugepage_info, 0);
if (hpi == NULL) {
RTE_LOG(ERR, EAL, "Could not mmap %s\n", eal_hugepage_info_path());
goto error;
}
/* Obtain a file descriptor for contiguous memory */
fd_hugepage = open(hpi->hugedir, O_RDWR);
if (fd_hugepage < 0) {
RTE_LOG(ERR, EAL, "Could not open %s\n", hpi->hugedir);
goto error;
}
/* Map the contiguous memory into each memory segment */
for (i = 0; i < hpi->num_pages[0]; i++) {
void *addr;
struct rte_memseg *seg = &mcfg->memseg[i];
addr = mmap(seg->addr, hpi->hugepage_sz, PROT_READ|PROT_WRITE,
MAP_SHARED|MAP_FIXED, fd_hugepage, i * PAGE_SIZE);
if (addr == MAP_FAILED || addr != seg->addr) {
RTE_LOG(ERR, EAL, "Failed to mmap buffer %u from %s\n",
i, hpi->hugedir);
goto error;
}
}
/* hugepage_info is no longer required */
munmap((void *)(uintptr_t)hpi, sizeof(struct hugepage_info));
close(fd_hugepage_info);
close(fd_hugepage);
return 0;
error:
if (fd_hugepage_info >= 0)
close(fd_hugepage_info);
if (fd_hugepage >= 0)
close(fd_hugepage);
return -1;
}
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 physically contiguous memory...\n");
const int retval = rte_eal_process_type() == RTE_PROC_PRIMARY ?
rte_eal_contigmem_init() :
rte_eal_contigmem_attach();
if (retval < 0)
return -1;
if (internal_config.no_shconf == 0 && rte_eal_memdevice_init() < 0)
return -1;
return 0;
}

View File

@ -0,0 +1,519 @@
/*-
* 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 <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdarg.h>
#include <errno.h>
#include <dirent.h>
#include <limits.h>
#include <sys/queue.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/pciio.h>
#include <dev/pci/pcireg.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_tailq.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_pci_dev_ids.h"
#include "eal_filesystem.h"
#include "eal_private.h"
/**
* @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;
/* forward prototype of function called in pci_switch_module below */
static int pci_uio_map_resource(struct rte_pci_device *dev);
/* map a particular resource from a file */
static void *
pci_map_resource(struct rte_pci_device *dev, void *requested_addr,
const char *devname, off_t offset, size_t size)
{
int fd;
void *mapaddr;
/*
* open devname, to mmap it
*/
fd = open(devname, O_RDWR);
if (fd < 0) {
RTE_LOG(ERR, EAL, "Cannot open %s: %s\n",
devname, strerror(errno));
goto fail;
}
/* Map the PCI memory resource of device */
mapaddr = mmap(requested_addr, size, PROT_READ | PROT_WRITE,
MAP_SHARED, fd, offset);
if (mapaddr == MAP_FAILED ||
(requested_addr != NULL && mapaddr != requested_addr)) {
RTE_LOG(ERR, EAL, "%s(): cannot mmap(%s(%d), %p, 0x%lx, 0x%lx):"
" %s (%p)\n", __func__, devname, fd, requested_addr,
(unsigned long)size, (unsigned long)offset,
strerror(errno), mapaddr);
close(fd);
goto fail;
}
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
/* save fd if in primary process */
dev->intr_handle.fd = fd;
dev->intr_handle.type = RTE_INTR_HANDLE_UIO;
} else {
/* fd is not needed in slave process, close it */
dev->intr_handle.fd = -1;
dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
close(fd);
}
RTE_LOG(DEBUG, EAL, " PCI memory mapped at %p\n", mapaddr);
return mapaddr;
fail:
dev->intr_handle.fd = -1;
dev->intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
return NULL;
}
#ifndef OFF_MAX
#define OFF_MAX ((uint64_t)(off_t)-1)
#endif
static int
pci_uio_map_secondary(struct rte_pci_device *dev)
{
size_t i;
struct uio_resource *uio_res;
TAILQ_FOREACH(uio_res, uio_res_list, next) {
/* skip this element if it doesn't match our PCI address */
if (memcmp(&uio_res->pci_addr, &dev->addr, sizeof(dev->addr)))
continue;
for (i = 0; i != uio_res->nb_maps; i++) {
if (pci_map_resource(dev, uio_res->maps[i].addr,
uio_res->path,
(off_t)uio_res->maps[i].offset,
(size_t)uio_res->maps[i].size) !=
uio_res->maps[i].addr) {
RTE_LOG(ERR, EAL,
"Cannot mmap device resource\n");
return (-1);
}
}
return (0);
}
RTE_LOG(ERR, EAL, "Cannot find resource for device\n");
return -1;
}
/* map the PCI resource of a PCI device in virtual memory */
static int
pci_uio_map_resource(struct rte_pci_device *dev)
{
int i, j;
char devname[PATH_MAX]; /* contains the /dev/uioX */
void *mapaddr;
uint64_t phaddr;
uint64_t offset;
uint64_t pagesz;
struct rte_pci_addr *loc = &dev->addr;
struct uio_resource *uio_res;
struct uio_map *maps;
dev->intr_handle.fd = -1;
rte_snprintf(devname, sizeof(devname), "/dev/uio@pci:%u:%u:%u",
dev->addr.bus, dev->addr.devid, dev->addr.function);
if (access(devname, O_RDWR) < 0) {
RTE_LOG(WARNING, EAL, " "PCI_PRI_FMT" not managed by UIO driver, "
"skipping\n", loc->domain, loc->bus, loc->devid, loc->function);
return -1;
}
/* secondary processes - use already recorded details */
if ((rte_eal_process_type() != RTE_PROC_PRIMARY) &&
(dev->id.vendor_id != PCI_VENDOR_ID_QUMRANET))
return (pci_uio_map_secondary(dev));
if(dev->id.vendor_id == PCI_VENDOR_ID_QUMRANET) {
/* I/O port address already assigned */
/* rte_virtio_pmd does not need any other bar even if available */
return (0);
}
/* allocate the mapping details for secondary processes*/
if ((uio_res = rte_zmalloc("UIO_RES", sizeof (*uio_res), 0)) == NULL) {
RTE_LOG(ERR, EAL,
"%s(): cannot store uio mmap details\n", __func__);
return (-1);
}
rte_snprintf(uio_res->path, sizeof(uio_res->path), "%s", devname);
memcpy(&uio_res->pci_addr, &dev->addr, sizeof(uio_res->pci_addr));
/* Map all BARs */
pagesz = sysconf(_SC_PAGESIZE);
maps = uio_res->maps;
for (i = uio_res->nb_maps = 0; i != PCI_MAX_RESOURCE; i++) {
j = uio_res->nb_maps;
/* skip empty BAR */
if ((phaddr = dev->mem_resource[i].phys_addr) == 0)
continue;
/* if matching map is found, then use it */
offset = i * pagesz;
maps[j].offset = offset;
maps[j].phaddr = dev->mem_resource[i].phys_addr;
maps[j].size = dev->mem_resource[i].len;
if (maps[j].addr != NULL ||
(mapaddr = pci_map_resource(dev,
NULL, devname, (off_t)offset,
(size_t)maps[j].size)) == NULL) {
rte_free(uio_res);
return (-1);
}
maps[j].addr = mapaddr;
uio_res->nb_maps++;
dev->mem_resource[i].addr = mapaddr;
}
TAILQ_INSERT_TAIL(uio_res_list, uio_res, next);
return (0);
}
/* parse the "resource" sysfs file */
#define IORESOURCE_MEM 0x00000200
/* Compare two PCI device addresses. */
static int
pci_addr_comparison(struct rte_pci_addr *addr, struct rte_pci_addr *addr2)
{
uint64_t dev_addr = (addr->domain << 24) + (addr->bus << 16) + (addr->devid << 8) + addr->function;
uint64_t dev_addr2 = (addr2->domain << 24) + (addr2->bus << 16) + (addr2->devid << 8) + addr2->function;
if (dev_addr > dev_addr2)
return 1;
else
return 0;
}
/* Scan one pci sysfs entry, and fill the devices list from it. */
static int
pci_scan_one(int dev_pci_fd, struct pci_conf *conf)
{
struct rte_pci_device *dev;
struct pci_bar_io bar;
unsigned i, max;
dev = malloc(sizeof(*dev));
if (dev == NULL) {
return -1;
}
memset(dev, 0, sizeof(*dev));
dev->addr.domain = conf->pc_sel.pc_domain;
dev->addr.bus = conf->pc_sel.pc_bus;
dev->addr.devid = conf->pc_sel.pc_dev;
dev->addr.function = conf->pc_sel.pc_func;
/* get vendor id */
dev->id.vendor_id = conf->pc_vendor;
/* get device id */
dev->id.device_id = conf->pc_device;
/* get subsystem_vendor id */
dev->id.subsystem_vendor_id = conf->pc_subvendor;
/* get subsystem_device id */
dev->id.subsystem_device_id = conf->pc_subdevice;
/* TODO: get max_vfs */
dev->max_vfs = 0;
/* FreeBSD has no NUMA support (yet) */
dev->numa_node = 0;
/* parse resources */
switch (conf->pc_hdr & PCIM_HDRTYPE) {
case PCIM_HDRTYPE_NORMAL:
max = PCIR_MAX_BAR_0;
break;
case PCIM_HDRTYPE_BRIDGE:
max = PCIR_MAX_BAR_1;
break;
case PCIM_HDRTYPE_CARDBUS:
max = PCIR_MAX_BAR_2;
break;
default:
goto skipdev;
}
for (i = 0; i <= max; i++) {
bar.pbi_sel = conf->pc_sel;
bar.pbi_reg = PCIR_BAR(i);
if (ioctl(dev_pci_fd, PCIOCGETBAR, &bar) < 0)
continue;
dev->mem_resource[i].len = bar.pbi_length;
if (PCI_BAR_IO(bar.pbi_base)) {
dev->mem_resource[i].addr = (void *)(bar.pbi_base & ~((uint64_t)0xf));
continue;
}
dev->mem_resource[i].phys_addr = bar.pbi_base & ~((uint64_t)0xf);
}
/* device is valid, add in list (sorted) */
if (TAILQ_EMPTY(&device_list)) {
TAILQ_INSERT_TAIL(&device_list, dev, next);
}
else {
struct rte_pci_device *dev2 = NULL;
TAILQ_FOREACH(dev2, &device_list, next) {
if (pci_addr_comparison(&dev->addr, &dev2->addr))
continue;
else {
TAILQ_INSERT_BEFORE(dev2, dev, next);
return 0;
}
}
TAILQ_INSERT_TAIL(&device_list, dev, next);
}
return 0;
skipdev:
free(dev);
return 0;
}
/*
* 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)
{
int fd = -1;
unsigned dev_count = 0;
struct pci_conf matches[16];
struct pci_conf_io conf_io = {
.pat_buf_len = 0,
.num_patterns = 0,
.patterns = NULL,
.match_buf_len = sizeof(matches),
.matches = &matches[0],
};
fd = open("/dev/pci", O_RDONLY);
if (fd < 0) {
RTE_LOG(ERR, EAL, "%s(): error opening /dev/pci\n", __func__);
goto error;
}
do {
unsigned i;
if (ioctl(fd, PCIOCGETCONF, &conf_io) < 0) {
RTE_LOG(ERR, EAL, "%s(): error with ioctl on /dev/pci: %s\n",
__func__, strerror(errno));
goto error;
}
for (i = 0; i < conf_io.num_matches; i++)
if (pci_scan_one(fd, &matches[i]) < 0)
goto error;
dev_count += conf_io.num_matches;
} while(conf_io.status == PCI_GETCONF_MORE_DEVS);
close(fd);
RTE_LOG(ERR, EAL, "PCI scan found %u devices\n", dev_count);
return 0;
error:
if (fd >= 0)
close(fd);
return -1;
}
/*
* 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;
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->blacklisted) {
RTE_LOG(DEBUG, EAL, " Device is blacklisted, not initializing\n");
return 0;
}
/* just map the NIC resources */
if (pci_uio_map_resource(dev) < 0)
return -1;
/* We always should have BAR0 mapped */
if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
dev->mem_resource[0].addr == NULL) {
RTE_LOG(ERR, EAL,
"%s(): BAR0 is not mapped\n",
__func__);
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(&driver_list);
TAILQ_INIT(&device_list);
uio_res_list = RTE_TAILQ_RESERVE_BY_IDX(RTE_TAILQ_PCI, 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;
}

View File

@ -0,0 +1,233 @@
/*-
* 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 <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <sched.h>
#include <pthread_np.h>
#include <sys/queue.h>
#include <rte_debug.h>
#include <rte_atomic.h>
#include <rte_launch.h>
#include <rte_log.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_per_lcore.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include "eal_private.h"
#include "eal_thread.h"
RTE_DEFINE_PER_LCORE(unsigned, _lcore_id);
/*
* Send a message to a slave lcore identified by slave_id to call a
* function f with argument arg. Once the execution is done, the
* remote lcore switch in FINISHED state.
*/
int
rte_eal_remote_launch(int (*f)(void *), void *arg, unsigned slave_id)
{
int n;
char c = 0;
int m2s = lcore_config[slave_id].pipe_master2slave[1];
int s2m = lcore_config[slave_id].pipe_slave2master[0];
if (lcore_config[slave_id].state != WAIT)
return -EBUSY;
lcore_config[slave_id].f = f;
lcore_config[slave_id].arg = arg;
/* send message */
n = 0;
while (n == 0 || (n < 0 && errno == EINTR))
n = write(m2s, &c, 1);
if (n < 0)
rte_panic("cannot write on configuration pipe\n");
/* wait ack */
do {
n = read(s2m, &c, 1);
} while (n < 0 && errno == EINTR);
if (n <= 0)
rte_panic("cannot read on configuration pipe\n");
return 0;
}
/* set affinity for current thread */
static int
eal_thread_set_affinity(void)
{
int s;
pthread_t thread;
/*
* According to the section VERSIONS of the CPU_ALLOC man page:
*
* The CPU_ZERO(), CPU_SET(), CPU_CLR(), and CPU_ISSET() macros were added
* in glibc 2.3.3.
*
* CPU_COUNT() first appeared in glibc 2.6.
*
* CPU_AND(), CPU_OR(), CPU_XOR(), CPU_EQUAL(), CPU_ALLOC(),
* CPU_ALLOC_SIZE(), CPU_FREE(), CPU_ZERO_S(), CPU_SET_S(), CPU_CLR_S(),
* CPU_ISSET_S(), CPU_AND_S(), CPU_OR_S(), CPU_XOR_S(), and CPU_EQUAL_S()
* first appeared in glibc 2.7.
*/
#if defined(CPU_ALLOC)
size_t size;
cpu_set_t *cpusetp;
cpusetp = CPU_ALLOC(RTE_MAX_LCORE);
if (cpusetp == NULL) {
RTE_LOG(ERR, EAL, "CPU_ALLOC failed\n");
return -1;
}
size = CPU_ALLOC_SIZE(RTE_MAX_LCORE);
CPU_ZERO_S(size, cpusetp);
CPU_SET_S(rte_lcore_id(), size, cpusetp);
thread = pthread_self();
s = pthread_setaffinity_np(thread, size, cpusetp);
if (s != 0) {
RTE_LOG(ERR, EAL, "pthread_setaffinity_np failed\n");
CPU_FREE(cpusetp);
return -1;
}
CPU_FREE(cpusetp);
#else /* CPU_ALLOC */
cpuset_t cpuset;
CPU_ZERO( &cpuset );
CPU_SET( rte_lcore_id(), &cpuset );
thread = pthread_self();
s = pthread_setaffinity_np(thread, sizeof( cpuset ), &cpuset);
if (s != 0) {
RTE_LOG(ERR, EAL, "pthread_setaffinity_np failed\n");
return -1;
}
#endif
return 0;
}
void eal_thread_init_master(unsigned lcore_id)
{
/* set the lcore ID in per-lcore memory area */
RTE_PER_LCORE(_lcore_id) = lcore_id;
/* set CPU affinity */
if (eal_thread_set_affinity() < 0)
rte_panic("cannot set affinity\n");
}
/* main loop of threads */
__attribute__((noreturn)) void *
eal_thread_loop(__attribute__((unused)) void *arg)
{
char c;
int n, ret;
unsigned lcore_id;
pthread_t thread_id;
int m2s, s2m;
thread_id = pthread_self();
/* retrieve our lcore_id from the configuration structure */
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (thread_id == lcore_config[lcore_id].thread_id)
break;
}
if (lcore_id == RTE_MAX_LCORE)
rte_panic("cannot retrieve lcore id\n");
RTE_LOG(DEBUG, EAL, "Core %u is ready (tid=%p)\n",
lcore_id, thread_id);
m2s = lcore_config[lcore_id].pipe_master2slave[0];
s2m = lcore_config[lcore_id].pipe_slave2master[1];
/* set the lcore ID in per-lcore memory area */
RTE_PER_LCORE(_lcore_id) = lcore_id;
/* set CPU affinity */
if (eal_thread_set_affinity() < 0)
rte_panic("cannot set affinity\n");
/* read on our pipe to get commands */
while (1) {
void *fct_arg;
/* wait command */
do {
n = read(m2s, &c, 1);
} while (n < 0 && errno == EINTR);
if (n <= 0)
rte_panic("cannot read on configuration pipe\n");
lcore_config[lcore_id].state = RUNNING;
/* send ack */
n = 0;
while (n == 0 || (n < 0 && errno == EINTR))
n = write(s2m, &c, 1);
if (n < 0)
rte_panic("cannot write on configuration pipe\n");
if (lcore_config[lcore_id].f == NULL)
rte_panic("NULL function pointer\n");
/* call the function and store the return value */
fct_arg = lcore_config[lcore_id].arg;
ret = lcore_config[lcore_id].f(fct_arg);
lcore_config[lcore_id].ret = ret;
rte_wmb();
lcore_config[lcore_id].state = FINISHED;
}
/* never reached */
/* pthread_exit(NULL); */
/* return NULL; */
}

View File

@ -0,0 +1,308 @@
/*-
* 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 <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/queue.h>
#include <pthread.h>
#include <errno.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_cycles.h>
#include <rte_tailq.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"
enum timer_source eal_timer_source = EAL_TIMER_HPET;
/* The frequency of the RDTSC timer resolution */
static uint64_t eal_tsc_resolution_hz = 0;
#ifdef RTE_LIBEAL_USE_HPET
#define DEV_HPET "/dev/hpet"
/* Maximum number of counters. */
#define HPET_TIMER_NUM 3
/* General capabilities register */
#define CLK_PERIOD_SHIFT 32 /* Clock period shift. */
#define CLK_PERIOD_MASK 0xffffffff00000000ULL /* Clock period mask. */
#define COUNT_SIZE_CAP_SHIFT 13 /* Count size capa. shift. */
#define COUNT_SIZE_CAP_MASK 0x0000000000002000ULL /* Count size capa. mask. */
/**
* HPET timer registers. From the Intel IA-PC HPET (High Precision Event
* Timers) Specification.
*/
struct eal_hpet_regs {
/* Memory-mapped, software visible registers */
uint64_t capabilities; /**< RO General Capabilities Register. */
uint64_t reserved0; /**< Reserved for future use. */
uint64_t config; /**< RW General Configuration Register. */
uint64_t reserved1; /**< Reserved for future use. */
uint64_t isr; /**< RW Clear General Interrupt Status. */
uint64_t reserved2[25]; /**< Reserved for future use. */
union {
uint64_t counter; /**< RW Main Counter Value Register. */
struct {
uint32_t counter_l; /**< RW Main Counter Low. */
uint32_t counter_h; /**< RW Main Counter High. */
};
};
uint64_t reserved3; /**< Reserved for future use. */
struct {
uint64_t config; /**< RW Timer Config and Capability Reg. */
uint64_t comp; /**< RW Timer Comparator Value Register. */
uint64_t fsb; /**< RW FSB Interrupt Route Register. */
uint64_t reserved4; /**< Reserved for future use. */
} timers[HPET_TIMER_NUM]; /**< Set of HPET timers. */
};
/* Mmap'd hpet registers */
static volatile struct eal_hpet_regs *eal_hpet = NULL;
/* Period at which the HPET counter increments in
* femtoseconds (10^-15 seconds). */
static uint32_t eal_hpet_resolution_fs = 0;
/* Frequency of the HPET counter in Hz */
static uint64_t eal_hpet_resolution_hz = 0;
/* Incremented 4 times during one 32bits hpet full count */
static uint32_t eal_hpet_msb;
static pthread_t msb_inc_thread_id;
/*
* This function runs on a specific thread to update a global variable
* containing used to process MSB of the HPET (unfortunatelly, we need
* this because hpet is 32 bits by default under linux).
*/
static void
hpet_msb_inc(__attribute__((unused)) void *arg)
{
uint32_t t;
while (1) {
t = (eal_hpet->counter_l >> 30);
if (t != (eal_hpet_msb & 3))
eal_hpet_msb ++;
sleep(10);
}
}
uint64_t
rte_get_hpet_hz(void)
{
if(internal_config.no_hpet)
rte_panic("Error, HPET called, but no HPET present\n");
return eal_hpet_resolution_hz;
}
uint64_t
rte_get_hpet_cycles(void)
{
uint32_t t, msb;
uint64_t ret;
if(internal_config.no_hpet)
rte_panic("Error, HPET called, but no HPET present\n");
t = eal_hpet->counter_l;
msb = eal_hpet_msb;
ret = (msb + 2 - (t >> 30)) / 4;
ret <<= 32;
ret += t;
return ret;
}
#endif
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;
}
#ifdef RTE_LIBEAL_USE_HPET
/*
* Open and mmap /dev/hpet (high precision event timer) that will
* provide our time reference.
*/
int
rte_eal_hpet_init(int make_default)
{
int fd, ret;
if (internal_config.no_hpet) {
RTE_LOG(INFO, EAL, "HPET is disabled\n");
return -1;
}
fd = open(DEV_HPET, O_RDONLY);
if (fd < 0) {
RTE_LOG(ERR, EAL, "ERROR: Cannot open "DEV_HPET": %s!\n",
strerror(errno));
internal_config.no_hpet = 1;
return -1;
}
eal_hpet = mmap(NULL, 1024, PROT_READ, MAP_SHARED, fd, 0);
if (eal_hpet == MAP_FAILED) {
RTE_LOG(ERR, EAL, "ERROR: Cannot mmap "DEV_HPET"!\n"
"Please enable CONFIG_HPET_MMAP in your kernel configuration "
"to allow HPET support.\n"
"To run without using HPET, set CONFIG_RTE_LIBEAL_USE_HPET=n "
"in your build configuration or use '--no-hpet' EAL flag.\n");
close(fd);
internal_config.no_hpet = 1;
return -1;
}
close(fd);
eal_hpet_resolution_fs = (uint32_t)((eal_hpet->capabilities &
CLK_PERIOD_MASK) >>
CLK_PERIOD_SHIFT);
eal_hpet_resolution_hz = (1000ULL*1000ULL*1000ULL*1000ULL*1000ULL) /
(uint64_t)eal_hpet_resolution_fs;
RTE_LOG(INFO, EAL, "HPET frequency is ~%"PRIu64" kHz\n",
eal_hpet_resolution_hz/1000);
eal_hpet_msb = (eal_hpet->counter_l >> 30);
/* create a thread that will increment a global variable for
* msb (hpet is 32 bits by default under linux) */
ret = pthread_create(&msb_inc_thread_id, NULL,
(void *(*)(void *))hpet_msb_inc, NULL);
if (ret < 0) {
RTE_LOG(ERR, EAL, "ERROR: Cannot create HPET timer thread!\n");
internal_config.no_hpet = 1;
return -1;
}
if (make_default)
eal_timer_source = EAL_TIMER_HPET;
return 0;
}
#endif
static int
set_tsc_freq_from_clock(void)
{
#ifdef CLOCK_MONOTONIC_RAW
#define NS_PER_SEC 1E9
struct timespec sleeptime = {.tv_nsec = 5E8 }; /* 1/2 second */
struct timespec t_start, t_end;
if (clock_gettime(CLOCK_MONOTONIC_RAW, &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;
}
#endif
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;
}
/*
* This function measures the TSC frequency. It uses a variety of approaches.
*
* 1. If kernel provides CLOCK_MONOTONIC_RAW we use that to tune the TSC value
* 2. If kernel does not provide that, and we have HPET support, tune using HPET
* 3. Lastly, if neither of the above can be used, just sleep for 1 second and
* tune off that, printing a warning about inaccuracy of timing
*/
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)
{
eal_timer_source = EAL_TIMER_TSC;
set_tsc_freq();
return 0;
}

View File

@ -0,0 +1,118 @@
/*-
* 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.
*/
/**
* @file
* Stores functions and path defines for files and directories
* on the filesystem for Linux, that are used by the Linux EAL.
*/
#ifndef _EAL_LINUXAPP_FILESYSTEM_H
#define _EAL_LINUXAPP_FILESYSTEM_H
/** Path of rte config file. */
#define RUNTIME_CONFIG_FMT "%s/.%s_config"
#include <stdint.h>
#include <limits.h>
#include <unistd.h>
#include <stdlib.h>
#include <rte_string_fns.h>
#include "eal_internal_cfg.h"
static const char *default_config_dir = "/var/run";
static inline const char *
eal_runtime_config_path(void)
{
static char buffer[PATH_MAX]; /* static so auto-zeroed */
const char *directory = default_config_dir;
const char *home_dir = getenv("HOME");
if (getuid() != 0 && home_dir != NULL)
directory = home_dir;
rte_snprintf(buffer, sizeof(buffer) - 1, RUNTIME_CONFIG_FMT, directory,
internal_config.hugefile_prefix);
return buffer;
}
/** Path of hugepage info file. */
#define HUGEPAGE_INFO_FMT "%s/.%s_hugepage_info"
static inline const char *
eal_hugepage_info_path(void)
{
static char buffer[PATH_MAX]; /* static so auto-zeroed */
const char *directory = default_config_dir;
const char *home_dir = getenv("HOME");
if (getuid() != 0 && home_dir != NULL)
directory = home_dir;
rte_snprintf(buffer, sizeof(buffer) - 1, HUGEPAGE_INFO_FMT, directory,
internal_config.hugefile_prefix);
return buffer;
}
/** String format for hugepage map files. */
#define HUGEFILE_FMT "%s/%smap_%d"
#define TEMP_HUGEFILE_FMT "%s/%smap_temp_%d"
static inline const char *
eal_get_hugefile_path(char *buffer, size_t buflen, const char *hugedir, int f_id)
{
rte_snprintf(buffer, buflen, HUGEFILE_FMT, hugedir,
internal_config.hugefile_prefix, f_id);
buffer[buflen - 1] = '\0';
return buffer;
}
#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
static inline const char *
eal_get_hugefile_temp_path(char *buffer, size_t buflen, const char *hugedir, int f_id)
{
rte_snprintf(buffer, buflen, TEMP_HUGEFILE_FMT, hugedir,
internal_config.hugefile_prefix, f_id);
buffer[buflen - 1] = '\0';
return buffer;
}
#endif
/** define the default filename prefix for the %s values above */
#define HUGEFILE_PREFIX_DEFAULT "rte"
/** Function to read a single numeric value from a file on the filesystem.
* Used to read information from files on /sys */
int eal_parse_sysfs_value(const char *filename, unsigned long *val);
#endif /* _EAL_LINUXAPP_FILESYSTEM_H */

View File

@ -0,0 +1,67 @@
/*-
* 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.
*/
#ifndef RTE_LINUXAPP_HUGEPAGES_H_
#define RTE_LINUXAPP_HUGEPAGES_H_
#include <stddef.h>
#include <stdint.h>
#include <limits.h>
#define MAX_HUGEPAGE_PATH PATH_MAX
/**
* Structure used to store informations about hugepages that we mapped
* through the files in hugetlbfs.
*/
struct hugepage_file {
void *orig_va; /**< virtual addr of first mmap() */
void *final_va; /**< virtual addr of 2nd mmap() */
uint64_t physaddr; /**< physical addr */
size_t size; /**< the page size */
int socket_id; /**< NUMA socket ID */
int file_id; /**< the '%d' in HUGEFILE_FMT */
int memseg_id; /**< the memory segment to which page belongs */
#ifdef RTE_EAL_SINGLE_FILE_SEGMENTS
int repeated; /**< number of times the page size is repeated */
#endif
char filepath[MAX_HUGEPAGE_PATH]; /**< path to backing file on filesystem */
};
/**
* Read the information from linux on what hugepages are available
* for the EAL to use
*/
int eal_hugepage_info_init(void);
#endif /* EAL_HUGEPAGES_H_ */

View File

@ -0,0 +1,86 @@
/*-
* 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.
*/
/**
* @file
* Holds the structures for the eal internal configuration
*/
#ifndef _EAL_LINUXAPP_INTERNAL_CFG
#define _EAL_LINUXAPP_INTERNAL_CFG
#include <rte_eal.h>
#define MAX_HUGEPAGE_SIZES 3 /**< support up to 3 page sizes */
/*
* internal configuration structure for the number, size and
* mount points of hugepages
*/
struct hugepage_info {
size_t hugepage_sz; /**< size of a huge page */
const char *hugedir; /**< dir where hugetlbfs is mounted */
uint32_t num_pages[RTE_MAX_NUMA_NODES];
/**< number of hugepages of that size on each socket */
int lock_descriptor; /**< file descriptor for hugepage dir */
};
/**
* internal configuration
*/
struct internal_config {
volatile size_t memory; /**< amount of asked memory */
volatile unsigned force_nchannel; /**< force number of channels */
volatile unsigned force_nrank; /**< force number of ranks */
volatile unsigned no_hugetlbfs; /**< true to disable hugetlbfs */
volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
volatile unsigned no_pci; /**< true to disable PCI */
volatile unsigned no_hpet; /**< true to disable HPET */
volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
* instead of native TSC */
volatile unsigned no_shconf; /**< true if there is no shared config */
volatile enum rte_proc_type_t process_type; /* multi-process proc type */
/* true to try allocating memory on specific sockets */
volatile unsigned force_sockets;
volatile uint64_t socket_mem[RTE_MAX_NUMA_NODES]; /**< amount of memory per socket */
uintptr_t base_virtaddr; /**< base address to try and reserve memory from */
volatile int syslog_facility; /**< facility passed to openlog() */
const char *hugefile_prefix; /**< the base filename of hugetlbfs files */
const char *hugepage_dir; /**< specific hugetlbfs directory to use */
unsigned num_hugepage_sizes; /**< how many sizes on this system */
struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
};
extern struct internal_config internal_config; /**< Global EAL configuration. */
#endif

View File

@ -0,0 +1,53 @@
/*-
* 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.
*/
#ifndef _EAL_LINUXAPP_THREAD_H_
#define _EAL_LINUXAPP_THREAD_H_
/**
* basic loop of thread, called for each thread by eal_init().
*
* @param arg
* opaque pointer
*/
__attribute__((noreturn)) void *eal_thread_loop(void *arg);
/**
* Init per-lcore info for master thread
*
* @param lcore_id
* identifier of master lcore
*/
void eal_thread_init_master(unsigned lcore_id);
#endif /* _EAL_LINUXAPP_PRIVATE_H_ */

View File

@ -0,0 +1,107 @@
/*-
* This file is provided under a dual BSD/LGPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GNU LESSER GENERAL PUBLIC LICENSE
*
* Copyright(c) 2007-2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
* Contact Information:
* Intel Corporation
*
*
* 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.
*
*/
#ifndef _RTE_DOM0_COMMON_H_
#define _RTE_DOM0_COMMON_H_
#ifdef __KERNEL__
#include <linux/if.h>
#endif
#define DOM0_NAME_MAX 256
#define DOM0_MM_DEV "/dev/dom0_mm"
#define DOM0_CONTIG_NUM_ORDER 9 /**< 2M order */
#define DOM0_NUM_MEMSEG 512 /**< Maximum nb. of memory segment. */
#define DOM0_MEMBLOCK_SIZE 0x200000 /**< Maximum nb. of memory block(2M). */
#define DOM0_CONFIG_MEMSIZE 4096 /**< Maximum config memory size(4G). */
#define DOM0_NUM_MEMBLOCK (DOM0_CONFIG_MEMSIZE / 2) /**< Maximum nb. of 2M memory block. */
#define RTE_DOM0_IOCTL_PREPARE_MEMSEG _IOWR(0, 1 , struct memory_info)
#define RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG _IOWR(0, 2 , char *)
#define RTE_DOM0_IOCTL_GET_NUM_MEMSEG _IOWR(0, 3, int)
#define RTE_DOM0_IOCTL_GET_MEMSEG_INFO _IOWR(0, 4, void *)
/**
* A structure used to store memory information.
*/
struct memory_info {
char name[DOM0_NAME_MAX];
uint64_t size;
};
/**
* A structure used to store memory segment information.
*/
struct memseg_info {
uint32_t idx;
uint64_t pfn;
uint64_t size;
uint64_t mfn[DOM0_NUM_MEMBLOCK];
};
/**
* A structure used to store memory block information.
*/
struct memblock_info {
uint8_t exchange_flag;
uint64_t vir_addr;
uint64_t pfn;
uint64_t mfn;
};
#endif /* _RTE_DOM0_COMMON_H_ */

View File

@ -0,0 +1,54 @@
/*-
* 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.
*/
#ifndef _RTE_INTERRUPTS_H_
#error "don't include this file directly, please include generic <rte_interrupts.h>"
#endif
#ifndef _RTE_LINUXAPP_INTERRUPTS_H_
#define _RTE_LINUXAPP_INTERRUPTS_H_
enum rte_intr_handle_type {
RTE_INTR_HANDLE_UNKNOWN = 0,
RTE_INTR_HANDLE_UIO, /**< uio device handle */
RTE_INTR_HANDLE_ALARM, /**< alarm handle */
RTE_INTR_HANDLE_MAX
};
/** Handle for interrupts. */
struct rte_intr_handle {
int fd; /**< file descriptor */
enum rte_intr_handle_type type; /**< handle type */
};
#endif /* _RTE_LINUXAPP_INTERRUPTS_H_ */

View File

@ -0,0 +1,166 @@
/*-
* This file is provided under a dual BSD/LGPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* GNU LESSER GENERAL PUBLIC LICENSE
*
* Copyright(c) 2007-2014 Intel Corporation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2.1 of the GNU Lesser General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*
* Contact Information:
* Intel Corporation
*
*
* 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.
*
*/
#ifndef _RTE_KNI_COMMON_H_
#define _RTE_KNI_COMMON_H_
#ifdef __KERNEL__
#include <linux/if.h>
#endif
/**
* KNI name is part of memzone name.
*/
#define RTE_KNI_NAMESIZE 32
/*
* Request id.
*/
enum rte_kni_req_id {
RTE_KNI_REQ_UNKNOWN = 0,
RTE_KNI_REQ_CHANGE_MTU,
RTE_KNI_REQ_CFG_NETWORK_IF,
RTE_KNI_REQ_MAX,
};
/*
* Structure for KNI request.
*/
struct rte_kni_request {
uint32_t req_id; /**< Request id */
union {
uint32_t new_mtu; /**< New MTU */
uint8_t if_up; /**< 1: interface up, 0: interface down */
};
int32_t result; /**< Result for processing request */
} __attribute__((__packed__));
/*
* Fifo struct mapped in a shared memory. It describes a circular buffer FIFO
* Write and read should wrap arround. Fifo is empty when write == read
* Writing should never overwrite the read position
*/
struct rte_kni_fifo {
volatile unsigned write; /**< Next position to be written*/
volatile unsigned read; /**< Next position to be read */
unsigned len; /**< Circular buffer length */
unsigned elem_size; /**< Pointer size - for 32/64 bit OS */
void * volatile buffer[0]; /**< The buffer contains mbuf pointers */
};
/*
* The kernel image of the rte_mbuf struct, with only the relevant fields.
* Padding is necessary to assure the offsets of these fields
*/
struct rte_kni_mbuf {
void *pool;
void *buf_addr;
char pad0[14];
uint16_t ol_flags; /**< Offload features. */
void *next;
void *data; /**< Start address of data in segment buffer. */
uint16_t data_len; /**< Amount of data in segment buffer. */
char pad2[2];
uint16_t pkt_len; /**< Total pkt len: sum of all segment data_len. */
} __attribute__((__aligned__(64)));
/*
* Struct used to create a KNI device. Passed to the kernel in IOCTL call
*/
struct rte_kni_device_info {
char name[RTE_KNI_NAMESIZE]; /**< Network device name for KNI */
phys_addr_t tx_phys;
phys_addr_t rx_phys;
phys_addr_t alloc_phys;
phys_addr_t free_phys;
/* Used by Ethtool */
phys_addr_t req_phys;
phys_addr_t resp_phys;
phys_addr_t sync_phys;
void * sync_va;
/* mbuf mempool */
void * mbuf_va;
phys_addr_t mbuf_phys;
/* PCI info */
uint16_t vendor_id; /**< Vendor ID or PCI_ANY_ID. */
uint16_t device_id; /**< Device ID or PCI_ANY_ID. */
uint8_t bus; /**< Device bus */
uint8_t devid; /**< Device ID */
uint8_t function; /**< Device function. */
uint16_t group_id; /**< Group ID */
uint32_t core_id; /**< core ID to bind for kernel thread */
uint8_t force_bind : 1; /**< Flag for kernel thread binding */
/* mbuf size */
unsigned mbuf_size;
};
#define KNI_DEVICE "kni"
#define RTE_KNI_IOCTL_TEST _IOWR(0, 1, int)
#define RTE_KNI_IOCTL_CREATE _IOWR(0, 2, struct rte_kni_device_info)
#define RTE_KNI_IOCTL_RELEASE _IOWR(0, 3, struct rte_kni_device_info)
#endif /* _RTE_KNI_COMMON_H_ */

View File

@ -0,0 +1,67 @@
/*-
* 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.
*/
#ifndef _RTE_LCORE_H_
#error "don't include this file directly, please include generic <rte_lcore.h>"
#endif
#ifndef _RTE_LINUXAPP_LCORE_H_
#define _RTE_LINUXAPP_LCORE_H_
/**
* @file
* API for lcore and socket manipulation in linuxapp environment
*/
/**
* structure storing internal configuration (per-lcore)
*/
struct lcore_config {
unsigned detected; /**< true if lcore was detected */
pthread_t thread_id; /**< pthread identifier */
int pipe_master2slave[2]; /**< communication pipe with master */
int pipe_slave2master[2]; /**< communication pipe with master */
lcore_function_t * volatile f; /**< function to call */
void * volatile arg; /**< argument of function */
volatile int ret; /**< return value of function */
volatile enum rte_lcore_state_t state; /**< lcore state */
unsigned socket_id; /**< physical socket id for this lcore */
unsigned core_id; /**< core number on socket for this lcore */
};
/**
* internal configuration (per-lcore)
*/
extern struct lcore_config lcore_config[RTE_MAX_LCORE];
#endif /* _RTE_LINUXAPP_LCORE_H_ */

View File

@ -0,0 +1,67 @@
/*-
* 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.
*/
#ifndef _RTE_PER_LCORE_H_
#error "don't include this file directly, please include generic <rte_per_lcore.h>"
#endif
#ifndef _RTE_LINUXAPP_PER_LCORE_H_
#define _RTE_LINUXAPP_PER_LCORE_H_
/**
* @file
* Per-lcore variables in RTE on linuxapp environment
*/
#include <pthread.h>
/**
* Macro to define a per lcore variable "var" of type "type", don't
* use keywords like "static" or "volatile" in type, just prefix the
* whole macro.
*/
#define RTE_DEFINE_PER_LCORE(type, name) \
__thread __typeof__(type) per_lcore_##name
/**
* Macro to declare an extern per lcore variable "var" of type "type"
*/
#define RTE_DECLARE_PER_LCORE(type, name) \
extern __thread __typeof__(type) per_lcore_##name
/**
* Read/write the per-lcore variable value
*/
#define RTE_PER_LCORE(name) (per_lcore_##name)
#endif /* _RTE_LINUXAPP_PER_LCORE_H_ */

View File

@ -0,0 +1,36 @@
# 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.
#
KMOD= nic_uio
SRCS= nic_uio.c device_if.h bus_if.h pci_if.h
.include <bsd.kmod.mk>

View File

@ -0,0 +1,52 @@
# 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
#
# module name and path
#
MODULE = nic_uio
#
# CFLAGS
#
MODULE_CFLAGS += -I$(SRCDIR)
MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
MODULE_CFLAGS += -Winline -Wall -Werror
MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
#
# all source are stored in SRCS-y
#
SRCS-y := nic_uio.c
include $(RTE_SDK)/mk/rte.bsdmodule.mk

View File

@ -0,0 +1,325 @@
/* -
* 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/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h> /* defines used in kernel.h */
#include <sys/module.h>
#include <sys/kernel.h> /* types used in module initialization */
#include <sys/conf.h> /* cdevsw struct */
#include <sys/bus.h> /* structs, prototypes for pci bus stuff and DEVMETHOD */
#include <sys/rman.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <machine/bus.h>
#include <dev/pci/pcivar.h> /* For pci_get macros! */
#include <dev/pci/pcireg.h> /* The softc holds our per-instance data. */
#include <vm/vm.h>
#include <vm/uma.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>
#include <vm/vm_pager.h>
#define MAX_BARS (PCIR_MAX_BAR_0 + 1)
struct nic_uio_softc {
device_t dev_t;
struct cdev *my_cdev;
int bar_id[MAX_BARS];
struct resource *bar_res[MAX_BARS];
u_long bar_start[MAX_BARS];
u_long bar_size[MAX_BARS];
};
/* Function prototypes */
static d_open_t nic_uio_open;
static d_close_t nic_uio_close;
static d_mmap_t nic_uio_mmap;
static d_mmap_single_t nic_uio_mmap_single;
static int nic_uio_probe(device_t dev);
static int nic_uio_attach(device_t dev);
static int nic_uio_detach(device_t dev);
static int nic_uio_shutdown(void);
static int nic_uio_modevent(module_t mod, int type, void *arg);
static struct cdevsw uio_cdevsw = {
.d_name = "nic_uio",
.d_version = D_VERSION,
.d_open = nic_uio_open,
.d_close = nic_uio_close,
.d_mmap = nic_uio_mmap,
.d_mmap_single = nic_uio_mmap_single,
};
static device_method_t nic_uio_methods[] = {
DEVMETHOD(device_probe, nic_uio_probe),
DEVMETHOD(device_attach, nic_uio_attach),
DEVMETHOD(device_detach, nic_uio_detach),
DEVMETHOD_END
};
struct device {
int vend;
int dev;
};
struct pci_bdf {
uint32_t bus;
uint32_t devid;
uint32_t function;
};
#define RTE_PCI_DEV_ID_DECL_EM(vend, dev) {vend, dev},
#define RTE_PCI_DEV_ID_DECL_IGB(vend, dev) {vend, dev},
#define RTE_PCI_DEV_ID_DECL_IGBVF(vend, dev) {vend, dev},
#define RTE_PCI_DEV_ID_DECL_IXGBE(vend, dev) {vend, dev},
#define RTE_PCI_DEV_ID_DECL_IXGBEVF(vend, dev) {vend, dev},
#define RTE_PCI_DEV_ID_DECL_VIRTIO(vend, dev) {vend, dev},
const struct device devices[] = {
#include <rte_pci_dev_ids.h>
};
#define NUM_DEVICES (sizeof(devices)/sizeof(devices[0]))
static devclass_t nic_uio_devclass;
DEFINE_CLASS_0(nic_uio, nic_uio_driver, nic_uio_methods, sizeof(struct nic_uio_softc));
DRIVER_MODULE(nic_uio, pci, nic_uio_driver, nic_uio_devclass, nic_uio_modevent, 0);
static int
nic_uio_mmap(struct cdev *cdev, vm_ooffset_t offset, vm_paddr_t *paddr,
int prot, vm_memattr_t *memattr)
{
*paddr = offset;
return (0);
}
static int
nic_uio_mmap_single(struct cdev *cdev, vm_ooffset_t *offset, vm_size_t size,
struct vm_object **obj, int nprot)
{
/*
* The BAR index is encoded in the offset. Divide the offset by
* PAGE_SIZE to get the index of the bar requested by the user
* app.
*/
unsigned bar = *offset/PAGE_SIZE;
struct nic_uio_softc *sc = cdev->si_drv1;
if (bar >= MAX_BARS)
return EINVAL;
if (sc->bar_res[bar] == NULL) {
sc->bar_id[bar] = PCIR_BAR(bar);
if (PCI_BAR_IO(pci_read_config(sc->dev_t, sc->bar_id[bar], 4)))
sc->bar_res[bar] = bus_alloc_resource_any(sc->dev_t, SYS_RES_IOPORT,
&sc->bar_id[bar], RF_ACTIVE);
else
sc->bar_res[bar] = bus_alloc_resource_any(sc->dev_t, SYS_RES_MEMORY,
&sc->bar_id[bar], RF_ACTIVE);
}
if (sc->bar_res[bar] == NULL)
return ENXIO;
sc->bar_start[bar] = rman_get_start(sc->bar_res[bar]);
sc->bar_size[bar] = rman_get_size(sc->bar_res[bar]);
device_printf(sc->dev_t, "Bar %u @ %lx, size %lx\n", bar,
sc->bar_start[bar], sc->bar_size[bar]);
*offset = sc->bar_start[bar];
*obj = vm_pager_allocate(OBJT_DEVICE, cdev, size, nprot, *offset,
curthread->td_ucred);
return 0;
}
int
nic_uio_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
{
return 0;
}
int
nic_uio_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
{
return 0;
}
static int
nic_uio_probe (device_t dev)
{
int i;
for (i = 0; i < NUM_DEVICES; i++)
if (pci_get_vendor(dev) == devices[i].vend &&
pci_get_device(dev) == devices[i].dev) {
device_set_desc(dev, "Intel(R) DPDK PCI Device");
return (BUS_PROBE_SPECIFIC);
}
return (ENXIO);
}
static int
nic_uio_attach(device_t dev)
{
int i;
struct nic_uio_softc *sc;
sc = device_get_softc(dev);
sc->dev_t = dev;
sc->my_cdev = make_dev(&uio_cdevsw, device_get_unit(dev),
UID_ROOT, GID_WHEEL, 0600, "uio@pci:%u:%u:%u",
pci_get_bus(dev), pci_get_slot(dev), pci_get_function(dev));
if (sc->my_cdev == NULL)
return ENXIO;
sc->my_cdev->si_drv1 = sc;
for (i = 0; i < MAX_BARS; i++)
sc->bar_res[i] = NULL;
pci_enable_busmaster(dev);
return 0;
}
static int
nic_uio_detach(device_t dev)
{
int i;
struct nic_uio_softc *sc;
sc = device_get_softc(dev);
for (i = 0; i < MAX_BARS; i++)
if (sc->bar_res[i] != NULL) {
if (PCI_BAR_IO(pci_read_config(dev, sc->bar_id[i], 4)))
bus_release_resource(dev, SYS_RES_IOPORT, sc->bar_id[i],
sc->bar_res[i]);
else
bus_release_resource(dev, SYS_RES_MEMORY, sc->bar_id[i],
sc->bar_res[i]);
}
if (sc->my_cdev != NULL)
destroy_dev(sc->my_cdev);
return 0;
}
static void
nic_uio_load(void)
{
uint32_t bus, device, function;
int i;
device_t dev;
char bdf_str[256];
char *token, *remaining;
memset(bdf_str, 0, sizeof(bdf_str));
TUNABLE_STR_FETCH("hw.nic_uio.bdfs", bdf_str, sizeof(bdf_str));
remaining = bdf_str;
/*
* Users should specify PCI BDFs in the format "b:d:f,b:d:f,b:d:f".
* But the code below does not try differentiate between : and ,
* and just blindly uses 3 tokens at a time to construct a
* bus/device/function tuple.
*
* There is no checking on strtol() return values, but this should
* be OK. Worst case is it cannot convert and returns 0. This
* could give us a different BDF than intended, but as long as the
* PCI device/vendor ID does not match it will not matter.
*/
while (1) {
if (remaining == NULL || remaining[0] == '\0')
break;
token = strsep(&remaining, ",:");
if (token == NULL)
break;
bus = strtol(token, NULL, 10);
token = strsep(&remaining, ",:");
if (token == NULL)
break;
device = strtol(token, NULL, 10);
token = strsep(&remaining, ",:");
if (token == NULL)
break;
function = strtol(token, NULL, 10);
dev = pci_find_bsf(bus, device, function);
if (dev != NULL)
for (i = 0; i < NUM_DEVICES; i++)
if (pci_get_vendor(dev) == devices[i].vend &&
pci_get_device(dev) == devices[i].dev)
device_detach(dev);
}
}
static void
nic_uio_unload(void)
{
}
static int
nic_uio_shutdown(void)
{
return (0);
}
static int
nic_uio_modevent(module_t mod, int type, void *arg)
{
switch (type) {
case MOD_LOAD:
nic_uio_load();
break;
case MOD_UNLOAD:
nic_uio_unload();
break;
case MOD_SHUTDOWN:
nic_uio_shutdown();
break;
default:
break;
}
return (0);
}

View File

@ -53,7 +53,11 @@ rte_strerror(int errnum)
* themselves if errnum is too big, we handle that case here */
if (errnum > RTE_MAX_ERRNO)
rte_snprintf(RTE_PER_LCORE(retval), RETVAL_SZ,
#ifdef RTE_EXEC_ENV_BSDAPP
"Unknown error: %d", errnum);
#else
"Unknown error %d", errnum);
#endif
else
switch (errnum){
case E_RTE_SECONDARY:

View File

@ -102,66 +102,6 @@ struct log_cur_msg {
} __rte_cache_aligned;
static struct log_cur_msg log_cur_msg[RTE_MAX_LCORE]; /**< per core log */
/* early logs */
/*
* early log function, used during boot when mempool (hence log
* history) is not available
*/
static ssize_t
early_log_write(__attribute__((unused)) void *c, const char *buf, size_t size)
{
ssize_t ret;
ret = fwrite(buf, size, 1, stdout);
fflush(stdout);
if (ret == 0)
return -1;
return ret;
}
static ssize_t
early_log_read(__attribute__((unused)) void *c,
__attribute__((unused)) char *buf,
__attribute__((unused)) size_t size)
{
return 0;
}
/*
* this is needed because cookies_io_functions_t has a different
* prototype between newlib and glibc
*/
#ifdef RTE_EXEC_ENV_LINUXAPP
static int
early_log_seek(__attribute__((unused)) void *c,
__attribute__((unused)) off64_t *offset,
__attribute__((unused)) int whence)
{
return -1;
}
#else
static int
early_log_seek(__attribute__((unused)) void *c,
__attribute__((unused)) _off_t *offset,
__attribute__((unused)) int whence)
{
return -1;
}
#endif
static int
early_log_close(__attribute__((unused)) void *c)
{
return 0;
}
static cookie_io_functions_t early_log_func = {
.read = early_log_read,
.write = early_log_write,
.seek = early_log_seek,
.close = early_log_close
};
static FILE *early_log_stream;
/* default logs */
@ -342,22 +282,6 @@ rte_log(uint32_t level, uint32_t logtype, const char *format, ...)
return ret;
}
/*
* init the log library, called by rte_eal_init() to enable early
* logs
*/
int
rte_eal_log_early_init(void)
{
early_log_stream = fopencookie(NULL, "w+", early_log_func);
if (early_log_stream == NULL) {
printf("Cannot configure early_log_stream\n");
return -1;
}
rte_openlog_stream(early_log_stream);
return 0;
}
/*
* called by environment-specific log init function to initialize log
* history

View File

@ -54,7 +54,9 @@ enum rte_page_sizes {
};
#define SOCKET_ID_ANY -1 /**< Any NUMA socket. */
#ifndef CACHE_LINE_SIZE
#define CACHE_LINE_SIZE 64 /**< Cache line size. */
#endif
#define CACHE_LINE_MASK (CACHE_LINE_SIZE-1) /**< Cache line mask. */
#define CACHE_LINE_ROUNDUP(size) \

View File

@ -133,3 +133,65 @@ rte_eal_log_init(const char *id, int facility)
return 0;
}
/* early logs */
/*
* early log function, used during boot when mempool (hence log
* history) is not available
*/
static ssize_t
early_log_write(__attribute__((unused)) void *c, const char *buf, size_t size)
{
ssize_t ret;
ret = fwrite(buf, size, 1, stdout);
fflush(stdout);
if (ret == 0)
return -1;
return ret;
}
static ssize_t
early_log_read(__attribute__((unused)) void *c,
__attribute__((unused)) char *buf,
__attribute__((unused)) size_t size)
{
return 0;
}
static int
early_log_seek(__attribute__((unused)) void *c,
__attribute__((unused)) off64_t *offset,
__attribute__((unused)) int whence)
{
return -1;
}
static int
early_log_close(__attribute__((unused)) void *c)
{
return 0;
}
static cookie_io_functions_t early_log_func = {
.read = early_log_read,
.write = early_log_write,
.seek = early_log_seek,
.close = early_log_close
};
static FILE *early_log_stream;
/*
* init the log library, called by rte_eal_init() to enable early
* logs
*/
int
rte_eal_log_early_init(void)
{
early_log_stream = fopencookie(NULL, "w+", early_log_func);
if (early_log_stream == NULL) {
printf("Cannot configure early_log_stream\n");
return -1;
}
rte_openlog_stream(early_log_stream);
return 0;
}

View File

@ -31,8 +31,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <string.h>
#include <sys/user.h>
#include <linux/binfmts.h>
#include <unistd.h>
#include <rte_malloc.h>
#include <rte_log.h>
@ -121,14 +120,14 @@ rte_eth_pcap_tokenize_args(struct args_dict *dict,
return -1;
}
num_of_pairs = rte_strsplit(args, strnlen(args, MAX_ARG_STRLEN), pairs,
num_of_pairs = rte_strsplit(args, strnlen(args, sysconf(_SC_ARG_MAX)), pairs,
RTE_ETH_PCAP_ARG_PARSER_MAX_ARGS, RTE_ETH_PCAP_PAIRS_DELIM);
for (i = 0; i < num_of_pairs; i++) {
pair[0] = NULL;
pair[1] = NULL;
rte_strsplit(pairs[i], strnlen(pairs[i], MAX_ARG_STRLEN), pair, 2,
rte_strsplit(pairs[i], strnlen(pairs[i], sysconf(_SC_ARG_MAX)), pair, 2,
RTE_ETH_PCAP_KEY_VALUE_DELIM);
if (pair[0] == NULL || pair[1] == NULL || pair[0][0] == 0

View File

@ -35,7 +35,13 @@
#define _VIRTIO_PCI_H_
#include <stdint.h>
#ifdef __FreeBSD__
#include <sys/types.h>
#include <machine/cpufunc.h>
#else
#include <sys/io.h>
#endif
#include <rte_ethdev.h>
@ -204,6 +210,28 @@ struct virtio_net_config {
/* The alignment to use between consumer and producer parts of vring. */
#define VIRTIO_PCI_VRING_ALIGN 4096
#ifdef __FreeBSD__
static inline void
outb_p(unsigned char data, unsigned int port)
{
outb(port, (u_char)data);
}
static inline void
outw_p(unsigned short data, unsigned int port)
{
outw(port, (u_short)data);
}
static inline void
outl_p(unsigned int data, unsigned int port)
{
outl(port, (u_int)data);
}
#endif
#define VIRTIO_PCI_REG_ADDR(hw, reg) \
(unsigned short)((hw)->io_base + (reg))

View File

@ -51,7 +51,7 @@ ARCH ?= x86_64
CROSS ?=
CPU_CFLAGS ?= -m64
CPU_LDFLAGS ?= -melf_x86_64
CPU_LDFLAGS ?=
CPU_ASFLAGS ?= -felf64
export ARCH CROSS CPU_CFLAGS CPU_LDFLAGS CPU_ASFLAGS

View File

@ -0,0 +1,36 @@
# 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.
exec-env-appinstall:
@true
exec-env-appclean:
@true

View File

@ -0,0 +1,61 @@
# 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.
#
# exec-env:
#
# - define EXECENV_CFLAGS variable (overriden by cmdline)
# - define EXECENV_LDFLAGS variable (overriden by cmdline)
# - define EXECENV_ASFLAGS variable (overriden by cmdline)
# - may override any previously defined variable
#
# examples for RTE_EXEC_ENV: linuxapp, baremetal
#
ifeq ($(RTE_BUILD_SHARED_LIB),y)
EXECENV_CFLAGS = -pthread -fPIC
else
EXECENV_CFLAGS = -pthread
endif
EXECENV_LDFLAGS =
EXECENV_LDLIBS = -lexecinfo
EXECENV_ASFLAGS =
ifeq ($(RTE_BUILD_SHARED_LIB),y)
EXECENV_LDLIBS += -lgcc_s
endif
# force applications to link with gcc/icc instead of using ld
LINK_USING_CC := 1
BSDMAKE=/usr/bin/make
export EXECENV_CFLAGS EXECENV_LDFLAGS EXECENV_ASFLAGS

118
mk/rte.bsdmodule.mk Normal file
View File

@ -0,0 +1,118 @@
# 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.
##### if sourced from kernel Kbuild system
ifneq ($(KERNELRELEASE),)
override EXTRA_CFLAGS = $(MODULE_CFLAGS) $(EXTRA_KERNEL_CFLAGS)
obj-m += $(MODULE).o
ifneq ($(MODULE),$(notdir $(SRCS-y:%.c=%)))
$(MODULE)-objs += $(notdir $(SRCS-y:%.c=%.o))
endif
##### if launched from rte build system
else
include $(RTE_SDK)/mk/internal/rte.install-pre.mk
include $(RTE_SDK)/mk/internal/rte.clean-pre.mk
include $(RTE_SDK)/mk/internal/rte.build-pre.mk
include $(RTE_SDK)/mk/internal/rte.depdirs-pre.mk
# DPDK uses a more up-to-date gcc, so clear the override here.
unexport CC
# VPATH contains at least SRCDIR
VPATH += $(SRCDIR)
_BUILD = $(MODULE).ko
_INSTALL = $(INSTALL-FILES-y) $(SYMLINK-FILES-y) \
$(RTE_OUTPUT)/kmod/$(MODULE).ko
_CLEAN = doclean
SRCS_LINKS = $(addsuffix _link,$(SRCS-y))
compare = $(strip $(subst $(1),,$(2)) $(subst $(2),,$(1)))
.PHONY: all
all: install
.PHONY: install
install: build _postinstall
_postinstall: build
.PHONY: build
build: _postbuild
# Link all sources in build directory
%_link: FORCE
$(if $(call compare,$(notdir $*),$*),\
@if [ ! -f $(notdir $(*)) ]; then ln -nfs $(SRCDIR)/$(*) . ; fi,\
@if [ ! -f $(notdir $(*)) ]; then ln -nfs $(SRCDIR)/$(*) . ; fi)
# build module
$(MODULE).ko: $(SRCS_LINKS)
@if [ ! -f $(notdir Makefile) ]; then ln -nfs $(SRCDIR)/Makefile . ; fi
@if [ ! -f $(notdir BSDmakefile) ]; then ln -nfs $(SRCDIR)/BSDmakefile . ; fi
@MAKEFLAGS= $(BSDMAKE) -v
# install module in $(RTE_OUTPUT)/kmod
$(RTE_OUTPUT)/kmod/$(MODULE).ko: $(MODULE).ko
@echo INSTALL-MODULE $(MODULE).ko
@[ -d $(RTE_OUTPUT)/kmod ] || mkdir -p $(RTE_OUTPUT)/kmod
@cp -f $(MODULE).ko $(RTE_OUTPUT)/kmod
# install module
modules_install:
@MAKEFLAGS= $(BSDMAKE) install
.PHONY: clean
clean: _postclean
# do a make clean and remove links
.PHONY: doclean
doclean:
@if [ ! -f $(notdir Makefile) ]; then ln -nfs $(SRCDIR)/Makefile . ; fi
$(Q)$(MAKE) -C $(RTE_KERNELDIR) M=$(CURDIR) O=$(RTE_KERNELDIR) clean
@$(foreach FILE,$(SRCS-y) $(SRCS-n) $(SRCS-),\
if [ -h $(notdir $(FILE)) ]; then rm -f $(notdir $(FILE)) ; fi ;)
@if [ -h $(notdir Makefile) ]; then rm -f $(notdir Makefile) ; fi
@rm -f $(_BUILD_TARGETS) $(_INSTALL_TARGETS) $(_CLEAN_TARGETS) \
$(INSTALL-FILES-all)
include $(RTE_SDK)/mk/internal/rte.install-post.mk
include $(RTE_SDK)/mk/internal/rte.clean-post.mk
include $(RTE_SDK)/mk/internal/rte.build-post.mk
include $(RTE_SDK)/mk/internal/rte.depdirs-post.mk
.PHONY: FORCE
FORCE:
endif

View File

@ -68,7 +68,7 @@ clean: $(CLEANDIRS)
@[ -d $(RTE_OUTPUT)/include ] || mkdir -p $(RTE_OUTPUT)/include
@$(RTE_SDK)/scripts/gen-config-h.sh $(RTE_OUTPUT)/.config \
> $(RTE_OUTPUT)/include/rte_config.h
$(Q)$(MAKE) -f $(RTE_SDK)/Makefile gcovclean
$(Q)$(MAKE) -f $(RTE_SDK)/GNUmakefile gcovclean
@echo Clean complete
.SECONDEXPANSION: