first public release

version 1.2.3

Signed-off-by: Intel
This commit is contained in:
Intel 2012-09-04 13:54:00 +01:00 committed by Thomas Monjalon
parent 0c9a540ed2
commit af75078fec
435 changed files with 169022 additions and 0 deletions

47
Makefile Normal file
View File

@ -0,0 +1,47 @@
# BSD LICENSE
#
# Copyright(c) 2010-2012 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.
#
# version: DPDK.L.1.2.3-3
#
# 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

42
app/Makefile Normal file
View File

@ -0,0 +1,42 @@
# BSD LICENSE
#
# Copyright(c) 2010-2012 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.
#
# version: DPDK.L.1.2.3-3
include $(RTE_SDK)/mk/rte.vars.mk
DIRS-$(CONFIG_RTE_APP_TEST) += test
DIRS-$(CONFIG_RTE_TEST_PMD) += test-pmd
DIRS-$(CONFIG_RTE_APP_CHKINCS) += chkincs
DIRS-$(CONFIG_RTE_LIBRTE_EAL_LINUXAPP) += dump_cfg
include $(RTE_SDK)/mk/rte.subdir.mk

96
app/chkincs/Makefile Normal file
View File

@ -0,0 +1,96 @@
# BSD LICENSE
#
# Copyright(c) 2010-2012 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.
#
# version: DPDK.L.1.2.3-3
include $(RTE_SDK)/mk/rte.vars.mk
#
# library name
#
APP = chkincs
#
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_APP_CHKINCS) += test.c \
test_alarm.c \
test_atomic.c \
test_branch_prediction.c \
test_byteorder.c \
test_common.c \
test_cpuflags.c \
test_cycles.c \
test_debug.c \
test_eal.c \
test_errno.c \
test_ethdev.c \
test_ether.c \
test_fbk_hash.c \
test_hash_crc.c \
test_hash.c \
test_interrupts.c \
test_ip.c \
test_jhash.c \
test_launch.c \
test_lcore.c \
test_log.c \
test_lpm.c \
test_malloc.c \
test_mbuf.c \
test_memcpy.c \
test_memory.c \
test_mempool.c \
test_memzone.c \
test_pci_dev_ids.c \
test_pci.c \
test_per_lcore.c \
test_prefetch.c \
test_random.c \
test_ring.c \
test_rwlock.c \
test_sctp.c \
test_spinlock.c \
test_string_fns.c \
test_tailq.c \
test_tcp.c \
test_timer.c \
test_udp.c \
test_version.c
CFLAGS += -O0 -fno-inline
CFLAGS += $(WERROR_FLAGS)
# this application needs libraries first
DEPDIRS-$(CONFIG_RTE_APP_CHKINCS) += lib
include $(RTE_SDK)/mk/rte.app.mk

50
app/chkincs/test.c Normal file
View File

@ -0,0 +1,50 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
main(__attribute__((unused)) int argc, __attribute__((unused)) char **argv)
{
return 0;
}

90
app/chkincs/test.h Normal file
View File

@ -0,0 +1,90 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#ifndef _TEST_H_
#define _TEST_H_
/* icc on baremetal gives us troubles with function named 'main' */
#ifdef RTE_EXEC_ENV_BAREMETAL
#define main _main
#endif
int main(int argc, char **argv);
int test_alarm(void);
int test_atomic(void);
int test_branch_prediction(void);
int test_byteorder(void);
int test_common(void);
int test_cpuflags(void);
int test_cycles(void);
int test_debug(void);
int test_eal(void);
int test_errno(void);
int test_ethdev(void);
int test_ether(void);
int test_fbk_hash(void);
int test_hash_crc(void);
int test_hash(void);
int test_interrupts(void);
int test_ip(void);
int test_jhash(void);
int test_launch(void);
int test_lcore(void);
int test_log(void);
int test_lpm(void);
int test_malloc(void);
int test_mbuf(void);
int test_memcpy(void);
int test_memory(void);
int test_mempool(void);
int test_memzone(void);
int test_pci_dev_ids(void);
int test_pci(void);
int test_per_lcore(void);
int test_prefetch(void);
int test_random(void);
int test_ring(void);
int test_rwlock(void);
int test_sctp(void);
int test_spinlock(void);
int test_string_fns(void);
int test_tailq(void);
int test_tcp(void);
int test_timer(void);
int test_udp(void);
int test_version(void);
#endif

53
app/chkincs/test_alarm.c Normal file
View File

@ -0,0 +1,53 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_alarm.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_alarm(void)
{
rte_eal_alarm_set(10, 0, 0);
return 1;
}

93
app/chkincs/test_atomic.c Normal file
View File

@ -0,0 +1,93 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_atomic.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_atomic(void)
{
rte_atomic16_t a16 = RTE_ATOMIC16_INIT(1);
rte_atomic32_t a32 = RTE_ATOMIC32_INIT(1);
rte_atomic64_t a64 = RTE_ATOMIC64_INIT(1);
int x;
rte_mb();
rte_wmb();
rte_rmb();
rte_atomic16_init(&a16);
rte_atomic16_set(&a16, 1);
x = rte_atomic16_read(&a16);
rte_atomic16_inc(&a16);
rte_atomic16_dec(&a16);
rte_atomic16_add(&a16, 5);
rte_atomic16_sub(&a16, 5);
x = rte_atomic16_test_and_set(&a16);
x = rte_atomic16_add_return(&a16, 10);
rte_atomic32_init(&a32);
rte_atomic32_set(&a32, 1);
x = rte_atomic32_read(&a32);
rte_atomic32_inc(&a32);
rte_atomic32_dec(&a32);
rte_atomic32_add(&a32, 5);
rte_atomic32_sub(&a32, 5);
x = rte_atomic32_test_and_set(&a32);
x = rte_atomic32_add_return(&a32, 10);
rte_atomic64_init(&a64);
rte_atomic64_set(&a64, 1);
x = rte_atomic64_read(&a64);
rte_atomic64_inc(&a64);
rte_atomic64_dec(&a64);
rte_atomic64_add(&a64, 5);
rte_atomic64_sub(&a64, 5);
x = rte_atomic64_test_and_set(&a64);
x = rte_atomic64_add_return(&a64, 10);
(void)x;
return 1;
}

View File

@ -0,0 +1,58 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_branch_prediction.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int test_branch_prediction(void)
{
int a = 1;
int b = 2;
if (likely(a < b))
return 0;
else if (unlikely(a < b))
return 1;
else return 2;
}

View File

@ -0,0 +1,84 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_byteorder.h>
#include "test.h"
static volatile uint16_t u16 = 0x1337;
static volatile uint32_t u32 = 0xdeadbeefUL;
static volatile uint64_t u64 = 0xdeadcafebabefaceULL;
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_byteorder(void)
{
uint16_t res_u16;
uint32_t res_u32;
uint64_t res_u64;
res_u16 = rte_bswap16(u16);
res_u32 = rte_bswap32(u32);
res_u64 = rte_bswap64(u64);
res_u16 = rte_cpu_to_le_16(u16);
res_u32 = rte_cpu_to_le_32(u32);
res_u64 = rte_cpu_to_le_64(u64);
res_u16 = rte_cpu_to_be_16(u16);
res_u32 = rte_cpu_to_be_32(u32);
res_u64 = rte_cpu_to_be_64(u64);
res_u16 = rte_le_to_cpu_16(u16);
res_u32 = rte_le_to_cpu_32(u32);
res_u64 = rte_le_to_cpu_64(u64);
res_u16 = rte_be_to_cpu_16(u16);
res_u32 = rte_be_to_cpu_32(u32);
res_u64 = rte_be_to_cpu_64(u64);
(void)res_u16;
(void)res_u32;
(void)res_u64;
return 1;
}

76
app/chkincs/test_common.c Normal file
View File

@ -0,0 +1,76 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_common.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
static int
test_func(__rte_unused int var1, int var2)
{
RTE_SET_USED(var2);
return 1;
}
static int static_var1 = 3;
static int static_var2 = 6;
int
test_common(void)
{
int *ptr1 = &static_var1, *ptr2 = &static_var2;
int var;
ptr2 = RTE_PTR_ADD(ptr1, 10);
ptr2 = RTE_PTR_SUB(ptr1, 5);
var = RTE_PTR_DIFF(ptr1, ptr2);
var = RTE_ALIGN(var, 16);
RTE_BUILD_BUG_ON(0);
var = RTE_MIN(10, 5);
var = RTE_MAX(10, 5);
return test_func(10, 5);
}

View File

@ -0,0 +1,53 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_cpuflags.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_cpuflags(void)
{
rte_cpu_get_flag_enabled(RTE_CPUFLAG_SSE3);
return 1;
}

63
app/chkincs/test_cycles.c Normal file
View File

@ -0,0 +1,63 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_cycles.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_cycles(void)
{
uint64_t hz, c;
hz = rte_get_hpet_hz();
c = rte_get_hpet_cycles();
rte_delay_us(10);
rte_delay_ms(10);
c = rte_rdtsc();
(void)hz;
(void)c;
return 1;
}

55
app/chkincs/test_debug.c Normal file
View File

@ -0,0 +1,55 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_debug.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_debug(void)
{
rte_dump_stack();
rte_dump_registers();
rte_panic("oops %d", 10);
return 1;
}

52
app/chkincs/test_eal.c Normal file
View File

@ -0,0 +1,52 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_eal.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_eal(void)
{
return 1;
}

54
app/chkincs/test_errno.c Normal file
View File

@ -0,0 +1,54 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_errno.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_errno(void)
{
if (rte_errno != 0)
return -1;
return 1;
}

72
app/chkincs/test_ethdev.c Normal file
View File

@ -0,0 +1,72 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_ethdev.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
static struct rte_eth_conf port_conf;
static struct rte_eth_rxconf rx_conf;
static struct rte_eth_txconf tx_conf;
static struct rte_mempool *mp;
int
test_ethdev(void)
{
struct rte_eth_link link;
int x;
struct ether_addr ea;
x = rte_eth_dev_count();
x = rte_eth_dev_configure(0, 1, 1, &port_conf);
rte_eth_macaddr_get(0, &ea);
x = rte_eth_rx_queue_setup(0, 0, 128, 0, &rx_conf, mp);
x = rte_eth_tx_queue_setup(0, 0, 128, 0, &tx_conf);
rte_eth_link_get(0, &link);
x = rte_eth_dev_start(0);
(void)x;
return 1;
}

52
app/chkincs/test_ether.c Normal file
View File

@ -0,0 +1,52 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_ether.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_ether(void)
{
return 1;
}

View File

@ -0,0 +1,53 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_fbk_hash.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_fbk_hash(void)
{
void * ptr = (void *)RTE_FBK_HASH_FUNC_DEFAULT;
return ptr == ptr;
}

85
app/chkincs/test_hash.c Normal file
View File

@ -0,0 +1,85 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_hash.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
/* Parameters used for hash table in unit test functions. */
static struct rte_hash_parameters ut_params = {
"name", /* name */
64, /* entries */
4, /* bucket_entries */
8, /* key_len */
0, /* hash_func */
0, /* hash_func_init_val */
0, /* socket_id */
};
struct key {
char key[8];
};
/* Keys used by unit test functions */
static struct key keys[1] = {
{
{ 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, },
}
};
int test_hash(void)
{
struct rte_hash *handle;
int32_t pos0;
handle = rte_hash_create(&ut_params);
if (handle == 0) {
return -1;
}
pos0 = rte_hash_add_key(handle, &keys[0]);
pos0 = rte_hash_lookup(handle, &keys[0]);
pos0 = rte_hash_del_key(handle, &keys[0]);
rte_hash_free(handle);
(void)pos0; /* remove compiler warning */
return 0;
}

View File

@ -0,0 +1,52 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_hash_crc.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_hash_crc(void)
{
return 1;
}

View File

@ -0,0 +1,53 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_interrupts.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_interrupts(void)
{
rte_intr_callback_register(0, 0, 0);
return 1;
}

53
app/chkincs/test_ip.c Normal file
View File

@ -0,0 +1,53 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_ip.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_ip(void)
{
uint64_t var = IPv4(1,1,1,1);
return IS_IPV4_MCAST(var);
}

54
app/chkincs/test_jhash.c Normal file
View File

@ -0,0 +1,54 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_jhash.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_jhash(void)
{
uint32_t a = 1, b = 2, c = 3;
__rte_jhash_mix(a,b,c);
return 1;
}

68
app/chkincs/test_launch.c Normal file
View File

@ -0,0 +1,68 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_launch.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
static int
test_launch_per_core(__attribute__((unused)) void *arg)
{
return 0;
}
int
test_launch(void)
{
enum rte_lcore_state_t s;
rte_eal_remote_launch(test_launch_per_core, (void *)0, 0);
rte_eal_wait_lcore(0);
rte_eal_mp_remote_launch(test_launch_per_core, (void *)0, CALL_MASTER);
rte_eal_mp_wait_lcore();
s = rte_eal_get_lcore_state(0);
(void)s;
return 0;
}

66
app/chkincs/test_lcore.c Normal file
View File

@ -0,0 +1,66 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_lcore.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_lcore(void)
{
unsigned x;
x = rte_socket_id();
x = rte_lcore_id();
x = rte_lcore_to_socket_id(x);
x = rte_lcore_count();
x = rte_lcore_is_enabled(x);
RTE_LCORE_FOREACH(x)
(void)x;
RTE_LCORE_FOREACH_SLAVE(x)
(void)x;
return 0;
}

58
app/chkincs/test_log.c Normal file
View File

@ -0,0 +1,58 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_log.h>
#include "test.h"
#define RTE_LOGTYPE_TESTAPP1 RTE_LOGTYPE_USER1
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_log(void)
{
rte_set_log_type(RTE_LOGTYPE_TESTAPP1, 1);
rte_set_log_level(RTE_LOG_DEBUG);
RTE_LOG(DEBUG, TESTAPP1, "this is a debug level message %d\n", 1);
rte_log_dump_history();
return 0;
}

64
app/chkincs/test_lpm.c Normal file
View File

@ -0,0 +1,64 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_lpm.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_lpm(void)
{
struct rte_lpm *lpm = 0;
uint32_t ip = 0;
uint8_t depth = 24, next_hop_add = 100, next_hop_return = 0;
lpm = rte_lpm_create(__func__, -1, 256, RTE_LPM_HEAP);
if (lpm == 0)
return -1;
rte_lpm_add(lpm, ip, depth, next_hop_add);
rte_lpm_lookup(lpm, ip, &next_hop_return);
rte_lpm_delete(lpm, ip, depth);
rte_lpm_lookup(lpm, ip, &next_hop_return);
rte_lpm_free(lpm);
return 0;
}

57
app/chkincs/test_malloc.c Normal file
View File

@ -0,0 +1,57 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_malloc.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_malloc(void)
{
void *p1;
p1 = rte_malloc("dummy", 1000, 8);
rte_free(p1);
return 0;
}

110
app/chkincs/test_mbuf.c Normal file
View File

@ -0,0 +1,110 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_mbuf.h>
#include "test.h"
#define MBUF_SIZE 2048
#define NB_MBUF 128
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_mbuf(void)
{
struct rte_mempool *mbuf_pool;
struct rte_mbuf *m, *m1;
char *hdr;
int x;
int* ptr;
mbuf_pool = rte_mempool_create("test_mbuf_pool", NB_MBUF,
MBUF_SIZE, 32, 0,
(void (*)(struct rte_mempool*, void*)) 0, (void *)0,
rte_pktmbuf_init, (void *)0,
SOCKET_ID_ANY, 0);
if (mbuf_pool == NULL) {
return -1;
}
m = rte_pktmbuf_alloc(mbuf_pool);
if(m == NULL) {
return -1;
}
m1 = RTE_MBUF_FROM_BADDR(RTE_MBUF_TO_BADDR(m));
(void)m1;
x = rte_pktmbuf_pkt_len(m);
x = rte_pktmbuf_data_len(m);
x = rte_pktmbuf_headroom(m);
x = rte_pktmbuf_tailroom(m);
x = rte_pktmbuf_is_contiguous(m);
m = rte_pktmbuf_lastseg(m);
hdr = rte_pktmbuf_mtod(m, char *);
rte_pktmbuf_dump(m, 0);
hdr = rte_pktmbuf_append(m, 10);
x = rte_pktmbuf_trim(m, 10);
hdr = rte_pktmbuf_prepend(m, 10);
hdr = rte_pktmbuf_adj(m, 10);
ptr = (int*) rte_ctrlmbuf_data(m);
*ptr = rte_ctrlmbuf_len(m);
*ptr = rte_pktmbuf_pkt_len(m);
*ptr = rte_pktmbuf_data_len(m);
rte_pktmbuf_free_seg(m);
rte_pktmbuf_free(m);
RTE_MBUF_PREFETCH_TO_FREE(m);
rte_mbuf_sanity_check(m, RTE_MBUF_CTRL, 1);
(void)x;
(void)hdr;
return 0;
}

58
app/chkincs/test_memcpy.c Normal file
View File

@ -0,0 +1,58 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_memcpy.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_memcpy(void)
{
char buf[16];
const char s[] = "hello\n";
volatile int a = 10;
rte_memcpy(buf, s, sizeof(s));
rte_memcpy(buf, s, a);
return 0;
}

65
app/chkincs/test_memory.c Normal file
View File

@ -0,0 +1,65 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_memory.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
static int a __rte_cache_aligned;
int
test_memory(void)
{
const struct rte_memseg *mem;
int s = CACHE_LINE_ROUNDUP(10);
rte_dump_physmem_layout();
s = rte_eal_get_physmem_size();
mem = rte_eal_get_physmem_layout();
(void)a;
(void)s;
(void)mem;
return 0;
}

111
app/chkincs/test_mempool.c Normal file
View File

@ -0,0 +1,111 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_mempool.h>
#include "test.h"
#define MAX_BULK 16
#define MEMPOOL_ELT_SIZE 2048
#define MEMPOOL_SIZE 2047
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_mempool(void)
{
struct rte_mempool *mp;
void *ptrs[MAX_BULK];
int x;
phys_addr_t addr;
mp = rte_mempool_create("test_nocache", MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE, 0, 0,
(void (*)(struct rte_mempool*, void*)) 0,
(void *)0,
(void (*)(struct rte_mempool*, void*, void*, unsigned int)) 0,
(void *)0,
SOCKET_ID_ANY, 0);
if (mp == NULL) {
return -1;
}
rte_mempool_set_bulk_count(mp, MAX_BULK);
rte_mempool_dump(mp);
rte_mempool_mc_get_bulk(mp, ptrs, 1);
rte_mempool_mc_get_bulk(mp, ptrs, MAX_BULK);
rte_mempool_sc_get_bulk(mp, ptrs, 1);
rte_mempool_sc_get_bulk(mp, ptrs, MAX_BULK);
rte_mempool_get_bulk(mp, ptrs, 1);
rte_mempool_get_bulk(mp, ptrs, MAX_BULK);
rte_mempool_mc_get(mp, ptrs);
rte_mempool_sc_get(mp, ptrs);
rte_mempool_get(mp, ptrs);
rte_mempool_mp_put_bulk(mp, ptrs, 1);
rte_mempool_mp_put_bulk(mp, ptrs, MAX_BULK);
rte_mempool_sp_put_bulk(mp, ptrs, 1);
rte_mempool_sp_put_bulk(mp, ptrs, MAX_BULK);
rte_mempool_put_bulk(mp, ptrs, 1);
rte_mempool_put_bulk(mp, ptrs, MAX_BULK);
rte_mempool_mp_put(mp, ptrs);
rte_mempool_sp_put(mp, ptrs);
rte_mempool_put(mp, ptrs);
__MEMPOOL_STAT_ADD(mp, put, 1);
__mempool_check_cookies(mp, 0, 0, 0);
x = rte_mempool_count(mp);
x = rte_mempool_free_count(mp);
x = rte_mempool_full(mp);
x = rte_mempool_empty(mp);
addr = rte_mempool_virt2phy(mp, ptrs[0]);
rte_mempool_audit(mp);
ptrs[0] = rte_mempool_get_priv(mp);
(void)x;
(void)addr;
return 0;
}

View File

@ -0,0 +1,61 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_memzone.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_memzone(void)
{
const struct rte_memzone *memzone1;
memzone1 = rte_memzone_lookup("testzone1");
memzone1 = rte_memzone_reserve("testzone1", 100,
0, 0);
rte_memzone_dump();
(void)memzone1;
return 0;
}

86
app/chkincs/test_pci.c Normal file
View File

@ -0,0 +1,86 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_pci.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
static int my_driver_init(struct rte_pci_driver *dr,
struct rte_pci_device *dev);
struct rte_pci_id my_driver_id[] = {
{
0x8086,
0x10E8,
PCI_ANY_ID,
PCI_ANY_ID,
},
{
0, 0, 0, 0 /* sentinel */
},
};
struct rte_pci_driver my_driver = {
{0, 0},
"test_driver",
my_driver_init,
my_driver_id,
RTE_PCI_DRV_NEED_IGB_UIO,
};
static int
my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr,
__attribute__((unused)) struct rte_pci_device *dev)
{
return 0;
}
int
test_pci(void)
{
struct rte_pci_id id = {RTE_PCI_DEVICE(0, 0)};
rte_eal_pci_dump();
rte_eal_pci_register(&my_driver);
rte_eal_pci_probe();
(void)id;
return 0;
}

View File

@ -0,0 +1,60 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include "test.h"
struct A {
int x;
int y;
};
static struct A a[] = {
#define RTE_PCI_DEV_ID_DECL(vend, dev) {vend, dev},
#include <rte_pci_dev_ids.h>
};
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_pci_dev_ids(void)
{
return a[0].x;
}

View File

@ -0,0 +1,57 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_per_lcore.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
static RTE_DEFINE_PER_LCORE(unsigned, test) = 0x12345678;
int
test_per_lcore(void)
{
if (RTE_PER_LCORE(test) != 0x12345678)
return -1;
return 0;
}

View File

@ -0,0 +1,58 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_prefetch.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_prefetch(void)
{
int a;
rte_prefetch0(&a);
rte_prefetch1(&a);
rte_prefetch2(&a);
return 0;
}

54
app/chkincs/test_random.c Normal file
View File

@ -0,0 +1,54 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_random.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_random(void)
{
rte_srand(1);
rte_rand();
return 0;
}

97
app/chkincs/test_ring.c Normal file
View File

@ -0,0 +1,97 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_ring.h>
#include "test.h"
#define MAX_BULK 16
#define RING_SIZE 4096
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_ring(void)
{
struct rte_ring *r;
void *ptrs[MAX_BULK];
int x;
r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
if (r == 0) {
return -1;
}
rte_ring_dump(r);
rte_ring_set_bulk_count(r, MAX_BULK);
rte_ring_set_water_mark(r, 50);
rte_ring_sp_enqueue_bulk(r, &ptrs[0], 1);
rte_ring_mp_enqueue_bulk(r, &ptrs[0], 1);
rte_ring_sp_enqueue_bulk(r, &ptrs[0], MAX_BULK);
rte_ring_mp_enqueue_bulk(r, &ptrs[0], MAX_BULK);
rte_ring_enqueue_bulk(r, &ptrs[0], MAX_BULK);
rte_ring_enqueue_bulk(r, &ptrs[0], MAX_BULK);
rte_ring_sp_enqueue(r, &ptrs[0]);
rte_ring_mp_enqueue(r, &ptrs[0]);
rte_ring_enqueue(r, &ptrs[0]);
rte_ring_sc_dequeue_bulk(r, &ptrs[0], 1);
rte_ring_sc_dequeue_bulk(r, &ptrs[0], MAX_BULK);
rte_ring_mc_dequeue_bulk(r, &ptrs[0], 1);
rte_ring_mc_dequeue_bulk(r, &ptrs[0], MAX_BULK);
rte_ring_dequeue_bulk(r, &ptrs[0], 1);
rte_ring_dequeue_bulk(r, &ptrs[0], MAX_BULK);
rte_ring_sc_dequeue(r, &ptrs[0]);
rte_ring_mc_dequeue(r, &ptrs[0]);
rte_ring_dequeue(r, &ptrs[0]);
__RING_STAT_ADD(r, enq_fail, 10);
x = rte_ring_full(r);
x = rte_ring_empty(r);
x = rte_ring_count(r);
x = rte_ring_free_count(r);
(void)x;
return 0;
}

60
app/chkincs/test_rwlock.c Normal file
View File

@ -0,0 +1,60 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_rwlock.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_rwlock(void)
{
rte_rwlock_t rwl = RTE_RWLOCK_INITIALIZER;
rte_rwlock_init(&rwl);
rte_rwlock_write_lock(&rwl);
rte_rwlock_write_unlock(&rwl);
rte_rwlock_read_lock(&rwl);
rte_rwlock_read_unlock(&rwl);
return 0;
}

52
app/chkincs/test_sctp.c Normal file
View File

@ -0,0 +1,52 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_sctp.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_sctp(void)
{
return 0;
}

View File

@ -0,0 +1,59 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_spinlock.h>
#include "test.h"
static rte_spinlock_t sl = RTE_SPINLOCK_INITIALIZER;
static rte_spinlock_recursive_t slr = RTE_SPINLOCK_RECURSIVE_INITIALIZER;
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_spinlock(void)
{
rte_spinlock_init(&sl);
rte_spinlock_lock(&sl);
rte_spinlock_unlock(&sl);
rte_spinlock_recursive_lock(&slr);
return 0;
}

View File

@ -0,0 +1,52 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_string_fns.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_string_fns(void)
{
return 0;
}

55
app/chkincs/test_tailq.c Normal file
View File

@ -0,0 +1,55 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_tailq.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_tailq(void)
{
struct rte_dummy *t1, *t2;
t1 = RTE_TAILQ_RESERVE("dummy", rte_dummy);
t2 = RTE_TAILQ_LOOKUP("dummy", rte_dummy);
return (t1 == t2) ? 0 : -1;
}

52
app/chkincs/test_tcp.c Normal file
View File

@ -0,0 +1,52 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_tcp.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_tcp(void)
{
return 0;
}

74
app/chkincs/test_timer.c Normal file
View File

@ -0,0 +1,74 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_timer.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
/* timer callback for basic tests */
static void
timer_cb(__attribute__((unused)) struct rte_timer *tim,
__attribute__((unused)) void *arg)
{
return;
}
int
test_timer(void)
{
int x;
struct rte_timer tim = RTE_TIMER_INITIALIZER;
rte_timer_subsystem_init();
rte_timer_init(&tim);
rte_timer_reset(&tim, 1234, SINGLE, 0, timer_cb, &x);
rte_timer_stop(&tim);
rte_timer_reset_sync(&tim, 1234, SINGLE, 0, timer_cb, &x);
rte_timer_stop_sync(&tim);
x = rte_timer_pending(&tim);
rte_timer_manage();
rte_timer_dump_stats();
return 0;
}

52
app/chkincs/test_udp.c Normal file
View File

@ -0,0 +1,52 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include "test.h"
#include <rte_udp.h>
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_udp(void)
{
return 0;
}

View File

@ -0,0 +1,52 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <rte_version.h>
#include "test.h"
/*
* ^
* / \
* / | \ WARNING: this test program does *not* show how to use the
* / . \ API. Its only goal is to check dependencies of include files.
* /_______\
*/
int
test_version(void)
{
return 1;
}

49
app/dump_cfg/Makefile Normal file
View File

@ -0,0 +1,49 @@
# BSD LICENSE
#
# Copyright(c) 2010-2012 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.
#
# version: DPDK.L.1.2.3-3
#
include $(RTE_SDK)/mk/rte.vars.mk
APP = dump_cfg
CFLAGS += $(WERROR_FLAGS)
#
# all source are stored in SRCS-y
#
SRCS-y := dump_cfg_main.c
# this application needs libraries first
DEPDIRS-y += lib
include $(RTE_SDK)/mk/rte.app.mk

View File

@ -0,0 +1,229 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <unistd.h>
#include <getopt.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/mman.h>
#include <sys/queue.h>
#include <limits.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_string_fns.h>
/* some functions used for printing out the memory segments and memory zones information */
#define PRINT_STR_FIELD(structname, field) do{ \
count+= rte_snprintf(buf + count, len-count, " %s='%s',", \
#field, (const char *)structname->field);\
} while(0)
#define PRINT_PTR_FIELD(structname, field) do{ \
count+= rte_snprintf(buf + count, len-count, " %s=%p,", \
#field, (void *)structname->field);\
} while(0)
#define PRINT_UINT_FIELD(structname, field) do{ \
count+= rte_snprintf(buf + count, len-count, " %s=%llu,", \
#field, (unsigned long long)structname->field);\
} while(0)
#define PRINT_INT_FIELD(structname, field) do{ \
count+= rte_snprintf(buf + count, len-count, " %s=%lld,", \
#field, (long long)structname->field);\
} while(0)
#define PRINT_CUSTOM_FIELD(structname, field, print_fn) do{ \
char buf2[1024]; \
count+= rte_snprintf(buf + count, len-count, " %s=%s,", \
#field, print_fn(structname->field, buf2, sizeof(buf2)));\
} while(0)
static inline const char *
memseg_to_str(const struct rte_memseg *seg, char *buf, size_t len)
{
int count = 0;
count += rte_snprintf(buf + count, len - count, "{");
PRINT_UINT_FIELD(seg, phys_addr);
PRINT_PTR_FIELD(seg, addr);
PRINT_UINT_FIELD(seg, len);
PRINT_INT_FIELD(seg, socket_id);
PRINT_UINT_FIELD(seg, hugepage_sz);
PRINT_UINT_FIELD(seg, nchannel);
PRINT_UINT_FIELD(seg, nrank);
rte_snprintf(buf + count - 1, len - count + 1, " }");
return buf;
}
static inline const char *
memzone_to_str(const struct rte_memzone *zone, char *buf, size_t len)
{
int count = 0;
count += rte_snprintf(buf + count, len - count, "{");
PRINT_STR_FIELD(zone, name);
PRINT_UINT_FIELD(zone, phys_addr);
PRINT_PTR_FIELD(zone, addr);
PRINT_UINT_FIELD(zone, len);
PRINT_INT_FIELD(zone, socket_id);
PRINT_UINT_FIELD(zone, flags);
rte_snprintf(buf + count - 1, len - count + 1, " }");
return buf;
}
static inline const char *
tailq_to_str(const struct rte_tailq_head *tailq, char *buf, size_t len)
{
int count = 0;
count += rte_snprintf(buf + count, len - count, "{");
PRINT_STR_FIELD(tailq, qname);
const struct rte_dummy_head *head = &tailq->tailq_head;
PRINT_PTR_FIELD(head, tqh_first);
PRINT_PTR_FIELD(head, tqh_last);
rte_snprintf(buf + count - 1, len - count + 1, " }");
return buf;
}
#define PREFIX "prefix"
static const char *directory = "/var/run";
static const char *pre = "rte";
static void
usage(const char *prgname)
{
printf("%s --prefix <prefix>\n\n"
"dump_config option list:\n"
"\t--"PREFIX": filename prefix\n",
prgname);
}
static int
dmp_cfg_parse_args(int argc, char **argv)
{
const char *prgname = argv[0];
const char *home_dir = getenv("HOME");
int opt;
int option_index;
static struct option lgopts[] = {
{PREFIX, 1, 0, 0},
{0, 0, 0, 0}
};
if (getuid() != 0 && home_dir != NULL)
directory = home_dir;
while ((opt = getopt_long(argc, argv, "",
lgopts, &option_index)) != EOF) {
switch (opt) {
case 0:
if (!strcmp(lgopts[option_index].name, PREFIX))
pre = optarg;
else{
usage(prgname);
return -1;
}
break;
default:
usage(prgname);
return -1;
}
}
return 0;
}
int
main(int argc, char **argv)
{
char buffer[1024];
char path[PATH_MAX];
int i;
int fd = 0;
dmp_cfg_parse_args(argc, argv);
rte_snprintf(path, sizeof(path), "%s/.%s_config", directory, pre);
printf("Path to mem_config: %s\n\n", path);
fd = open(path, O_RDWR);
if (fd < 0){
printf("Error with config open\n");
return 1;
}
struct rte_mem_config *cfg = mmap(NULL, sizeof(*cfg), PROT_READ, \
MAP_SHARED, fd, 0);
if (cfg == NULL){
printf("Error with config mmap\n");
close(fd);
return 1;
}
close(fd);
printf("----------- MEMORY_SEGMENTS -------------\n");
for (i = 0; i < RTE_MAX_MEMSEG; i++){
if (cfg->memseg[i].addr == NULL) break;
printf("Segment %d: ", i);
printf("%s\n", memseg_to_str(&cfg->memseg[i], buffer, sizeof(buffer)));
}
printf("--------- END_MEMORY_SEGMENTS -----------\n");
printf("------------ MEMORY_ZONES ---------------\n");
for (i = 0; i < RTE_MAX_MEMZONE; i++){
if (cfg->memzone[i].addr == NULL) break;
printf("Zone %d: ", i);
printf("%s\n", memzone_to_str(&cfg->memzone[i], buffer, sizeof(buffer)));
}
printf("---------- END_MEMORY_ZONES -------------\n");
printf("------------- TAIL_QUEUES ---------------\n");
for (i = 0; i < RTE_MAX_TAILQ; i++){
if (cfg->tailq_head[i].qname[0] == '\0') break;
printf("Tailq %d: ", i);
printf("%s\n", tailq_to_str(&cfg->tailq_head[i], buffer, sizeof(buffer)));
}
printf("----------- END_TAIL_QUEUES -------------\n");
return 0;
}

63
app/test-pmd/Makefile Normal file
View File

@ -0,0 +1,63 @@
# BSD LICENSE
#
# Copyright(c) 2010-2012 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.
#
# version: DPDK.L.1.2.3-3
include $(RTE_SDK)/mk/rte.vars.mk
#
# library name
#
APP = testpmd
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
#
# all source are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_TEST_PMD) := testpmd.c
SRCS-$(CONFIG_RTE_TEST_PMD) += parameters.c
SRCS-$(CONFIG_RTE_TEST_PMD) += cmdline.c
SRCS-$(CONFIG_RTE_TEST_PMD) += config.c
SRCS-$(CONFIG_RTE_TEST_PMD) += iofwd.c
SRCS-$(CONFIG_RTE_TEST_PMD) += macfwd.c
SRCS-$(CONFIG_RTE_TEST_PMD) += rxonly.c
SRCS-$(CONFIG_RTE_TEST_PMD) += txonly.c
SRCS-$(CONFIG_RTE_TEST_PMD) += csumonly.c
ifeq ($(CONFIG_RTE_LIBRTE_IEEE1588),y)
SRCS-$(CONFIG_RTE_TEST_PMD) += ieee1588fwd.c
endif
# this application needs libraries first
DEPDIRS-$(CONFIG_RTE_TEST_PMD) += lib
include $(RTE_SDK)/mk/rte.app.mk

2180
app/test-pmd/cmdline.c Normal file

File diff suppressed because it is too large Load Diff

1142
app/test-pmd/config.c Normal file

File diff suppressed because it is too large Load Diff

449
app/test-pmd/csumonly.c Normal file
View File

@ -0,0 +1,449 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdarg.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_cycles.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_memory.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_memcpy.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_ip.h>
#include <rte_tcp.h>
#include <rte_udp.h>
#include <rte_sctp.h>
#include <rte_prefetch.h>
#include <rte_string_fns.h>
#include "testpmd.h"
#define IP_DEFTTL 64 /* from RFC 1340. */
#define IP_VERSION 0x40
#define IP_HDRLEN 0x05 /* default IP header length == five 32-bits words. */
#define IP_VHL_DEF (IP_VERSION | IP_HDRLEN)
/* Pseudo Header for IPv4/UDP/TCP checksum */
struct psd_header {
uint32_t src_addr; /* IP address of source host. */
uint32_t dst_addr; /* IP address of destination host(s). */
uint8_t zero; /* zero. */
uint8_t proto; /* L4 protocol type. */
uint16_t len; /* L4 length. */
} __attribute__((__packed__));
/* Pseudo Header for IPv6/UDP/TCP checksum */
struct ipv6_psd_header {
uint8_t src_addr[16]; /* IP address of source host. */
uint8_t dst_addr[16]; /* IP address of destination host(s). */
uint32_t len; /* L4 length. */
uint8_t zero[3]; /* zero. */
uint8_t proto; /* L4 protocol. */
} __attribute__((__packed__));
static inline uint16_t
get_16b_sum(uint16_t *ptr16, uint32_t nr)
{
uint32_t sum = 0;
while (nr > 1)
{
sum +=*ptr16;
nr -= sizeof(uint16_t);
ptr16++;
if (sum > UINT16_MAX)
sum -= UINT16_MAX;
}
/* If length is in odd bytes */
if (nr)
sum += *((uint8_t*)ptr16);
sum = ((sum & 0xffff0000) >> 16) + (sum & 0xffff);
sum &= 0x0ffff;
return (uint16_t)sum;
}
static inline uint16_t
get_ipv4_cksum(struct ipv4_hdr *ipv4_hdr)
{
uint16_t cksum;
cksum = get_16b_sum((uint16_t*)ipv4_hdr, sizeof(struct ipv4_hdr));
return (uint16_t)((cksum == 0xffff)?cksum:~cksum);
}
static inline
uint16_t get_ipv4_psd_sum (struct ipv4_hdr * ip_hdr)
{
struct psd_header psd_hdr;
psd_hdr.src_addr = ip_hdr->src_addr;
psd_hdr.dst_addr = ip_hdr->dst_addr;
psd_hdr.zero = 0;
psd_hdr.proto = ip_hdr->next_proto_id;
psd_hdr.len = rte_cpu_to_be_16((uint16_t)(rte_be_to_cpu_16(ip_hdr->total_length)
- sizeof(struct ipv4_hdr)));
return get_16b_sum((uint16_t*)&psd_hdr, sizeof(struct psd_header));
}
static inline
uint16_t get_ipv6_psd_sum (struct ipv6_hdr * ip_hdr)
{
struct ipv6_psd_header psd_hdr;
rte_memcpy(psd_hdr.src_addr, ip_hdr->src_addr, sizeof(ip_hdr->src_addr)
+ sizeof(ip_hdr->dst_addr));
psd_hdr.zero[0] = 0;
psd_hdr.zero[1] = 0;
psd_hdr.zero[2] = 0;
psd_hdr.proto = ip_hdr->proto;
psd_hdr.len = ip_hdr->payload_len;
return get_16b_sum((uint16_t*)&psd_hdr, sizeof(struct ipv6_psd_header));
}
static inline uint16_t
get_ipv4_udptcp_checksum(struct ipv4_hdr *ipv4_hdr, uint16_t *l4_hdr)
{
uint32_t cksum;
uint32_t l4_len;
l4_len = rte_be_to_cpu_16(ipv4_hdr->total_length) - sizeof(struct ipv4_hdr);
cksum = get_16b_sum(l4_hdr, l4_len);
cksum += get_ipv4_psd_sum(ipv4_hdr);
cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
cksum = (~cksum) & 0xffff;
if (cksum == 0)
cksum = 0xffff;
return (uint16_t)cksum;
}
static inline uint16_t
get_ipv6_udptcp_checksum(struct ipv6_hdr *ipv6_hdr, uint16_t *l4_hdr)
{
uint32_t cksum;
uint32_t l4_len;
l4_len = rte_be_to_cpu_16(ipv6_hdr->payload_len);
cksum = get_16b_sum(l4_hdr, l4_len);
cksum += get_ipv6_psd_sum(ipv6_hdr);
cksum = ((cksum & 0xffff0000) >> 16) + (cksum & 0xffff);
cksum = (~cksum) & 0xffff;
if (cksum == 0)
cksum = 0xffff;
return (uint16_t)cksum;
}
/*
* Forwarding of packets. Change the checksum field with HW or SW methods
* The HW/SW method selection depends on the ol_flags on every packet
*/
static void
pkt_burst_checksum_forward(struct fwd_stream *fs)
{
struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
struct rte_port *txp;
struct rte_mbuf *mb;
struct ether_hdr *eth_hdr;
struct ipv4_hdr *ipv4_hdr;
struct ipv6_hdr *ipv6_hdr;
struct udp_hdr *udp_hdr;
struct tcp_hdr *tcp_hdr;
struct sctp_hdr *sctp_hdr;
uint16_t nb_rx;
uint16_t nb_tx;
uint16_t i;
uint16_t ol_flags;
uint16_t pkt_ol_flags;
uint16_t tx_ol_flags;
uint16_t l4_proto;
uint8_t l2_len;
uint8_t l3_len;
uint32_t rx_bad_ip_csum;
uint32_t rx_bad_l4_csum;
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
uint64_t start_tsc;
uint64_t end_tsc;
uint64_t core_cycles;
#endif
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
start_tsc = rte_rdtsc();
#endif
/*
* Receive a burst of packets and forward them.
*/
nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
nb_pkt_per_burst);
if (unlikely(nb_rx == 0))
return;
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
#endif
fs->rx_packets += nb_rx;
rx_bad_ip_csum = 0;
rx_bad_l4_csum = 0;
txp = &ports[fs->tx_port];
tx_ol_flags = txp->tx_ol_flags;
for (i = 0; i < nb_rx; i++) {
mb = pkts_burst[i];
l2_len = sizeof(struct ether_hdr);
pkt_ol_flags = mb->ol_flags;
ol_flags = (uint16_t) (pkt_ol_flags & (~PKT_TX_L4_MASK));
eth_hdr = (struct ether_hdr *) mb->pkt.data;
if (rte_be_to_cpu_16(eth_hdr->ether_type) == ETHER_TYPE_VLAN) {
/* Only allow single VLAN label here */
l2_len += sizeof(struct vlan_hdr);
}
/* Update the L3/L4 checksum error packet count */
rx_bad_ip_csum += (uint16_t) ((pkt_ol_flags & PKT_RX_IP_CKSUM_BAD) != 0);
rx_bad_l4_csum += (uint16_t) ((pkt_ol_flags & PKT_RX_L4_CKSUM_BAD) != 0);
/*
* Simplify the protocol parsing
* Assuming the incoming packets format as
* Ethernet2 + optional single VLAN
* + ipv4 or ipv6
* + udp or tcp or sctp or others
*/
if (pkt_ol_flags & PKT_RX_IPV4_HDR) {
/* Do not support ipv4 option field */
l3_len = sizeof(struct ipv4_hdr) ;
ipv4_hdr = (struct ipv4_hdr *) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len);
l4_proto = ipv4_hdr->next_proto_id;
/* Do not delete, this is required by HW*/
ipv4_hdr->hdr_checksum = 0;
if (tx_ol_flags & 0x1) {
/* HW checksum */
ol_flags |= PKT_TX_IP_CKSUM;
}
else {
/* SW checksum calculation */
ipv4_hdr->src_addr++;
ipv4_hdr->hdr_checksum = get_ipv4_cksum(ipv4_hdr);
}
if (l4_proto == IPPROTO_UDP) {
udp_hdr = (struct udp_hdr*) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len + l3_len);
if (tx_ol_flags & 0x2) {
/* HW Offload */
ol_flags |= PKT_TX_UDP_CKSUM;
/* Pseudo header sum need be set properly */
udp_hdr->dgram_cksum = get_ipv4_psd_sum(ipv4_hdr);
}
else {
/* SW Implementation, clear checksum field first */
udp_hdr->dgram_cksum = 0;
udp_hdr->dgram_cksum = get_ipv4_udptcp_checksum(ipv4_hdr,
(uint16_t*)udp_hdr);
}
}
else if (l4_proto == IPPROTO_TCP){
tcp_hdr = (struct tcp_hdr*) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len + l3_len);
if (tx_ol_flags & 0x4) {
ol_flags |= PKT_TX_TCP_CKSUM;
tcp_hdr->cksum = get_ipv4_psd_sum(ipv4_hdr);
}
else {
tcp_hdr->cksum = 0;
tcp_hdr->cksum = get_ipv4_udptcp_checksum(ipv4_hdr,
(uint16_t*)tcp_hdr);
}
}
else if (l4_proto == IPPROTO_SCTP) {
sctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len + l3_len);
if (tx_ol_flags & 0x8) {
ol_flags |= PKT_TX_SCTP_CKSUM;
sctp_hdr->cksum = 0;
/* Sanity check, only number of 4 bytes supported */
if ((rte_be_to_cpu_16(ipv4_hdr->total_length) % 4) != 0)
printf("sctp payload must be a multiple "
"of 4 bytes for checksum offload");
}
else {
sctp_hdr->cksum = 0;
/* CRC32c sample code available in RFC3309 */
}
}
/* End of L4 Handling*/
}
else {
ipv6_hdr = (struct ipv6_hdr *) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len);
l3_len = sizeof(struct ipv6_hdr) ;
l4_proto = ipv6_hdr->proto;
if (l4_proto == IPPROTO_UDP) {
udp_hdr = (struct udp_hdr*) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len + l3_len);
if (tx_ol_flags & 0x2) {
/* HW Offload */
ol_flags |= PKT_TX_UDP_CKSUM;
udp_hdr->dgram_cksum = get_ipv6_psd_sum(ipv6_hdr);
}
else {
/* SW Implementation */
/* checksum field need be clear first */
udp_hdr->dgram_cksum = 0;
udp_hdr->dgram_cksum = get_ipv6_udptcp_checksum(ipv6_hdr,
(uint16_t*)udp_hdr);
}
}
else if (l4_proto == IPPROTO_TCP) {
tcp_hdr = (struct tcp_hdr*) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len + l3_len);
if (tx_ol_flags & 0x4) {
ol_flags |= PKT_TX_TCP_CKSUM;
tcp_hdr->cksum = get_ipv6_psd_sum(ipv6_hdr);
}
else {
tcp_hdr->cksum = 0;
tcp_hdr->cksum = get_ipv6_udptcp_checksum(ipv6_hdr,
(uint16_t*)tcp_hdr);
}
}
else if (l4_proto == IPPROTO_SCTP) {
sctp_hdr = (struct sctp_hdr*) (rte_pktmbuf_mtod(mb,
unsigned char *) + l2_len + l3_len);
if (tx_ol_flags & 0x8) {
ol_flags |= PKT_TX_SCTP_CKSUM;
sctp_hdr->cksum = 0;
/* Sanity check, only number of 4 bytes supported by HW */
if ((rte_be_to_cpu_16(ipv6_hdr->payload_len) % 4) != 0)
printf("sctp payload must be a multiple "
"of 4 bytes for checksum offload");
}
else {
/* CRC32c sample code available in RFC3309 */
sctp_hdr->cksum = 0;
}
} else {
printf("Test flow control for 1G PMD \n");
}
/* End of L4 Handling*/
}
/* Combine the packet header write. VLAN is not consider here */
mb->pkt.l2_len = l2_len;
mb->pkt.l3_len = l3_len;
mb->ol_flags = ol_flags;
}
nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
fs->tx_packets += nb_tx;
fs->rx_bad_ip_csum += rx_bad_ip_csum;
fs->rx_bad_l4_csum += rx_bad_l4_csum;
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
#endif
if (unlikely(nb_tx < nb_rx)) {
fs->fwd_dropped += (nb_rx - nb_tx);
do {
rte_pktmbuf_free(pkts_burst[nb_tx]);
} while (++nb_tx < nb_rx);
}
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
end_tsc = rte_rdtsc();
core_cycles = (end_tsc - start_tsc);
fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
#endif
}
struct fwd_engine csum_fwd_engine = {
.fwd_mode_name = "csum",
.port_fwd_begin = NULL,
.port_fwd_end = NULL,
.packet_fwd = pkt_burst_checksum_forward,
};

657
app/test-pmd/ieee1588fwd.c Normal file
View File

@ -0,0 +1,657 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_cycles.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_memory.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_string_fns.h>
#include "testpmd.h"
/**
* The structure of a PTP V2 packet.
*
* Only the minimum fields used by the ieee1588 test are represented.
*/
struct ptpv2_msg {
uint8_t msg_id;
uint8_t version; /**< must be 0x02 */
uint8_t unused[34];
};
#define PTP_SYNC_MESSAGE 0x0
#define PTP_DELAY_REQ_MESSAGE 0x1
#define PTP_PATH_DELAY_REQ_MESSAGE 0x2
#define PTP_PATH_DELAY_RESP_MESSAGE 0x3
#define PTP_FOLLOWUP_MESSAGE 0x8
#define PTP_DELAY_RESP_MESSAGE 0x9
#define PTP_PATH_DELAY_FOLLOWUP_MESSAGE 0xA
#define PTP_ANNOUNCE_MESSAGE 0xB
#define PTP_SIGNALLING_MESSAGE 0xC
#define PTP_MANAGEMENT_MESSAGE 0xD
/*
* Forwarding of IEEE1588 Precise Time Protocol (PTP) packets.
*
* In this mode, packets are received one by one and are expected to be
* PTP V2 L2 Ethernet frames (with the specific Ethernet type "0x88F7")
* containing PTP "sync" messages (version 2 at offset 1, and message ID
* 0 at offset 0).
*
* Check that each received packet is a IEEE1588 PTP V2 packet of type
* PTP_SYNC_MESSAGE, and that it has been identified and timestamped
* by the hardware.
* Check that the value of the last RX timestamp recorded by the controller
* is greater than the previous one.
*
* If everything is OK, send the received packet back on the same port,
* requesting for it to be timestamped by the hardware.
* Check that the value of the last TX timestamp recorded by the controller
* is greater than the previous one.
*/
/*
* 1GbE 82576 Kawela registers used for IEEE1588 hardware support
*/
#define IGBE_82576_ETQF(n) (0x05CB0 + (4 * (n)))
#define IGBE_82576_ETQF_FILTER_ENABLE (1 << 26)
#define IGBE_82576_ETQF_1588_TIMESTAMP (1 << 30)
#define IGBE_82576_TSYNCRXCTL 0x0B620
#define IGBE_82576_TSYNCRXCTL_RXTS_ENABLE (1 << 4)
#define IGBE_82576_RXSTMPL 0x0B624
#define IGBE_82576_RXSTMPH 0x0B628
#define IGBE_82576_RXSATRL 0x0B62C
#define IGBE_82576_RXSATRH 0x0B630
#define IGBE_82576_TSYNCTXCTL 0x0B614
#define IGBE_82576_TSYNCTXCTL_TXTS_ENABLE (1 << 4)
#define IGBE_82576_TXSTMPL 0x0B618
#define IGBE_82576_TXSTMPH 0x0B61C
#define IGBE_82576_SYSTIML 0x0B600
#define IGBE_82576_SYSTIMH 0x0B604
#define IGBE_82576_TIMINCA 0x0B608
#define IGBE_82576_TIMADJL 0x0B60C
#define IGBE_82576_TIMADJH 0x0B610
#define IGBE_82576_TSAUXC 0x0B640
#define IGBE_82576_TRGTTIML0 0x0B644
#define IGBE_82576_TRGTTIMH0 0x0B648
#define IGBE_82576_TRGTTIML1 0x0B64C
#define IGBE_82576_TRGTTIMH1 0x0B650
#define IGBE_82576_AUXSTMPL0 0x0B65C
#define IGBE_82576_AUXSTMPH0 0x0B660
#define IGBE_82576_AUXSTMPL1 0x0B664
#define IGBE_82576_AUXSTMPH1 0x0B668
#define IGBE_82576_TSYNCRXCFG 0x05F50
#define IGBE_82576_TSSDP 0x0003C
/*
* 10GbE 82599 Niantic registers used for IEEE1588 hardware support
*/
#define IXGBE_82599_ETQF(n) (0x05128 + (4 * (n)))
#define IXGBE_82599_ETQF_FILTER_ENABLE (1 << 31)
#define IXGBE_82599_ETQF_1588_TIMESTAMP (1 << 30)
#define IXGBE_82599_TSYNCRXCTL 0x05188
#define IXGBE_82599_TSYNCRXCTL_RXTS_ENABLE (1 << 4)
#define IXGBE_82599_RXSTMPL 0x051E8
#define IXGBE_82599_RXSTMPH 0x051A4
#define IXGBE_82599_RXSATRL 0x051A0
#define IXGBE_82599_RXSATRH 0x051A8
#define IXGBE_82599_RXMTRL 0x05120
#define IXGBE_82599_TSYNCTXCTL 0x08C00
#define IXGBE_82599_TSYNCTXCTL_TXTS_ENABLE (1 << 4)
#define IXGBE_82599_TXSTMPL 0x08C04
#define IXGBE_82599_TXSTMPH 0x08C08
#define IXGBE_82599_SYSTIML 0x08C0C
#define IXGBE_82599_SYSTIMH 0x08C10
#define IXGBE_82599_TIMINCA 0x08C14
#define IXGBE_82599_TIMADJL 0x08C18
#define IXGBE_82599_TIMADJH 0x08C1C
#define IXGBE_82599_TSAUXC 0x08C20
#define IXGBE_82599_TRGTTIML0 0x08C24
#define IXGBE_82599_TRGTTIMH0 0x08C28
#define IXGBE_82599_TRGTTIML1 0x08C2C
#define IXGBE_82599_TRGTTIMH1 0x08C30
#define IXGBE_82599_AUXSTMPL0 0x08C3C
#define IXGBE_82599_AUXSTMPH0 0x08C40
#define IXGBE_82599_AUXSTMPL1 0x08C44
#define IXGBE_82599_AUXSTMPH1 0x08C48
/**
* Mandatory ETQF register for IEEE1588 packets filter.
*/
#define ETQF_FILTER_1588_REG 3
/**
* Recommended value for increment and period of
* the Increment Attribute Register.
*/
#define IEEE1588_TIMINCA_INIT ((0x02 << 24) | 0x00F42400)
/**
* Data structure with pointers to port-specific functions.
*/
typedef void (*ieee1588_start_t)(portid_t pi); /**< Start IEEE1588 feature. */
typedef void (*ieee1588_stop_t)(portid_t pi); /**< Stop IEEE1588 feature. */
typedef int (*tmst_read_t)(portid_t pi, uint64_t *tmst); /**< Read TMST regs */
struct port_ieee1588_ops {
ieee1588_start_t ieee1588_start;
ieee1588_stop_t ieee1588_stop;
tmst_read_t rx_tmst_read;
tmst_read_t tx_tmst_read;
};
/**
* 1GbE 82576 IEEE1588 operations.
*/
static void
igbe_82576_ieee1588_start(portid_t pi)
{
uint32_t tsync_ctl;
/*
* Start incrementation of the System Time registers used to
* timestamp PTP packets.
*/
port_id_pci_reg_write(pi, IGBE_82576_TIMINCA, IEEE1588_TIMINCA_INIT);
port_id_pci_reg_write(pi, IGBE_82576_TSAUXC, 0);
/*
* Enable L2 filtering of IEEE1588 Ethernet frame types.
*/
port_id_pci_reg_write(pi, IGBE_82576_ETQF(ETQF_FILTER_1588_REG),
(ETHER_TYPE_1588 |
IGBE_82576_ETQF_FILTER_ENABLE |
IGBE_82576_ETQF_1588_TIMESTAMP));
/*
* Enable timestamping of received PTP packets.
*/
tsync_ctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCRXCTL);
tsync_ctl |= IGBE_82576_TSYNCRXCTL_RXTS_ENABLE;
port_id_pci_reg_write(pi, IGBE_82576_TSYNCRXCTL, tsync_ctl);
/*
* Enable Timestamping of transmitted PTP packets.
*/
tsync_ctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCTXCTL);
tsync_ctl |= IGBE_82576_TSYNCTXCTL_TXTS_ENABLE;
port_id_pci_reg_write(pi, IGBE_82576_TSYNCTXCTL, tsync_ctl);
}
static void
igbe_82576_ieee1588_stop(portid_t pi)
{
uint32_t tsync_ctl;
/*
* Disable Timestamping of transmitted PTP packets.
*/
tsync_ctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCTXCTL);
tsync_ctl &= ~IGBE_82576_TSYNCTXCTL_TXTS_ENABLE;
port_id_pci_reg_write(pi, IGBE_82576_TSYNCTXCTL, tsync_ctl);
/*
* Disable timestamping of received PTP packets.
*/
tsync_ctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCRXCTL);
tsync_ctl &= ~IGBE_82576_TSYNCRXCTL_RXTS_ENABLE;
port_id_pci_reg_write(pi, IGBE_82576_TSYNCRXCTL, tsync_ctl);
/*
* Disable L2 filtering of IEEE1588 Ethernet types.
*/
port_id_pci_reg_write(pi, IGBE_82576_ETQF(ETQF_FILTER_1588_REG), 0);
/*
* Stop incrementation of the System Time registers.
*/
port_id_pci_reg_write(pi, IGBE_82576_TIMINCA, 0);
}
/**
* Return the 64-bit value contained in the RX IEEE1588 timestamp registers
* of a 1GbE 82576 port.
*
* @param pi
* The port identifier.
*
* @param tmst
* The address of a 64-bit variable to return the value of the RX timestamp.
*
* @return
* -1: the RXSTMPL and RXSTMPH registers of the port are not valid.
* 0: the variable pointed to by the "tmst" parameter contains the value
* of the RXSTMPL and RXSTMPH registers of the port.
*/
static int
igbe_82576_rx_timestamp_read(portid_t pi, uint64_t *tmst)
{
uint32_t tsync_rxctl;
uint32_t rx_stmpl;
uint32_t rx_stmph;
tsync_rxctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCRXCTL);
if ((tsync_rxctl & 0x01) == 0)
return (-1);
rx_stmpl = port_id_pci_reg_read(pi, IGBE_82576_RXSTMPL);
rx_stmph = port_id_pci_reg_read(pi, IGBE_82576_RXSTMPH);
*tmst = (uint64_t)(((uint64_t) rx_stmph << 32) | rx_stmpl);
return (0);
}
/**
* Return the 64-bit value contained in the TX IEEE1588 timestamp registers
* of a 1GbE 82576 port.
*
* @param pi
* The port identifier.
*
* @param tmst
* The address of a 64-bit variable to return the value of the TX timestamp.
*
* @return
* -1: the TXSTMPL and TXSTMPH registers of the port are not valid.
* 0: the variable pointed to by the "tmst" parameter contains the value
* of the TXSTMPL and TXSTMPH registers of the port.
*/
static int
igbe_82576_tx_timestamp_read(portid_t pi, uint64_t *tmst)
{
uint32_t tsync_txctl;
uint32_t tx_stmpl;
uint32_t tx_stmph;
tsync_txctl = port_id_pci_reg_read(pi, IGBE_82576_TSYNCTXCTL);
if ((tsync_txctl & 0x01) == 0)
return (-1);
tx_stmpl = port_id_pci_reg_read(pi, IGBE_82576_TXSTMPL);
tx_stmph = port_id_pci_reg_read(pi, IGBE_82576_TXSTMPH);
*tmst = (uint64_t)(((uint64_t) tx_stmph << 32) | tx_stmpl);
return (0);
}
static struct port_ieee1588_ops igbe_82576_ieee1588_ops = {
.ieee1588_start = igbe_82576_ieee1588_start,
.ieee1588_stop = igbe_82576_ieee1588_stop,
.rx_tmst_read = igbe_82576_rx_timestamp_read,
.tx_tmst_read = igbe_82576_tx_timestamp_read,
};
/**
* 10GbE 82599 IEEE1588 operations.
*/
static void
ixgbe_82599_ieee1588_start(portid_t pi)
{
uint32_t tsync_ctl;
/*
* Start incrementation of the System Time registers used to
* timestamp PTP packets.
*/
port_id_pci_reg_write(pi, IXGBE_82599_TIMINCA, IEEE1588_TIMINCA_INIT);
/*
* Enable L2 filtering of IEEE1588 Ethernet frame types.
*/
port_id_pci_reg_write(pi, IXGBE_82599_ETQF(ETQF_FILTER_1588_REG),
(ETHER_TYPE_1588 |
IXGBE_82599_ETQF_FILTER_ENABLE |
IXGBE_82599_ETQF_1588_TIMESTAMP));
/*
* Enable timestamping of received PTP packets.
*/
tsync_ctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCRXCTL);
tsync_ctl |= IXGBE_82599_TSYNCRXCTL_RXTS_ENABLE;
port_id_pci_reg_write(pi, IXGBE_82599_TSYNCRXCTL, tsync_ctl);
/*
* Enable Timestamping of transmitted PTP packets.
*/
tsync_ctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCTXCTL);
tsync_ctl |= IXGBE_82599_TSYNCTXCTL_TXTS_ENABLE;
port_id_pci_reg_write(pi, IXGBE_82599_TSYNCTXCTL, tsync_ctl);
}
static void
ixgbe_82599_ieee1588_stop(portid_t pi)
{
uint32_t tsync_ctl;
/*
* Disable Timestamping of transmitted PTP packets.
*/
tsync_ctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCTXCTL);
tsync_ctl &= ~IXGBE_82599_TSYNCTXCTL_TXTS_ENABLE;
port_id_pci_reg_write(pi, IXGBE_82599_TSYNCTXCTL, tsync_ctl);
/*
* Disable timestamping of received PTP packets.
*/
tsync_ctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCRXCTL);
tsync_ctl &= ~IXGBE_82599_TSYNCRXCTL_RXTS_ENABLE;
port_id_pci_reg_write(pi, IXGBE_82599_TSYNCRXCTL, tsync_ctl);
/*
* Disable L2 filtering of IEEE1588 Ethernet frame types.
*/
port_id_pci_reg_write(pi, IXGBE_82599_ETQF(ETQF_FILTER_1588_REG), 0);
/*
* Stop incrementation of the System Time registers.
*/
port_id_pci_reg_write(pi, IXGBE_82599_TIMINCA, 0);
}
/**
* Return the 64-bit value contained in the RX IEEE1588 timestamp registers
* of a 10GbE 82599 port.
*
* @param pi
* The port identifier.
*
* @param tmst
* The address of a 64-bit variable to return the value of the TX timestamp.
*
* @return
* -1: the RX timestamp registers of the port are not valid.
* 0: the variable pointed to by the "tmst" parameter contains the value
* of the RXSTMPL and RXSTMPH registers of the port.
*/
static int
ixgbe_82599_rx_timestamp_read(portid_t pi, uint64_t *tmst)
{
uint32_t tsync_rxctl;
uint32_t rx_stmpl;
uint32_t rx_stmph;
tsync_rxctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCRXCTL);
if ((tsync_rxctl & 0x01) == 0)
return (-1);
rx_stmpl = port_id_pci_reg_read(pi, IXGBE_82599_RXSTMPL);
rx_stmph = port_id_pci_reg_read(pi, IXGBE_82599_RXSTMPH);
*tmst = (uint64_t)(((uint64_t) rx_stmph << 32) | rx_stmpl);
return (0);
}
/**
* Return the 64-bit value contained in the TX IEEE1588 timestamp registers
* of a 10GbE 82599 port.
*
* @param pi
* The port identifier.
*
* @param tmst
* The address of a 64-bit variable to return the value of the TX timestamp.
*
* @return
* -1: the TXSTMPL and TXSTMPH registers of the port are not valid.
* 0: the variable pointed to by the "tmst" parameter contains the value
* of the TXSTMPL and TXSTMPH registers of the port.
*/
static int
ixgbe_82599_tx_timestamp_read(portid_t pi, uint64_t *tmst)
{
uint32_t tsync_txctl;
uint32_t tx_stmpl;
uint32_t tx_stmph;
tsync_txctl = port_id_pci_reg_read(pi, IXGBE_82599_TSYNCTXCTL);
if ((tsync_txctl & 0x01) == 0)
return (-1);
tx_stmpl = port_id_pci_reg_read(pi, IXGBE_82599_TXSTMPL);
tx_stmph = port_id_pci_reg_read(pi, IXGBE_82599_TXSTMPH);
*tmst = (uint64_t)(((uint64_t) tx_stmph << 32) | tx_stmpl);
return (0);
}
static struct port_ieee1588_ops ixgbe_82599_ieee1588_ops = {
.ieee1588_start = ixgbe_82599_ieee1588_start,
.ieee1588_stop = ixgbe_82599_ieee1588_stop,
.rx_tmst_read = ixgbe_82599_rx_timestamp_read,
.tx_tmst_read = ixgbe_82599_tx_timestamp_read,
};
static void
port_ieee1588_rx_timestamp_check(portid_t pi)
{
struct port_ieee1588_ops *ieee_ops;
uint64_t rx_tmst;
ieee_ops = (struct port_ieee1588_ops *)ports[pi].fwd_ctx;
if (ieee_ops->rx_tmst_read(pi, &rx_tmst) < 0) {
printf("Port %u: RX timestamp registers not valid\n",
(unsigned) pi);
return;
}
printf("Port %u RX timestamp value 0x%"PRIu64"\n",
(unsigned) pi, rx_tmst);
}
#define MAX_TX_TMST_WAIT_MICROSECS 1000 /**< 1 milli-second */
static void
port_ieee1588_tx_timestamp_check(portid_t pi)
{
struct port_ieee1588_ops *ieee_ops;
uint64_t tx_tmst;
unsigned wait_us;
ieee_ops = (struct port_ieee1588_ops *)ports[pi].fwd_ctx;
wait_us = 0;
while ((ieee_ops->tx_tmst_read(pi, &tx_tmst) < 0) &&
(wait_us < MAX_TX_TMST_WAIT_MICROSECS)) {
rte_delay_us(1);
wait_us++;
}
if (wait_us >= MAX_TX_TMST_WAIT_MICROSECS) {
printf("Port %u: TX timestamp registers not valid after"
"%u micro-seconds\n",
(unsigned) pi, (unsigned) MAX_TX_TMST_WAIT_MICROSECS);
return;
}
printf("Port %u TX timestamp value 0x%"PRIu64" validated after "
"%u micro-second%s\n",
(unsigned) pi, tx_tmst, wait_us,
(wait_us == 1) ? "" : "s");
}
static void
ieee1588_packet_fwd(struct fwd_stream *fs)
{
struct rte_mbuf *mb;
struct ether_hdr *eth_hdr;
struct ptpv2_msg *ptp_hdr;
uint16_t eth_type;
/*
* Receive 1 packet at a time.
*/
if (rte_eth_rx_burst(fs->rx_port, fs->rx_queue, &mb, 1) == 0)
return;
fs->rx_packets += 1;
/*
* Check that the received packet is a PTP packet that was detected
* by the hardware.
*/
eth_hdr = (struct ether_hdr *)mb->pkt.data;
eth_type = rte_be_to_cpu_16(eth_hdr->ether_type);
if (! (mb->ol_flags & PKT_RX_IEEE1588_PTP)) {
if (eth_type == ETHER_TYPE_1588) {
printf("Port %u Received PTP packet not filtered"
" by hardware\n",
(unsigned) fs->rx_port);
} else {
printf("Port %u Received non PTP packet type=0x%4x "
"len=%u\n",
(unsigned) fs->rx_port, eth_type,
(unsigned) mb->pkt.pkt_len);
}
rte_pktmbuf_free(mb);
return;
}
if (eth_type != ETHER_TYPE_1588) {
printf("Port %u Received NON PTP packet wrongly"
" detected by hardware\n",
(unsigned) fs->rx_port);
rte_pktmbuf_free(mb);
return;
}
/*
* Check that the received PTP packet is a PTP V2 packet of type
* PTP_SYNC_MESSAGE.
*/
ptp_hdr = (struct ptpv2_msg *) ((char *) mb->pkt.data +
sizeof(struct ether_hdr));
if (ptp_hdr->version != 0x02) {
printf("Port %u Received PTP V2 Ethernet frame with wrong PTP"
" protocol version 0x%x (should be 0x02)\n",
(unsigned) fs->rx_port, ptp_hdr->version);
rte_pktmbuf_free(mb);
return;
}
if (ptp_hdr->msg_id != PTP_SYNC_MESSAGE) {
printf("Port %u Received PTP V2 Ethernet frame with unexpected"
" messageID 0x%x (expected 0x0 - PTP_SYNC_MESSAGE)\n",
(unsigned) fs->rx_port, ptp_hdr->msg_id);
rte_pktmbuf_free(mb);
return;
}
printf("Port %u IEEE1588 PTP V2 SYNC Message filtered by hardware\n",
(unsigned) fs->rx_port);
/*
* Check that the received PTP packet has been timestamped by the
* hardware.
*/
if (! (mb->ol_flags & PKT_RX_IEEE1588_TMST)) {
printf("Port %u Received PTP packet not timestamped"
" by hardware\n",
(unsigned) fs->rx_port);
rte_pktmbuf_free(mb);
return;
}
/* Check the RX timestamp */
port_ieee1588_rx_timestamp_check(fs->rx_port);
/* Forward PTP packet with hardware TX timestamp */
mb->ol_flags |= PKT_TX_IEEE1588_TMST;
fs->tx_packets += 1;
if (rte_eth_tx_burst(fs->rx_port, fs->tx_queue, &mb, 1) == 0) {
printf("Port %u sent PTP packet dropped\n",
(unsigned) fs->rx_port);
fs->fwd_dropped += 1;
rte_pktmbuf_free(mb);
return;
}
/*
* Check the TX timestamp.
*/
port_ieee1588_tx_timestamp_check(fs->rx_port);
}
static void
port_ieee1588_fwd_begin(portid_t pi)
{
struct port_ieee1588_ops *ieee_ops;
if (strcmp(ports[pi].dev_info.driver_name, "rte_igb_pmd") == 0)
ieee_ops = &igbe_82576_ieee1588_ops;
else
ieee_ops = &ixgbe_82599_ieee1588_ops;
ports[pi].fwd_ctx = ieee_ops;
(ieee_ops->ieee1588_start)(pi);
}
static void
port_ieee1588_fwd_end(portid_t pi)
{
struct port_ieee1588_ops *ieee_ops;
ieee_ops = (struct port_ieee1588_ops *)ports[pi].fwd_ctx;
(ieee_ops->ieee1588_stop)(pi);
}
struct fwd_engine ieee1588_fwd_engine = {
.fwd_mode_name = "ieee1588",
.port_fwd_begin = port_ieee1588_fwd_begin,
.port_fwd_end = port_ieee1588_fwd_end,
.packet_fwd = ieee1588_packet_fwd,
};

131
app/test-pmd/iofwd.c Normal file
View File

@ -0,0 +1,131 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_cycles.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_string_fns.h>
#include "testpmd.h"
/*
* Forwarding of packets in I/O mode.
* Forward packets "as-is".
* This is the fastest possible forwarding operation, as it does not access
* to packets data.
*/
static void
pkt_burst_io_forward(struct fwd_stream *fs)
{
struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
uint16_t nb_rx;
uint16_t nb_tx;
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
uint64_t start_tsc;
uint64_t end_tsc;
uint64_t core_cycles;
#endif
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
start_tsc = rte_rdtsc();
#endif
/*
* Receive a burst of packets and forward them.
*/
nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
nb_pkt_per_burst);
if (unlikely(nb_rx == 0))
return;
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
#endif
fs->rx_packets += nb_rx;
nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
fs->tx_packets += nb_tx;
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
#endif
if (unlikely(nb_tx < nb_rx)) {
fs->fwd_dropped += (nb_rx - nb_tx);
do {
rte_pktmbuf_free(pkts_burst[nb_tx]);
} while (++nb_tx < nb_rx);
}
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
end_tsc = rte_rdtsc();
core_cycles = (end_tsc - start_tsc);
fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
#endif
}
struct fwd_engine io_fwd_engine = {
.fwd_mode_name = "io",
.port_fwd_begin = NULL,
.port_fwd_end = NULL,
.packet_fwd = pkt_burst_io_forward,
};

148
app/test-pmd/macfwd.c Normal file
View File

@ -0,0 +1,148 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_cycles.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_memory.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_ip.h>
#include <rte_string_fns.h>
#include "testpmd.h"
/*
* Forwarding of packets in MAC mode.
* Change the source and the destination Ethernet addressed of packets
* before forwarding them.
*/
static void
pkt_burst_mac_forward(struct fwd_stream *fs)
{
struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
struct rte_port *txp;
struct rte_mbuf *mb;
struct ether_hdr *eth_hdr;
uint16_t nb_rx;
uint16_t nb_tx;
uint16_t i;
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
uint64_t start_tsc;
uint64_t end_tsc;
uint64_t core_cycles;
#endif
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
start_tsc = rte_rdtsc();
#endif
/*
* Receive a burst of packets and forward them.
*/
nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
nb_pkt_per_burst);
if (unlikely(nb_rx == 0))
return;
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
#endif
fs->rx_packets += nb_rx;
txp = &ports[fs->tx_port];
for (i = 0; i < nb_rx; i++) {
mb = pkts_burst[i];
eth_hdr = (struct ether_hdr *) mb->pkt.data;
ether_addr_copy(&peer_eth_addrs[fs->peer_addr],
&eth_hdr->d_addr);
ether_addr_copy(&ports[fs->tx_port].eth_addr,
&eth_hdr->s_addr);
mb->ol_flags = txp->tx_ol_flags;
mb->pkt.l2_len = sizeof(struct ether_hdr);
mb->pkt.l3_len = sizeof(struct ipv4_hdr);
mb->pkt.vlan_tci = txp->tx_vlan_id;
}
nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_rx);
fs->tx_packets += nb_tx;
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
#endif
if (unlikely(nb_tx < nb_rx)) {
fs->fwd_dropped += (nb_rx - nb_tx);
do {
rte_pktmbuf_free(pkts_burst[nb_tx]);
} while (++nb_tx < nb_rx);
}
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
end_tsc = rte_rdtsc();
core_cycles = (end_tsc - start_tsc);
fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
#endif
}
struct fwd_engine mac_fwd_engine = {
.fwd_mode_name = "mac",
.port_fwd_begin = NULL,
.port_fwd_end = NULL,
.packet_fwd = pkt_burst_mac_forward,
};

646
app/test-pmd/parameters.c Normal file
View File

@ -0,0 +1,646 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <errno.h>
#include <getopt.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h>
#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_cycles.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_mempool.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_string_fns.h>
#include <cmdline_parse.h>
#include <cmdline_parse_etheraddr.h>
#include "testpmd.h"
static void
usage(char* progname)
{
printf("usage: %s [--interactive|-i] [--help|-h] | ["
"--coremask=COREMASK --portmask=PORTMASK --numa "
"--eth-peers-configfile= | "
"--eth-peer=X,M:M:M:M:M:M | --nb-cores= | --nb-ports= | "
"--pkt-filter-mode= |"
"--rss-ip | --rss-udp | "
"--rxpt= | --rxht= | --rxwt= | --rxfreet= | "
"--txpt= | --txht= | --txwt= | --txfreet= | "
"--txrst= ]\n",
progname);
printf(" --interactive: run in interactive mode\n");
printf(" --help: display this message and quit\n");
printf(" --eth-peers-configfile=name of file with ethernet addresses "
"of peer ports\n");
printf(" --eth-peer=X,M:M:M:M:M:M set the mac address of the X peer "
"port (0 <= X < %d)\n", RTE_MAX_ETHPORTS);
printf(" --nb-cores=N set the number of forwarding cores"
" (1 <= N <= %d)\n", nb_lcores);
printf(" --nb-ports=N set the number of forwarding ports"
" (1 <= N <= %d)\n", nb_ports);
printf(" --coremask=COREMASK: hexadecimal bitmask of cores running "
"the packet forwarding test\n");
printf(" --portmask=PORTMASK: hexadecimal bitmask of ports used "
"by the packet forwarding test\n");
printf(" --numa: enable NUMA-aware allocation of RX/TX rings and of "
" RX memory buffers (mbufs)\n");
printf(" --mbuf-size=N set the data size of mbuf to N bytes\n");
printf(" --max-pkt-len=N set the maximum size of packet to N bytes\n");
printf(" --pkt-filter-mode=N: set Flow director mode "
"( N: none (default mode) or signature or perfect)\n");
printf(" --pkt-filter-report-hash=N: set Flow director report mode "
"( N: none or match (default) or always)\n");
printf(" --pkt-filter-size=N: set Flow director mode "
"( N: 64K (default mode) or 128K or 256K)\n");
printf(" --pkt-filter-flexbytes-offset=N: set flexbytes-offset."
" The offset is defined in word units counted from the"
" first byte of the destination Ethernet MAC address."
" 0 <= N <= 32\n");
printf(" --pkt-filter-drop-queue=N: set drop-queue."
" In perfect mode, when you add a rule with queue -1"
" the packet will be enqueued into the rx drop-queue."
" If the drop-queue doesn't exist, the packet is dropped."
" By default drop-queue=127\n");
printf(" --crc-strip: enable CRC stripping by hardware\n");
printf(" --enable-rx-cksum: enable rx hardware checksum offload\n");
printf(" --disable-hw-vlan: disable hardware vlan\n");
printf(" --disable-rss: disable rss\n");
printf(" --port-topology=N: set port topology (N: paired (default) or "
"chained)\n");
printf(" --rss-ip: set RSS functions to IPv4/IPv6 only \n");
printf(" --rss-udp: set RSS functions to IPv4/IPv6 + UDP\n");
printf(" --rxq=N set the number of RX queues per port to N\n");
printf(" --rxd=N set the number of descriptors in RX rings to N\n");
printf(" --txq=N set the number of TX queues per port to N\n");
printf(" --txd=N set the number of descriptors in TX rings to N\n");
printf(" --burst=N set the number of packets per burst to N\n");
printf(" --mbcache=N set the cache of mbuf memory pool to N\n");
printf(" --rxpt=N set prefetch threshold register of RX rings to N"
" (0 <= N <= 16)\n");
printf(" --rxht=N set the host threshold register of RX rings to N"
" (0 <= N <= 16)\n");
printf(" --rxfreet=N set the free threshold of RX descriptors to N"
" (0 <= N < value of rxd)\n");
printf(" --rxwt=N set the write-back threshold register of RX rings"
" to N (0 <= N <= 16)\n");
printf(" --txpt=N set the prefetch threshold register of TX rings"
" to N (0 <= N <= 16)\n");
printf(" --txht=N set the nhost threshold register of TX rings to N"
" (0 <= N <= 16)\n");
printf(" --txwt=N set the write-back threshold register of TX rings"
" to N (0 <= N <= 16)\n");
printf(" --txfreet=N set the transmit free threshold of TX rings to N"
" (0 <= N <= value of txd)\n");
printf(" --txrst=N set the transmit RS bit threshold of TX rings to N"
" (0 <= N <= value of txd)\n");
}
static int
init_peer_eth_addrs(char *config_filename)
{
FILE *config_file;
portid_t i;
char buf[50];
config_file = fopen(config_filename, "r");
if (config_file == NULL) {
perror("open log file failed\n");
return -1;
}
for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
if (fgets(buf, sizeof(buf), config_file) == NULL)
break;
if (cmdline_parse_etheraddr(NULL, buf, &peer_eth_addrs[i]) < 0 ){
printf("bad format of mac address on line %d\n", i);
fclose(config_file);
return -1;
}
}
fclose(config_file);
nb_peer_eth_addrs = (portid_t) i;
return 0;
}
/*
* Parse the coremask given as argument (hexadecimal string) and set
* the global configuration of forwarding cores.
*/
static void
parse_fwd_coremask(const char *coremask)
{
char *end;
unsigned long long int cm;
/* parse hexadecimal string */
end = NULL;
cm = strtoull(coremask, &end, 16);
if ((coremask[0] == '\0') || (end == NULL) || (*end != '\0'))
rte_exit(EXIT_FAILURE, "Invalid fwd core mask\n");
else
set_fwd_lcores_mask((uint64_t) cm);
}
/*
* Parse the coremask given as argument (hexadecimal string) and set
* the global configuration of forwarding cores.
*/
static void
parse_fwd_portmask(const char *portmask)
{
char *end;
unsigned long long int pm;
/* parse hexadecimal string */
end = NULL;
pm = strtoull(portmask, &end, 16);
if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
rte_exit(EXIT_FAILURE, "Invalid fwd port mask\n");
else
set_fwd_ports_mask((uint64_t) pm);
}
void
launch_args_parse(int argc, char** argv)
{
int n, opt;
char **argvopt;
int opt_idx;
static struct option lgopts[] = {
{ "help", 0, 0, 0 },
{ "interactive", 0, 0, 0 },
{ "eth-peers-configfile", 1, 0, 0 },
{ "eth-peer", 1, 0, 0 },
{ "ports", 1, 0, 0 },
{ "nb-cores", 1, 0, 0 },
{ "nb-ports", 1, 0, 0 },
{ "coremask", 1, 0, 0 },
{ "portmask", 1, 0, 0 },
{ "numa", 0, 0, 0 },
{ "mbuf-size", 1, 0, 0 },
{ "max-pkt-len", 1, 0, 0 },
{ "pkt-filter-mode", 1, 0, 0 },
{ "pkt-filter-report-hash", 1, 0, 0 },
{ "pkt-filter-size", 1, 0, 0 },
{ "pkt-filter-flexbytes-offset",1, 0, 0 },
{ "pkt-filter-drop-queue", 1, 0, 0 },
{ "crc-strip", 0, 0, 0 },
{ "disable-hw-vlan", 0, 0, 0 },
{ "disable-rss", 0, 0, 0 },
{ "port-topology", 1, 0, 0 },
{ "rss-ip", 0, 0, 0 },
{ "rss-udp", 0, 0, 0 },
{ "rxq", 1, 0, 0 },
{ "txq", 1, 0, 0 },
{ "rxd", 1, 0, 0 },
{ "txd", 1, 0, 0 },
{ "burst", 1, 0, 0 },
{ "mbcache", 1, 0, 0 },
{ "txpt", 1, 0, 0 },
{ "txht", 1, 0, 0 },
{ "txwt", 1, 0, 0 },
{ "txfreet", 1, 0, 0 },
{ "txrst", 1, 0, 0 },
{ "rxpt", 1, 0, 0 },
{ "rxht", 1, 0, 0 },
{ "rxwt", 1, 0, 0 },
{ "rxfreet", 1, 0, 0 },
{ 0, 0, 0, 0 },
};
argvopt = argv;
while ((opt = getopt_long(argc, argvopt, "ih",
lgopts, &opt_idx)) != EOF) {
switch (opt) {
case 'i':
printf("Interactive-mode selected\n");
interactive = 1;
break;
case 0: /*long options */
if (!strcmp(lgopts[opt_idx].name, "help")) {
usage(argv[0]);
rte_exit(EXIT_SUCCESS, "Displayed help\n");
}
if (!strcmp(lgopts[opt_idx].name, "interactive")) {
printf("Interactive-mode selected\n");
interactive = 1;
}
if (!strcmp(lgopts[opt_idx].name,
"eth-peers-configfile")) {
if (init_peer_eth_addrs(optarg) != 0)
rte_exit(EXIT_FAILURE,
"Cannot open logfile\n");
}
if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
char *port_end;
uint8_t c, peer_addr[6];
errno = 0;
n = strtoul(optarg, &port_end, 10);
if (errno != 0 || port_end == optarg || *port_end++ != ',')
rte_exit(EXIT_FAILURE,
"Invalid eth-peer: %s", optarg);
if (n >= RTE_MAX_ETHPORTS)
rte_exit(EXIT_FAILURE,
"eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
n, RTE_MAX_ETHPORTS);
if (cmdline_parse_etheraddr(NULL, port_end, &peer_addr) < 0 )
rte_exit(EXIT_FAILURE,
"Invalid ethernet address: %s\n",
port_end);
for (c = 0; c < 6; c++)
peer_eth_addrs[n].addr_bytes[c] =
peer_addr[c];
nb_peer_eth_addrs++;
}
if (!strcmp(lgopts[opt_idx].name, "nb-ports")) {
n = atoi(optarg);
if (n > 0 && n <= nb_ports)
nb_fwd_ports = (uint8_t) n;
else
rte_exit(EXIT_FAILURE,
"nb-ports should be > 0 and <= %d\n",
nb_ports);
}
if (!strcmp(lgopts[opt_idx].name, "nb-cores")) {
n = atoi(optarg);
if (n > 0 && n <= nb_lcores)
nb_fwd_lcores = (uint8_t) n;
else
rte_exit(EXIT_FAILURE,
"nb-cores should be > 0 and <= %d\n",
nb_lcores);
}
if (!strcmp(lgopts[opt_idx].name, "coremask"))
parse_fwd_coremask(optarg);
if (!strcmp(lgopts[opt_idx].name, "portmask"))
parse_fwd_portmask(optarg);
if (!strcmp(lgopts[opt_idx].name, "numa"))
numa_support = 1;
if (!strcmp(lgopts[opt_idx].name, "mbuf-size")) {
n = atoi(optarg);
if (n > 0 && n <= 0xFFFF)
mbuf_data_size = (uint16_t) n;
else
rte_exit(EXIT_FAILURE,
"mbuf-size should be > 0 and < 65536\n");
}
if (!strcmp(lgopts[opt_idx].name, "max-pkt-len")) {
n = atoi(optarg);
if (n >= ETHER_MIN_LEN) {
rx_mode.max_rx_pkt_len = (uint32_t) n;
if (n > ETHER_MAX_LEN)
rx_mode.jumbo_frame = 1;
} else
rte_exit(EXIT_FAILURE,
"Invalid max-pkt-len=%d - should be > %d\n",
n, ETHER_MIN_LEN);
}
if (!strcmp(lgopts[opt_idx].name, "pkt-filter-mode")) {
if (!strcmp(optarg, "signature"))
fdir_conf.mode =
RTE_FDIR_MODE_SIGNATURE;
else if (!strcmp(optarg, "perfect"))
fdir_conf.mode = RTE_FDIR_MODE_PERFECT;
else if (!strcmp(optarg, "none"))
fdir_conf.mode = RTE_FDIR_MODE_NONE;
else
rte_exit(EXIT_FAILURE,
"pkt-mode-invalid %s invalid - must be: "
"none, signature or perfect\n",
optarg);
}
if (!strcmp(lgopts[opt_idx].name,
"pkt-filter-report-hash")) {
if (!strcmp(optarg, "none"))
fdir_conf.status =
RTE_FDIR_NO_REPORT_STATUS;
else if (!strcmp(optarg, "match"))
fdir_conf.status =
RTE_FDIR_REPORT_STATUS;
else if (!strcmp(optarg, "always"))
fdir_conf.status =
RTE_FDIR_REPORT_STATUS_ALWAYS;
else
rte_exit(EXIT_FAILURE,
"pkt-filter-report-hash %s invalid "
"- must be: none or match or always\n",
optarg);
}
if (!strcmp(lgopts[opt_idx].name, "pkt-filter-size")) {
if (!strcmp(optarg, "64K"))
fdir_conf.pballoc =
RTE_FDIR_PBALLOC_64K;
else if (!strcmp(optarg, "128K"))
fdir_conf.pballoc =
RTE_FDIR_PBALLOC_128K;
else if (!strcmp(optarg, "256K"))
fdir_conf.pballoc =
RTE_FDIR_PBALLOC_256K;
else
rte_exit(EXIT_FAILURE, "pkt-filter-size %s invalid -"
" must be: 64K or 128K or 256K\n",
optarg);
}
if (!strcmp(lgopts[opt_idx].name,
"pkt-filter-flexbytes-offset")) {
n = atoi(optarg);
if ( n >= 0 && n <= (int) 32)
fdir_conf.flexbytes_offset =
(uint8_t) n;
else
rte_exit(EXIT_FAILURE,
"flexbytes %d invalid - must"
"be >= 0 && <= 32\n", n);
}
if (!strcmp(lgopts[opt_idx].name,
"pkt-filter-drop-queue")) {
n = atoi(optarg);
if (n >= 0)
fdir_conf.drop_queue = (uint8_t) n;
else
rte_exit(EXIT_FAILURE,
"drop queue %d invalid - must"
"be >= 0 \n", n);
}
if (!strcmp(lgopts[opt_idx].name, "crc-strip"))
rx_mode.hw_strip_crc = 1;
if (!strcmp(lgopts[opt_idx].name, "enable-rx-cksum"))
rx_mode.hw_ip_checksum = 1;
if (!strcmp(lgopts[opt_idx].name, "disable-hw-vlan"))
rx_mode.hw_vlan_filter = 0;
if (!strcmp(lgopts[opt_idx].name, "disable-rss"))
rss_hf = 0;
if (!strcmp(lgopts[opt_idx].name, "port-topology")) {
if (!strcmp(optarg, "paired"))
port_topology = PORT_TOPOLOGY_PAIRED;
else if (!strcmp(optarg, "chained"))
port_topology = PORT_TOPOLOGY_CHAINED;
else
rte_exit(EXIT_FAILURE, "port-topology %s invalid -"
" must be: paired or chained \n",
optarg);
}
if (!strcmp(lgopts[opt_idx].name, "rss-ip"))
rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6;
if (!strcmp(lgopts[opt_idx].name, "rss-udp"))
rss_hf = ETH_RSS_IPV4 | ETH_RSS_IPV6 |
ETH_RSS_IPV4_UDP;
if (!strcmp(lgopts[opt_idx].name, "rxq")) {
n = atoi(optarg);
if (n >= 1 && n <= (int) MAX_QUEUE_ID)
nb_rxq = (queueid_t) n;
else
rte_exit(EXIT_FAILURE, "rxq %d invalid - must be"
" >= 1 && <= %d\n", n,
(int) MAX_QUEUE_ID);
}
if (!strcmp(lgopts[opt_idx].name, "txq")) {
n = atoi(optarg);
if (n >= 1 && n <= (int) MAX_QUEUE_ID)
nb_txq = (queueid_t) n;
else
rte_exit(EXIT_FAILURE, "txq %d invalid - must be"
" >= 1 && <= %d\n", n,
(int) MAX_QUEUE_ID);
}
if (!strcmp(lgopts[opt_idx].name, "rxd")) {
n = atoi(optarg);
if (n > 0)
nb_rxd = (uint16_t) n;
else
rte_exit(EXIT_FAILURE, "rxd must be > 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "txd")) {
n = atoi(optarg);
if (n > 0)
nb_txd = (uint16_t) n;
else
rte_exit(EXIT_FAILURE, "txd must be in > 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "burst")) {
n = atoi(optarg);
if ((n >= 1) && (n <= MAX_PKT_BURST))
nb_pkt_per_burst = (uint16_t) n;
else
rte_exit(EXIT_FAILURE,
"burst must >= 1 and <= %d]",
MAX_PKT_BURST);
}
if (!strcmp(lgopts[opt_idx].name, "mbcache")) {
n = atoi(optarg);
if ((n >= 0) &&
(n <= RTE_MEMPOOL_CACHE_MAX_SIZE))
mb_mempool_cache = (uint16_t) n;
else
rte_exit(EXIT_FAILURE,
"mbcache must be >= 0 and <= %d\n",
RTE_MEMPOOL_CACHE_MAX_SIZE);
}
if (!strcmp(lgopts[opt_idx].name, "txpt")) {
n = atoi(optarg);
if (n >= 0)
tx_thresh.pthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "txpt must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "txht")) {
n = atoi(optarg);
if (n >= 0)
tx_thresh.hthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "txht must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "txwt")) {
n = atoi(optarg);
if (n >= 0)
tx_thresh.wthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "txwt must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "txfreet")) {
n = atoi(optarg);
if (n >= 0)
tx_free_thresh = (uint16_t)n;
else
rte_exit(EXIT_FAILURE, "txfreet must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "txrst")) {
n = atoi(optarg);
if (n >= 0)
tx_rs_thresh = (uint16_t)n;
else
rte_exit(EXIT_FAILURE, "txrst must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "rxpt")) {
n = atoi(optarg);
if (n >= 0)
rx_thresh.pthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "rxpt must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "rxht")) {
n = atoi(optarg);
if (n >= 0)
rx_thresh.hthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "rxht must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "rxwt")) {
n = atoi(optarg);
if (n >= 0)
rx_thresh.wthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "rxwt must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "rxd")) {
n = atoi(optarg);
if (n > 0) {
if (rx_free_thresh >= n)
rte_exit(EXIT_FAILURE,
"rxd must be > "
"rx_free_thresh(%d)\n",
(int)rx_free_thresh);
else
nb_rxd = (uint16_t) n;
} else
rte_exit(EXIT_FAILURE,
"rxd(%d) invalid - must be > 0\n",
n);
}
if (!strcmp(lgopts[opt_idx].name, "txd")) {
n = atoi(optarg);
if (n > 0)
nb_txd = (uint16_t) n;
else
rte_exit(EXIT_FAILURE, "txd must be in > 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "txpt")) {
n = atoi(optarg);
if (n >= 0)
tx_thresh.pthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "txpt must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "txht")) {
n = atoi(optarg);
if (n >= 0)
tx_thresh.hthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "txht must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "txwt")) {
n = atoi(optarg);
if (n >= 0)
tx_thresh.wthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "txwt must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "rxpt")) {
n = atoi(optarg);
if (n >= 0)
rx_thresh.pthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "rxpt must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "rxht")) {
n = atoi(optarg);
if (n >= 0)
rx_thresh.hthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "rxht must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "rxwt")) {
n = atoi(optarg);
if (n >= 0)
rx_thresh.wthresh = (uint8_t)n;
else
rte_exit(EXIT_FAILURE, "rxwt must be >= 0\n");
}
if (!strcmp(lgopts[opt_idx].name, "rxfreet")) {
n = atoi(optarg);
if (n >= 0)
rx_free_thresh = (uint16_t)n;
else
rte_exit(EXIT_FAILURE, "rxfreet must be >= 0\n");
}
break;
case 'h':
usage(argv[0]);
rte_exit(EXIT_SUCCESS, "Displayed help\n");
break;
default:
usage(argv[0]);
rte_exit(EXIT_FAILURE,
"Command line is incomplete or incorrect\n");
break;
}
}
}

194
app/test-pmd/rxonly.c Normal file
View File

@ -0,0 +1,194 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_cycles.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_memory.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_string_fns.h>
#include "testpmd.h"
#define MAX_PKT_RX_FLAGS 11
static const char *pkt_rx_flag_names[MAX_PKT_RX_FLAGS] = {
"VLAN_PKT",
"RSS_HASH",
"PKT_RX_FDIR",
"IP_CKSUM",
"IP_CKSUM_BAD",
"IPV4_HDR",
"IPV4_HDR_EXT",
"IPV6_HDR",
"IPV6_HDR_EXT",
"IEEE1588_PTP",
"IEEE1588_TMST",
};
static inline void
print_ether_addr(const char *what, struct ether_addr *eth_addr)
{
printf("%s%02X:%02X:%02X:%02X:%02X:%02X",
what,
eth_addr->addr_bytes[0],
eth_addr->addr_bytes[1],
eth_addr->addr_bytes[2],
eth_addr->addr_bytes[3],
eth_addr->addr_bytes[4],
eth_addr->addr_bytes[5]);
}
/*
* Received a burst of packets.
*/
static void
pkt_burst_receive(struct fwd_stream *fs)
{
struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
struct rte_mbuf *mb;
struct ether_hdr *eth_hdr;
uint16_t eth_type;
uint16_t ol_flags;
uint16_t nb_rx;
uint16_t i;
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
uint64_t start_tsc;
uint64_t end_tsc;
uint64_t core_cycles;
#endif
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
start_tsc = rte_rdtsc();
#endif
/*
* Receive a burst of packets.
*/
nb_rx = rte_eth_rx_burst(fs->rx_port, fs->rx_queue, pkts_burst,
nb_pkt_per_burst);
if (unlikely(nb_rx == 0))
return;
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
fs->rx_burst_stats.pkt_burst_spread[nb_rx]++;
#endif
fs->rx_packets += nb_rx;
/*
* Dump each received packet if verbose_level > 0.
*/
if (verbose_level > 0)
printf("port %u/queue %u: received %u packets\n",
(unsigned) fs->rx_port,
(unsigned) fs->rx_queue,
(unsigned) nb_rx);
for (i = 0; i < nb_rx; i++) {
mb = pkts_burst[i];
if (verbose_level == 0) {
rte_pktmbuf_free(mb);
continue;
}
eth_hdr = (struct ether_hdr *) mb->pkt.data;
eth_type = RTE_BE_TO_CPU_16(eth_hdr->ether_type);
ol_flags = mb->ol_flags;
print_ether_addr(" src=", &eth_hdr->s_addr);
print_ether_addr(" - dst=", &eth_hdr->d_addr);
printf(" - type=0x%04x - length=%u - nb_segs=%d",
eth_type, (unsigned) mb->pkt.pkt_len,
(int)mb->pkt.nb_segs);
if (ol_flags & PKT_RX_RSS_HASH)
printf(" - RSS hash=0x%x", (unsigned) mb->pkt.hash.rss);
else if (ol_flags & PKT_RX_FDIR)
printf(" - FDIR hash=0x%x - FDIR id=0x%x ",
mb->pkt.hash.fdir.hash, mb->pkt.hash.fdir.id);
if (ol_flags & PKT_RX_VLAN_PKT)
printf(" - VLAN tci=0x%x", mb->pkt.vlan_tci);
printf("\n");
if (ol_flags != 0) {
int rxf;
for (rxf = 0; rxf < MAX_PKT_RX_FLAGS; rxf++) {
if (ol_flags & (1 << rxf))
printf(" PKT_RX_%s\n",
pkt_rx_flag_names[rxf]);
}
}
rte_pktmbuf_free(mb);
}
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
end_tsc = rte_rdtsc();
core_cycles = (end_tsc - start_tsc);
fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
#endif
}
struct fwd_engine rx_only_engine = {
.fwd_mode_name = "rxonly",
.port_fwd_begin = NULL,
.port_fwd_end = NULL,
.packet_fwd = pkt_burst_receive,
};

1105
app/test-pmd/testpmd.c Normal file

File diff suppressed because it is too large Load Diff

413
app/test-pmd/testpmd.h Normal file
View File

@ -0,0 +1,413 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#ifndef _TESTPMD_H_
#define _TESTPMD_H_
/* icc on baremetal gives us troubles with function named 'main' */
#ifdef RTE_EXEC_ENV_BAREMETAL
#define main _main
int main(int argc, char **argv);
#endif
/*
* Default size of the mbuf data buffer to receive standard 1518-byte
* Ethernet frames in a mono-segment memory buffer.
*/
#define DEFAULT_MBUF_DATA_SIZE 2048 /**< Default size of mbuf data buffer. */
/*
* The maximum number of segments per packet is used when creating
* scattered transmit packets composed of a list of mbufs.
*/
#define RTE_MAX_SEGS_PER_PKT 255 /**< pkt.nb_segs is a 8-bit unsigned char. */
#define MAX_PKT_BURST 512
#define DEF_PKT_BURST 16
#define CACHE_LINE_SIZE_ROUNDUP(size) \
(CACHE_LINE_SIZE * ((size + CACHE_LINE_SIZE - 1) / CACHE_LINE_SIZE))
typedef uint8_t lcoreid_t;
typedef uint8_t portid_t;
typedef uint16_t queueid_t;
typedef uint16_t streamid_t;
#define MAX_QUEUE_ID ((1 << (sizeof(queueid_t) * 8)) - 1)
enum {
PORT_TOPOLOGY_PAIRED,
PORT_TOPOLOGY_CHAINED
};
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
/**
* The data structure associated with RX and TX packet burst statistics
* that are recorded for each forwarding stream.
*/
struct pkt_burst_stats {
unsigned int pkt_burst_spread[MAX_PKT_BURST];
};
#endif
/**
* The data structure associated with a forwarding stream between a receive
* port/queue and a transmit port/queue.
*/
struct fwd_stream {
/* "read-only" data */
portid_t rx_port; /**< port to poll for received packets */
queueid_t rx_queue; /**< RX queue to poll on "rx_port" */
portid_t tx_port; /**< forwarding port of received packets */
queueid_t tx_queue; /**< TX queue to send forwarded packets */
streamid_t peer_addr; /**< index of peer ethernet address of packets */
/* "read-write" results */
unsigned int rx_packets; /**< received packets */
unsigned int tx_packets; /**< received packets transmitted */
unsigned int fwd_dropped; /**< received packets not forwarded */
unsigned int rx_bad_ip_csum ; /**< received packets has bad ip checksum */
unsigned int rx_bad_l4_csum ; /**< received packets has bad l4 checksum */
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
uint64_t core_cycles; /**< used for RX and TX processing */
#endif
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
struct pkt_burst_stats rx_burst_stats;
struct pkt_burst_stats tx_burst_stats;
#endif
};
/**
* The data structure associated with each port.
* tx_ol_flags is slightly different from ol_flags of rte_mbuf.
* Bit 0: Insert IP checksum
* Bit 1: Insert UDP checksum
* Bit 2: Insert TCP checksum
* Bit 3: Insert SCTP checksum
* Bit 11: Insert VLAN Label
*/
struct rte_port {
struct rte_eth_dev_info dev_info; /**< PCI info + driver name */
struct rte_eth_conf dev_conf; /**< Port configuration. */
struct ether_addr eth_addr; /**< Port ethernet address */
struct rte_eth_stats stats; /**< Last port statistics */
uint64_t tx_dropped; /**< If no descriptor in TX ring */
struct fwd_stream *rx_stream; /**< Port RX stream, if unique */
struct fwd_stream *tx_stream; /**< Port TX stream, if unique */
unsigned int socket_id; /**< For NUMA support */
uint16_t tx_ol_flags;/**< Offload Flags of TX packets. */
uint16_t tx_vlan_id; /**< Tag Id. in TX VLAN packets. */
void *fwd_ctx; /**< Forwarding mode context */
uint64_t rx_bad_ip_csum; /**< rx pkts with bad ip checksum */
uint64_t rx_bad_l4_csum; /**< rx pkts with bad l4 checksum */
};
/**
* The data structure associated with each forwarding logical core.
* The logical cores are internally numbered by a core index from 0 to
* the maximum number of logical cores - 1.
* The system CPU identifier of all logical cores are setup in a global
* CPU id. configuration table.
*/
struct fwd_lcore {
struct rte_mempool *mbp; /**< The mbuf pool to use by this core */
streamid_t stream_idx; /**< index of 1st stream in "fwd_streams" */
streamid_t stream_nb; /**< number of streams in "fwd_streams" */
lcoreid_t cpuid_idx; /**< index of logical core in CPU id table */
queueid_t tx_queue; /**< TX queue to send forwarded packets */
volatile char stopped; /**< stop forwarding when set */
};
/*
* Forwarding mode operations:
* - IO forwarding mode (default mode)
* Forwards packets unchanged.
*
* - MAC forwarding mode
* Set the source and the destination Ethernet addresses of packets
* before forwarding them.
*
* - IEEE1588 forwarding mode
* Check that received IEEE1588 Precise Time Protocol (PTP) packets are
* filtered and timestamped by the hardware.
* Forwards packets unchanged on the same port.
* Check that sent IEEE1588 PTP packets are timestamped by the hardware.
*/
typedef void (*port_fwd_begin_t)(portid_t pi);
typedef void (*port_fwd_end_t)(portid_t pi);
typedef void (*packet_fwd_t)(struct fwd_stream *fs);
struct fwd_engine {
const char *fwd_mode_name; /**< Forwarding mode name. */
port_fwd_begin_t port_fwd_begin; /**< NULL if nothing special to do. */
port_fwd_end_t port_fwd_end; /**< NULL if nothing special to do. */
packet_fwd_t packet_fwd; /**< Mandatory. */
};
extern struct fwd_engine io_fwd_engine;
extern struct fwd_engine mac_fwd_engine;
extern struct fwd_engine rx_only_engine;
extern struct fwd_engine tx_only_engine;
extern struct fwd_engine csum_fwd_engine;
#ifdef RTE_LIBRTE_IEEE1588
extern struct fwd_engine ieee1588_fwd_engine;
#endif
extern struct fwd_engine * fwd_engines[]; /**< NULL terminated array. */
/**
* Forwarding Configuration
*
*/
struct fwd_config {
struct fwd_engine *fwd_eng; /**< Packet forwarding mode. */
streamid_t nb_fwd_streams; /**< Nb. of forward streams to process. */
lcoreid_t nb_fwd_lcores; /**< Nb. of logical cores to launch. */
portid_t nb_fwd_ports; /**< Nb. of ports involved. */
};
/* globals used for configuration */
extern uint16_t verbose_level; /**< Drives messages being displayed, if any. */
extern uint8_t interactive;
extern uint8_t numa_support; /**< set by "--numa" parameter */
extern uint16_t port_topology; /**< set by "--port-topology" parameter */
/*
* Configuration of logical cores:
* nb_fwd_lcores <= nb_cfg_lcores <= nb_lcores
*/
extern lcoreid_t nb_lcores; /**< Number of logical cores probed at init time. */
extern lcoreid_t nb_cfg_lcores; /**< Number of configured logical cores. */
extern lcoreid_t nb_fwd_lcores; /**< Number of forwarding logical cores. */
extern unsigned int fwd_lcores_cpuids[RTE_MAX_LCORE];
/*
* Configuration of Ethernet ports:
* nb_fwd_ports <= nb_cfg_ports <= nb_ports
*/
extern portid_t nb_ports; /**< Number of ethernet ports probed at init time. */
extern portid_t nb_cfg_ports; /**< Number of configured ports. */
extern portid_t nb_fwd_ports; /**< Number of forwarding ports. */
extern portid_t fwd_ports_ids[RTE_MAX_ETHPORTS];
extern struct rte_port *ports;
extern struct rte_eth_rxmode rx_mode;
extern uint16_t rss_hf;
extern queueid_t nb_rxq;
extern queueid_t nb_txq;
extern uint16_t nb_rxd;
extern uint16_t nb_txd;
extern uint16_t rx_free_thresh;
extern uint16_t tx_free_thresh;
extern uint16_t tx_rs_thresh;
extern uint16_t mbuf_data_size; /**< Mbuf data space size. */
extern struct rte_fdir_conf fdir_conf;
/*
* Configuration of packet segments used by the "txonly" processing engine.
*/
#define TXONLY_DEF_PACKET_LEN 64
extern uint16_t tx_pkt_length; /**< Length of TXONLY packet */
extern uint16_t tx_pkt_seg_lengths[RTE_MAX_SEGS_PER_PKT]; /**< Seg. lengths */
extern uint8_t tx_pkt_nb_segs; /**< Number of segments in TX packets */
extern uint16_t nb_pkt_per_burst;
extern uint16_t mb_mempool_cache;
extern struct rte_eth_thresh rx_thresh;
extern struct rte_eth_thresh tx_thresh;
extern struct fwd_config cur_fwd_config;
extern struct fwd_engine *cur_fwd_eng;
extern struct fwd_lcore **fwd_lcores;
extern struct fwd_stream **fwd_streams;
extern portid_t nb_peer_eth_addrs; /**< Number of peer ethernet addresses. */
extern struct ether_addr peer_eth_addrs[RTE_MAX_ETHPORTS];
static inline unsigned int
lcore_num(void)
{
unsigned int i;
for (i = 0; i < RTE_MAX_LCORE; ++i)
if (fwd_lcores_cpuids[i] == rte_lcore_id())
return i;
rte_panic("lcore_id of current thread not found in fwd_lcores_cpuids\n");
}
static inline struct fwd_lcore *
current_fwd_lcore(void)
{
return fwd_lcores[lcore_num()];
}
/* Mbuf Pools */
static inline void
mbuf_poolname_build(unsigned int sock_id, char* mp_name, int name_size)
{
rte_snprintf(mp_name, name_size, "mbuf_pool_socket_%u", sock_id);
}
static inline struct rte_mempool *
mbuf_pool_find(unsigned int sock_id)
{
char pool_name[RTE_MEMPOOL_NAMESIZE];
mbuf_poolname_build(sock_id, pool_name, sizeof(pool_name));
return (rte_mempool_lookup((const char *)pool_name));
}
/**
* Read/Write operations on a PCI register of a port.
*/
static inline uint32_t
port_pci_reg_read(struct rte_port *port, uint32_t reg_off)
{
void *reg_addr;
uint32_t reg_v;
reg_addr = (void *)((char *)port->dev_info.pci_dev->mem_resource.addr +
reg_off);
reg_v = *((volatile uint32_t *)reg_addr);
return rte_le_to_cpu_32(reg_v);
}
#define port_id_pci_reg_read(pt_id, reg_off) \
port_pci_reg_read(&ports[(pt_id)], (reg_off))
static inline void
port_pci_reg_write(struct rte_port *port, uint32_t reg_off, uint32_t reg_v)
{
void *reg_addr;
reg_addr = (void *)((char *)port->dev_info.pci_dev->mem_resource.addr +
reg_off);
*((volatile uint32_t *)reg_addr) = rte_cpu_to_le_32(reg_v);
}
#define port_id_pci_reg_write(pt_id, reg_off, reg_value) \
port_pci_reg_write(&ports[(pt_id)], (reg_off), (reg_value))
/* Prototypes */
void launch_args_parse(int argc, char** argv);
void prompt(void);
void nic_stats_display(portid_t port_id);
void nic_stats_clear(portid_t port_id);
void port_infos_display(portid_t port_id);
void fwd_lcores_config_display(void);
void fwd_config_display(void);
void rxtx_config_display(void);
void fwd_config_setup(void);
void set_def_fwd_config(void);
void port_reg_bit_display(portid_t port_id, uint32_t reg_off, uint8_t bit_pos);
void port_reg_bit_set(portid_t port_id, uint32_t reg_off, uint8_t bit_pos,
uint8_t bit_v);
void port_reg_bit_field_display(portid_t port_id, uint32_t reg_off,
uint8_t bit1_pos, uint8_t bit2_pos);
void port_reg_bit_field_set(portid_t port_id, uint32_t reg_off,
uint8_t bit1_pos, uint8_t bit2_pos, uint32_t value);
void port_reg_display(portid_t port_id, uint32_t reg_off);
void port_reg_set(portid_t port_id, uint32_t reg_off, uint32_t value);
void rx_ring_desc_display(portid_t port_id, queueid_t rxq_id, uint16_t rxd_id);
void tx_ring_desc_display(portid_t port_id, queueid_t txq_id, uint16_t txd_id);
void set_fwd_lcores_list(unsigned int *lcorelist, unsigned int nb_lc);
void set_fwd_lcores_mask(uint64_t lcoremask);
void set_fwd_lcores_number(uint16_t nb_lc);
void set_fwd_ports_list(unsigned int *portlist, unsigned int nb_pt);
void set_fwd_ports_mask(uint64_t portmask);
void set_fwd_ports_number(uint16_t nb_pt);
void rx_vlan_filter_set(portid_t port_id, uint16_t vlan_id, int on);
void rx_vlan_all_filter_set(portid_t port_id, int on);
void tx_vlan_set(portid_t port_id, uint16_t vlan_id);
void tx_vlan_reset(portid_t port_id);
void tx_cksum_set(portid_t port_id, uint8_t cksum_mask);
void set_verbose_level(uint16_t vb_level);
void set_tx_pkt_segments(unsigned *seg_lengths, unsigned nb_segs);
void set_nb_pkt_per_burst(uint16_t pkt_burst);
void set_pkt_forwarding_mode(const char *fwd_mode);
void start_packet_forwarding(int with_tx_first);
void stop_packet_forwarding(void);
void pmd_test_exit(void);
void fdir_add_signature_filter(portid_t port_id, uint8_t queue_id,
struct rte_fdir_filter *fdir_filter);
void fdir_update_signature_filter(portid_t port_id, uint8_t queue_id,
struct rte_fdir_filter *fdir_filter);
void fdir_remove_signature_filter(portid_t port_id,
struct rte_fdir_filter *fdir_filter);
void fdir_get_infos(portid_t port_id);
void fdir_add_perfect_filter(portid_t port_id, uint16_t soft_id,
uint8_t queue_id, uint8_t drop,
struct rte_fdir_filter *fdir_filter);
void fdir_update_perfect_filter(portid_t port_id, uint16_t soft_id,
uint8_t queue_id, uint8_t drop,
struct rte_fdir_filter *fdir_filter);
void fdir_remove_perfect_filter(portid_t port_id, uint16_t soft_id,
struct rte_fdir_filter *fdir_filter);
void fdir_set_masks(portid_t port_id, struct rte_fdir_masks *fdir_masks);
/*
* Work-around of a compilation error with ICC on invocations of the
* rte_be_to_cpu_16() function.
*/
#ifdef __GCC__
#define RTE_BE_TO_CPU_16(be_16_v) rte_be_to_cpu_16((be_16_v))
#define RTE_CPU_TO_BE_16(cpu_16_v) rte_cpu_to_be_16((cpu_16_v))
#else
#ifdef __big_endian__
#define RTE_BE_TO_CPU_16(be_16_v) (be_16_v)
#define RTE_CPU_TO_BE_16(cpu_16_v) (cpu_16_v)
#else
#define RTE_BE_TO_CPU_16(be_16_v) \
(uint16_t) ((((be_16_v) & 0xFF) << 8) | ((be_16_v) >> 8))
#define RTE_CPU_TO_BE_16(cpu_16_v) \
(uint16_t) ((((cpu_16_v) & 0xFF) << 8) | ((cpu_16_v) >> 8))
#endif
#endif /* __GCC__ */
#endif /* _TESTPMD_H_ */

317
app/test-pmd/txonly.c Normal file
View File

@ -0,0 +1,317 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <sys/stat.h>
#include <rte_common.h>
#include <rte_byteorder.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_cycles.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_memory.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_memcpy.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include <rte_ether.h>
#include <rte_ethdev.h>
#include <rte_ip.h>
#include <rte_tcp.h>
#include <rte_udp.h>
#include <rte_string_fns.h>
#include "testpmd.h"
#define UDP_SRC_PORT 1024
#define UDP_DST_PORT 1024
#define IP_SRC_ADDR ((192 << 24) | (168 << 16) | (0 << 8) | 1)
#define IP_DST_ADDR ((192 << 24) | (168 << 16) | (0 << 8) | 2)
#define IP_DEFTTL 64 /* from RFC 1340. */
#define IP_VERSION 0x40
#define IP_HDRLEN 0x05 /* default IP header length == five 32-bits words. */
#define IP_VHL_DEF (IP_VERSION | IP_HDRLEN)
static struct ipv4_hdr pkt_ip_hdr; /**< IP header of transmitted packets. */
static struct udp_hdr pkt_udp_hdr; /**< UDP header of transmitted packets. */
static inline struct rte_mbuf *
tx_mbuf_alloc(struct rte_mempool *mp)
{
struct rte_mbuf *m;
void *mb;
if (rte_mempool_get(mp, &mb) < 0)
return NULL;
m = (struct rte_mbuf *)mb;
__rte_mbuf_sanity_check(m, RTE_MBUF_PKT, 1);
return m;
}
static void
copy_buf_to_pkt_segs(void* buf, unsigned len, struct rte_mbuf *pkt,
unsigned offset)
{
struct rte_mbuf *seg;
void *seg_buf;
unsigned copy_len;
seg = pkt;
while (offset >= seg->pkt.data_len) {
offset -= seg->pkt.data_len;
seg = seg->pkt.next;
}
copy_len = seg->pkt.data_len - offset;
seg_buf = ((char *) seg->pkt.data + offset);
while (len > copy_len) {
rte_memcpy(seg_buf, buf, (size_t) copy_len);
len -= copy_len;
buf = ((char*) buf + copy_len);
seg = seg->pkt.next;
seg_buf = seg->pkt.data;
}
rte_memcpy(seg_buf, buf, (size_t) len);
}
static inline void
copy_buf_to_pkt(void* buf, unsigned len, struct rte_mbuf *pkt, unsigned offset)
{
if (offset + len <= pkt->pkt.data_len) {
rte_memcpy(((char *) pkt->pkt.data + offset), buf, (size_t) len);
return;
}
copy_buf_to_pkt_segs(buf, len, pkt, offset);
}
static void
setup_pkt_udp_ip_headers(struct ipv4_hdr *ip_hdr,
struct udp_hdr *udp_hdr,
uint16_t pkt_data_len)
{
uint16_t *ptr16;
uint32_t ip_cksum;
uint16_t pkt_len;
/*
* Initialize UDP header.
*/
pkt_len = (uint16_t) (pkt_data_len + sizeof(struct udp_hdr));
udp_hdr->src_port = rte_cpu_to_be_16(UDP_SRC_PORT);
udp_hdr->dst_port = rte_cpu_to_be_16(UDP_DST_PORT);
udp_hdr->dgram_len = RTE_CPU_TO_BE_16(pkt_len);
udp_hdr->dgram_cksum = 0; /* No UDP checksum. */
/*
* Initialize IP header.
*/
pkt_len = (uint16_t) (pkt_len + sizeof(struct ipv4_hdr));
ip_hdr->version_ihl = IP_VHL_DEF;
ip_hdr->type_of_service = 0;
ip_hdr->fragment_offset = 0;
ip_hdr->time_to_live = IP_DEFTTL;
ip_hdr->next_proto_id = IPPROTO_UDP;
ip_hdr->packet_id = 0;
ip_hdr->total_length = RTE_CPU_TO_BE_16(pkt_len);
ip_hdr->src_addr = rte_cpu_to_be_32(IP_SRC_ADDR);
ip_hdr->dst_addr = rte_cpu_to_be_32(IP_DST_ADDR);
/*
* Compute IP header checksum.
*/
ptr16 = (uint16_t*) ip_hdr;
ip_cksum = 0;
ip_cksum += ptr16[0]; ip_cksum += ptr16[1];
ip_cksum += ptr16[2]; ip_cksum += ptr16[3];
ip_cksum += ptr16[4];
ip_cksum += ptr16[6]; ip_cksum += ptr16[7];
ip_cksum += ptr16[8]; ip_cksum += ptr16[9];
/*
* Reduce 32 bit checksum to 16 bits and complement it.
*/
ip_cksum = ((ip_cksum & 0xFFFF0000) >> 16) +
(ip_cksum & 0x0000FFFF);
if (ip_cksum > 65535)
ip_cksum -= 65535;
ip_cksum = (~ip_cksum) & 0x0000FFFF;
if (ip_cksum == 0)
ip_cksum = 0xFFFF;
ip_hdr->hdr_checksum = (uint16_t) ip_cksum;
}
/*
* Transmit a burst of multi-segments packets.
*/
static void
pkt_burst_transmit(struct fwd_stream *fs)
{
struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
struct rte_mbuf *pkt;
struct rte_mbuf *pkt_seg;
struct rte_mempool *mbp;
struct ether_hdr eth_hdr;
uint16_t nb_tx;
uint16_t nb_pkt;
uint16_t vlan_tci;
uint16_t ol_flags;
uint8_t i;
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
uint64_t start_tsc;
uint64_t end_tsc;
uint64_t core_cycles;
#endif
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
start_tsc = rte_rdtsc();
#endif
mbp = current_fwd_lcore()->mbp;
vlan_tci = ports[fs->tx_port].tx_vlan_id;
ol_flags = ports[fs->tx_port].tx_ol_flags;
for (nb_pkt = 0; nb_pkt < nb_pkt_per_burst; nb_pkt++) {
pkt = tx_mbuf_alloc(mbp);
if (pkt == NULL) {
nomore_mbuf:
if (nb_pkt == 0)
return;
break;
}
pkt->pkt.data_len = tx_pkt_seg_lengths[0];
pkt_seg = pkt;
for (i = 1; i < tx_pkt_nb_segs; i++) {
pkt_seg->pkt.next = tx_mbuf_alloc(mbp);
if (pkt_seg->pkt.next == NULL) {
rte_pktmbuf_free(pkt);
goto nomore_mbuf;
}
pkt_seg = pkt_seg->pkt.next;
pkt_seg->pkt.data_len = tx_pkt_seg_lengths[i];
}
pkt_seg->pkt.next = NULL; /* Last segment of packet. */
/*
* Initialize Ethernet header.
*/
ether_addr_copy(&peer_eth_addrs[fs->peer_addr],&eth_hdr.d_addr);
ether_addr_copy(&ports[fs->tx_port].eth_addr, &eth_hdr.s_addr);
eth_hdr.ether_type = rte_cpu_to_be_16(ETHER_TYPE_IPv4);
/*
* Copy headers in first packet segment(s).
*/
copy_buf_to_pkt(&eth_hdr, sizeof(eth_hdr), pkt, 0);
copy_buf_to_pkt(&pkt_ip_hdr, sizeof(pkt_ip_hdr), pkt,
sizeof(struct ether_hdr));
copy_buf_to_pkt(&pkt_udp_hdr, sizeof(pkt_udp_hdr), pkt,
sizeof(struct ether_hdr) +
sizeof(struct ipv4_hdr));
/*
* Complete first mbuf of packet and append it to the
* burst of packets to be transmitted.
*/
pkt->pkt.nb_segs = tx_pkt_nb_segs;
pkt->pkt.pkt_len = tx_pkt_length;
pkt->ol_flags = ol_flags;
pkt->pkt.vlan_tci = vlan_tci;
pkt->pkt.l2_len = sizeof(struct ether_hdr);
pkt->pkt.l3_len = sizeof(struct ipv4_hdr);
pkts_burst[nb_pkt] = pkt;
}
nb_tx = rte_eth_tx_burst(fs->tx_port, fs->tx_queue, pkts_burst, nb_pkt);
fs->tx_packets += nb_tx;
#ifdef RTE_TEST_PMD_RECORD_BURST_STATS
fs->tx_burst_stats.pkt_burst_spread[nb_tx]++;
#endif
if (unlikely(nb_tx < nb_pkt)) {
if (verbose_level > 0 && fs->fwd_dropped == 0)
printf("port %d tx_queue %d - drop "
"(nb_pkt:%u - nb_tx:%u)=%u packets\n",
fs->tx_port, fs->tx_queue,
(unsigned) nb_pkt, (unsigned) nb_tx,
(unsigned) (nb_pkt - nb_tx));
fs->fwd_dropped += (nb_pkt - nb_tx);
do {
rte_pktmbuf_free(pkts_burst[nb_tx]);
} while (++nb_tx < nb_pkt);
}
#ifdef RTE_TEST_PMD_RECORD_CORE_CYCLES
end_tsc = rte_rdtsc();
core_cycles = (end_tsc - start_tsc);
fs->core_cycles = (uint64_t) (fs->core_cycles + core_cycles);
#endif
}
static void
tx_only_begin(__attribute__((unused)) portid_t pi)
{
uint16_t pkt_data_len;
pkt_data_len = (uint16_t) (tx_pkt_length - (sizeof(struct ether_hdr) +
sizeof(struct ipv4_hdr) +
sizeof(struct udp_hdr)));
setup_pkt_udp_ip_headers(&pkt_ip_hdr, &pkt_udp_hdr, pkt_data_len);
}
struct fwd_engine tx_only_engine = {
.fwd_mode_name = "txonly",
.port_fwd_begin = tx_only_begin,
.port_fwd_end = NULL,
.packet_fwd = pkt_burst_transmit,
};

82
app/test/Makefile Normal file
View File

@ -0,0 +1,82 @@
# BSD LICENSE
#
# Copyright(c) 2010-2012 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.
#
# version: DPDK.L.1.2.3-3
include $(RTE_SDK)/mk/rte.vars.mk
#
# library name
#
APP = test
#
# all sources are stored in SRCS-y
#
SRCS-$(CONFIG_RTE_APP_TEST) := commands.c
SRCS-$(CONFIG_RTE_APP_TEST) += test.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_pci.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_prefetch.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_byteorder.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_per_lcore.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_atomic.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_malloc.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_cycles.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_spinlock.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_memory.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_memzone.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_ring.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_rwlock.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_timer.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_mempool.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_mbuf.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_logs.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_memcpy.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_hash.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_lpm.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_debug.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_errno.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_tailq.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_string_fns.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_mp_secondary.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_cpuflags.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_eal_flags.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_alarm.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_interrupts.c
SRCS-$(CONFIG_RTE_APP_TEST) += test_version.c
CFLAGS += -O3
CFLAGS += $(WERROR_FLAGS)
# this application needs libraries first
DEPDIRS-$(CONFIG_RTE_APP_TEST) += lib
include $(RTE_SDK)/mk/rte.app.mk

664
app/test/autotest.py Executable file
View File

@ -0,0 +1,664 @@
#!/usr/bin/python
# BSD LICENSE
#
# Copyright(c) 2010-2012 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.
#
# version: DPDK.L.1.2.3-3
# Script that uses qemu controlled by python-pexpect to check that
# all autotests are working in the baremetal environment.
import sys, pexpect, time, os, re
directory = sys.argv[2]
target = sys.argv[3]
log_file = "%s.txt"%(target)
if "baremetal" in target:
cmdline = "qemu-system-x86_64 -cdrom %s.iso -boot d "%(sys.argv[1])
cmdline += "-m 2000 -smp 4 -nographic -net nic,model=e1000"
platform = "QEMU x86_64"
else:
cmdline = "%s -c f -n 4"%(sys.argv[1])
try:
platform = open("/root/rte_platform_model.txt").read()
except:
platform = "unknown"
print cmdline
report_hdr=""".. <COPYRIGHT_TAG>
"""
test_whitelist=None
test_blacklist=None
class SubTest:
"Defines a subtest"
def __init__(self, title, function, command=None, timeout=10, genreport=None):
self.title = title
self.function = function
self.command = command
self.timeout = timeout
self.genreport = genreport
class AutoTest:
"""This class contains all methods needed to launch several
automatic tests, archive test results, log, and generate a nice
test report in restructured text"""
title = "new"
mainlog = None
logbuf = None
literal = 0
test_list = []
report_list = []
child = None
def __init__(self, pexpectchild, filename, mode):
"Init the Autotest class"
self.mainlog = file(filename, mode)
self.child = pexpectchild
pexpectchild.logfile = self
def register(self, filename, title, subtest_list):
"Register a test with a list of subtests"
test = {}
test["filename"] = filename
test["title"] = title
test["subtest_list"] = subtest_list
self.test_list.append(test)
def start(self):
"start the tests, and fill the internal report_list field"
for t in self.test_list:
report = {}
report["date"] = time.asctime()
report["title"] = t["title"]
report["filename"] = t["filename"]
report["subreport_list"] = []
report["fails"] = 0
report["success"] = 0
report["subreport_list"] = []
for st in t["subtest_list"]:
if test_whitelist is not None and st.title not in test_whitelist:
continue
if test_blacklist is not None and st.title in test_blacklist:
continue
subreport = {}
self.reportbuf = ""
subreport["title"] = st.title
subreport["func"] = st.function
subreport["command"] = st.command
subreport["timeout"] = st.timeout
subreport["genreport"] = st.genreport
# launch subtest
print "%s (%s): "%(subreport["title"], subreport["command"]),
sys.stdout.flush()
start = time.time()
res = subreport["func"](self.child,
command = subreport["command"],
timeout = subreport["timeout"])
t = int(time.time() - start)
subreport["time"] = "%dmn%d"%(t/60, t%60)
subreport["result"] = res[0] # 0 or -1
subreport["result_str"] = res[1] # cause of fail
subreport["logs"] = self.reportbuf
print "%s [%s]"%(subreport["result_str"], subreport["time"])
if subreport["result"] == 0:
report["success"] += 1
else:
report["fails"] += 1
report["subreport_list"].append(subreport)
self.report_list.append(report)
def gen_report(self):
for report in self.report_list:
# main report header and stats
self.literal = 0
reportlog = file(report["filename"], "w")
reportlog.write(report_hdr)
reportlog.write(report["title"] + "\n")
reportlog.write(re.sub(".", "=", report["title"]) + "\n\n")
reportlog.write("Autogenerated test report:\n\n" )
reportlog.write("- date: **%s**\n"%(report["date"]))
reportlog.write("- target: **%s**\n"%(target))
reportlog.write("- success: **%d**\n"%(report["success"]))
reportlog.write("- fails: **%d**\n"%(report["fails"]))
reportlog.write("- platform: **%s**\n\n"%(platform))
# summary
reportlog.write(".. csv-table:: Test results summary\n")
reportlog.write(' :header: "Name", "Result"\n\n')
for subreport in report["subreport_list"]:
if subreport["result"] == 0:
res_str = "Success"
else:
res_str = "Failure"
reportlog.write(' "%s", "%s"\n'%(subreport["title"], res_str))
reportlog.write('\n')
# subreports
for subreport in report["subreport_list"]:
# print subtitle
reportlog.write(subreport["title"] + "\n")
reportlog.write(re.sub(".", "-", subreport["title"]) + "\n\n")
# print logs
reportlog.write("::\n \n ")
s = subreport["logs"].replace("\n", "\n ")
reportlog.write(s)
# print result
reportlog.write("\n\n")
reportlog.write("**" + subreport["result_str"] + "**\n\n")
# custom genreport
if subreport["genreport"] != None:
s = subreport["genreport"]()
reportlog.write(s)
reportlog.close()
# displayed on console
print
print "-------------------------"
print
if report["fails"] == 0:
print "All test OK"
else:
print "%s test(s) failed"%(report["fails"])
# file API, to store logs from pexpect
def write(self, buf):
s = buf[:]
s = s.replace("\r", "")
self.mainlog.write(s)
self.reportbuf += s
def flush(self):
self.mainlog.flush()
def close(self):
self.mainlog.close()
# Try to match prompt: return 0 on success, else return -1
def wait_prompt(child):
for i in range(3):
index = child.expect(["RTE>>", pexpect.TIMEOUT], timeout = 1)
child.sendline("")
if index == 0:
return 0
print "Cannot find prompt"
return -1
# Try to match prompt after boot: return 0 on success, else return -1
def wait_boot(child):
index = child.expect(["RTE>>", pexpect.TIMEOUT],
timeout = 120)
if index == 0:
return 0
if (wait_prompt(child) == -1):
print "Target did not boot, failed"
return -1
return 0
# quit RTE
def quit(child):
if wait_boot(child) != 0:
return -1, "Cannot find prompt"
child.sendline("quit")
return 0, "Success"
# Default function to launch an autotest that does not need to
# interact with the user. Basically, this function calls the autotest
# function through command line interface, then check that it displays
# "Test OK" or "Test Failed".
def default_autotest(child, command, timeout=10):
if wait_prompt(child) != 0:
return -1, "Failed: cannot find prompt"
child.sendline(command)
index = child.expect(["Test OK", "Test Failed",
pexpect.TIMEOUT], timeout = timeout)
if index == 1:
return -1, "Failed"
elif index == 2:
return -1, "Failed [Timeout]"
return 0, "Success"
# wait boot
def boot_autotest(child, **kargs):
if wait_boot(child) != 0:
return -1, "Cannot find prompt"
return 0, "Success"
# Test memory dump. We need to check that at least one memory zone is
# displayed.
def memory_autotest(child, command, **kargs):
if wait_prompt(child) != 0:
return -1, "Failed: cannot find prompt"
child.sendline(command)
regexp = "phys:0x[0-9a-f]*, len:0x([0-9a-f]*), virt:0x[0-9a-f]*, socket_id:[0-9]*"
index = child.expect([regexp, pexpect.TIMEOUT], timeout = 180)
if index != 0:
return -1, "Failed: timeout"
size = int(child.match.groups()[0], 16)
if size <= 0:
return -1, "Failed: bad size"
index = child.expect(["Test OK", "Test Failed",
pexpect.TIMEOUT], timeout = 10)
if index == 1:
return -1, "Failed: C code returned an error"
elif index == 2:
return -1, "Failed: timeout"
return 0, "Success"
# Test some libc functions including scanf. This requires a
# interaction with the user (simulated in expect), so we cannot use
# default_autotest() here.
def string_autotest(child, command, **kargs):
if wait_prompt(child) != 0:
return -1, "Failed: cannot find prompt"
child.sendline(command)
index = child.expect(["Now, test scanf, enter this number",
pexpect.TIMEOUT], timeout = 10)
if index != 0:
return -1, "Failed: timeout"
child.sendline("123456")
index = child.expect(["number=123456", pexpect.TIMEOUT], timeout = 10)
if index != 0:
return -1, "Failed: timeout (2)"
index = child.expect(["Test OK", "Test Failed",
pexpect.TIMEOUT], timeout = 10)
if index != 0:
return -1, "Failed: C code returned an error"
return 0, "Success"
# Test spinlock. This requires to check the order of displayed lines:
# we cannot use default_autotest() here.
def spinlock_autotest(child, command, **kargs):
i = 0
ir = 0
if wait_prompt(child) != 0:
return -1, "Failed: cannot find prompt"
child.sendline(command)
while True:
index = child.expect(["Test OK",
"Test Failed",
"Hello from core ([0-9]*) !",
"Hello from within recursive locks from ([0-9]*) !",
pexpect.TIMEOUT], timeout = 20)
# ok
if index == 0:
break
# message, check ordering
elif index == 2:
if int(child.match.groups()[0]) < i:
return -1, "Failed: bad order"
i = int(child.match.groups()[0])
elif index == 3:
if int(child.match.groups()[0]) < ir:
return -1, "Failed: bad order"
ir = int(child.match.groups()[0])
# fail
else:
return -1, "Failed: timeout or error"
return 0, "Success"
# Test rwlock. This requires to check the order of displayed lines:
# we cannot use default_autotest() here.
def rwlock_autotest(child, command, **kargs):
i = 0
if wait_prompt(child) != 0:
return -1, "Failed: cannot find prompt"
child.sendline(command)
while True:
index = child.expect(["Test OK",
"Test Failed",
"Hello from core ([0-9]*) !",
"Global write lock taken on master core ([0-9]*)",
pexpect.TIMEOUT], timeout = 10)
# ok
if index == 0:
if i != 0xffff:
return -1, "Failed: a message is missing"
break
# message, check ordering
elif index == 2:
if int(child.match.groups()[0]) < i:
return -1, "Failed: bad order"
i = int(child.match.groups()[0])
# must be the last message, check ordering
elif index == 3:
i = 0xffff
# fail
else:
return -1, "Failed: timeout or error"
return 0, "Success"
# Test logs. This requires to check the order of displayed lines:
# we cannot use default_autotest() here.
def logs_autotest(child, command, **kargs):
i = 0
if wait_prompt(child) != 0:
return -1, "Failed: cannot find prompt"
child.sendline(command)
log_list = [
"TESTAPP1: this is a debug level message",
"TESTAPP1: this is a info level message",
"TESTAPP1: this is a warning level message",
"TESTAPP2: this is a info level message",
"TESTAPP2: this is a warning level message",
"TESTAPP1: this is a debug level message",
"TESTAPP1: this is a debug level message",
"TESTAPP1: this is a info level message",
"TESTAPP1: this is a warning level message",
"TESTAPP2: this is a info level message",
"TESTAPP2: this is a warning level message",
"TESTAPP1: this is a debug level message",
]
for log_msg in log_list:
index = child.expect([log_msg,
"Test OK",
"Test Failed",
pexpect.TIMEOUT], timeout = 10)
# not ok
if index != 0:
return -1, "Failed: timeout or error"
index = child.expect(["Test OK",
"Test Failed",
pexpect.TIMEOUT], timeout = 10)
return 0, "Success"
# Test timers. This requires to check the order of displayed lines:
# we cannot use default_autotest() here.
def timer_autotest(child, command, **kargs):
i = 0
if wait_prompt(child) != 0:
return -1, "Failed: cannot find prompt"
child.sendline(command)
index = child.expect(["Start timer stress tests \(30 seconds\)",
"Test Failed",
pexpect.TIMEOUT], timeout = 10)
# not ok
if index != 0:
return -1, "Failed: timeout or error"
index = child.expect(["Start timer basic tests \(30 seconds\)",
"Test Failed",
pexpect.TIMEOUT], timeout = 40)
# not ok
if index != 0:
return -1, "Failed: timeout or error (2)"
prev_lcore_timer1 = -1
lcore_tim0 = -1
lcore_tim1 = -1
lcore_tim2 = -1
lcore_tim3 = -1
while True:
index = child.expect(["TESTTIMER: ([0-9]*): callback id=([0-9]*) count=([0-9]*) on core ([0-9]*)",
"Test OK",
"Test Failed",
pexpect.TIMEOUT], timeout = 10)
if index == 1:
break
if index != 0:
return -1, "Failed: timeout or error (3)"
try:
t = int(child.match.groups()[0])
id = int(child.match.groups()[1])
cnt = int(child.match.groups()[2])
lcore = int(child.match.groups()[3])
except:
return -1, "Failed: cannot parse output"
# timer0 always expires on the same core when cnt < 20
if id == 0:
if lcore_tim0 == -1:
lcore_tim0 = lcore
elif lcore != lcore_tim0 and cnt < 20:
return -1, "Failed: lcore != lcore_tim0 (%d, %d)"%(lcore, lcore_tim0)
if cnt > 21:
return -1, "Failed: tim0 cnt > 21"
# timer1 each time expires on a different core
if id == 1:
if lcore == lcore_tim1:
return -1, "Failed: lcore == lcore_tim1 (%d, %d)"%(lcore, lcore_tim1)
lcore_tim1 = lcore
if cnt > 10:
return -1, "Failed: tim1 cnt > 30"
# timer0 always expires on the same core
if id == 2:
if lcore_tim2 == -1:
lcore_tim2 = lcore
elif lcore != lcore_tim2:
return -1, "Failed: lcore != lcore_tim2 (%d, %d)"%(lcore, lcore_tim2)
if cnt > 30:
return -1, "Failed: tim2 cnt > 30"
# timer0 always expires on the same core
if id == 3:
if lcore_tim3 == -1:
lcore_tim3 = lcore
elif lcore != lcore_tim3:
return -1, "Failed: lcore_tim3 changed (%d -> %d)"%(lcore, lcore_tim3)
if cnt > 30:
return -1, "Failed: tim3 cnt > 30"
# must be 2 different cores
if lcore_tim0 == lcore_tim3:
return -1, "Failed: lcore_tim0 (%d) == lcore_tim3 (%d)"%(lcore_tim0, lcore_tim3)
return 0, "Success"
# Ring autotest
def ring_autotest(child, command, timeout=10):
if wait_prompt(child) != 0:
return -1, "Failed: cannot find prompt"
child.sendline(command)
index = child.expect(["Test OK", "Test Failed",
pexpect.TIMEOUT], timeout = timeout)
if index != 0:
return -1, "Failed"
child.sendline("set_watermark test 100")
child.sendline("set_quota test 16")
child.sendline("dump_ring test")
index = child.expect([" watermark=100",
pexpect.TIMEOUT], timeout = 1)
if index != 0:
return -1, "Failed: bad watermark"
index = child.expect([" bulk_default=16",
pexpect.TIMEOUT], timeout = 1)
if index != 0:
return -1, "Failed: bad quota"
return 0, "Success"
def ring_genreport():
s = "Performance curves\n"
s += "------------------\n\n"
sdk = os.getenv("RTE_SDK")
script = os.path.join(sdk, "app/test/graph_ring.py")
title ='"Autotest %s %s"'%(target, time.asctime())
filename = target + ".txt"
os.system("/usr/bin/python %s %s %s"%(script, filename, title))
for f in os.listdir("."):
if not f.startswith("ring"):
continue
if not f.endswith(".svg"):
continue
# skip single producer/consumer
if "_sc" in f:
continue
if "_sp" in f:
continue
f = f[:-4] + ".png"
s += ".. figure:: ../../images/autotests/%s/%s\n"%(target, f)
s += " :width: 50%\n\n"
s += " %s\n\n"%(f)
return s
def mempool_genreport():
s = "Performance curves\n"
s += "------------------\n\n"
sdk = os.getenv("RTE_SDK")
script = os.path.join(sdk, "app/test/graph_mempool.py")
title ='"Autotest %s %s"'%(target, time.asctime())
filename = target + ".txt"
os.system("/usr/bin/python %s %s %s"%(script, filename, title))
for f in os.listdir("."):
if not f.startswith("mempool"):
continue
if not f.endswith(".svg"):
continue
# skip when n_keep = 128
if "_128." in f:
continue
f = f[:-4] + ".png"
s += ".. figure:: ../../images/autotests/%s/%s\n"%(target, f)
s += " :width: 50%\n\n"
s += " %s\n\n"%(f)
return s
#
# main
#
if len(sys.argv) > 4:
testlist=sys.argv[4].split(',')
if testlist[0].startswith('-'):
testlist[0]=testlist[0].lstrip('-')
test_blacklist=testlist
else:
test_whitelist=testlist
child = pexpect.spawn(cmdline)
autotest = AutoTest(child, log_file,'w')
# timeout for memcpy and hash test
if "baremetal" in target:
timeout = 60*180
else:
timeout = 180
autotest.register("eal_report.rst", "EAL-%s"%(target),
[ SubTest("Boot", boot_autotest, "boot_autotest"),
SubTest("EAL Flags", default_autotest, "eal_flags_autotest"),
SubTest("Version", default_autotest, "version_autotest"),
SubTest("PCI", default_autotest, "pci_autotest"),
SubTest("Memory", memory_autotest, "memory_autotest"),
SubTest("Lcore launch", default_autotest, "per_lcore_autotest"),
SubTest("Spinlock", spinlock_autotest, "spinlock_autotest"),
SubTest("Rwlock", rwlock_autotest, "rwlock_autotest"),
SubTest("Atomic", default_autotest, "atomic_autotest"),
SubTest("Byte order", default_autotest, "byteorder_autotest"),
SubTest("Prefetch", default_autotest, "prefetch_autotest"),
SubTest("Debug", default_autotest, "debug_autotest"),
SubTest("Cycles", default_autotest, "cycles_autotest"),
SubTest("Logs", logs_autotest, "logs_autotest"),
SubTest("Memzone", default_autotest, "memzone_autotest"),
SubTest("Cpu flags", default_autotest, "cpuflags_autotest"),
SubTest("Memcpy", default_autotest, "memcpy_autotest", timeout),
SubTest("String Functions", default_autotest, "string_autotest"),
SubTest("Alarm", default_autotest, "alarm_autotest", 30),
SubTest("Interrupt", default_autotest, "interrupt_autotest"),
])
autotest.register("ring_report.rst", "Ring-%s"%(target),
[ SubTest("Ring", ring_autotest, "ring_autotest", 30*60,
ring_genreport)
])
if "baremetal" in target:
timeout = 60*60*3
else:
timeout = 60*30
autotest.register("mempool_report.rst", "Mempool-%s"%(target),
[ SubTest("Mempool", default_autotest, "mempool_autotest",
timeout, mempool_genreport)
])
autotest.register("mbuf_report.rst", "Mbuf-%s"%(target),
[ SubTest("Mbuf", default_autotest, "mbuf_autotest", timeout=120)
])
autotest.register("timer_report.rst", "Timer-%s"%(target),
[ SubTest("Timer", timer_autotest, "timer_autotest")
])
autotest.register("malloc_report.rst", "Malloc-%s"%(target),
[ SubTest("Malloc", default_autotest, "malloc_autotest")
])
# only do the hash autotest if supported by the platform
if not (platform.startswith("Intel(R) Core(TM)2 Quad CPU") or
platform.startswith("QEMU")):
autotest.register("hash_report.rst", "Hash-%s"%(target),
[ SubTest("Hash", default_autotest, "hash_autotest", timeout)
])
autotest.register("lpm_report.rst", "LPM-%s"%(target),
[ SubTest("Lpm", default_autotest, "lpm_autotest", timeout)
])
autotest.register("eal2_report.rst", "EAL2-%s"%(target),
[ SubTest("TailQ", default_autotest, "tailq_autotest"),
SubTest("Errno", default_autotest, "errno_autotest"),
SubTest("Multiprocess", default_autotest, "multiprocess_autotest")
])
autotest.start()
autotest.gen_report()
quit(child)
child.terminate()
sys.exit(0)

391
app/test/commands.c Normal file
View File

@ -0,0 +1,391 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <termios.h>
#ifndef __linux__
#include <net/socket.h>
#endif
#include <inttypes.h>
#include <errno.h>
#include <sys/queue.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_cycles.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_timer.h>
#include <cmdline_rdline.h>
#include <cmdline_parse.h>
#include <cmdline_parse_ipaddr.h>
#include <cmdline_parse_num.h>
#include <cmdline_parse_string.h>
#include <cmdline.h>
#include "test.h"
/****************/
struct cmd_autotest_result {
cmdline_fixed_string_t autotest;
};
static void cmd_autotest_parsed(void *parsed_result,
__attribute__((unused)) struct cmdline *cl,
__attribute__((unused)) void *data)
{
struct cmd_autotest_result *res = parsed_result;
int ret = 0;
int all = 0;
if (!strcmp(res->autotest, "all_autotests"))
all = 1;
if (all || !strcmp(res->autotest, "version_autotest"))
ret |= test_version();
if (all || !strcmp(res->autotest, "debug_autotest"))
ret |= test_debug();
if (all || !strcmp(res->autotest, "pci_autotest"))
ret |= test_pci();
if (all || !strcmp(res->autotest, "prefetch_autotest"))
ret |= test_prefetch();
if (all || !strcmp(res->autotest, "byteorder_autotest"))
ret |= test_byteorder();
if (all || !strcmp(res->autotest, "per_lcore_autotest"))
ret |= test_per_lcore();
if (all || !strcmp(res->autotest, "atomic_autotest"))
ret |= test_atomic();
if (all || !strcmp(res->autotest, "malloc_autotest"))
ret |= test_malloc();
if (all || !strcmp(res->autotest, "spinlock_autotest"))
ret |= test_spinlock();
if (all || !strcmp(res->autotest, "memory_autotest"))
ret |= test_memory();
if (all || !strcmp(res->autotest, "memzone_autotest"))
ret |= test_memzone();
if (all || !strcmp(res->autotest, "rwlock_autotest"))
ret |= test_rwlock();
if (all || !strcmp(res->autotest, "mbuf_autotest"))
ret |= test_mbuf();
if (all || !strcmp(res->autotest, "logs_autotest"))
ret |= test_logs();
if (all || !strcmp(res->autotest, "errno_autotest"))
ret |= test_errno();
if (all || !strcmp(res->autotest, "hash_autotest"))
ret |= test_hash();
if (all || !strcmp(res->autotest, "lpm_autotest"))
ret |= test_lpm();
if (all || !strcmp(res->autotest, "cpuflags_autotest"))
ret |= test_cpuflags();
/* tailq autotest must go after all lpm and hashs tests or any other
* tests which need to create tailq objects (ring and mempool are implicitly
* created in earlier tests so can go later)
*/
if (all || !strcmp(res->autotest, "tailq_autotest"))
ret |= test_tailq();
if (all || !strcmp(res->autotest, "multiprocess_autotest"))
ret |= test_mp_secondary();
if (all || !strcmp(res->autotest, "memcpy_autotest"))
ret |= test_memcpy();
if (all || !strcmp(res->autotest, "string_autotest"))
ret |= test_string_fns();
if (all || !strcmp(res->autotest, "eal_flags_autotest"))
ret |= test_eal_flags();
if (all || !strcmp(res->autotest, "alarm_autotest"))
ret |= test_alarm();
if (all || !strcmp(res->autotest, "interrupt_autotest"))
ret |= test_interrupt();
if (all || !strcmp(res->autotest, "cycles_autotest"))
ret |= test_cycles();
if (all || !strcmp(res->autotest, "ring_autotest"))
ret |= test_ring();
if (all || !strcmp(res->autotest, "timer_autotest"))
ret |= test_timer();
if (all || !strcmp(res->autotest, "mempool_autotest"))
ret |= test_mempool();
if (ret == 0)
printf("Test OK\n");
else
printf("Test Failed\n");
fflush(stdout);
}
cmdline_parse_token_string_t cmd_autotest_autotest =
TOKEN_STRING_INITIALIZER(struct cmd_autotest_result, autotest,
"pci_autotest#memory_autotest#"
"per_lcore_autotest#spinlock_autotest#"
"rwlock_autotest#atomic_autotest#"
"byteorder_autotest#prefetch_autotest#"
"cycles_autotest#logs_autotest#"
"memzone_autotest#ring_autotest#"
"mempool_autotest#mbuf_autotest#"
"timer_autotest#malloc_autotest#"
"memcpy_autotest#hash_autotest#"
"lpm_autotest#debug_autotest#"
"errno_autotest#tailq_autotest#"
"string_autotest#multiprocess_autotest#"
"cpuflags_autotest#eal_flags_autotest#"
"alarm_autotest#interrupt_autotest#"
"version_autotest#"
"all_autotests");
cmdline_parse_inst_t cmd_autotest = {
.f = cmd_autotest_parsed, /* function to call */
.data = NULL, /* 2nd arg of func */
.help_str = "launch autotest",
.tokens = { /* token list, NULL terminated */
(void *)&cmd_autotest_autotest,
NULL,
},
};
/****************/
struct cmd_dump_result {
cmdline_fixed_string_t dump;
};
static void
dump_struct_sizes(void)
{
#define DUMP_SIZE(t) printf("sizeof(" #t ") = %u\n", (unsigned)sizeof(t));
DUMP_SIZE(struct rte_mbuf);
DUMP_SIZE(struct rte_pktmbuf);
DUMP_SIZE(struct rte_ctrlmbuf);
DUMP_SIZE(struct rte_mempool);
DUMP_SIZE(struct rte_ring);
#undef DUMP_SIZE
}
static void cmd_dump_parsed(void *parsed_result,
__attribute__((unused)) struct cmdline *cl,
__attribute__((unused)) void *data)
{
struct cmd_dump_result *res = parsed_result;
if (!strcmp(res->dump, "dump_physmem"))
rte_dump_physmem_layout();
else if (!strcmp(res->dump, "dump_memzone"))
rte_memzone_dump();
else if (!strcmp(res->dump, "dump_log_history"))
rte_log_dump_history();
else if (!strcmp(res->dump, "dump_struct_sizes"))
dump_struct_sizes();
else if (!strcmp(res->dump, "dump_ring"))
rte_ring_list_dump();
else if (!strcmp(res->dump, "dump_mempool"))
rte_mempool_list_dump();
}
cmdline_parse_token_string_t cmd_dump_dump =
TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
"dump_physmem#dump_memzone#dump_log_history#"
"dump_struct_sizes#dump_ring#dump_mempool");
cmdline_parse_inst_t cmd_dump = {
.f = cmd_dump_parsed, /* function to call */
.data = NULL, /* 2nd arg of func */
.help_str = "dump status",
.tokens = { /* token list, NULL terminated */
(void *)&cmd_dump_dump,
NULL,
},
};
/****************/
struct cmd_dump_one_result {
cmdline_fixed_string_t dump;
cmdline_fixed_string_t name;
};
static void cmd_dump_one_parsed(void *parsed_result, struct cmdline *cl,
__attribute__((unused)) void *data)
{
struct cmd_dump_one_result *res = parsed_result;
if (!strcmp(res->dump, "dump_ring")) {
struct rte_ring *r;
r = rte_ring_lookup(res->name);
if (r == NULL) {
cmdline_printf(cl, "Cannot find ring\n");
return;
}
rte_ring_dump(r);
}
else if (!strcmp(res->dump, "dump_mempool")) {
struct rte_mempool *mp;
mp = rte_mempool_lookup(res->name);
if (mp == NULL) {
cmdline_printf(cl, "Cannot find mempool\n");
return;
}
rte_mempool_dump(mp);
}
}
cmdline_parse_token_string_t cmd_dump_one_dump =
TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, dump,
"dump_ring#dump_mempool");
cmdline_parse_token_string_t cmd_dump_one_name =
TOKEN_STRING_INITIALIZER(struct cmd_dump_one_result, name, NULL);
cmdline_parse_inst_t cmd_dump_one = {
.f = cmd_dump_one_parsed, /* function to call */
.data = NULL, /* 2nd arg of func */
.help_str = "dump one ring/mempool: dump_ring|dump_mempool <name>",
.tokens = { /* token list, NULL terminated */
(void *)&cmd_dump_one_dump,
(void *)&cmd_dump_one_name,
NULL,
},
};
/****************/
struct cmd_set_ring_result {
cmdline_fixed_string_t set;
cmdline_fixed_string_t name;
uint32_t value;
};
static void cmd_set_ring_parsed(void *parsed_result, struct cmdline *cl,
__attribute__((unused)) void *data)
{
struct cmd_set_ring_result *res = parsed_result;
struct rte_ring *r;
int ret;
r = rte_ring_lookup(res->name);
if (r == NULL) {
cmdline_printf(cl, "Cannot find ring\n");
return;
}
if (!strcmp(res->set, "set_quota")) {
ret = rte_ring_set_bulk_count(r, res->value);
if (ret != 0)
cmdline_printf(cl, "Cannot set quota\n");
}
else if (!strcmp(res->set, "set_watermark")) {
ret = rte_ring_set_water_mark(r, res->value);
if (ret != 0)
cmdline_printf(cl, "Cannot set water mark\n");
}
}
cmdline_parse_token_string_t cmd_set_ring_set =
TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, set,
"set_quota#set_watermark");
cmdline_parse_token_string_t cmd_set_ring_name =
TOKEN_STRING_INITIALIZER(struct cmd_set_ring_result, name, NULL);
cmdline_parse_token_num_t cmd_set_ring_value =
TOKEN_NUM_INITIALIZER(struct cmd_set_ring_result, value, UINT32);
cmdline_parse_inst_t cmd_set_ring = {
.f = cmd_set_ring_parsed, /* function to call */
.data = NULL, /* 2nd arg of func */
.help_str = "set quota/watermark: "
"set_quota|set_watermark <ring_name> <value>",
.tokens = { /* token list, NULL terminated */
(void *)&cmd_set_ring_set,
(void *)&cmd_set_ring_name,
(void *)&cmd_set_ring_value,
NULL,
},
};
/****************/
struct cmd_quit_result {
cmdline_fixed_string_t quit;
};
static void
cmd_quit_parsed(__attribute__((unused)) void *parsed_result,
struct cmdline *cl,
__attribute__((unused)) void *data)
{
cmdline_quit(cl);
}
cmdline_parse_token_string_t cmd_quit_quit =
TOKEN_STRING_INITIALIZER(struct cmd_quit_result, quit,
"quit");
cmdline_parse_inst_t cmd_quit = {
.f = cmd_quit_parsed, /* function to call */
.data = NULL, /* 2nd arg of func */
.help_str = "exit application",
.tokens = { /* token list, NULL terminated */
(void *)&cmd_quit_quit,
NULL,
},
};
/****************/
cmdline_parse_ctx_t main_ctx[] = {
(cmdline_parse_inst_t *)&cmd_autotest,
(cmdline_parse_inst_t *)&cmd_dump,
(cmdline_parse_inst_t *)&cmd_dump_one,
(cmdline_parse_inst_t *)&cmd_set_ring,
(cmdline_parse_inst_t *)&cmd_quit,
NULL,
};

193
app/test/graph_mempool.py Executable file
View File

@ -0,0 +1,193 @@
#!/usr/bin/env python
# BSD LICENSE
#
# Copyright(c) 2010-2012 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.
#
# version: DPDK.L.1.2.3-3
import sys, re
import numpy as np
import matplotlib
matplotlib.use('Agg') # we don't want to use X11
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
INT = "([-+]?[0-9][0-9]*)"
class MempoolTest:
l = []
def __init__(self):
pass
# sort a test case list
def sort(self, x, y):
for t in [ "cache", "cores", "n_get_bulk", "n_put_bulk",
"n_keep", "rate" ]:
if x[t] > y[t]:
return 1
if x[t] < y[t]:
return -1
return 0
# add a test case
def add(self, **args):
self.l.append(args)
# get an ordered list matching parameters
# ex: r.get(enq_core=1, deq_core=1)
def get(self, **args):
retlist = []
for t in self.l:
add_it = 1
for a in args:
if args[a] != t[a]:
add_it = 0
break
if add_it:
retlist.append(t)
retlist.sort(cmp=self.sort)
return retlist
# return an ordered list of all values for this param or param list
# ex: r.get_value_list("enq_core")
def get_value_list(self, param):
retlist = []
if type(param) is not list:
param = [param]
for t in self.l:
entry = []
for p in param:
entry.append(t[p])
if len(entry) == 1:
entry = entry[0]
else:
entry = tuple(entry)
if not entry in retlist:
retlist.append(entry)
retlist.sort()
return retlist
# read the file and return a MempoolTest object containing all data
def read_data_from_file(filename):
mempool_test = MempoolTest()
# parse the file: it produces a list of dict containing the data for
# each test case (each dict in the list corresponds to a line)
f = open(filename)
while True:
l = f.readline()
if l == "":
break
regexp = "mempool_autotest "
regexp += "cache=%s cores=%s "%(INT, INT)
regexp += "n_get_bulk=%s n_put_bulk=%s "%(INT, INT)
regexp += "n_keep=%s rate_persec=%s"%(INT, INT)
m = re.match(regexp, l)
if m == None:
continue
mempool_test.add(cache = int(m.groups()[0]),
cores = int(m.groups()[1]),
n_get_bulk = int(m.groups()[2]),
n_put_bulk = int(m.groups()[3]),
n_keep = int(m.groups()[4]),
rate = int(m.groups()[5]))
f.close()
return mempool_test
def millions(x, pos):
return '%1.1fM' % (x*1e-6)
# graph one, with specific parameters -> generate a .svg file
def graph_one(str, mempool_test, cache, cores, n_keep):
filename = "mempool_%d_%d_%d.svg"%(cache, cores, n_keep)
n_get_bulk_list = mempool_test.get_value_list("n_get_bulk")
N_n_get_bulk = len(n_get_bulk_list)
get_names = map(lambda x:"get=%d"%x, n_get_bulk_list)
n_put_bulk_list = mempool_test.get_value_list("n_put_bulk")
N_n_put_bulk = len(n_put_bulk_list)
put_names = map(lambda x:"put=%d"%x, n_put_bulk_list)
N = N_n_get_bulk * (N_n_put_bulk + 1)
rates = []
colors = []
for n_get_bulk in mempool_test.get_value_list("n_get_bulk"):
col = 0.
for n_put_bulk in mempool_test.get_value_list("n_put_bulk"):
col += 0.9 / len(mempool_test.get_value_list("n_put_bulk"))
r = mempool_test.get(cache=cache, cores=cores,
n_get_bulk=n_get_bulk,
n_put_bulk=n_put_bulk, n_keep=n_keep)
if len(r) != 0:
r = r[0]["rate"]
rates.append(r)
colors.append((1. - col, 0.2, col, 1.)) # rgba
rates.append(0)
colors.append((0.,0.,0.,0.))
ind = np.arange(N) # the x locations for the groups
width = 1 # the width of the bars: can also be len(x) sequence
formatter = FuncFormatter(millions)
fig = plt.figure()
p = plt.bar(ind, tuple(rates), width, color=tuple(colors))
fig.axes[0].yaxis.set_major_formatter(formatter)
plt.ylabel('Obj/sec')
#plt.ylim(0, 400000000.)
title = "Mempool autotest \"%s\"\n"%(str)
title += "cache=%d, core(s)=%d, n_keep=%d"%(cache, cores, n_keep)
plt.title(title)
ind_names = np.arange(N_n_get_bulk) * (N_n_put_bulk+1) + (N_n_put_bulk+1) / 2
plt.xticks(ind_names, tuple(get_names))
plt.legend(tuple([p[i] for i in range(N_n_put_bulk)]), tuple(put_names),
loc="upper left")
plt.savefig(filename)
if len(sys.argv) != 3:
print "usage: graph_mempool.py file title"
sys.exit(1)
mempool_test = read_data_from_file(sys.argv[1])
for cache, cores, n_keep in mempool_test.get_value_list(["cache", "cores",
"n_keep"]):
graph_one(sys.argv[2], mempool_test, cache, cores, n_keep)

201
app/test/graph_ring.py Executable file
View File

@ -0,0 +1,201 @@
#!/usr/bin/env python
# BSD LICENSE
#
# Copyright(c) 2010-2012 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.
#
# version: DPDK.L.1.2.3-3
import sys, re
import numpy as np
import matplotlib
matplotlib.use('Agg') # we don't want to use X11
import matplotlib.pyplot as plt
from matplotlib.ticker import FuncFormatter
INT = "([-+]?[0-9][0-9]*)"
class RingTest:
l = []
def __init__(self):
pass
# sort a test case list
def sort(self, x, y):
for t in [ "enq_core", "deq_core", "enq_bulk", "deq_bulk", "rate" ]:
if x[t] > y[t]:
return 1
if x[t] < y[t]:
return -1
return 0
# add a test case
def add(self, **args):
self.l.append(args)
# get an ordered list matching parameters
# ex: r.get(enq_core=1, deq_core=1)
def get(self, **args):
retlist = []
for t in self.l:
add_it = 1
for a in args:
if args[a] != t[a]:
add_it = 0
break
if add_it:
retlist.append(t)
retlist.sort(cmp=self.sort)
return retlist
# return an ordered list of all values for this param or param list
# ex: r.get_value_list("enq_core")
def get_value_list(self, param):
retlist = []
if type(param) is not list:
param = [param]
for t in self.l:
entry = []
for p in param:
entry.append(t[p])
if len(entry) == 1:
entry = entry[0]
else:
entry = tuple(entry)
if not entry in retlist:
retlist.append(entry)
retlist.sort()
return retlist
# read the file and return a RingTest object containing all data
def read_data_from_file(filename):
ring_test = RingTest()
# parse the file: it produces a list of dict containing the data for
# each test case (each dict in the list corresponds to a line)
f = open(filename)
while True:
l = f.readline()
if l == "":
break
regexp = "ring_autotest "
regexp += "e/d_core=%s,%s e/d_bulk=%s,%s "%(INT, INT, INT, INT)
regexp += "sp=%s sc=%s "%(INT, INT)
regexp += "rate_persec=%s"%(INT)
m = re.match(regexp, l)
if m == None:
continue
ring_test.add(enq_core = int(m.groups()[0]),
deq_core = int(m.groups()[1]),
enq_bulk = int(m.groups()[2]),
deq_bulk = int(m.groups()[3]),
sp = int(m.groups()[4]),
sc = int(m.groups()[5]),
rate = int(m.groups()[6]))
f.close()
return ring_test
def millions(x, pos):
return '%1.1fM' % (x*1e-6)
# graph one, with specific parameters -> generate a .svg file
def graph_one(str, ring_test, enq_core, deq_core, sp, sc):
filename = "ring_%d_%d"%(enq_core, deq_core)
if sp:
sp_str = "sp"
else:
sp_str = "mp"
if sc:
sc_str = "sc"
else:
sc_str = "mc"
filename += "_%s_%s.svg"%(sp_str, sc_str)
enq_bulk_list = ring_test.get_value_list("enq_bulk")
N_enq_bulk = len(enq_bulk_list)
enq_names = map(lambda x:"enq=%d"%x, enq_bulk_list)
deq_bulk_list = ring_test.get_value_list("deq_bulk")
N_deq_bulk = len(deq_bulk_list)
deq_names = map(lambda x:"deq=%d"%x, deq_bulk_list)
N = N_enq_bulk * (N_deq_bulk + 1)
rates = []
colors = []
for enq_bulk in ring_test.get_value_list("enq_bulk"):
col = 0.
for deq_bulk in ring_test.get_value_list("deq_bulk"):
col += 0.9 / len(ring_test.get_value_list("deq_bulk"))
r = ring_test.get(enq_core=enq_core, deq_core=deq_core,
enq_bulk=enq_bulk, deq_bulk=deq_bulk,
sp=sp, sc=sc)
r = r[0]["rate"]
rates.append(r)
colors.append((1. - col, 0.2, col, 1.)) # rgba
rates.append(0)
colors.append((0.,0.,0.,0.))
ind = np.arange(N) # the x locations for the groups
width = 1 # the width of the bars: can also be len(x) sequence
formatter = FuncFormatter(millions)
fig = plt.figure()
p = plt.bar(ind, tuple(rates), width, color=tuple(colors))
fig.axes[0].yaxis.set_major_formatter(formatter)
plt.ylabel('Obj/sec')
#plt.ylim(0, 400000000.)
plt.title("Ring autotest \"%s\"\nenq core(s)=%d, deq core(s)=%d, %s, %s"\
%(str, enq_core, deq_core, sp_str, sc_str))
ind_names = np.arange(N_enq_bulk) * (N_deq_bulk+1) + (N_deq_bulk+1) / 2
plt.xticks(ind_names, tuple(enq_names))
plt.legend(tuple([p[i] for i in range(N_deq_bulk)]), tuple(deq_names),
loc="upper left")
plt.savefig(filename)
if len(sys.argv) != 3:
print "usage: graph_ring.py file title"
sys.exit(1)
ring_test = read_data_from_file(sys.argv[1])
for enq_core, deq_core, sp, sc in \
ring_test.get_value_list(["enq_core", "deq_core", "sp", "sc"]):
graph_one(sys.argv[2], ring_test, enq_core, deq_core, sp, sc)

89
app/test/process.h Normal file
View File

@ -0,0 +1,89 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#ifndef _PROCESS_H_
#define _PROCESS_H_
#ifndef RTE_EXEC_ENV_BAREMETAL
/*
* 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
* subprocess the source of the call, the env_value parameter is set in the
* environment as $RTE_TEST
*/
static inline int
process_dup(const char *const argv[], int numargs, const char *env_value)
{
char *argv_cpy[numargs + 1];
int i, fd, status;
char path[32];
pid_t pid = fork();
if (pid < 0)
return -1;
else if (pid == 0) {
/* make a copy of the arguments to be passed to exec */
for (i = 0; i < numargs; i++)
argv_cpy[i] = strdup(argv[i]);
argv_cpy[i] = NULL;
/* 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);
if (access(path, F_OK) == 0)
close(fd);
}
printf("Running binary with argv[]:");
for (i = 0; i < numargs; i++)
printf("'%s' ", argv_cpy[i]);
printf("\n");
/* 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)
rte_panic("Cannot exec\n");
}
/* parent process does a wait */
while (wait(&status) != pid)
;
return status;
}
#endif /* not baremetal */
#endif /* _PROCESS_H_ */

153
app/test/test.c Normal file
View File

@ -0,0 +1,153 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#include <termios.h>
#include <ctype.h>
#include <sys/queue.h>
#include <cmdline_rdline.h>
#include <cmdline_parse.h>
#include <cmdline_socket.h>
#include <cmdline.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_timer.h>
#include <rte_string_fns.h>
#include "test.h"
const char *prgname; /* to be set to argv[0] */
#ifndef RTE_EXEC_ENV_BAREMETAL
static const char *recursive_call; /* used in linuxapp for MP and other tests */
static int
no_action(void){ return 0; }
static int
do_recursive_call(void)
{
unsigned i;
struct {
const char *env_var;
int (*action_fn)(void);
} actions[] = {
{ "run_secondary_instances", test_mp_secondary },
{ "test_missing_c_flag", no_action },
{ "test_missing_n_flag", no_action },
{ "test_no_hpet_flag", no_action },
{ "test_invalid_b_flag", no_action },
{ "test_invalid_r_flag", no_action },
{ "test_misc_flags", no_action },
};
if (recursive_call == NULL)
return -1;
for (i = 0; i < sizeof(actions)/sizeof(actions[0]); i++) {
if (strcmp(actions[i].env_var, recursive_call) == 0)
return (actions[i].action_fn)();
}
return -1;
}
#endif
void
test_hexdump(const char *title, const void *buf, unsigned int len)
{
unsigned int i, out, ofs;
const unsigned char *data = buf;
#define LINE_LEN 80
char line[LINE_LEN]; /* space needed 8+16*3+3+16 == 75 */
printf("%s at [%p], len=%u\n", title, data, len);
ofs = 0;
while (ofs < len) {
/* format 1 line in the buffer, then use printf to print them */
out = rte_snprintf(line, LINE_LEN, "%08X", ofs);
for (i = 0; ofs+i < len && i < 16; i++)
out += rte_snprintf(line+out, LINE_LEN - out, " %02X",
data[ofs+i]&0xff);
for(; i <= 16; i++)
out += rte_snprintf(line+out, LINE_LEN - out, " ");
for(i = 0; ofs < len && i < 16; i++, ofs++) {
unsigned char c = data[ofs];
if (!isascii(c) || !isprint(c))
c = '.';
out += rte_snprintf(line+out, LINE_LEN - out, "%c", c);
}
printf("%s\n", line);
}
}
int
main(int argc, char **argv)
{
struct cmdline *cl;
int ret;
ret = rte_eal_init(argc, argv);
if (ret < 0)
return -1;
rte_timer_subsystem_init();
argc -= ret;
argv += ret;
prgname = argv[0];
#ifndef RTE_EXEC_ENV_BAREMETAL
if ((recursive_call = getenv(RECURSIVE_ENV_VAR)) != NULL)
return do_recursive_call();
#endif
cl = cmdline_stdin_new(main_ctx, "RTE>>");
if (cl == NULL) {
return -1;
}
cmdline_interact(cl);
cmdline_stdin_exit(cl);
return 0;
}

85
app/test/test.h Normal file
View File

@ -0,0 +1,85 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#ifndef _TEST_H_
#define _TEST_H_
/* icc on baremetal gives us troubles with function named 'main' */
#ifdef RTE_EXEC_ENV_BAREMETAL
#define main _main
#endif
#define RECURSIVE_ENV_VAR "RTE_TEST_RECURSIVE"
extern const char *prgname;
extern cmdline_parse_ctx_t main_ctx[];
void test_hexdump(const char *title, const void *buf, unsigned int len);
int main(int argc, char **argv);
int test_pci(void);
int test_memory(void);
int test_per_lcore(void);
int test_spinlock(void);
int test_rwlock(void);
int test_atomic(void);
int test_byteorder(void);
int test_prefetch(void);
int test_cycles(void);
int test_logs(void);
int test_memzone(void);
int test_ring(void);
int test_mempool(void);
int test_mbuf(void);
int test_timer(void);
int test_malloc(void);
int test_memcpy(void);
int test_hash(void);
int test_lpm(void);
int test_debug(void);
int test_errno(void);
int test_tailq(void);
int test_string_fns(void);
int test_mp_secondary(void);
int test_cpuflags(void);
int test_eal_flags(void);
int test_alarm(void);
int test_interrupt(void);
int test_version(void);
int test_pci_run;
#endif

258
app/test/test_alarm.c Normal file
View File

@ -0,0 +1,258 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <cmdline_parse.h>
#include <rte_common.h>
#include <rte_cycles.h>
#include <rte_interrupts.h>
#include <rte_common.h>
#include <rte_atomic.h>
#include <rte_alarm.h>
#include "test.h"
#define US_PER_MS 1000
#define RTE_TEST_ALARM_TIMEOUT 3000 /* ms */
#define RTE_TEST_CHECK_PERIOD 1000 /* ms */
static volatile int flag;
static void
test_alarm_callback(void *cb_arg)
{
flag = 1;
printf("Callback setting flag - OK. [cb_arg = %p]\n", cb_arg);
}
static rte_atomic32_t cb_count;
static void
test_multi_cb(void *arg)
{
rte_atomic32_inc(&cb_count);
printf("In %s - arg = %p\n", __func__, arg);
}
static volatile int recursive_error = 0;
static void
test_remove_in_callback(void *arg)
{
printf("In %s - arg = %p\n", __func__, arg);
if (rte_eal_alarm_cancel(test_remove_in_callback, arg) ||
rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1)) {
printf("Error - cancelling callback from within function succeeded!\n");
recursive_error = 1;
}
flag = (int)((uintptr_t)arg);
}
static volatile int flag_2;
static void
test_remove_in_callback_2(void *arg)
{
if (rte_eal_alarm_cancel(test_remove_in_callback_2, arg) || rte_eal_alarm_cancel(test_remove_in_callback_2, (void *)-1)) {
printf("Error - cancelling callback of test_remove_in_callback_2\n");
return;
}
flag_2 = 1;
}
static int
test_multi_alarms(void)
{
int rm_count = 0;
cb_count.cnt = 0;
printf("Expect 6 callbacks in order...\n");
/* add two alarms in order */
rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)1);
rte_eal_alarm_set(2000 * US_PER_MS, test_multi_cb, (void *)2);
/* now add in reverse order */
rte_eal_alarm_set(6000 * US_PER_MS, test_multi_cb, (void *)6);
rte_eal_alarm_set(5000 * US_PER_MS, test_multi_cb, (void *)5);
rte_eal_alarm_set(4000 * US_PER_MS, test_multi_cb, (void *)4);
rte_eal_alarm_set(3000 * US_PER_MS, test_multi_cb, (void *)3);
/* wait for expiry */
rte_delay_ms(6500);
if (cb_count.cnt != 6) {
printf("Missing callbacks\n");
/* remove any callbacks that might remain */
rte_eal_alarm_cancel(test_multi_cb, (void *)-1);
return -1;
}
cb_count.cnt = 0;
printf("Expect only callbacks with args 1 and 3...\n");
/* Add 3 flags, then delete one */
rte_eal_alarm_set(3000 * US_PER_MS, test_multi_cb, (void *)3);
rte_eal_alarm_set(2000 * US_PER_MS, test_multi_cb, (void *)2);
rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)1);
rm_count = rte_eal_alarm_cancel(test_multi_cb, (void *)2);
rte_delay_ms(3500);
if (cb_count.cnt != 2 || rm_count != 1) {
printf("Error: invalid flags count or alarm removal failure"
" - flags value = %d, expected = %d\n", cb_count.cnt, 2);
/* remove any callbacks that might remain */
rte_eal_alarm_cancel(test_multi_cb, (void *)-1);
return -1;
}
printf("Testing adding and then removing multiple alarms\n");
/* finally test that no callbacks are called if we delete them all*/
rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)1);
rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)2);
rte_eal_alarm_set(1000 * US_PER_MS, test_multi_cb, (void *)3);
rm_count = rte_eal_alarm_cancel(test_alarm_callback, (void *)-1);
if (rm_count != 0) {
printf("Error removing non-existant alarm succeeded\n");
rte_eal_alarm_cancel(test_multi_cb, (void *) -1);
return -1;
}
rm_count = rte_eal_alarm_cancel(test_multi_cb, (void *) -1);
if (rm_count != 3) {
printf("Error removing all pending alarm callbacks\n");
return -1;
}
/* Test that we cannot cancel an alarm from within the callback itself
* Also test that we can cancel head-of-line callbacks ok.*/
flag = 0;
recursive_error = 0;
rte_eal_alarm_set(1000 * US_PER_MS, test_remove_in_callback, (void *)1);
rte_eal_alarm_set(2000 * US_PER_MS, test_remove_in_callback, (void *)2);
rm_count = rte_eal_alarm_cancel(test_remove_in_callback, (void *)1);
if (rm_count != 1) {
printf("Error cancelling head-of-list callback\n");
return -1;
}
rte_delay_ms(1500);
if (flag != 0) {
printf("Error, cancelling head-of-list leads to premature callback\n");
return -1;
}
rte_delay_ms(1000);
if (flag != 2) {
printf("Error - expected callback not called\n");
rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1);
return -1;
}
if (recursive_error == 1)
return -1;
/* Check if it can cancel all for the same callback */
printf("Testing canceling all for the same callback\n");
flag_2 = 0;
rte_eal_alarm_set(1000 * US_PER_MS, test_remove_in_callback, (void *)1);
rte_eal_alarm_set(2000 * US_PER_MS, test_remove_in_callback_2, (void *)2);
rte_eal_alarm_set(3000 * US_PER_MS, test_remove_in_callback_2, (void *)3);
rte_eal_alarm_set(4000 * US_PER_MS, test_remove_in_callback, (void *)4);
rm_count = rte_eal_alarm_cancel(test_remove_in_callback_2, (void *)-1);
if (rm_count != 2) {
printf("Error, cannot cancel all for the same callback\n");
return -1;
}
rm_count = rte_eal_alarm_cancel(test_remove_in_callback, (void *)-1);
if (rm_count != 2) {
printf("Error, cannot cancel all for the same callback\n");
return -1;
}
return 0;
}
int
test_alarm(void)
{
int count = 0;
/* check if the callback will be called */
printf("check if the callback will be called\n");
flag = 0;
if (rte_eal_alarm_set(RTE_TEST_ALARM_TIMEOUT * US_PER_MS,
test_alarm_callback, NULL) < 0) {
printf("fail to set alarm callback\n");
return -1;
}
while (flag == 0 && count ++ < 6)
rte_delay_ms(RTE_TEST_CHECK_PERIOD);
if (flag == 0){
printf("Callback not called\n");
return -1;
}
/* check if it will fail to set alarm with wrong us value */
printf("check if it will fail to set alarm with wrong ms values\n");
if (rte_eal_alarm_set(0, test_alarm_callback,
NULL) >= 0) {
printf("should not be successful with 0 us value\n");
return -1;
}
if (rte_eal_alarm_set(UINT64_MAX - 1, test_alarm_callback,
NULL) >= 0) {
printf("should not be successful with (UINT64_MAX-1) us value\n");
return -1;
}
/* check if it will fail to set alarm with null callback parameter */
printf("check if it will fail to set alarm with null callback parameter\n");
if (rte_eal_alarm_set(RTE_TEST_ALARM_TIMEOUT, NULL, NULL) >= 0) {
printf("should not be successful to set alarm with null callback parameter\n");
return -1;
}
/* check if it will fail to remove alarm with null callback parameter */
printf("check if it will fail to remove alarm with null callback parameter\n");
if (rte_eal_alarm_cancel(NULL, NULL) == 0) {
printf("should not be successful to remove alarm with null callback parameter");
return -1;
}
if (test_multi_alarms() != 0)
return -1;
return 0;
}

381
app/test/test_atomic.c Normal file
View File

@ -0,0 +1,381 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_per_lcore.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include "test.h"
/*
* Atomic Variables
* ================
*
* - The main test function performs three subtests. The first test
* checks that the usual inc/dec/add/sub functions are working
* correctly:
*
* - Initialize 16-bit, 32-bit and 64-bit atomic variables to specific
* values.
*
* - These variables are incremented and decremented on each core at
* the same time in ``test_atomic_usual()``.
*
* - The function checks that once all lcores finish their function,
* the value of the atomic variables are still the same.
*
* - The second test verifies the behavior of "test and set" functions.
*
* - Initialize 16-bit, 32-bit and 64-bit atomic variables to zero.
*
* - Invoke ``test_atomic_tas()`` on each lcore: before doing anything
* else. The cores are waiting a synchro using ``while
* (rte_atomic32_read(&val) == 0)`` which is triggered by the main test
* function. Then all cores do a
* ``rte_atomicXX_test_and_set()`` at the same time. If it is successful,
* it increments another atomic counter.
*
* - The main function checks that the atomic counter was incremented
* twice only (one for 16-bit, one for 32-bit and one for 64-bit values).
*
* - Test "add/sub and return"
*
* - Initialize 16-bit, 32-bit and 64-bit atomic variables to zero.
*
* - Invoke ``test_atomic_addsub_return()`` on each lcore. Before doing
* anything else, the cores are waiting a synchro. Each lcore does
* this operation several times::
*
* tmp = rte_atomicXX_add_return(&a, 1);
* atomic_add(&count, tmp);
* tmp = rte_atomicXX_sub_return(&a, 1);
* atomic_sub(&count, tmp+1);
*
* - At the end of the test, the *count* value must be 0.
*/
#define NUM_ATOMIC_TYPES 3
#define N 10000
static rte_atomic16_t a16;
static rte_atomic32_t a32;
static rte_atomic64_t a64;
static rte_atomic32_t count;
static rte_atomic32_t synchro;
static int
test_atomic_usual(__attribute__((unused)) void *arg)
{
unsigned i;
while (rte_atomic32_read(&synchro) == 0)
;
for (i = 0; i < N; i++)
rte_atomic16_inc(&a16);
for (i = 0; i < N; i++)
rte_atomic16_dec(&a16);
for (i = 0; i < (N / 5); i++)
rte_atomic16_add(&a16, 5);
for (i = 0; i < (N / 5); i++)
rte_atomic16_sub(&a16, 5);
for (i = 0; i < N; i++)
rte_atomic32_inc(&a32);
for (i = 0; i < N; i++)
rte_atomic32_dec(&a32);
for (i = 0; i < (N / 5); i++)
rte_atomic32_add(&a32, 5);
for (i = 0; i < (N / 5); i++)
rte_atomic32_sub(&a32, 5);
for (i = 0; i < N; i++)
rte_atomic64_inc(&a64);
for (i = 0; i < N; i++)
rte_atomic64_dec(&a64);
for (i = 0; i < (N / 5); i++)
rte_atomic64_add(&a64, 5);
for (i = 0; i < (N / 5); i++)
rte_atomic64_sub(&a64, 5);
return 0;
}
static int
test_atomic_tas(__attribute__((unused)) void *arg)
{
while (rte_atomic32_read(&synchro) == 0)
;
if (rte_atomic16_test_and_set(&a16))
rte_atomic32_inc(&count);
if (rte_atomic32_test_and_set(&a32))
rte_atomic32_inc(&count);
if (rte_atomic64_test_and_set(&a64))
rte_atomic32_inc(&count);
return 0;
}
static int
test_atomic_addsub_and_return(__attribute__((unused)) void *arg)
{
uint32_t tmp16;
uint32_t tmp32;
uint64_t tmp64;
unsigned i;
while (rte_atomic32_read(&synchro) == 0)
;
for (i = 0; i < N; i++) {
tmp16 = rte_atomic16_add_return(&a16, 1);
rte_atomic32_add(&count, tmp16);
tmp16 = rte_atomic16_sub_return(&a16, 1);
rte_atomic32_sub(&count, tmp16+1);
tmp32 = rte_atomic32_add_return(&a32, 1);
rte_atomic32_add(&count, tmp32);
tmp32 = rte_atomic32_sub_return(&a32, 1);
rte_atomic32_sub(&count, tmp32+1);
tmp64 = rte_atomic64_add_return(&a64, 1);
rte_atomic32_add(&count, tmp64);
tmp64 = rte_atomic64_sub_return(&a64, 1);
rte_atomic32_sub(&count, tmp64+1);
}
return 0;
}
/*
* rte_atomic32_inc_and_test() would increase a 32 bits counter by one and then
* test if that counter is equal to 0. It would return true if the counter is 0
* and false if the counter is not 0. rte_atomic64_inc_and_test() could do the
* same thing but for a 64 bits counter.
* Here checks that if the 32/64 bits counter is equal to 0 after being atomically
* increased by one. If it is, increase the variable of "count" by one which would
* be checked as the result later.
*
*/
static int
test_atomic_inc_and_test(__attribute__((unused)) void *arg)
{
while (rte_atomic32_read(&synchro) == 0)
;
if (rte_atomic16_inc_and_test(&a16)) {
rte_atomic32_inc(&count);
}
if (rte_atomic32_inc_and_test(&a32)) {
rte_atomic32_inc(&count);
}
if (rte_atomic64_inc_and_test(&a64)) {
rte_atomic32_inc(&count);
}
return 0;
}
/*
* rte_atomicXX_dec_and_test() should decrease a 32 bits counter by one and then
* test if that counter is equal to 0. It should return true if the counter is 0
* and false if the counter is not 0.
* This test checks if the counter is equal to 0 after being atomically
* decreased by one. If it is, increase the value of "count" by one which is to
* be checked as the result later.
*/
static int
test_atomic_dec_and_test(__attribute__((unused)) void *arg)
{
while (rte_atomic32_read(&synchro) == 0)
;
if (rte_atomic16_dec_and_test(&a16))
rte_atomic32_inc(&count);
if (rte_atomic32_dec_and_test(&a32))
rte_atomic32_inc(&count);
if (rte_atomic64_dec_and_test(&a64))
rte_atomic32_inc(&count);
return 0;
}
int
test_atomic(void)
{
rte_atomic16_init(&a16);
rte_atomic32_init(&a32);
rte_atomic64_init(&a64);
rte_atomic32_init(&count);
rte_atomic32_init(&synchro);
rte_atomic16_set(&a16, 1UL << 10);
rte_atomic32_set(&a32, 1UL << 10);
rte_atomic64_set(&a64, 1ULL << 33);
printf("usual inc/dec/add/sub functions\n");
rte_eal_mp_remote_launch(test_atomic_usual, NULL, SKIP_MASTER);
rte_atomic32_set(&synchro, 1);
rte_eal_mp_wait_lcore();
rte_atomic32_set(&synchro, 0);
if (rte_atomic16_read(&a16) != 1UL << 10) {
printf("Atomic16 usual functions failed\n");
return -1;
}
if (rte_atomic32_read(&a32) != 1UL << 10) {
printf("Atomic32 usual functions failed\n");
return -1;
}
if (rte_atomic64_read(&a64) != 1ULL << 33) {
printf("Atomic64 usual functions failed\n");
return -1;
}
printf("test and set\n");
rte_atomic64_set(&a64, 0);
rte_atomic32_set(&a32, 0);
rte_atomic16_set(&a16, 0);
rte_atomic32_set(&count, 0);
rte_eal_mp_remote_launch(test_atomic_tas, NULL, SKIP_MASTER);
rte_atomic32_set(&synchro, 1);
rte_eal_mp_wait_lcore();
rte_atomic32_set(&synchro, 0);
if (rte_atomic32_read(&count) != NUM_ATOMIC_TYPES) {
printf("Atomic test and set failed\n");
return -1;
}
printf("add/sub and return\n");
rte_atomic64_set(&a64, 0);
rte_atomic32_set(&a32, 0);
rte_atomic16_set(&a16, 0);
rte_atomic32_set(&count, 0);
rte_eal_mp_remote_launch(test_atomic_addsub_and_return, NULL,
SKIP_MASTER);
rte_atomic32_set(&synchro, 1);
rte_eal_mp_wait_lcore();
rte_atomic32_set(&synchro, 0);
if (rte_atomic32_read(&count) != 0) {
printf("Atomic add/sub+return failed\n");
return -1;
}
/*
* Set a64, a32 and a16 with the same value of minus "number of slave
* lcores", launch all slave lcores to atomically increase by one and
* test them respectively.
* Each lcore should have only one chance to increase a64 by one and
* then check if it is equal to 0, but there should be only one lcore
* that finds that it is 0. It is similar for a32 and a16.
* Then a variable of "count", initialized to zero, is increased by
* one if a64, a32 or a16 is 0 after being increased and tested
* atomically.
* We can check if "count" is finally equal to 3 to see if all slave
* lcores performed "atomic inc and test" right.
*/
printf("inc and test\n");
rte_atomic64_clear(&a64);
rte_atomic32_clear(&a32);
rte_atomic16_clear(&a16);
rte_atomic32_clear(&synchro);
rte_atomic32_clear(&count);
rte_atomic64_set(&a64, (int64_t)(1 - (int64_t)rte_lcore_count()));
rte_atomic32_set(&a32, (int32_t)(1 - (int32_t)rte_lcore_count()));
rte_atomic16_set(&a16, (int16_t)(1 - (int16_t)rte_lcore_count()));
rte_eal_mp_remote_launch(test_atomic_inc_and_test, NULL, SKIP_MASTER);
rte_atomic32_set(&synchro, 1);
rte_eal_mp_wait_lcore();
rte_atomic32_clear(&synchro);
if (rte_atomic32_read(&count) != NUM_ATOMIC_TYPES) {
printf("Atomic inc and test failed %d\n", count.cnt);
return -1;
}
/*
* Same as above, but this time we set the values to "number of slave
* lcores", and decrement instead of increment.
*/
printf("dec and test\n");
rte_atomic32_clear(&synchro);
rte_atomic32_clear(&count);
rte_atomic64_set(&a64, (int64_t)(rte_lcore_count() - 1));
rte_atomic32_set(&a32, (int32_t)(rte_lcore_count() - 1));
rte_atomic16_set(&a16, (int16_t)(rte_lcore_count() - 1));
rte_eal_mp_remote_launch(test_atomic_dec_and_test, NULL, SKIP_MASTER);
rte_atomic32_set(&synchro, 1);
rte_eal_mp_wait_lcore();
rte_atomic32_clear(&synchro);
if (rte_atomic32_read(&count) != NUM_ATOMIC_TYPES) {
printf("Atomic dec and test failed\n");
return -1;
}
return 0;
}

97
app/test/test_byteorder.c Normal file
View File

@ -0,0 +1,97 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <inttypes.h>
#include <cmdline_parse.h>
#include <rte_byteorder.h>
#include "test.h"
static volatile uint16_t u16 = 0x1337;
static volatile uint32_t u32 = 0xdeadbeefUL;
static volatile uint64_t u64 = 0xdeadcafebabefaceULL;
/*
* Byteorder functions
* ===================
*
* - check that optimized byte swap functions are working for each
* size (16, 32, 64 bits)
*/
int
test_byteorder(void)
{
uint16_t res_u16;
uint32_t res_u32;
uint64_t res_u64;
res_u16 = rte_bswap16(u16);
printf("%"PRIx16" -> %"PRIx16"\n", u16, res_u16);
if (res_u16 != 0x3713)
return -1;
res_u32 = rte_bswap32(u32);
printf("%"PRIx32" -> %"PRIx32"\n", u32, res_u32);
if (res_u32 != 0xefbeaddeUL)
return -1;
res_u64 = rte_bswap64(u64);
printf("%"PRIx64" -> %"PRIx64"\n", u64, res_u64);
if (res_u64 != 0xcefabebafecaaddeULL)
return -1;
res_u16 = rte_bswap16(0x1337);
printf("const %"PRIx16" -> %"PRIx16"\n", 0x1337, res_u16);
if (res_u16 != 0x3713)
return -1;
res_u32 = rte_bswap32(0xdeadbeefUL);
printf("const %"PRIx32" -> %"PRIx32"\n", (uint32_t) 0xdeadbeef, res_u32);
if (res_u32 != 0xefbeaddeUL)
return -1;
res_u64 = rte_bswap64(0xdeadcafebabefaceULL);
printf("const %"PRIx64" -> %"PRIx64"\n", (uint64_t) 0xdeadcafebabefaceULL, res_u64);
if (res_u64 != 0xcefabebafecaaddeULL)
return -1;
return 0;
}

134
app/test/test_cpuflags.c Normal file
View File

@ -0,0 +1,134 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <cmdline_parse.h>
#include <errno.h>
#include <stdint.h>
#include <rte_cpuflags.h>
#include <rte_debug.h>
#include "test.h"
/* convenience define */
#define CHECK_FOR_FLAG(x) \
result = rte_cpu_get_flag_enabled(x); \
printf("%s\n", cpu_flag_result(result)); \
if (result == -ENOENT) \
return -1;
/*
* Helper function to display result
*/
static inline const char *
cpu_flag_result(int result)
{
switch (result) {
case 0:
return "NOT PRESENT";
case 1:
return "OK";
default:
return "ERROR";
}
}
/*
* CPUID test
* ===========
*
* - Check flags from different registers with rte_cpu_get_flag_enabled()
* - Check if register and CPUID functions fail properly
*/
int
test_cpuflags(void)
{
int result;
printf("\nChecking for flags from different registers...\n");
printf("Check for SSE:\t\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_SSE);
printf("Check for SSE2:\t\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_SSE2);
printf("Check for SSE3:\t\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_SSE3);
printf("Check for SSE4.1:\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_SSE4_1);
printf("Check for SSE4.2:\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_SSE4_2);
printf("Check for AVX:\t\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_AVX);
printf("Check for AVX2:\t\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_AVX2);
printf("Check for TRBOBST:\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_TRBOBST);
printf("Check for ENERGY_EFF:\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_ENERGY_EFF);
printf("Check for LAHF_SAHF:\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_LAHF_SAHF);
printf("Check for 1GB_PG:\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_1GB_PG);
printf("Check for INVTSC:\t");
CHECK_FOR_FLAG(RTE_CPUFLAG_INVTSC);
/*
* Check if invalid data is handled properly
*/
printf("\nCheck for invalid flag:\t");
result = rte_cpu_get_flag_enabled(RTE_CPUFLAG_NUMFLAGS);
printf("%s\n", cpu_flag_result(result));
if (result != -ENOENT)
return -1;
return 0;
}

94
app/test/test_cycles.c Normal file
View File

@ -0,0 +1,94 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <cmdline_parse.h>
#include <rte_common.h>
#include <rte_cycles.h>
#include "test.h"
#define N 10000
/*
* Cycles test
* ===========
*
* - Loop N times and check that the timer alway increments and
* never decrements during this loop.
*
* - Wait one second using rte_usleep() and check that the increment
* of cycles is correct with regard to the frequency of the timer.
*/
int
test_cycles(void)
{
unsigned i;
uint64_t start_cycles, cycles, prev_cycles;
uint64_t hz = rte_get_hpet_hz();
uint64_t max_inc = (hz / 100); /* 10 ms max between 2 reads */
/* check that the timer is always incrementing */
start_cycles = rte_get_hpet_cycles();
prev_cycles = start_cycles;
for (i=0; i<N; i++) {
cycles = rte_get_hpet_cycles();
if ((uint64_t)(cycles - prev_cycles) > max_inc) {
printf("increment too high or going backwards\n");
return -1;
}
prev_cycles = cycles;
}
/* check that waiting 1 second is precise */
prev_cycles = rte_get_hpet_cycles();
rte_delay_us(1000000);
cycles = rte_get_hpet_cycles();
if ((uint64_t)(cycles - prev_cycles) > (hz + max_inc)) {
printf("delay_us is not accurate\n");
return -1;
}
cycles = rte_get_hpet_cycles();
if ((uint64_t)(cycles - prev_cycles) < (hz)) {
printf("delay_us is not accurate\n");
return -1;
}
return 0;
}

150
app/test/test_debug.c Normal file
View File

@ -0,0 +1,150 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <sys/wait.h>
#include <unistd.h>
#include <cmdline_parse.h>
#include <rte_debug.h>
#include <rte_common.h>
#include "test.h"
/*
* Debug test
* ==========
*
* - Call rte_dump_stack() and rte_dump_registers(). The result is not checked
* currently, as the functions are not implemented on baremetal.
* - Check that rte_panic() terminates the program using a non-zero error code.
* (Only implemented on linux, since it requires the fork() system call)
*/
#ifdef RTE_EXEC_ENV_BAREMETAL
/* baremetal - don't test rte_panic or rte_exit */
static int
test_panic(void)
{
return 0;
}
static int
test_exit(void)
{
return 0;
}
#else
/* linuxapp - use fork() to test rte_panic() */
static int
test_panic(void)
{
int pid;
int status;
pid = fork();
if (pid == 0)
rte_panic("Test Debug\n");
else if (pid < 0){
printf("Fork Failed\n");
return -1;
}
wait(&status);
if(status == 0){
printf("Child process terminated normally!\n");
return -1;
} else
printf("Child process terminated as expected - Test passed!\n");
return 0;
}
/* linuxapp - use fork() to test rte_exit() */
static int
test_exit_val(int exit_val)
{
int pid;
int status;
pid = fork();
if (pid == 0)
rte_exit(exit_val, __func__);
else if (pid < 0){
printf("Fork Failed\n");
return -1;
}
wait(&status);
printf("Child process status: %d\n", status);
if(!WIFEXITED(status) || WEXITSTATUS(status) != (uint8_t)exit_val){
printf("Child process terminated with incorrect return code!\n");
return -1;
}
return 0;
}
static int
test_exit(void)
{
int test_vals[] = { 0, 1, 2, 255, -1 };
unsigned i;
for (i = 0; i < sizeof(test_vals) / sizeof(test_vals[0]); i++){
if (test_exit_val(test_vals[i]) < 0)
return -1;
}
printf("%s Passed\n", __func__);
return 0;
}
#endif
int
test_debug(void)
{
rte_dump_stack();
rte_dump_registers();
if (test_panic() < 0)
return -1;
if (test_exit() < 0)
return -1;
return 0;
}

303
app/test/test_eal_flags.c Normal file
View File

@ -0,0 +1,303 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <cmdline_parse.h>
#include "test.h"
#ifndef RTE_EXEC_ENV_BAREMETAL
#include <string.h>
#include <stdarg.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
#include <rte_debug.h>
#include <rte_string_fns.h>
#include "process.h"
#define mp_flag "--proc-type=secondary"
#define no_hpet "--no-hpet"
#define no_huge "--no-huge"
#define no_shconf "--no-shconf"
#define launch_proc(ARGV) process_dup(ARGV, \
sizeof(ARGV)/(sizeof(ARGV[0])), __func__)
/*
* Test that the app doesn't run without invalid blacklist option.
* Final test ensures it does run with valid options as sanity check
*/
static int
test_invalid_b_flag(void)
{
const char *blinval[][8] = {
{prgname, mp_flag, "-n", "1", "-c", "1", "-b", "error"},
{prgname, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0"},
{prgname, mp_flag, "-n", "1", "-c", "1", "-b", "0:error:0.1"},
{prgname, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1error"},
{prgname, mp_flag, "-n", "1", "-c", "1", "-b", "error0:0:0.1"},
{prgname, mp_flag, "-n", "1", "-c", "1", "-b", "0:0:0.1.2"},
};
/* Test with valid blacklist option */
const char *blval[] = {prgname, mp_flag, "-n", "1", "-c", "1", "-b", "FF:09:0B.3"};
int i;
for (i = 0; i != sizeof (blinval) / sizeof (blinval[0]); i++) {
if (launch_proc(blinval[i]) == 0) {
printf("Error - process did run ok with invalid "
"blacklist parameter\n");
return -1;
}
}
if (launch_proc(blval) != 0) {
printf("Error - process did not run ok with valid blacklist value\n");
return -1;
}
return 0;
}
/*
* Test that the app doesn't run with invalid -r option.
*/
static int
test_invalid_r_flag(void)
{
const char *rinval[][8] = {
{prgname, mp_flag, "-n", "1", "-c", "1", "-r", "error"},
{prgname, mp_flag, "-n", "1", "-c", "1", "-r", "0"},
{prgname, mp_flag, "-n", "1", "-c", "1", "-r", "-1"},
{prgname, mp_flag, "-n", "1", "-c", "1", "-r", "17"},
};
/* Test with valid blacklist option */
const char *rval[] = {prgname, mp_flag, "-n", "1", "-c", "1", "-r", "16"};
int i;
for (i = 0; i != sizeof (rinval) / sizeof (rinval[0]); i++) {
if (launch_proc(rinval[i]) == 0) {
printf("Error - process did run ok with invalid "
"-r (rank) parameter\n");
return -1;
}
}
if (launch_proc(rval) != 0) {
printf("Error - process did not run ok with valid -r (rank) value\n");
return -1;
}
return 0;
}
/*
* Test that the app doesn't run without the coremask flag. In all cases
* should give an error and fail to run
*/
static int
test_missing_c_flag(void)
{
/* -c flag but no coremask value */
const char *argv1[] = { prgname, mp_flag, "-n", "3", "-c"};
/* No -c flag at all */
const char *argv2[] = { prgname, mp_flag, "-n", "3"};
/* bad coremask value */
const char *argv3[] = { prgname, mp_flag, "-n", "3", "-c", "error" };
/* sanity check of tests - valid coremask value */
const char *argv4[] = { prgname, mp_flag, "-n", "3", "-c", "1" };
if (launch_proc(argv1) == 0
|| launch_proc(argv2) == 0
|| launch_proc(argv3) == 0) {
printf("Error - process ran without error when missing -c flag\n");
return -1;
}
if (launch_proc(argv4) != 0) {
printf("Error - process did not run ok with valid coremask value\n");
return -1;
}
return 0;
}
/*
* Test that the app doesn't run without the -n flag. In all cases
* should give an error and fail to run.
* Since -n is not compulsory for MP, we instead use --no-huge and --no-shconf
* flags.
*/
static int
test_missing_n_flag(void)
{
/* -n flag but no value */
const char *argv1[] = { prgname, no_huge, no_shconf, "-c", "1", "-n"};
/* No -n flag at all */
const char *argv2[] = { prgname, no_huge, no_shconf, "-c", "1"};
/* bad numeric value */
const char *argv3[] = { prgname, no_huge, no_shconf, "-c", "1", "-n", "e" };
/* out-of-range value */
const char *argv4[] = { prgname, no_huge, no_shconf, "-c", "1", "-n", "9" };
/* sanity test - check with good value */
const char *argv5[] = { prgname, no_huge, no_shconf, "-c", "1", "-n", "2" };
if (launch_proc(argv1) == 0
|| launch_proc(argv2) == 0
|| launch_proc(argv3) == 0
|| launch_proc(argv4) == 0) {
printf("Error - process ran without error when missing -n flag\n");
return -1;
}
if (launch_proc(argv5) != 0) {
printf("Error - process did not run ok with valid num-channel value\n");
return -1;
}
return 0;
}
/*
* Test that the app runs with HPET, and without HPET
*/
static int
test_no_hpet_flag(void)
{
/* With --no-hpet */
const char *argv1[] = {prgname, mp_flag, no_hpet, "-c", "1", "-n", "2"};
/* Without --no-hpet */
const char *argv2[] = {prgname, mp_flag, "-c", "1", "-n", "2"};
if (launch_proc(argv1) != 0) {
printf("Error - process did not run ok with --no-hpet flag\n");
return -1;
}
if (launch_proc(argv2) != 0) {
printf("Error - process did not run ok without --no-hpet flag\n");
return -1;
}
return 0;
}
static int
test_misc_flags(void)
{
/* check that some general flags don't prevent things from working.
* All cases, apart from the first, app should run.
* No futher testing of output done.
*/
/* sanity check - failure with invalid option */
const char *argv0[] = {prgname, mp_flag, "-c", "1", "--invalid-opt"};
/* With --no-pci */
const char *argv1[] = {prgname, mp_flag, "-c", "1", "--no-pci"};
/* With -v */
const char *argv2[] = {prgname, mp_flag, "-c", "1", "-v"};
/* With -m - ignored for secondary processes */
const char *argv3[] = {prgname, mp_flag, "-c", "1", "-m", "32"};
if (launch_proc(argv0) == 0) {
printf("Error - process ran ok with invalid flag\n");
return -1;
}
if (launch_proc(argv1) != 0) {
printf("Error - process did not run ok with --no-pci flag\n");
return -1;
}
if (launch_proc(argv2) != 0) {
printf("Error - process did not run ok with -v flag\n");
return -1;
}
if (launch_proc(argv3) != 0) {
printf("Error - process did not run ok with -m flag\n");
return -1;
}
return 0;
}
int
test_eal_flags(void)
{
int ret = 0;
ret = test_missing_c_flag();
if (ret < 0) {
printf("Error in test_missing_c_flag()");
return ret;
}
ret = test_missing_n_flag();
if (ret < 0) {
printf("Error in test_missing_n_flag()");
return ret;
}
ret = test_no_hpet_flag();
if (ret < 0) {
printf("Error in test_no_hpet_flag()");
return ret;
}
ret = test_invalid_b_flag();
if (ret < 0) {
printf("Error in test_invalid_b_flag()");
return ret;
}
ret = test_invalid_r_flag();
if (ret < 0) {
printf("Error in test_invalid_r_flag()");
return ret;
}
ret = test_misc_flags();
if (ret < 0) {
printf("Error in test_misc_flags()");
return ret;
}
return ret;
}
#else
/* Baremetal version
* Multiprocess not applicable, so just return 0 always
*/
int
test_eal_flags(void)
{
printf("Multi-process not possible for baremetal, cannot test EAL flags\n");
return 0;
}
#endif

110
app/test/test_errno.c Normal file
View File

@ -0,0 +1,110 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdint.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <string.h>
#include <rte_per_lcore.h>
#include <rte_errno.h>
#include <rte_string_fns.h>
#include <cmdline_parse.h>
#include "test.h"
int
test_errno(void)
{
const char *rte_retval;
const char *libc_retval;
const char unknown_code_result[] = "Unknown error %d";
char expected_libc_retval[sizeof(unknown_code_result)+3];
/* use a small selection of standard errors for testing */
int std_errs[] = {EAGAIN, EBADF, EACCES, EINTR, EINVAL};
/* test ALL registered RTE error codes for overlap */
int rte_errs[] = {E_RTE_SECONDARY, E_RTE_NO_CONFIG, E_RTE_NO_TAILQ};
unsigned i;
rte_errno = 0;
if (rte_errno != 0)
return -1;
/* check for standard errors we return the same as libc */
for (i = 0; i < sizeof(std_errs)/sizeof(std_errs[0]); i++){
rte_retval = rte_strerror(std_errs[i]);
libc_retval = strerror(std_errs[i]);
printf("rte_strerror: '%s', strerror: '%s'\n",
rte_retval, libc_retval);
if (strcmp(rte_retval, libc_retval) != 0)
return -1;
}
/* for rte-specific errors ensure we return a different string
* and that the string for libc is for an unknown error
*/
for (i = 0; i < sizeof(rte_errs)/sizeof(rte_errs[0]); i++){
rte_retval = rte_strerror(rte_errs[i]);
libc_retval = strerror(rte_errs[i]);
printf("rte_strerror: '%s', strerror: '%s'\n",
rte_retval, libc_retval);
if (strcmp(rte_retval, libc_retval) == 0)
return -1;
/* generate appropriate error string for unknown error number
* and then check that this is what we got back. If not, we have
* a duplicate error number that conflicts with errno.h */
rte_snprintf(expected_libc_retval, sizeof(expected_libc_retval),
unknown_code_result, rte_errs[i]);
if (strcmp(expected_libc_retval, libc_retval) != 0){
printf("Error, duplicate error code %d\n", rte_errs[i]);
return -1;
}
}
/* ensure that beyond RTE_MAX_ERRNO, we always get an unknown code */
rte_retval = rte_strerror(RTE_MAX_ERRNO + 1);
libc_retval = strerror(RTE_MAX_ERRNO + 1);
rte_snprintf(expected_libc_retval, sizeof(expected_libc_retval),
unknown_code_result, RTE_MAX_ERRNO + 1);
printf("rte_strerror: '%s', strerror: '%s'\n",
rte_retval, libc_retval);
if ((strcmp(rte_retval, libc_retval) != 0) ||
(strcmp(expected_libc_retval, libc_retval) != 0)){
printf("Failed test for RTE_MAX_ERRNO + 1 value\n");
return -1;
}
return 0;
}

1785
app/test/test_hash.c Normal file

File diff suppressed because it is too large Load Diff

419
app/test/test_interrupts.c Normal file
View File

@ -0,0 +1,419 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <cmdline_parse.h>
#include <rte_common.h>
#include <rte_cycles.h>
#include <rte_interrupts.h>
#include "test.h"
#define TEST_INTERRUPT_CHECK_INTERVAL 1000 /* ms */
enum test_interrupt_handl_type {
TEST_INTERRUPT_HANDLE_INVALID,
TEST_INTERRUPT_HANDLE_VALID,
TEST_INTERRUPT_HANDLE_CASE1,
TEST_INTERRUPT_HANDLE_MAX
};
static volatile int flag;
static struct rte_intr_handle intr_handles[TEST_INTERRUPT_HANDLE_MAX];
#ifdef RTE_EXEC_ENV_LINUXAPP
union intr_pipefds{
struct {
int pipefd[2];
};
struct {
int readfd;
int writefd;
};
};
static union intr_pipefds pfds;
static inline int
test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle)
{
if (!intr_handle || intr_handle->fd < 0)
return -1;
return 0;
}
static int
test_interrupt_init(void)
{
if (pipe(pfds.pipefd) < 0)
return -1;
intr_handles[TEST_INTERRUPT_HANDLE_INVALID].fd = -1;
intr_handles[TEST_INTERRUPT_HANDLE_INVALID].type = RTE_INTR_HANDLE_UNKNOWN;
intr_handles[TEST_INTERRUPT_HANDLE_VALID].fd = pfds.readfd;
intr_handles[TEST_INTERRUPT_HANDLE_VALID].type = RTE_INTR_HANDLE_UNKNOWN;
intr_handles[TEST_INTERRUPT_HANDLE_CASE1].fd = pfds.readfd;
intr_handles[TEST_INTERRUPT_HANDLE_CASE1].type = RTE_INTR_HANDLE_ALARM;
return 0;
}
static int
test_interrupt_deinit(void)
{
close(pfds.pipefd[0]);
close(pfds.pipefd[1]);
return 0;
}
static int
test_interrupt_trigger_interrupt(void)
{
if (write(pfds.writefd, "1", 1) < 0)
return -1;
return 0;
}
static int
test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l,
struct rte_intr_handle *intr_handle_r)
{
if (!intr_handle_l || !intr_handle_r)
return -1;
if (intr_handle_l->fd != intr_handle_r->fd ||
intr_handle_l->type != intr_handle_r->type)
return -1;
return 0;
}
#else
/* to be implemented for baremetal later */
static inline int
test_interrupt_handle_sanity_check(struct rte_intr_handle *intr_handle)
{
RTE_SET_USED(intr_handle);
return 0;
}
static int
test_interrupt_init(void)
{
return 0;
}
static int
test_interrupt_deinit(void)
{
return 0;
}
static int
test_interrupt_trigger_interrupt(void)
{
return 0;
}
static int
test_interrupt_handle_compare(struct rte_intr_handle *intr_handle_l,
struct rte_intr_handle *intr_handle_r)
{
(void)intr_handle_l;
(void)intr_handle_r;
return 0;
}
#endif /* RTE_EXEC_ENV_LINUXAPP */
static void
test_interrupt_callback(struct rte_intr_handle *intr_handle, void *arg)
{
if (test_interrupt_handle_sanity_check(intr_handle) < 0) {
printf("null or invalid intr_handle for %s\n", __FUNCTION__);
return;
}
if (rte_intr_callback_unregister(intr_handle,
test_interrupt_callback, arg) <= 0) {
printf("fail to unregister callback\n");
return;
}
if (test_interrupt_handle_compare(intr_handle,
&(intr_handles[TEST_INTERRUPT_HANDLE_VALID])) == 0) {
flag = 1;
}
}
static void
test_interrupt_callback_1(struct rte_intr_handle *intr_handle, void *arg)
{
if (test_interrupt_handle_sanity_check(intr_handle) < 0) {
printf("null or invalid intr_handle for %s\n", __FUNCTION__);
return;
}
if (rte_intr_callback_unregister(intr_handle,
test_interrupt_callback_1, arg) <= 0) {
printf("fail to unregister callback\n");
return;
}
}
static int
test_interrupt_enable(void)
{
struct rte_intr_handle test_intr_handle;
/* check with null intr_handle */
if (rte_intr_enable(NULL) == 0) {
printf("unexpectedly enable null intr_handle successfully\n");
return -1;
}
/* check with invalid intr_handle */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
if (rte_intr_enable(&test_intr_handle) == 0) {
printf("unexpectedly enable invalid intr_handle "
"successfully\n");
return -1;
}
/* check with valid intr_handle */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
if (rte_intr_enable(&test_intr_handle) == 0) {
printf("unexpectedly enable a specific intr_handle "
"successfully\n");
return -1;
}
/* check with specific valid intr_handle */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
if (rte_intr_enable(&test_intr_handle) == 0) {
printf("unexpectedly enable a specific intr_handle "
"successfully\n");
return -1;
}
return 0;
}
static int
test_interrupt_disable(void)
{
struct rte_intr_handle test_intr_handle;
/* check with null intr_handle */
if (rte_intr_disable(NULL) == 0) {
printf("unexpectedly disable null intr_handle "
"successfully\n");
return -1;
}
/* check with invalid intr_handle */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
if (rte_intr_disable(&test_intr_handle) == 0) {
printf("unexpectedly disable invalid intr_handle "
"successfully\n");
return -1;
}
/* check with valid intr_handle */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
if (rte_intr_disable(&test_intr_handle) == 0) {
printf("unexpectedly disable a specific intr_handle "
"successfully\n");
return -1;
}
/* check with specific valid intr_handle */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_CASE1];
if (rte_intr_disable(&test_intr_handle) == 0) {
printf("unexpectedly disable a specific intr_handle "
"successfully\n");
return -1;
}
return 0;
}
int
test_interrupt(void)
{
int count = 0, ret = -1;
struct rte_intr_handle test_intr_handle;
if (test_interrupt_init() < 0) {
printf("fail to do test init\n");
return -1;
}
printf("check if callback registered can be called\n");
/* check if callback registered can be called */
flag = 0;
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
if (rte_intr_callback_register(&test_intr_handle,
test_interrupt_callback, NULL) < 0) {
printf("fail to register callback\n");
goto out;
}
/* trigger an interrupt and then check if the callback can be called */
if (test_interrupt_trigger_interrupt() < 0) {
printf("fail to trigger an interrupt\n");
goto out;
}
/* check flag in 3 seconds */
while (flag == 0 && count++ < 3)
rte_delay_ms(TEST_INTERRUPT_CHECK_INTERVAL);
if (flag == 0) {
printf("registered callback has not been called\n");
goto out;
}
rte_delay_ms(1000);
printf("start register/unregister test\n");
/* check if it will fail to register cb with intr_handle = NULL */
if (rte_intr_callback_register(NULL, test_interrupt_callback,
NULL) == 0) {
printf("unexpectedly register successfully with null "
"intr_handle\n");
goto out;
}
/* check if it will fail to register cb with invalid intr_handle */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
if (rte_intr_callback_register(&test_intr_handle,
test_interrupt_callback, NULL) == 0) {
printf("unexpectedly register successfully with invalid "
"intr_handle\n");
goto out;
}
/* check if it will fail to register without callback */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
if (rte_intr_callback_register(&test_intr_handle, NULL, NULL) == 0) {
printf("unexpectedly register successfully with "
"null callback\n");
goto out;
}
/* check if it will fail to unregister cb with intr_handle = NULL */
if (rte_intr_callback_unregister(NULL,
test_interrupt_callback, NULL) > 0) {
printf("unexpectedly unregister successfully with "
"null intr_handle\n");
goto out;
}
/* check if it will fail to unregister cb with invalid intr_handle */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_INVALID];
if (rte_intr_callback_unregister(&test_intr_handle,
test_interrupt_callback, NULL) > 0) {
printf("unexpectedly unregister successfully with "
"invalid intr_handle\n");
goto out;
}
/* check if it is ok to register the same intr_handle twice */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
if (rte_intr_callback_register(&test_intr_handle,
test_interrupt_callback, NULL) < 0) {
printf("it fails to register test_interrupt_callback\n");
goto out;
}
if (rte_intr_callback_register(&test_intr_handle,
test_interrupt_callback_1, NULL) < 0) {
printf("it fails to register test_interrupt_callback_1\n");
goto out;
}
/* check if it will fail to unregister with invalid parameter */
if (rte_intr_callback_unregister(&test_intr_handle,
test_interrupt_callback, (void *)0xff) != 0) {
printf("unexpectedly unregisters successfully with invalid arg\n");
goto out;
}
if (rte_intr_callback_unregister(&test_intr_handle,
test_interrupt_callback, NULL) <= 0) {
printf("it fails to unregister test_interrupt_callback\n");
goto out;
}
if (rte_intr_callback_unregister(&test_intr_handle,
test_interrupt_callback_1, (void *)-1) <= 0) {
printf("it fails to unregister test_interrupt_callback_1 "
"for all\n");
goto out;
}
rte_delay_ms(1000);
printf("start interrupt enable/disable test\n");
/* check interrupt enable/disable functions */
if (test_interrupt_enable() < 0)
goto out;
rte_delay_ms(1000);
if (test_interrupt_disable() < 0)
goto out;
rte_delay_ms(1000);
ret = 0;
out:
/* clear registered callbacks */
test_intr_handle = intr_handles[TEST_INTERRUPT_HANDLE_VALID];
rte_intr_callback_unregister(&test_intr_handle,
test_interrupt_callback, (void *)-1);
rte_intr_callback_unregister(&test_intr_handle,
test_interrupt_callback_1, (void *)-1);
rte_delay_ms(2000);
/* deinit */
test_interrupt_deinit();
return ret;
}

96
app/test/test_logs.c Normal file
View File

@ -0,0 +1,96 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_log.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include "test.h"
#define RTE_LOGTYPE_TESTAPP1 RTE_LOGTYPE_USER1
#define RTE_LOGTYPE_TESTAPP2 RTE_LOGTYPE_USER2
/*
* Logs
* ====
*
* - Enable log types.
* - Set log level.
* - Send logs with different types and levels, some should not be displayed.
*/
int
test_logs(void)
{
/* enable these logs type */
rte_set_log_type(RTE_LOGTYPE_TESTAPP1, 1);
rte_set_log_type(RTE_LOGTYPE_TESTAPP2, 1);
/* log in debug level */
rte_set_log_level(RTE_LOG_DEBUG);
RTE_LOG(DEBUG, TESTAPP1, "this is a debug level message\n");
RTE_LOG(INFO, TESTAPP1, "this is a info level message\n");
RTE_LOG(WARNING, TESTAPP1, "this is a warning level message\n");
/* log in info level */
rte_set_log_level(RTE_LOG_INFO);
RTE_LOG(DEBUG, TESTAPP2, "debug level message (not displayed)\n");
RTE_LOG(INFO, TESTAPP2, "this is a info level message\n");
RTE_LOG(WARNING, TESTAPP2, "this is a warning level message\n");
/* disable one log type */
rte_set_log_type(RTE_LOGTYPE_TESTAPP2, 0);
/* log in debug level */
rte_set_log_level(RTE_LOG_DEBUG);
RTE_LOG(DEBUG, TESTAPP1, "this is a debug level message\n");
RTE_LOG(DEBUG, TESTAPP2, "debug level message (not displayed)\n");
rte_log_dump_history();
return 0;
}

1365
app/test/test_lpm.c Normal file

File diff suppressed because it is too large Load Diff

28947
app/test/test_lpm_routes.h Normal file

File diff suppressed because it is too large Load Diff

776
app/test/test_malloc.c Normal file
View File

@ -0,0 +1,776 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_common.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_per_lcore.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_malloc.h>
#include <rte_cycles.h>
#include <rte_random.h>
#include <rte_string_fns.h>
#include "test.h"
#define N 10000
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
#define MALLOC_MEMZONE_SIZE QUOTE(RTE_MALLOC_MEMZONE_SIZE)
/*
* Malloc
* ======
*
* Allocate some dynamic memory from heap (3 areas). Check that areas
* don't overlap an that alignment constraints match. This test is
* done many times on different lcores simultaneously.
*/
/* Test if memory overlaps: return 1 if true, or 0 if false. */
static int
is_memory_overlap(void *p1, size_t len1, void *p2, size_t len2)
{
unsigned long ptr1 = (unsigned long)p1;
unsigned long ptr2 = (unsigned long)p2;
if (ptr2 >= ptr1 && (ptr2 - ptr1) < len1)
return 1;
else if (ptr2 < ptr1 && (ptr1 - ptr2) < len2)
return 1;
return 0;
}
static int
is_aligned(void *p, int align)
{
unsigned long addr = (unsigned long)p;
unsigned mask = align - 1;
if (addr & mask)
return 0;
return 1;
}
static int
test_align_overlap_per_lcore(__attribute__((unused)) void *arg)
{
const unsigned align1 = 8,
align2 = 64,
align3 = 2048;
unsigned i,j;
void *p1 = NULL, *p2 = NULL, *p3 = NULL;
int ret = 0;
for (i = 0; i < N; i++) {
p1 = rte_zmalloc("dummy", 1000, align1);
if (!p1){
printf("rte_zmalloc returned NULL (i=%u)\n", i);
ret = -1;
break;
}
for(j = 0; j < 1000 ; j++) {
if( *(char *)p1 != 0) {
printf("rte_zmalloc didn't zeroed"
"the allocated memory\n");
ret = -1;
}
}
p2 = rte_malloc("dummy", 1000, align2);
if (!p2){
printf("rte_malloc returned NULL (i=%u)\n", i);
ret = -1;
rte_free(p1);
break;
}
p3 = rte_malloc("dummy", 1000, align3);
if (!p3){
printf("rte_malloc returned NULL (i=%u)\n", i);
ret = -1;
rte_free(p1);
rte_free(p2);
break;
}
if (is_memory_overlap(p1, 1000, p2, 1000)) {
printf("p1 and p2 overlaps\n");
ret = -1;
}
if (is_memory_overlap(p2, 1000, p3, 1000)) {
printf("p2 and p3 overlaps\n");
ret = -1;
}
if (is_memory_overlap(p1, 1000, p3, 1000)) {
printf("p1 and p3 overlaps\n");
ret = -1;
}
if (!is_aligned(p1, align1)) {
printf("p1 is not aligned\n");
ret = -1;
}
if (!is_aligned(p2, align2)) {
printf("p2 is not aligned\n");
ret = -1;
}
if (!is_aligned(p3, align3)) {
printf("p3 is not aligned\n");
ret = -1;
}
rte_free(p1);
rte_free(p2);
rte_free(p3);
}
rte_malloc_dump_stats("dummy");
return ret;
}
static int
test_reordered_free_per_lcore(__attribute__((unused)) void *arg)
{
const unsigned align1 = 8,
align2 = 64,
align3 = 2048;
unsigned i,j;
void *p1, *p2, *p3;
int ret = 0;
for (i = 0; i < 30; i++) {
p1 = rte_zmalloc("dummy", 1000, align1);
if (!p1){
printf("rte_zmalloc returned NULL (i=%u)\n", i);
ret = -1;
break;
}
for(j = 0; j < 1000 ; j++) {
if( *(char *)p1 != 0) {
printf("rte_zmalloc didn't zeroed"
"the allocated memory\n");
ret = -1;
}
}
/* use calloc to allocate 1000 16-byte items this time */
p2 = rte_calloc("dummy", 1000, 16, align2);
/* for third request use regular malloc again */
p3 = rte_malloc("dummy", 1000, align3);
if (!p2 || !p3){
printf("rte_malloc returned NULL (i=%u)\n", i);
ret = -1;
break;
}
if (is_memory_overlap(p1, 1000, p2, 1000)) {
printf("p1 and p2 overlaps\n");
ret = -1;
}
if (is_memory_overlap(p2, 1000, p3, 1000)) {
printf("p2 and p3 overlaps\n");
ret = -1;
}
if (is_memory_overlap(p1, 1000, p3, 1000)) {
printf("p1 and p3 overlaps\n");
ret = -1;
}
if (!is_aligned(p1, align1)) {
printf("p1 is not aligned\n");
ret = -1;
}
if (!is_aligned(p2, align2)) {
printf("p2 is not aligned\n");
ret = -1;
}
if (!is_aligned(p3, align3)) {
printf("p3 is not aligned\n");
ret = -1;
}
/* try freeing in every possible order */
switch (i%6){
case 0:
rte_free(p1);
rte_free(p2);
rte_free(p3);
break;
case 1:
rte_free(p1);
rte_free(p3);
rte_free(p2);
break;
case 2:
rte_free(p2);
rte_free(p1);
rte_free(p3);
break;
case 3:
rte_free(p2);
rte_free(p3);
rte_free(p1);
break;
case 4:
rte_free(p3);
rte_free(p1);
rte_free(p2);
break;
case 5:
rte_free(p3);
rte_free(p2);
rte_free(p1);
break;
}
}
rte_malloc_dump_stats("dummy");
return ret;
}
/* test function inside the malloc lib*/
static int
test_str_to_size(void)
{
struct {
const char *str;
uint64_t value;
} test_values[] =
{{ "5G", (uint64_t)5 * 1024 * 1024 *1024 },
{"0x20g", (uint64_t)0x20 * 1024 * 1024 *1024},
{"10M", 10 * 1024 * 1024},
{"050m", 050 * 1024 * 1024},
{"8K", 8 * 1024},
{"15k", 15 * 1024},
{"0200", 0200},
{"0x103", 0x103},
{"432", 432},
{"-1", 0}, /* negative values return 0 */
{" -2", 0},
{" -3MB", 0},
{"18446744073709551616", 0} /* ULLONG_MAX + 1 == out of range*/
};
unsigned i;
for (i = 0; i < sizeof(test_values)/sizeof(test_values[0]); i++)
if (rte_str_to_size(test_values[i].str) != test_values[i].value)
return -1;
return 0;
}
static int
test_big_alloc(void)
{
void *p1 = rte_malloc("BIG", rte_str_to_size(MALLOC_MEMZONE_SIZE) * 2, 1024);
if (!p1)
return -1;
rte_free(p1);
return 0;
}
static int
test_memzone_size_alloc(void)
{
void *p1 = rte_malloc("BIG", rte_str_to_size(MALLOC_MEMZONE_SIZE) - 128, 64);
if (!p1)
return -1;
rte_free(p1);
/* one extra check - check no crashes if free(NULL) */
rte_free(NULL);
return 0;
}
static int
test_rte_malloc_type_limits(void)
{
/* The type-limits functionality is not yet implemented,
* so always return 0 no matter what the retval.
*/
const char *typename = "limit_test";
rte_malloc_set_limit(typename, 64 * 1024);
rte_malloc_dump_stats(typename);
return 0;
}
static int
test_realloc(void)
{
const char hello_str[] = "Hello, world!";
const unsigned size1 = 1024;
const unsigned size2 = size1 + 1024;
const unsigned size3 = size2;
const unsigned size4 = size3 + 1024;
/* test data is the same even if element is moved*/
char *ptr1 = rte_zmalloc(NULL, size1, CACHE_LINE_SIZE);
if (!ptr1){
printf("NULL pointer returned from rte_zmalloc\n");
return -1;
}
rte_snprintf(ptr1, size1, "%s" ,hello_str);
char *ptr2 = rte_realloc(ptr1, size2, CACHE_LINE_SIZE);
if (!ptr2){
rte_free(ptr1);
printf("NULL pointer returned from rte_realloc\n");
return -1;
}
if (ptr1 == ptr2){
printf("unexpected - ptr1 == ptr2\n");
}
if (strcmp(ptr2, hello_str) != 0){
printf("Error - lost data from pointed area\n");
rte_free(ptr2);
return -1;
}
unsigned i;
for (i = strnlen(hello_str, sizeof(hello_str)); i < size1; i++)
if (ptr2[i] != 0){
printf("Bad data in realloc\n");
rte_free(ptr2);
return -1;
}
/* now allocate third element, free the second
* and resize third. It should not move. (ptr1 is now invalid)
*/
char *ptr3 = rte_zmalloc(NULL, size3, CACHE_LINE_SIZE);
if (!ptr3){
printf("NULL pointer returned from rte_zmalloc\n");
rte_free(ptr2);
return -1;
}
for (i = 0; i < size3; i++)
if (ptr3[i] != 0){
printf("Bad data in zmalloc\n");
rte_free(ptr3);
rte_free(ptr2);
return -1;
}
rte_free(ptr2);
/* first resize to half the size of the freed block */
char *ptr4 = rte_realloc(ptr3, size4, CACHE_LINE_SIZE);
if (!ptr4){
printf("NULL pointer returned from rte_realloc\n");
rte_free(ptr3);
return -1;
}
if (ptr3 != ptr4){
printf("Unexpected - ptr4 != ptr3\n");
rte_free(ptr4);
return -1;
}
/* now resize again to the full size of the freed block */
ptr4 = rte_realloc(ptr3, size3 + size2 + size1, CACHE_LINE_SIZE);
if (ptr3 != ptr4){
printf("Unexpected - ptr4 != ptr3 on second resize\n");
rte_free(ptr4);
return -1;
}
rte_free(ptr4);
/* now try a resize to a smaller size, see if it works */
const unsigned size5 = 1024;
const unsigned size6 = size5 / 2;
char *ptr5 = rte_malloc(NULL, size5, CACHE_LINE_SIZE);
if (!ptr5){
printf("NULL pointer returned from rte_malloc\n");
return -1;
}
char *ptr6 = rte_realloc(ptr5, size6, CACHE_LINE_SIZE);
if (!ptr6){
printf("NULL pointer returned from rte_realloc\n");
rte_free(ptr5);
return -1;
}
if (ptr5 != ptr6){
printf("Error, resizing to a smaller size moved data\n");
rte_free(ptr6);
return -1;
}
rte_free(ptr6);
/* check for behaviour changing alignment */
const unsigned size7 = 1024;
const unsigned orig_align = CACHE_LINE_SIZE;
unsigned new_align = CACHE_LINE_SIZE * 2;
char *ptr7 = rte_malloc(NULL, size7, orig_align);
if (!ptr7){
printf("NULL pointer returned from rte_malloc\n");
return -1;
}
/* calc an alignment we don't already have */
while(RTE_ALIGN(ptr7, new_align) == ptr7)
new_align *= 2;
char *ptr8 = rte_realloc(ptr7, size7, new_align);
if (!ptr8){
printf("NULL pointer returned from rte_realloc\n");
rte_free(ptr7);
return -1;
}
if (RTE_ALIGN(ptr8, new_align) != ptr8){
printf("Failure to re-align data\n");
rte_free(ptr8);
return -1;
}
rte_free(ptr8);
/* test behaviour when there is a free block after current one,
* but its not big enough
*/
unsigned size9 = 1024, size10 = 1024;
unsigned size11 = size9 + size10 + 256;
char *ptr9 = rte_malloc(NULL, size9, CACHE_LINE_SIZE);
if (!ptr9){
printf("NULL pointer returned from rte_malloc\n");
return -1;
}
char *ptr10 = rte_malloc(NULL, size10, CACHE_LINE_SIZE);
if (!ptr10){
printf("NULL pointer returned from rte_malloc\n");
return -1;
}
rte_free(ptr9);
char *ptr11 = rte_realloc(ptr10, size11, CACHE_LINE_SIZE);
if (!ptr11){
printf("NULL pointer returned from rte_realloc\n");
rte_free(ptr10);
return -1;
}
if (ptr11 == ptr10){
printf("Error, unexpected that realloc has not created new buffer\n");
rte_free(ptr11);
return -1;
}
rte_free(ptr11);
/* check we don't crash if we pass null to realloc
* We should get a malloc of the size requested*/
const size_t size12 = 1024;
size_t size12_check;
char *ptr12 = rte_realloc(NULL, size12, CACHE_LINE_SIZE);
if (!ptr12){
printf("NULL pointer returned from rte_realloc\n");
return -1;
}
if (rte_malloc_validate(ptr12, &size12_check) < 0 ||
size12_check != size12){
rte_free(ptr12);
return -1;
}
rte_free(ptr12);
return 0;
}
static int
test_random_alloc_free(void *_ __attribute__((unused)))
{
struct mem_list {
struct mem_list *next;
char data[0];
} *list_head = NULL;
unsigned i;
unsigned count = 0;
rte_srand((unsigned)rte_rdtsc());
for (i = 0; i < N; i++){
unsigned free_mem = 0;
size_t allocated_size;
while (!free_mem){
const unsigned mem_size = sizeof(struct mem_list) + \
rte_rand() % (64 * 1024);
const unsigned align = 1 << (rte_rand() % 12); /* up to 4k alignment */
struct mem_list *entry = rte_malloc(NULL,
mem_size, align);
if (entry == NULL)
return -1;
if (RTE_ALIGN(entry, align)!= entry)
return -1;
if (rte_malloc_validate(entry, &allocated_size) == -1
|| allocated_size < mem_size)
return -1;
memset(entry->data, rte_lcore_id(),
mem_size - sizeof(*entry));
entry->next = list_head;
if (rte_malloc_validate(entry, NULL) == -1)
return -1;
list_head = entry;
count++;
/* switch to freeing the memory with a 20% probability */
free_mem = ((rte_rand() % 10) >= 8);
}
while (list_head){
struct mem_list *entry = list_head;
list_head = list_head->next;
rte_free(entry);
}
}
printf("Lcore %u allocated/freed %u blocks\n", rte_lcore_id(), count);
return 0;
}
#define err_return() do { \
printf("%s: %d - Error\n", __func__, __LINE__); \
goto err_return; \
} while (0)
static int
test_rte_malloc_validate(void)
{
const size_t request_size = 1024;
size_t allocated_size;
char *data_ptr = rte_malloc(NULL, request_size, CACHE_LINE_SIZE);
if (data_ptr == NULL) {
printf("%s: %d - Allocation error\n", __func__, __LINE__);
return -1;
}
/* check that a null input returns -1 */
if (rte_malloc_validate(NULL, NULL) != -1)
err_return();
/* check that we get ok on a valid pointer */
if (rte_malloc_validate(data_ptr, &allocated_size) < 0)
err_return();
/* check that the returned size is ok */
if (allocated_size < request_size)
err_return();
#ifdef RTE_LIBRTE_MALLOC_DEBUG
int retval;
char *over_write_vals = NULL;
/****** change the header to be bad */
char save_buf[64];
over_write_vals = (char *)((uintptr_t)data_ptr - sizeof(save_buf));
/* first save the data as a backup before overwriting it */
memcpy(save_buf, over_write_vals, sizeof(save_buf));
memset(over_write_vals, 1, sizeof(save_buf));
/* then run validate */
retval = rte_malloc_validate(data_ptr, NULL);
/* finally restore the data again */
memcpy(over_write_vals, save_buf, sizeof(save_buf));
/* check we previously had an error */
if (retval != -1)
err_return();
/* check all ok again */
if (rte_malloc_validate(data_ptr, &allocated_size) < 0)
err_return();
/**** change the trailer to be bad */
over_write_vals = (char *)((uintptr_t)data_ptr + allocated_size);
/* first save the data as a backup before overwriting it */
memcpy(save_buf, over_write_vals, sizeof(save_buf));
memset(over_write_vals, 1, sizeof(save_buf));
/* then run validate */
retval = rte_malloc_validate(data_ptr, NULL);
/* finally restore the data again */
memcpy(over_write_vals, save_buf, sizeof(save_buf));
if (retval != -1)
err_return();
/* check all ok again */
if (rte_malloc_validate(data_ptr, &allocated_size) < 0)
err_return();
#endif
rte_free(data_ptr);
return 0;
err_return:
/*clean up */
rte_free(data_ptr);
return -1;
}
static int
test_zero_aligned_alloc(void)
{
char *p1 = rte_malloc(NULL,1024, 0);
if (!p1)
goto err_return;
if (!rte_is_aligned(p1, CACHE_LINE_SIZE))
goto err_return;
rte_free(p1);
return 0;
err_return:
/*clean up */
if (p1) rte_free(p1);
return -1;
}
static int
test_malloc_bad_params(void)
{
const char *type = NULL;
size_t size = 0;
unsigned align = CACHE_LINE_SIZE;
/* rte_malloc expected to return null with inappropriate size */
char *bad_ptr = rte_malloc(type, size, align);
if (bad_ptr != NULL)
goto err_return;
/* rte_malloc expected to return null with inappropriate alignment */
align = 17;
size = 1024;
bad_ptr = rte_malloc(type, size, align);
if (bad_ptr != NULL)
goto err_return;
return 0;
err_return:
/* clean up pointer */
if (bad_ptr)
rte_free(bad_ptr);
return -1;
}
int
test_malloc(void)
{
unsigned lcore_id;
int ret = 0;
if (test_str_to_size() < 0){
printf("test_str_to_size() failed\n");
return -1;
}
else printf("test_str_to_size() passed\n");
if (test_memzone_size_alloc() < 0){
printf("test_memzone_size_alloc() failed\n");
return -1;
}
else printf("test_memzone_size_alloc() passed\n");
if (test_big_alloc() < 0){
printf("test_big_alloc() failed\n");
return -1;
}
else printf("test_big_alloc() passed\n");
if (test_zero_aligned_alloc() < 0){
printf("test_zero_aligned_alloc() failed\n");
return -1;
}
else printf("test_zero_aligned_alloc() passed\n");
if (test_malloc_bad_params() < 0){
printf("test_malloc_bad_params() failed\n");
return -1;
}
else printf("test_malloc_bad_params() passed\n");
if (test_realloc() < 0){
printf("test_realloc() failed\n");
return -1;
}
else printf("test_realloc() passed\n");
/*----------------------------*/
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
rte_eal_remote_launch(test_align_overlap_per_lcore, NULL, lcore_id);
}
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0)
ret = -1;
}
if (ret < 0){
printf("test_align_overlap_per_lcore() failed\n");
return ret;
}
else printf("test_align_overlap_per_lcore() passed\n");
/*----------------------------*/
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
rte_eal_remote_launch(test_reordered_free_per_lcore, NULL, lcore_id);
}
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0)
ret = -1;
}
if (ret < 0){
printf("test_reordered_free_per_lcore() failed\n");
return ret;
}
else printf("test_reordered_free_per_lcore() passed\n");
/*----------------------------*/
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
rte_eal_remote_launch(test_random_alloc_free, NULL, lcore_id);
}
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0)
ret = -1;
}
if (ret < 0){
printf("test_random_alloc_free() failed\n");
return ret;
}
else printf("test_random_alloc_free() passed\n");
/*----------------------------*/
ret = test_rte_malloc_type_limits();
if (ret < 0){
printf("test_rte_malloc_type_limits() failed\n");
return ret;
}
/* TODO: uncomment following line once type limits are valid */
/*else printf("test_rte_malloc_type_limits() passed\n");*/
/*----------------------------*/
ret = test_rte_malloc_validate();
if (ret < 0){
printf("test_rte_malloc_validate() failed\n");
return ret;
}
else printf("test_rte_malloc_validate() passed\n");
return 0;
}

875
app/test/test_mbuf.c Normal file
View File

@ -0,0 +1,875 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/queue.h>
#include <rte_common.h>
#include <rte_debug.h>
#include <rte_log.h>
#include <rte_common.h>
#include <rte_memory.h>
#include <rte_memcpy.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_mempool.h>
#include <rte_mbuf.h>
#include <rte_random.h>
#include <rte_cycles.h>
#include <cmdline_parse.h>
#include "test.h"
#define MBUF_SIZE 2048
#define NB_MBUF 128
#define MBUF_TEST_DATA_LEN 1464
#define MBUF_TEST_DATA_LEN2 50
#define MBUF_TEST_HDR1_LEN 20
#define MBUF_TEST_HDR2_LEN 30
#define MBUF_TEST_ALL_HDRS_LEN (MBUF_TEST_HDR1_LEN+MBUF_TEST_HDR2_LEN)
#define REFCNT_MAX_ITER 64
#define REFCNT_MAX_TIMEOUT 10
#define REFCNT_MAX_REF (RTE_MAX_LCORE)
#define REFCNT_MBUF_NUM 64
#define REFCNT_MBUF_SIZE (sizeof (struct rte_mbuf) + RTE_PKTMBUF_HEADROOM)
#define REFCNT_RING_SIZE (REFCNT_MBUF_NUM * REFCNT_MAX_REF)
#define MAKE_STRING(x) # x
static struct rte_mempool *pktmbuf_pool = NULL;
static struct rte_mempool *ctrlmbuf_pool = NULL;
#if defined RTE_MBUF_SCATTER_GATHER && defined RTE_MBUF_REFCNT_ATOMIC
static struct rte_mempool *refcnt_pool = NULL;
static struct rte_ring *refcnt_mbuf_ring = NULL;
static volatile uint32_t refcnt_stop_slaves;
static uint32_t refcnt_lcore[RTE_MAX_LCORE];
#endif
/*
* MBUF
* ====
*
* #. Allocate a mbuf pool.
*
* - The pool contains NB_MBUF elements, where each mbuf is MBUF_SIZE
* bytes long.
*
* #. Test multiple allocations of mbufs from this pool.
*
* - Allocate NB_MBUF and store pointers in a table.
* - If an allocation fails, return an error.
* - Free all these mbufs.
* - Repeat the same test to check that mbufs were freed correctly.
*
* #. Test data manipulation in pktmbuf.
*
* - Alloc an mbuf.
* - Append data using rte_pktmbuf_append().
* - Test for error in rte_pktmbuf_append() when len is too large.
* - Trim data at the end of mbuf using rte_pktmbuf_trim().
* - Test for error in rte_pktmbuf_trim() when len is too large.
* - Prepend a header using rte_pktmbuf_prepend().
* - Test for error in rte_pktmbuf_prepend() when len is too large.
* - Remove data at the beginning of mbuf using rte_pktmbuf_adj().
* - Test for error in rte_pktmbuf_adj() when len is too large.
* - Check that appended data is not corrupt.
* - Free the mbuf.
* - Between all these tests, check data_len and pkt_len, and
* that the mbuf is contiguous.
* - Repeat the test to check that allocation operations
* reinitialize the mbuf correctly.
*
*/
#define GOTO_FAIL(str, ...) do { \
printf("mbuf test FAILED (l.%d): <" str ">\n", \
__LINE__, ##__VA_ARGS__); \
goto fail; \
} while(0)
/*
* test data manipulation in mbuf with non-ascii data
*/
static int
test_pktmbuf_with_non_ascii_data(void)
{
struct rte_mbuf *m = NULL;
char *data;
m = rte_pktmbuf_alloc(pktmbuf_pool);
if (m == NULL)
GOTO_FAIL("Cannot allocate mbuf");
if (rte_pktmbuf_pkt_len(m) != 0)
GOTO_FAIL("Bad length");
data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN);
if (data == NULL)
GOTO_FAIL("Cannot append data");
if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
GOTO_FAIL("Bad pkt length");
if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
GOTO_FAIL("Bad data length");
memset(data, 0xff, rte_pktmbuf_pkt_len(m));
if (!rte_pktmbuf_is_contiguous(m))
GOTO_FAIL("Buffer should be continuous");
rte_pktmbuf_dump(m, MBUF_TEST_DATA_LEN);
rte_pktmbuf_free(m);
return 0;
fail:
if(m) {
rte_pktmbuf_free(m);
}
return -1;
}
/*
* test data manipulation in mbuf
*/
static int
test_one_pktmbuf(void)
{
struct rte_mbuf *m = NULL;
char *data, *data2, *hdr;
unsigned i;
printf("Test pktmbuf API\n");
/* alloc a mbuf */
m = rte_pktmbuf_alloc(pktmbuf_pool);
if (m == NULL)
GOTO_FAIL("Cannot allocate mbuf");
if (rte_pktmbuf_pkt_len(m) != 0)
GOTO_FAIL("Bad length");
rte_pktmbuf_dump(m, 0);
/* append data */
data = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN);
if (data == NULL)
GOTO_FAIL("Cannot append data");
if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
GOTO_FAIL("Bad pkt length");
if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
GOTO_FAIL("Bad data length");
memset(data, 0x66, rte_pktmbuf_pkt_len(m));
if (!rte_pktmbuf_is_contiguous(m))
GOTO_FAIL("Buffer should be continuous");
rte_pktmbuf_dump(m, MBUF_TEST_DATA_LEN);
rte_pktmbuf_dump(m, 2*MBUF_TEST_DATA_LEN);
/* this append should fail */
data2 = rte_pktmbuf_append(m, (uint16_t)(rte_pktmbuf_tailroom(m) + 1));
if (data2 != NULL)
GOTO_FAIL("Append should not succeed");
/* append some more data */
data2 = rte_pktmbuf_append(m, MBUF_TEST_DATA_LEN2);
if (data2 == NULL)
GOTO_FAIL("Cannot append data");
if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2)
GOTO_FAIL("Bad pkt length");
if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_DATA_LEN2)
GOTO_FAIL("Bad data length");
if (!rte_pktmbuf_is_contiguous(m))
GOTO_FAIL("Buffer should be continuous");
/* trim data at the end of mbuf */
if (rte_pktmbuf_trim(m, MBUF_TEST_DATA_LEN2) < 0)
GOTO_FAIL("Cannot trim data");
if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
GOTO_FAIL("Bad pkt length");
if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
GOTO_FAIL("Bad data length");
if (!rte_pktmbuf_is_contiguous(m))
GOTO_FAIL("Buffer should be continuous");
/* this trim should fail */
if (rte_pktmbuf_trim(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) == 0)
GOTO_FAIL("trim should not succeed");
/* prepend one header */
hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR1_LEN);
if (hdr == NULL)
GOTO_FAIL("Cannot prepend");
if (data - hdr != MBUF_TEST_HDR1_LEN)
GOTO_FAIL("Prepend failed");
if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN)
GOTO_FAIL("Bad pkt length");
if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_HDR1_LEN)
GOTO_FAIL("Bad data length");
if (!rte_pktmbuf_is_contiguous(m))
GOTO_FAIL("Buffer should be continuous");
memset(hdr, 0x55, MBUF_TEST_HDR1_LEN);
/* prepend another header */
hdr = rte_pktmbuf_prepend(m, MBUF_TEST_HDR2_LEN);
if (hdr == NULL)
GOTO_FAIL("Cannot prepend");
if (data - hdr != MBUF_TEST_ALL_HDRS_LEN)
GOTO_FAIL("Prepend failed");
if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN)
GOTO_FAIL("Bad pkt length");
if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN + MBUF_TEST_ALL_HDRS_LEN)
GOTO_FAIL("Bad data length");
if (!rte_pktmbuf_is_contiguous(m))
GOTO_FAIL("Buffer should be continuous");
memset(hdr, 0x55, MBUF_TEST_HDR2_LEN);
rte_mbuf_sanity_check(m, RTE_MBUF_PKT, 1);
rte_mbuf_sanity_check(m, RTE_MBUF_PKT, 0);
rte_pktmbuf_dump(m, 0);
/* this prepend should fail */
hdr = rte_pktmbuf_prepend(m, (uint16_t)(rte_pktmbuf_headroom(m) + 1));
if (hdr != NULL)
GOTO_FAIL("prepend should not succeed");
/* remove data at beginning of mbuf (adj) */
if (data != rte_pktmbuf_adj(m, MBUF_TEST_ALL_HDRS_LEN))
GOTO_FAIL("rte_pktmbuf_adj failed");
if (rte_pktmbuf_pkt_len(m) != MBUF_TEST_DATA_LEN)
GOTO_FAIL("Bad pkt length");
if (rte_pktmbuf_data_len(m) != MBUF_TEST_DATA_LEN)
GOTO_FAIL("Bad data length");
if (!rte_pktmbuf_is_contiguous(m))
GOTO_FAIL("Buffer should be continuous");
/* this adj should fail */
if (rte_pktmbuf_adj(m, (uint16_t)(rte_pktmbuf_data_len(m) + 1)) != NULL)
GOTO_FAIL("rte_pktmbuf_adj should not succeed");
/* check data */
if (!rte_pktmbuf_is_contiguous(m))
GOTO_FAIL("Buffer should be continuous");
for (i=0; i<MBUF_TEST_DATA_LEN; i++) {
if (data[i] != 0x66)
GOTO_FAIL("Data corrupted at offset %u", i);
}
/* free mbuf */
rte_pktmbuf_free(m);
m = NULL;
return 0;
fail:
if (m)
rte_pktmbuf_free(m);
return -1;
}
/*
* test control mbuf
*/
static int
test_one_ctrlmbuf(void)
{
struct rte_mbuf *m = NULL;
char message[] = "This is a message carried by a ctrlmbuf";
printf("Test ctrlmbuf API\n");
/* alloc a mbuf */
m = rte_ctrlmbuf_alloc(ctrlmbuf_pool);
if (m == NULL)
GOTO_FAIL("Cannot allocate mbuf");
if (rte_ctrlmbuf_len(m) != 0)
GOTO_FAIL("Bad length");
/* set data */
rte_ctrlmbuf_data(m) = &message;
rte_ctrlmbuf_len(m) = sizeof(message);
/* read data */
if (rte_ctrlmbuf_data(m) != message)
GOTO_FAIL("Invalid data pointer");
if (rte_ctrlmbuf_len(m) != sizeof(message))
GOTO_FAIL("Invalid len");
rte_mbuf_sanity_check(m, RTE_MBUF_CTRL, 0);
/* free mbuf */
rte_ctrlmbuf_free(m);
m = NULL;
return 0;
fail:
if (m)
rte_ctrlmbuf_free(m);
return -1;
}
static int
testclone_testupdate_testdetach(void)
{
#ifndef RTE_MBUF_SCATTER_GATHER
return 0;
#else
struct rte_mbuf *mc = NULL;
struct rte_mbuf *clone = NULL;
/* alloc a mbuf */
mc = rte_pktmbuf_alloc(pktmbuf_pool);
if (mc == NULL)
GOTO_FAIL("ooops not allocating mbuf");
if (rte_pktmbuf_pkt_len(mc) != 0)
GOTO_FAIL("Bad length");
/* clone the allocated mbuf */
clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
if (clone == NULL)
GOTO_FAIL("cannot clone data\n");
rte_pktmbuf_free(clone);
mc->pkt.next = rte_pktmbuf_alloc(pktmbuf_pool);
if(mc->pkt.next == NULL)
GOTO_FAIL("Next Pkt Null\n");
clone = rte_pktmbuf_clone(mc, pktmbuf_pool);
if (clone == NULL)
GOTO_FAIL("cannot clone data\n");
/* free mbuf */
rte_pktmbuf_free(mc);
rte_pktmbuf_free(clone);
mc = NULL;
clone = NULL;
return 0;
fail:
if (mc)
rte_pktmbuf_free(mc);
return -1;
#endif /* RTE_MBUF_SCATTER_GATHER */
}
#undef GOTO_FAIL
/*
* test allocation and free of mbufs
*/
static int
test_pktmbuf_pool(void)
{
unsigned i;
struct rte_mbuf *m[NB_MBUF];
int ret = 0;
for (i=0; i<NB_MBUF; i++)
m[i] = NULL;
/* alloc NB_MBUF mbufs */
for (i=0; i<NB_MBUF; i++) {
m[i] = rte_pktmbuf_alloc(pktmbuf_pool);
if (m[i] == NULL) {
printf("rte_pktmbuf_alloc() failed (%u)\n", i);
ret = -1;
}
}
struct rte_mbuf *extra = NULL;
extra = rte_pktmbuf_alloc(pktmbuf_pool);
if(extra != NULL) {
printf("Error pool not empty");
ret = -1;
}
#ifdef RTE_MBUF_SCATTER_GATHER
extra = rte_pktmbuf_clone(m[0], pktmbuf_pool);
if(extra != NULL) {
printf("Error pool not empty");
ret = -1;
}
#endif
/* free them */
for (i=0; i<NB_MBUF; i++) {
if (m[i] != NULL)
rte_pktmbuf_free(m[i]);
}
return ret;
}
static int
test_pktmbuf_free_segment(void)
{
unsigned i;
struct rte_mbuf *m[NB_MBUF];
int ret = 0;
for (i=0; i<NB_MBUF; i++)
m[i] = NULL;
/* alloc NB_MBUF mbufs */
for (i=0; i<NB_MBUF; i++) {
m[i] = rte_pktmbuf_alloc(pktmbuf_pool);
if (m[i] == NULL) {
printf("rte_pktmbuf_alloc() failed (%u)\n", i);
ret = -1;
}
}
/* free them */
for (i=0; i<NB_MBUF; i++) {
if (m[i] != NULL) {
struct rte_mbuf *mb, *mt;
mb = m[i];
while(mb != NULL) {
mt = mb;
mb = mb->pkt.next;
rte_pktmbuf_free_seg(mt);
}
}
}
return ret;
}
/*
* Stress test for rte_mbuf atomic refcnt.
* Implies that:
* RTE_MBUF_SCATTER_GATHER and RTE_MBUF_REFCNT_ATOMIC are both defined.
* For more efficency, recomended to run with RTE_LIBRTE_MBUF_DEBUG defined.
*/
#if defined RTE_MBUF_SCATTER_GATHER && defined RTE_MBUF_REFCNT_ATOMIC
static int
test_refcnt_slave(__attribute__((unused)) void *arg)
{
uint32_t lcore, free;
void *mp;
lcore = rte_lcore_id();
printf("%s started at lcore %u\n", __func__, lcore);
free = 0;
while (refcnt_stop_slaves == 0) {
if (rte_ring_dequeue(refcnt_mbuf_ring, &mp) == 0) {
free++;
rte_pktmbuf_free((struct rte_mbuf *)mp);
}
}
refcnt_lcore[lcore] += free;
printf("%s finished at lcore %u, "
"number of freed mbufs: %u\n",
__func__, lcore, free);
return (0);
}
static void
test_refcnt_iter(uint32_t lcore, uint32_t iter)
{
uint16_t ref;
uint32_t i, n, tref, wn;
struct rte_mbuf *m;
tref = 0;
/* For each mbuf in the pool:
* - allocate mbuf,
* - increment it's reference up to N+1,
* - enqueue it N times into the ring for slave cores to free.
*/
for (i = 0, n = rte_mempool_count(refcnt_pool);
i != n && (m = rte_pktmbuf_alloc(refcnt_pool)) != NULL;
i++) {
ref = RTE_MAX(rte_rand() % REFCNT_MAX_REF, 1UL);
tref += ref;
if ((ref & 1) != 0) {
rte_pktmbuf_refcnt_update(m, ref);
while (ref-- != 0)
rte_ring_enqueue(refcnt_mbuf_ring, m);
} else {
while (ref-- != 0) {
rte_pktmbuf_refcnt_update(m, 1);
rte_ring_enqueue(refcnt_mbuf_ring, m);
}
}
rte_pktmbuf_free(m);
}
if (i != n)
rte_panic("(lcore=%u, iter=%u): was able to allocate only "
"%u from %u mbufs\n", lcore, iter, i, n);
/* wait till slave lcores will consume all mbufs */
while (!rte_ring_empty(refcnt_mbuf_ring))
;
/* check that all mbufs are back into mempool by now */
for (wn = 0; wn != REFCNT_MAX_TIMEOUT; wn++) {
if ((i = rte_mempool_count(refcnt_pool)) == n) {
refcnt_lcore[lcore] += tref;
printf("%s(lcore=%u, iter=%u) completed, "
"%u references processed\n",
__func__, lcore, iter, tref);
return;
}
rte_delay_ms(1000);
}
rte_panic("(lcore=%u, iter=%u): after %us only "
"%u of %u mbufs left free\n", lcore, iter, wn, i, n);
}
static int
test_refcnt_master(void)
{
uint32_t i, lcore;
lcore = rte_lcore_id();
printf("%s started at lcore %u\n", __func__, lcore);
for (i = 0; i != REFCNT_MAX_ITER; i++)
test_refcnt_iter(lcore, i);
refcnt_stop_slaves = 1;
rte_wmb();
printf("%s finished at lcore %u\n", __func__, lcore);
return (0);
}
#endif
static int
test_refcnt_mbuf(void)
{
#if defined RTE_MBUF_SCATTER_GATHER && defined RTE_MBUF_REFCNT_ATOMIC
uint32_t lnum, master, slave, tref;
if ((lnum = rte_lcore_count()) == 1) {
printf("skipping %s, number of lcores: %u is not enough\n",
__func__, lnum);
return (0);
}
printf("starting %s, at %u lcores\n", __func__, lnum);
/* create refcnt pool & ring if they don't exist */
if (refcnt_pool == NULL &&
(refcnt_pool = rte_mempool_create(
MAKE_STRING(refcnt_pool),
REFCNT_MBUF_NUM, REFCNT_MBUF_SIZE, 0,
sizeof(struct rte_pktmbuf_pool_private),
rte_pktmbuf_pool_init, NULL, rte_pktmbuf_init, NULL,
SOCKET_ID_ANY, 0)) == NULL) {
printf("%s: cannot allocate " MAKE_STRING(refcnt_pool) "\n",
__func__);
return (-1);
}
if (refcnt_mbuf_ring == NULL &&
(refcnt_mbuf_ring = rte_ring_create("refcnt_mbuf_ring",
REFCNT_RING_SIZE, SOCKET_ID_ANY,
RING_F_SP_ENQ)) == NULL) {
printf("%s: cannot allocate " MAKE_STRING(refcnt_mbuf_ring)
"\n", __func__);
return (-1);
}
refcnt_stop_slaves = 0;
memset(refcnt_lcore, 0, sizeof (refcnt_lcore));
rte_eal_mp_remote_launch(test_refcnt_slave, NULL, SKIP_MASTER);
test_refcnt_master();
rte_eal_mp_wait_lcore();
/* check that we porcessed all references */
tref = 0;
master = rte_get_master_lcore();
RTE_LCORE_FOREACH_SLAVE(slave)
tref += refcnt_lcore[slave];
if (tref != refcnt_lcore[master])
rte_panic("refernced mbufs: %u, freed mbufs: %u\n",
tref, refcnt_lcore[master]);
rte_mempool_dump(refcnt_pool);
rte_ring_dump(refcnt_mbuf_ring);
#endif
return (0);
}
#ifdef RTE_EXEC_ENV_BAREMETAL
/* baremetal - don't test failing sanity checks */
static int
test_failing_mbuf_sanity_check(void)
{
return 0;
}
#else
#include <unistd.h>
#include <sys/wait.h>
/* linuxapp - use fork() to test mbuf errors panic */
static int
verify_mbuf_check_panics(struct rte_mbuf *buf)
{
int pid;
int status;
pid = fork();
if (pid == 0) {
rte_mbuf_sanity_check(buf, RTE_MBUF_PKT, 1); /* should panic */
exit(0); /* return normally if it doesn't panic */
} else if (pid < 0){
printf("Fork Failed\n");
return -1;
}
wait(&status);
if(status == 0)
return -1;
return 0;
}
static int
test_failing_mbuf_sanity_check(void)
{
struct rte_mbuf *buf;
struct rte_mbuf badbuf;
printf("Checking rte_mbuf_sanity_check for failure conditions\n");
/* get a good mbuf to use to make copies */
buf = rte_pktmbuf_alloc(pktmbuf_pool);
if (buf == NULL)
return -1;
printf("Checking good mbuf initially\n");
if (verify_mbuf_check_panics(buf) != -1)
return -1;
printf("Now checking for error conditions\n");
if (verify_mbuf_check_panics(NULL)) {
printf("Error with NULL mbuf test\n");
return -1;
}
badbuf = *buf;
badbuf.type = (uint8_t)-1;
if (verify_mbuf_check_panics(&badbuf)) {
printf("Error with bad-type mbuf test\n");
return -1;
}
badbuf = *buf;
badbuf.pool = NULL;
if (verify_mbuf_check_panics(&badbuf)) {
printf("Error with bad-pool mbuf test\n");
return -1;
}
badbuf = *buf;
badbuf.buf_physaddr = 0;
if (verify_mbuf_check_panics(&badbuf)) {
printf("Error with bad-physaddr mbuf test\n");
return -1;
}
badbuf = *buf;
badbuf.buf_addr = NULL;
if (verify_mbuf_check_panics(&badbuf)) {
printf("Error with bad-addr mbuf test\n");
return -1;
}
#ifdef RTE_MBUF_SCATTER_GATHER
badbuf = *buf;
badbuf.refcnt = 0;
if (verify_mbuf_check_panics(&badbuf)) {
printf("Error with bad-refcnt(0) mbuf test\n");
return -1;
}
badbuf = *buf;
badbuf.refcnt = UINT16_MAX;
if (verify_mbuf_check_panics(&badbuf)) {
printf("Error with bad-refcnt(MAX) mbuf test\n");
return -1;
}
#endif
return 0;
}
#endif
int
test_mbuf(void)
{
RTE_BUILD_BUG_ON(sizeof(struct rte_mbuf) != 64);
/* create pktmbuf pool if it does not exist */
if (pktmbuf_pool == NULL) {
pktmbuf_pool =
rte_mempool_create("test_pktmbuf_pool", NB_MBUF,
MBUF_SIZE, 32,
sizeof(struct rte_pktmbuf_pool_private),
rte_pktmbuf_pool_init, NULL,
rte_pktmbuf_init, NULL,
SOCKET_ID_ANY, 0);
}
if (pktmbuf_pool == NULL) {
printf("cannot allocate mbuf pool\n");
return -1;
}
/* test multiple mbuf alloc */
if (test_pktmbuf_pool() < 0) {
printf("test_mbuf_pool() failed\n");
return -1;
}
/* do it another time to check that all mbufs were freed */
if (test_pktmbuf_pool() < 0) {
printf("test_mbuf_pool() failed (2)\n");
return -1;
}
/* test data manipulation in mbuf */
if (test_one_pktmbuf() < 0) {
printf("test_one_mbuf() failed\n");
return -1;
}
/*
* do it another time, to check that allocation reinitialize
* the mbuf correctly
*/
if (test_one_pktmbuf() < 0) {
printf("test_one_mbuf() failed (2)\n");
return -1;
}
if (test_pktmbuf_with_non_ascii_data() < 0) {
printf("test_pktmbuf_with_non_ascii_data() failed\n");
return -1;
}
/* create ctrlmbuf pool if it does not exist */
if (ctrlmbuf_pool == NULL) {
ctrlmbuf_pool =
rte_mempool_create("test_ctrlmbuf_pool", NB_MBUF,
sizeof(struct rte_mbuf), 32, 0,
NULL, NULL,
rte_ctrlmbuf_init, NULL,
SOCKET_ID_ANY, 0);
}
/* test control mbuf */
if (test_one_ctrlmbuf() < 0) {
printf("test_one_ctrlmbuf() failed\n");
return -1;
}
/* test free pktmbuf segment one by one */
if (test_pktmbuf_free_segment() < 0) {
printf("test_pktmbuf_free_segment() failed.\n");
return -1;
}
if (testclone_testupdate_testdetach()<0){
printf("testclone_and_testupdate() failed \n");
return -1;
}
if (test_refcnt_mbuf()<0){
printf("test_refcnt_mbuf() failed \n");
return -1;
}
if (test_failing_mbuf_sanity_check() < 0) {
printf("test_failing_mbuf_sanity_check() failed\n");
return -1;
}
return 0;
}

429
app/test/test_memcpy.c Normal file
View File

@ -0,0 +1,429 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <rte_common.h>
#include <cmdline_parse.h>
#include <rte_cycles.h>
#include <rte_random.h>
#include <rte_malloc.h>
#include <rte_memcpy.h>
#include "test.h"
/*
* Set this to the maximum buffer size you want to test. If it is 0, then the
* values in the buf_sizes[] array below will be used.
*/
#define TEST_VALUE_RANGE 0
/* List of buffer sizes to test */
#if TEST_VALUE_RANGE == 0
static size_t buf_sizes[] = {
0, 1, 7, 8, 9, 15, 16, 17, 31, 32, 33, 63, 64, 65, 127, 128, 129, 255,
256, 257, 320, 384, 511, 512, 513, 1023, 1024, 1025, 1518, 1522, 1600,
2048, 3072, 4096, 5120, 6144, 7168, 8192
};
/* MUST be as large as largest packet size above */
#define SMALL_BUFFER_SIZE 8192
#else /* TEST_VALUE_RANGE != 0 */
static size_t buf_sizes[TEST_VALUE_RANGE];
#define SMALL_BUFFER_SIZE TEST_VALUE_RANGE
#endif /* TEST_VALUE_RANGE == 0 */
/*
* Arrays of this size are used for measuring uncached memory accesses by
* picking a random location within the buffer. Make this smaller if there are
* memory allocation errors.
*/
#define LARGE_BUFFER_SIZE (100 * 1024 * 1024)
/* How many times to run timing loop for performance tests */
#define TEST_ITERATIONS 1000000
#define TEST_BATCH_SIZE 100
/* Data is aligned on this many bytes (power of 2) */
#define ALIGNMENT_UNIT 16
/*
* Pointers used in performance tests. The two large buffers are for uncached
* access where random addresses within the buffer are used for each
* memcpy. The two small buffers are for cached access.
*/
static uint8_t *large_buf_read, *large_buf_write,
*small_buf_read, *small_buf_write;
/* Initialise data buffers. */
static int
init_buffers(void)
{
unsigned i;
large_buf_read = rte_malloc("memcpy", LARGE_BUFFER_SIZE, ALIGNMENT_UNIT);
if (large_buf_read == NULL)
goto error_large_buf_read;
large_buf_write = rte_malloc("memcpy", LARGE_BUFFER_SIZE, ALIGNMENT_UNIT);
if (large_buf_write == NULL)
goto error_large_buf_write;
small_buf_read = rte_malloc("memcpy", SMALL_BUFFER_SIZE, ALIGNMENT_UNIT);
if (small_buf_read == NULL)
goto error_small_buf_read;
small_buf_write = rte_malloc("memcpy", SMALL_BUFFER_SIZE, ALIGNMENT_UNIT);
if (small_buf_write == NULL)
goto error_small_buf_write;
for (i = 0; i < LARGE_BUFFER_SIZE; i++)
large_buf_read[i] = rte_rand();
for (i = 0; i < SMALL_BUFFER_SIZE; i++)
small_buf_read[i] = rte_rand();
return 0;
error_small_buf_write:
rte_free(small_buf_read);
error_small_buf_read:
rte_free(large_buf_write);
error_large_buf_write:
rte_free(large_buf_read);
error_large_buf_read:
printf("ERROR: not enough memory");
return -1;
}
/* Cleanup data buffers */
static void
free_buffers(void)
{
rte_free(large_buf_read);
rte_free(large_buf_write);
rte_free(small_buf_read);
rte_free(small_buf_write);
}
/*
* Get a random offset into large array, with enough space needed to perform
* max copy size. Offset is aligned.
*/
static inline size_t
get_rand_offset(void)
{
return ((rte_rand() % (LARGE_BUFFER_SIZE - SMALL_BUFFER_SIZE)) &
~(ALIGNMENT_UNIT - 1));
}
/* Fill in source and destination addresses. */
static inline void
fill_addr_arrays(size_t *dst_addr, int is_dst_cached,
size_t *src_addr, int is_src_cached)
{
unsigned int i;
for (i = 0; i < TEST_BATCH_SIZE; i++) {
dst_addr[i] = (is_dst_cached) ? 0 : get_rand_offset();
src_addr[i] = (is_src_cached) ? 0 : get_rand_offset();
}
}
/* Integer division with round to nearest */
static inline uint64_t
div_round(uint64_t dividend, uint64_t divisor)
{
return ((2 * dividend) + divisor) / (2 * divisor);
}
/*
* WORKAROUND: For some reason the first test doing an uncached write
* takes a very long time (~25 times longer than is expected). So we do
* it once without timing.
*/
static void
do_uncached_write(uint8_t *dst, int is_dst_cached,
const uint8_t *src, int is_src_cached, size_t size)
{
unsigned i, j;
size_t dst_addrs[TEST_BATCH_SIZE], src_addrs[TEST_BATCH_SIZE];
for (i = 0; i < (TEST_ITERATIONS / TEST_BATCH_SIZE); i++) {
fill_addr_arrays(dst_addrs, is_dst_cached,
src_addrs, is_src_cached);
for (j = 0; j < TEST_BATCH_SIZE; j++)
rte_memcpy(dst+dst_addrs[j], src+src_addrs[j], size);
}
}
/*
* Run a single memcpy performance test. This is a macro to ensure that if
* the "size" parameter is a constant it won't be converted to a variable.
*/
#define SINGLE_PERF_TEST(dst, is_dst_cached, src, is_src_cached, size) do { \
unsigned int iter, t; \
size_t dst_addrs[TEST_BATCH_SIZE], src_addrs[TEST_BATCH_SIZE]; \
uint64_t start_time, total_time = 0; \
uint64_t total_time2 = 0; \
for (iter = 0; iter < (TEST_ITERATIONS / TEST_BATCH_SIZE); iter++) { \
fill_addr_arrays(dst_addrs, is_dst_cached, \
src_addrs, is_src_cached); \
start_time = rte_rdtsc(); \
for (t = 0; t < TEST_BATCH_SIZE; t++) \
rte_memcpy(dst+dst_addrs[t], src+src_addrs[t], size); \
total_time += rte_rdtsc() - start_time; \
} \
for (iter = 0; iter < (TEST_ITERATIONS / TEST_BATCH_SIZE); iter++) { \
fill_addr_arrays(dst_addrs, is_dst_cached, \
src_addrs, is_src_cached); \
start_time = rte_rdtsc(); \
for (t = 0; t < TEST_BATCH_SIZE; t++) \
memcpy(dst+dst_addrs[t], src+src_addrs[t], size); \
total_time2 += rte_rdtsc() - start_time; \
} \
printf("%9u/", (unsigned)div_round(total_time, TEST_ITERATIONS)); \
printf("%4u", (unsigned)div_round(total_time2, TEST_ITERATIONS)); \
} while (0)
/* Run memcpy() tests for each cached/uncached permutation. */
#define ALL_PERF_TESTS_FOR_SIZE(n) do { \
if (__builtin_constant_p(n)) \
printf("\nC%6u ", (unsigned)n); \
else \
printf("\n%7u ", (unsigned)n); \
SINGLE_PERF_TEST(small_buf_write, 1, small_buf_read, 1, n); \
SINGLE_PERF_TEST(large_buf_write, 0, small_buf_read, 1, n); \
SINGLE_PERF_TEST(small_buf_write, 1, large_buf_read, 0, n); \
SINGLE_PERF_TEST(large_buf_write, 0, large_buf_read, 0, n); \
} while (0)
/*
* Run performance tests for a number of different sizes and cached/uncached
* permutations.
*/
static int
perf_test(void)
{
const unsigned num_buf_sizes = sizeof(buf_sizes) / sizeof(buf_sizes[0]);
unsigned i;
int ret;
ret = init_buffers();
if (ret != 0)
return ret;
#if TEST_VALUE_RANGE != 0
/* Setup buf_sizes array, if required */
for (i = 0; i < TEST_VALUE_RANGE; i++)
buf_sizes[i] = i;
#endif
/* See function comment */
do_uncached_write(large_buf_write, 0, small_buf_read, 1, SMALL_BUFFER_SIZE);
printf("\n** rte_memcpy()/memcpy performance tests **\n"
"======= ============== ============== ============== ==============\n"
" Size Cache to cache Cache to mem Mem to cache Mem to mem\n"
"(bytes) (ticks) (ticks) (ticks) (ticks)\n"
"------- -------------- -------------- -------------- --------------");
/* Do tests where size is a variable */
for (i = 0; i < num_buf_sizes; i++) {
ALL_PERF_TESTS_FOR_SIZE((size_t)buf_sizes[i]);
}
#ifdef RTE_MEMCPY_BUILTIN_CONSTANT_P
/* Do tests where size is a compile-time constant */
ALL_PERF_TESTS_FOR_SIZE(63U);
ALL_PERF_TESTS_FOR_SIZE(64U);
ALL_PERF_TESTS_FOR_SIZE(65U);
ALL_PERF_TESTS_FOR_SIZE(255U);
ALL_PERF_TESTS_FOR_SIZE(256U);
ALL_PERF_TESTS_FOR_SIZE(257U);
ALL_PERF_TESTS_FOR_SIZE(1023U);
ALL_PERF_TESTS_FOR_SIZE(1024U);
ALL_PERF_TESTS_FOR_SIZE(1025U);
ALL_PERF_TESTS_FOR_SIZE(1518U);
#endif
printf("\n======= ============== ============== ============== ==============\n\n");
free_buffers();
return 0;
}
/* Structure with base memcpy func pointer, and number of bytes it copies */
struct base_memcpy_func {
void (*func)(uint8_t *dst, const uint8_t *src);
unsigned size;
};
/* To create base_memcpy_func structure entries */
#define BASE_FUNC(n) {rte_mov##n, n}
/* Max number of bytes that can be copies with a "base" memcpy functions */
#define MAX_BASE_FUNC_SIZE 256
/*
* Test the "base" memcpy functions, that a copy fixed number of bytes.
*/
static int
base_func_test(void)
{
const struct base_memcpy_func base_memcpy_funcs[6] = {
BASE_FUNC(16),
BASE_FUNC(32),
BASE_FUNC(48),
BASE_FUNC(64),
BASE_FUNC(128),
BASE_FUNC(256),
};
unsigned i, j;
unsigned num_funcs = sizeof(base_memcpy_funcs) / sizeof(base_memcpy_funcs[0]);
uint8_t dst[MAX_BASE_FUNC_SIZE];
uint8_t src[MAX_BASE_FUNC_SIZE];
for (i = 0; i < num_funcs; i++) {
unsigned size = base_memcpy_funcs[i].size;
for (j = 0; j < size; j++) {
dst[j] = 0;
src[j] = (uint8_t) rte_rand();
}
base_memcpy_funcs[i].func(dst, src);
for (j = 0; j < size; j++)
if (dst[j] != src[j])
return -1;
}
return 0;
}
/*
* Create two buffers, and initialise one with random values. These are copied
* to the second buffer and then compared to see if the copy was successful.
* The bytes outside the copied area are also checked to make sure they were not
* changed.
*/
static int
test_single_memcpy(unsigned int off_src, unsigned int off_dst, size_t size)
{
unsigned int i;
uint8_t dest[SMALL_BUFFER_SIZE + ALIGNMENT_UNIT];
uint8_t src[SMALL_BUFFER_SIZE + ALIGNMENT_UNIT];
/* Setup buffers */
for (i = 0; i < SMALL_BUFFER_SIZE + ALIGNMENT_UNIT; i++) {
dest[i] = 0;
src[i] = (uint8_t) rte_rand();
}
/* Do the copy */
rte_memcpy(dest + off_dst, src + off_src, size);
/* Check nothing before offset is affected */
for (i = 0; i < off_dst; i++) {
if (dest[i] != 0) {
printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): "
"[modified before start of dst].\n",
(unsigned)size, off_src, off_dst);
return -1;
}
}
/* Check everything was copied */
for (i = 0; i < size; i++) {
if (dest[i + off_dst] != src[i + off_src]) {
printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): "
"[didn't copy byte %u].\n",
(unsigned)size, off_src, off_dst, i);
return -1;
}
}
/* Check nothing after copy was affected */
for (i = size; i < SMALL_BUFFER_SIZE; i++) {
if (dest[i + off_dst] != 0) {
printf("rte_memcpy() failed for %u bytes (offsets=%u,%u): "
"[copied too many].\n",
(unsigned)size, off_src, off_dst);
return -1;
}
}
return 0;
}
/*
* Check functionality for various buffer sizes and data offsets/alignments.
*/
static int
func_test(void)
{
unsigned int off_src, off_dst, i;
unsigned int num_buf_sizes = sizeof(buf_sizes) / sizeof(buf_sizes[0]);
int ret;
for (off_src = 0; off_src < ALIGNMENT_UNIT; off_src++) {
for (off_dst = 0; off_dst < ALIGNMENT_UNIT; off_dst++) {
for (i = 0; i < num_buf_sizes; i++) {
ret = test_single_memcpy(off_src, off_dst,
buf_sizes[i]);
if (ret != 0)
return -1;
}
}
}
return 0;
}
int
test_memcpy(void)
{
int ret;
ret = func_test();
if (ret != 0)
return -1;
ret = base_func_test();
if (ret != 0)
return -1;
ret = perf_test();
if (ret != 0)
return -1;
return 0;
}

92
app/test/test_memory.c Normal file
View File

@ -0,0 +1,92 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <cmdline_parse.h>
#include <rte_memory.h>
#include <rte_common.h>
#include "test.h"
/*
* Memory
* ======
*
* - Dump the mapped memory. The python-expect script checks that at
* least one line is dumped.
*
* - Check that memory size is different than 0.
*
* - Try to read all memory; it should not segfault.
*/
int
test_memory(void)
{
uint64_t s;
unsigned i, j;
const struct rte_memseg *mem;
volatile uint8_t x;
/*
* dump the mapped memory: the python-expect script checks
* that at least one line is dumped
*/
printf("Dump memory layout\n");
rte_dump_physmem_layout();
/* check that memory size is != 0 */
s = rte_eal_get_physmem_size();
if (s == 0) {
printf("No memory detected\n");
return -1;
}
/* try to read memory (should not segfault) */
mem = rte_eal_get_physmem_layout();
for (i = 0; i < RTE_MAX_MEMSEG && mem[i].addr != NULL ; i++) {
/* check memory */
for (j = 0; j<mem[i].len; j++) {
x = *((uint8_t *) mem[i].addr + j);
RTE_SET_USED(x);
}
}
return 0;
}

707
app/test/test_mempool.c Normal file
View File

@ -0,0 +1,707 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/queue.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_debug.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_cycles.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_ring.h>
#include <rte_mempool.h>
#include <rte_spinlock.h>
#include <rte_malloc.h>
#include <cmdline_parse.h>
#include "test.h"
/*
* Mempool
* =======
*
* #. Basic tests: done on one core with and without cache:
*
* - Get one object, put one object
* - Get two objects, put two objects
* - Get all objects, test that their content is not modified and
* put them back in the pool.
*
* #. Performance tests:
*
* Each core get *n_keep* objects per bulk of *n_get_bulk*. Then,
* objects are put back in the pool per bulk of *n_put_bulk*.
*
* This sequence is done during TIME_S seconds.
*
* This test is done on the following configurations:
*
* - Cores configuration (*cores*)
*
* - One core with cache
* - Two cores with cache
* - Max. cores with cache
* - One core without cache
* - Two cores without cache
* - Max. cores without cache
*
* - Bulk size (*n_get_bulk*, *n_put_bulk*)
*
* - Bulk get from 1 to 32
* - Bulk put from 1 to 32
*
* - Number of kept objects (*n_keep*)
*
* - 32
* - 128
*/
#define N 65536
#define TIME_S 5
#define MEMPOOL_ELT_SIZE 2048
#define MAX_KEEP 128
#define MEMPOOL_SIZE ((RTE_MAX_LCORE*(MAX_KEEP+RTE_MEMPOOL_CACHE_MAX_SIZE))-1)
static struct rte_mempool *mp;
static struct rte_mempool *mp_cache, *mp_nocache;
static rte_atomic32_t synchro;
/* number of objects in one bulk operation (get or put) */
static unsigned n_get_bulk;
static unsigned n_put_bulk;
/* number of objects retrived from mempool before putting them back */
static unsigned n_keep;
/* number of enqueues / dequeues */
struct mempool_test_stats {
unsigned enq_count;
} __rte_cache_aligned;
static struct mempool_test_stats stats[RTE_MAX_LCORE];
static int
per_lcore_mempool_test(__attribute__((unused)) void *arg)
{
void *obj_table[MAX_KEEP];
unsigned i, idx;
unsigned lcore_id = rte_lcore_id();
int ret;
uint64_t start_cycles, end_cycles;
uint64_t time_diff = 0, hz = rte_get_hpet_hz();
/* n_get_bulk and n_put_bulk must be divisors of n_keep */
if (((n_keep / n_get_bulk) * n_get_bulk) != n_keep)
return -1;
if (((n_keep / n_put_bulk) * n_put_bulk) != n_keep)
return -1;
stats[lcore_id].enq_count = 0;
/* wait synchro for slaves */
if (lcore_id != rte_get_master_lcore())
while (rte_atomic32_read(&synchro) == 0);
start_cycles = rte_get_hpet_cycles();
while (time_diff/hz < TIME_S) {
for (i = 0; likely(i < (N/n_keep)); i++) {
/* get n_keep objects by bulk of n_bulk */
idx = 0;
while (idx < n_keep) {
ret = rte_mempool_get_bulk(mp, &obj_table[idx],
n_get_bulk);
if (unlikely(ret < 0)) {
rte_mempool_dump(mp);
rte_ring_dump(mp->ring);
/* in this case, objects are lost... */
return -1;
}
idx += n_get_bulk;
}
/* put the objects back */
idx = 0;
while (idx < n_keep) {
rte_mempool_put_bulk(mp, &obj_table[idx],
n_put_bulk);
idx += n_put_bulk;
}
}
end_cycles = rte_get_hpet_cycles();
time_diff = end_cycles - start_cycles;
stats[lcore_id].enq_count += N;
}
return 0;
}
/* launch all the per-lcore test, and display the result */
static int
launch_cores(unsigned cores)
{
unsigned lcore_id;
unsigned rate;
int ret;
unsigned cores_save = cores;
rte_atomic32_set(&synchro, 0);
/* reset stats */
memset(stats, 0, sizeof(stats));
printf("mempool_autotest cache=%u cores=%u n_get_bulk=%u "
"n_put_bulk=%u n_keep=%u ",
(unsigned) mp->cache_size, cores, n_get_bulk, n_put_bulk, n_keep);
if (rte_mempool_count(mp) != MEMPOOL_SIZE) {
printf("mempool is not full\n");
return -1;
}
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (cores == 1)
break;
cores--;
rte_eal_remote_launch(per_lcore_mempool_test,
NULL, lcore_id);
}
/* start synchro and launch test on master */
rte_atomic32_set(&synchro, 1);
ret = per_lcore_mempool_test(NULL);
cores = cores_save;
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (cores == 1)
break;
cores--;
if (rte_eal_wait_lcore(lcore_id) < 0)
ret = -1;
}
if (ret < 0) {
printf("per-lcore test returned -1\n");
return -1;
}
rate = 0;
for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++)
rate += (stats[lcore_id].enq_count / TIME_S);
printf("rate_persec=%u\n", rate);
return 0;
}
/* for a given number of core, launch all test cases */
static int
do_one_mempool_test(unsigned cores)
{
unsigned bulk_tab_get[] = { 1, 4, 32, 0 };
unsigned bulk_tab_put[] = { 1, 4, 32, 0 };
unsigned keep_tab[] = { 32, 128, 0 };
unsigned *get_bulk_ptr;
unsigned *put_bulk_ptr;
unsigned *keep_ptr;
int ret;
for (get_bulk_ptr = bulk_tab_get; *get_bulk_ptr; get_bulk_ptr++) {
for (put_bulk_ptr = bulk_tab_put; *put_bulk_ptr; put_bulk_ptr++) {
for (keep_ptr = keep_tab; *keep_ptr; keep_ptr++) {
n_get_bulk = *get_bulk_ptr;
n_put_bulk = *put_bulk_ptr;
n_keep = *keep_ptr;
ret = launch_cores(cores);
if (ret < 0)
return -1;
}
}
}
return 0;
}
/*
* save the object number in the first 4 bytes of object data. All
* other bytes are set to 0.
*/
static void
my_obj_init(struct rte_mempool *mp, __attribute__((unused)) void *arg,
void *obj, unsigned i)
{
uint32_t *objnum = obj;
memset(obj, 0, mp->elt_size);
*objnum = i;
}
/* basic tests (done on one core) */
static int
test_mempool_basic(void)
{
uint32_t *objnum;
void **objtable;
void *obj, *obj2;
char *obj_data;
int ret = 0;
unsigned i, j;
unsigned old_bulk_count;
/* dump the mempool status */
rte_mempool_dump(mp);
old_bulk_count = rte_mempool_get_bulk_count(mp);
rte_mempool_dump(mp);
if (rte_mempool_set_bulk_count(mp, 0) == 0)
return -1;
if (rte_mempool_get_bulk_count(mp) == 0)
return -1;
if (rte_mempool_set_bulk_count(mp, 2) < 0)
return -1;
if (rte_mempool_get_bulk_count(mp) != 2)
return -1;
rte_mempool_dump(mp);
if (rte_mempool_set_bulk_count(mp, old_bulk_count) < 0)
return -1;
if (rte_mempool_get_bulk_count(mp) != old_bulk_count)
return -1;
rte_mempool_dump(mp);
printf("get an object\n");
if (rte_mempool_get(mp, &obj) < 0)
return -1;
rte_mempool_dump(mp);
printf("put the object back\n");
rte_mempool_put(mp, obj);
rte_mempool_dump(mp);
printf("get 2 objects\n");
if (rte_mempool_get(mp, &obj) < 0)
return -1;
if (rte_mempool_get(mp, &obj2) < 0) {
rte_mempool_put(mp, obj);
return -1;
}
rte_mempool_dump(mp);
printf("put the objects back\n");
rte_mempool_put(mp, obj);
rte_mempool_put(mp, obj2);
rte_mempool_dump(mp);
/*
* get many objects: we cannot get them all because the cache
* on other cores may not be empty.
*/
objtable = malloc(MEMPOOL_SIZE * sizeof(void *));
if (objtable == NULL) {
return -1;
}
for (i=0; i<MEMPOOL_SIZE; i++) {
if (rte_mempool_get(mp, &objtable[i]) < 0)
break;
}
/*
* for each object, check that its content was not modified,
* and put objects back in pool
*/
while (i--) {
obj = objtable[i];
obj_data = obj;
objnum = obj;
if (*objnum > MEMPOOL_SIZE) {
printf("bad object number\n");
ret = -1;
break;
}
for (j=sizeof(*objnum); j<mp->elt_size; j++) {
if (obj_data[j] != 0)
ret = -1;
}
rte_mempool_put(mp, objtable[i]);
}
free(objtable);
if (ret == -1)
printf("objects were modified!\n");
return ret;
}
static int test_mempool_creation_with_exceeded_cache_size(void)
{
struct rte_mempool *mp_cov;
mp_cov = rte_mempool_create("test_mempool_creation_with_exceeded_cache_size", MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE,
RTE_MEMPOOL_CACHE_MAX_SIZE + 32, 0,
NULL, NULL,
my_obj_init, NULL,
SOCKET_ID_ANY, 0);
if(NULL != mp_cov) {
return -1;
}
return 0;
}
static struct rte_mempool *mp_spsc;
static rte_spinlock_t scsp_spinlock;
static void *scsp_obj_table[MAX_KEEP];
/*
* single producer function
*/
static int test_mempool_single_producer(void)
{
unsigned int i;
void *obj = NULL;
uint64_t start_cycles, end_cycles;
uint64_t duration = rte_get_hpet_hz() * 8;
start_cycles = rte_get_hpet_cycles();
while (1) {
end_cycles = rte_get_hpet_cycles();
/* duration uses up, stop producing */
if (start_cycles + duration < end_cycles)
break;
rte_spinlock_lock(&scsp_spinlock);
for (i = 0; i < MAX_KEEP; i ++) {
if (NULL != scsp_obj_table[i])
obj = scsp_obj_table[i];
break;
}
rte_spinlock_unlock(&scsp_spinlock);
if (i >= MAX_KEEP) {
continue;
}
if (rte_mempool_from_obj(obj) != mp_spsc) {
printf("test_mempool_single_producer there is an obj not owned by this mempool\n");
return -1;
}
rte_mempool_sp_put(mp_spsc, obj);
rte_spinlock_lock(&scsp_spinlock);
scsp_obj_table[i] = NULL;
rte_spinlock_unlock(&scsp_spinlock);
}
return 0;
}
/*
* single consumer function
*/
static int test_mempool_single_consumer(void)
{
unsigned int i;
void * obj;
uint64_t start_cycles, end_cycles;
uint64_t duration = rte_get_hpet_hz() * 5;
start_cycles = rte_get_hpet_cycles();
while (1) {
end_cycles = rte_get_hpet_cycles();
/* duration uses up, stop consuming */
if (start_cycles + duration < end_cycles)
break;
rte_spinlock_lock(&scsp_spinlock);
for (i = 0; i < MAX_KEEP; i ++) {
if (NULL == scsp_obj_table[i])
break;
}
rte_spinlock_unlock(&scsp_spinlock);
if (i >= MAX_KEEP)
continue;
if (rte_mempool_sc_get(mp_spsc, &obj) < 0)
break;
rte_spinlock_lock(&scsp_spinlock);
scsp_obj_table[i] = obj;
rte_spinlock_unlock(&scsp_spinlock);
}
return 0;
}
/*
* test function for mempool test based on singple consumer and single producer, can run on one lcore only
*/
static int test_mempool_launch_single_consumer(__attribute__((unused)) void *arg)
{
return test_mempool_single_consumer();
}
static void my_mp_init(struct rte_mempool * mp, __attribute__((unused)) void * arg)
{
printf("mempool name is %s\n", mp->name);
/* nothing to be implemented here*/
return ;
}
/*
* it tests the mempool operations based on singple producer and single consumer
*/
static int
test_mempool_sp_sc(void)
{
int ret = 0;
unsigned lcore_id = rte_lcore_id();
unsigned lcore_next;
/* create a mempool with single producer/consumer ring */
if (NULL == mp_spsc) {
mp_spsc = rte_mempool_create("test_mempool_sp_sc", MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE, 0, 0,
my_mp_init, NULL,
my_obj_init, NULL,
SOCKET_ID_ANY, MEMPOOL_F_NO_CACHE_ALIGN | MEMPOOL_F_SP_PUT | MEMPOOL_F_SC_GET);
if (NULL == mp_spsc) {
return -1;
}
}
if (rte_mempool_lookup("test_mempool_sp_sc") != mp_spsc) {
printf("Cannot lookup mempool from its name\n");
return -1;
}
lcore_next = rte_get_next_lcore(lcore_id, 0, 1);
if (RTE_MAX_LCORE <= lcore_next)
return -1;
if (rte_eal_lcore_role(lcore_next) != ROLE_RTE)
return -1;
rte_spinlock_init(&scsp_spinlock);
memset(scsp_obj_table, 0, sizeof(scsp_obj_table));
rte_eal_remote_launch(test_mempool_launch_single_consumer, NULL, lcore_next);
if(test_mempool_single_producer() < 0)
ret = -1;
if(rte_eal_wait_lcore(lcore_next) < 0)
ret = -1;
return ret;
}
/*
* it tests some more basic of mempool
*/
static int
test_mempool_basic_ex(struct rte_mempool * mp)
{
unsigned i;
void **obj;
void *err_obj;
int ret = -1;
if (mp == NULL)
return ret;
obj = (void **)rte_zmalloc("test_mempool_basic_ex", (MEMPOOL_SIZE * sizeof(void *)), 0);
if (obj == NULL) {
printf("test_mempool_basic_ex fail to rte_malloc\n");
return ret;
}
printf("test_mempool_basic_ex now mempool (%s) has %u free entries\n", mp->name, rte_mempool_free_count(mp));
if (rte_mempool_full(mp) != 1) {
printf("test_mempool_basic_ex the mempool is not full but it should be\n");
goto fail_mp_basic_ex;
}
for (i = 0; i < MEMPOOL_SIZE; i ++) {
if (rte_mempool_mc_get(mp, &obj[i]) < 0) {
printf("fail_mp_basic_ex fail to get mempool object for [%u]\n", i);
goto fail_mp_basic_ex;
}
}
if (rte_mempool_mc_get(mp, &err_obj) == 0) {
printf("test_mempool_basic_ex get an impossible obj from mempool\n");
goto fail_mp_basic_ex;
}
printf("number: %u\n", i);
if (rte_mempool_empty(mp) != 1) {
printf("test_mempool_basic_ex the mempool is not empty but it should be\n");
goto fail_mp_basic_ex;
}
for (i = 0; i < MEMPOOL_SIZE; i ++) {
rte_mempool_mp_put(mp, obj[i]);
}
if (rte_mempool_full(mp) != 1) {
printf("test_mempool_basic_ex the mempool is not full but it should be\n");
goto fail_mp_basic_ex;
}
ret = 0;
fail_mp_basic_ex:
if (obj != NULL)
rte_free((void *)obj);
return ret;
}
static int
test_mempool_same_name_twice_creation(void)
{
struct rte_mempool *mp_tc;
mp_tc = rte_mempool_create("test_mempool_same_name_twice_creation", MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE, 0, 0,
NULL, NULL,
NULL, NULL,
SOCKET_ID_ANY, 0);
if (NULL == mp_tc)
return -1;
mp_tc = rte_mempool_create("test_mempool_same_name_twice_creation", MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE, 0, 0,
NULL, NULL,
NULL, NULL,
SOCKET_ID_ANY, 0);
if (NULL != mp_tc)
return -1;
return 0;
}
int
test_mempool(void)
{
rte_atomic32_init(&synchro);
/* create a mempool (without cache) */
if (mp_nocache == NULL)
mp_nocache = rte_mempool_create("test_nocache", MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE, 0, 0,
NULL, NULL,
my_obj_init, NULL,
SOCKET_ID_ANY, 0);
if (mp_nocache == NULL)
return -1;
/* create a mempool (with cache) */
if (mp_cache == NULL)
mp_cache = rte_mempool_create("test_cache", MEMPOOL_SIZE,
MEMPOOL_ELT_SIZE,
RTE_MEMPOOL_CACHE_MAX_SIZE, 0,
NULL, NULL,
my_obj_init, NULL,
SOCKET_ID_ANY, 0);
if (mp_cache == NULL)
return -1;
/* retrieve the mempool from its name */
if (rte_mempool_lookup("test_nocache") != mp_nocache) {
printf("Cannot lookup mempool from its name\n");
return -1;
}
rte_mempool_list_dump();
/* basic tests without cache */
mp = mp_nocache;
if (test_mempool_basic() < 0)
return -1;
/* basic tests with cache */
mp = mp_cache;
if (test_mempool_basic() < 0)
return -1;
/* more basic tests without cache */
if (test_mempool_basic_ex(mp_nocache) < 0)
return -1;
/* performance test with 1, 2 and max cores */
printf("start performance test (without cache)\n");
mp = mp_nocache;
if (do_one_mempool_test(1) < 0)
return -1;
if (do_one_mempool_test(2) < 0)
return -1;
if (do_one_mempool_test(rte_lcore_count()) < 0)
return -1;
/* performance test with 1, 2 and max cores */
printf("start performance test (with cache)\n");
mp = mp_cache;
if (do_one_mempool_test(1) < 0)
return -1;
if (do_one_mempool_test(2) < 0)
return -1;
if (do_one_mempool_test(rte_lcore_count()) < 0)
return -1;
/* mempool operation test based on single producer and single comsumer */
if (test_mempool_sp_sc() < 0)
return -1;
if (test_mempool_creation_with_exceeded_cache_size() < 0)
return -1;
if (test_mempool_same_name_twice_creation() < 0)
return -1;
rte_mempool_list_dump();
return 0;
}

639
app/test/test_memzone.c Normal file
View File

@ -0,0 +1,639 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_common.h>
#include "test.h"
/*
* Memzone
* =======
*
* - Search for three reserved zones or reserve them if they do not exist:
*
* - One is on any socket id.
* - The second is on socket 0.
* - The last one is on socket 1 (if socket 1 exists).
*
* - Check that the zones exist.
*
* - Check that the zones are cache-aligned.
*
* - Check that zones do not overlap.
*
* - Check that the zones are on the correct socket id.
*
* - Check that a lookup of the first zone returns the same pointer.
*
* - Check that it is not possible to create another zone with the
* same name as an existing zone.
*
* - Check flags for specific huge page size reservation
*/
/* Test if memory overlaps: return 1 if true, or 0 if false. */
static int
is_memory_overlap(phys_addr_t ptr1, size_t len1, phys_addr_t ptr2, size_t len2)
{
if (ptr2 >= ptr1 && (ptr2 - ptr1) < len1)
return 1;
else if (ptr2 < ptr1 && (ptr1 - ptr2) < len2)
return 1;
return 0;
}
static int
test_memzone_invalid_alignment(void)
{
const struct rte_memzone * mz;
mz = rte_memzone_lookup("invalid_alignment");
if (mz != NULL) {
printf("Zone with invalid alignment has been reserved\n");
return -1;
}
mz = rte_memzone_reserve_aligned("invalid_alignment", 100,
SOCKET_ID_ANY, 0, 100);
if (mz != NULL) {
printf("Zone with invalid alignment has been reserved\n");
return -1;
}
return 0;
}
static int
test_memzone_reserving_zone_size_bigger_than_the_maximum(void)
{
const struct rte_memzone * mz;
mz = rte_memzone_lookup("zone_size_bigger_than_the_maximum");
if (mz != NULL) {
printf("zone_size_bigger_than_the_maximum has been reserved\n");
return -1;
}
mz = rte_memzone_reserve("zone_size_bigger_than_the_maximum", 0x1900000000ULL,
SOCKET_ID_ANY, 0);
if (mz != NULL) {
printf("It is impossible to reserve such big a memzone\n");
return -1;
}
return 0;
}
static int
test_memzone_reserve_flags(void)
{
const struct rte_memzone *mz;
const struct rte_memseg *ms;
int hugepage_2MB_avail = 0;
int hugepage_1GB_avail = 0;
const int size = 100;
int i = 0;
ms = rte_eal_get_physmem_layout();
for (i = 0; i < RTE_MAX_MEMSEG; i++) {
if (ms[i].hugepage_sz == RTE_PGSIZE_2M)
hugepage_2MB_avail = 1;
if (ms[i].hugepage_sz == RTE_PGSIZE_1G)
hugepage_1GB_avail = 1;
}
/* Display the availability of 2MB and 1GB pages */
if (hugepage_2MB_avail)
printf("2MB Huge pages available\n");
if (hugepage_1GB_avail)
printf("1GB Huge pages available\n");
/*
* If 2MB pages available, check that a small memzone is correctly
* reserved from 2MB huge pages when requested by the RTE_MEMZONE_2MB flag.
* Also check that RTE_MEMZONE_SIZE_HINT_ONLY flag only defaults to an
* available page size (i.e 1GB ) when 2MB pages are unavailable.
*/
if (hugepage_2MB_avail) {
mz = rte_memzone_reserve("flag_zone_2M", size, SOCKET_ID_ANY,
RTE_MEMZONE_2MB);
if (mz == NULL) {
printf("MEMZONE FLAG 2MB\n");
return -1;
}
if (mz->hugepage_sz != RTE_PGSIZE_2M) {
printf("hugepage_sz not equal 2M\n");
return -1;
}
mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY,
RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY);
if (mz == NULL) {
printf("MEMZONE FLAG 2MB\n");
return -1;
}
if (mz->hugepage_sz != RTE_PGSIZE_2M) {
printf("hugepage_sz not equal 2M\n");
return -1;
}
/* Check if 1GB huge pages are unavailable, that function fails unless
* HINT flag is indicated
*/
if (!hugepage_1GB_avail) {
mz = rte_memzone_reserve("flag_zone_1G_HINT", size, SOCKET_ID_ANY,
RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY);
if (mz == NULL) {
printf("MEMZONE FLAG 1GB & HINT\n");
return -1;
}
if (mz->hugepage_sz != RTE_PGSIZE_2M) {
printf("hugepage_sz not equal 2M\n");
return -1;
}
mz = rte_memzone_reserve("flag_zone_1G", size, SOCKET_ID_ANY,
RTE_MEMZONE_1GB);
if (mz != NULL) {
printf("MEMZONE FLAG 1GB\n");
return -1;
}
}
}
/*As with 2MB tests above for 1GB huge page requests*/
if (hugepage_1GB_avail) {
mz = rte_memzone_reserve("flag_zone_1G", size, SOCKET_ID_ANY,
RTE_MEMZONE_1GB);
if (mz == NULL) {
printf("MEMZONE FLAG 1GB\n");
return -1;
}
if (mz->hugepage_sz != RTE_PGSIZE_1G) {
printf("hugepage_sz not equal 1G\n");
return -1;
}
mz = rte_memzone_reserve("flag_zone_1G_HINT", size, SOCKET_ID_ANY,
RTE_MEMZONE_1GB|RTE_MEMZONE_SIZE_HINT_ONLY);
if (mz == NULL) {
printf("MEMZONE FLAG 1GB\n");
return -1;
}
if (mz->hugepage_sz != RTE_PGSIZE_1G) {
printf("hugepage_sz not equal 1G\n");
return -1;
}
/* Check if 1GB huge pages are unavailable, that function fails unless
* HINT flag is indicated
*/
if (!hugepage_2MB_avail) {
mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY,
RTE_MEMZONE_2MB|RTE_MEMZONE_SIZE_HINT_ONLY);
if (mz == NULL){
printf("MEMZONE FLAG 2MB & HINT\n");
return -1;
}
if (mz->hugepage_sz != RTE_PGSIZE_1G) {
printf("hugepage_sz not equal 1G\n");
return -1;
}
mz = rte_memzone_reserve("flag_zone_2M", size, SOCKET_ID_ANY,
RTE_MEMZONE_2MB);
if (mz != NULL) {
printf("MEMZONE FLAG 2MB\n");
return -1;
}
}
if (hugepage_2MB_avail && hugepage_1GB_avail) {
mz = rte_memzone_reserve("flag_zone_2M_HINT", size, SOCKET_ID_ANY,
RTE_MEMZONE_2MB|RTE_MEMZONE_1GB);
if (mz != NULL) {
printf("BOTH SIZES SET\n");
return -1;
}
}
}
return 0;
}
static int
test_memzone_reserve_max(void)
{
const struct rte_memzone *mz;
const struct rte_config *config;
const struct rte_memseg *ms;
int memseg_idx = 0;
int memzone_idx = 0;
uint64_t len = 0;
void* last_addr;
uint64_t maxlen = 0;
/* get pointer to global configuration */
config = rte_eal_get_configuration();
ms = rte_eal_get_physmem_layout();
for (memseg_idx = 0; memseg_idx < RTE_MAX_MEMSEG; memseg_idx++){
/* ignore smaller memsegs as they can only get smaller */
if (ms[memseg_idx].len < maxlen)
continue;
len = ms[memseg_idx].len;
last_addr = ms[memseg_idx].addr;
/* cycle through all memzones */
for (memzone_idx = 0; memzone_idx < RTE_MAX_MEMZONE; memzone_idx++) {
/* stop when reaching last allocated memzone */
if (config->mem_config->memzone[memzone_idx].addr == NULL)
break;
/* check if the memzone is in our memseg and subtract length */
if ((config->mem_config->memzone[memzone_idx].addr >=
ms[memseg_idx].addr) &&
(config->mem_config->memzone[memzone_idx].addr <=
(RTE_PTR_ADD(ms[memseg_idx].addr,
(size_t)ms[memseg_idx].len)))) {
/* since the zones can now be aligned and occasionally skip
* some space, we should calculate the length based on
* reported length and start addresses difference. Addresses
* are allocated sequentially so we don't need to worry about
* them being in the right order.
*/
len -= (uintptr_t) RTE_PTR_SUB(
config->mem_config->memzone[memzone_idx].addr,
(uintptr_t) last_addr);
len -= config->mem_config->memzone[memzone_idx].len;
last_addr =
RTE_PTR_ADD(config->mem_config->memzone[memzone_idx].addr,
(size_t) config->mem_config->memzone[memzone_idx].len);
}
}
/* we don't need to calculate offset here since length
* is always cache-aligned */
if (len > maxlen)
maxlen = len;
}
mz = rte_memzone_reserve("max_zone", 0, SOCKET_ID_ANY, 0);
if (mz == NULL){
printf("Failed to reserve a big chunk of memory\n");
rte_dump_physmem_layout();
rte_memzone_dump();
return -1;
}
if (mz->len != maxlen) {
printf("Memzone reserve with 0 size did not return bigest block\n");
printf("Expected size = %" PRIu64 ", actual size = %" PRIu64 "\n",
maxlen, mz->len);
rte_dump_physmem_layout();
rte_memzone_dump();
return -1;
}
return 0;
}
static int
test_memzone_reserve_max_aligned(void)
{
const struct rte_memzone *mz;
const struct rte_config *config;
const struct rte_memseg *ms;
int memseg_idx = 0;
int memzone_idx = 0;
uint64_t addr_offset, len = 0;
void* last_addr;
uint64_t maxlen = 0;
/* get pointer to global configuration */
config = rte_eal_get_configuration();
ms = rte_eal_get_physmem_layout();
addr_offset = 0;
for (memseg_idx = 0; memseg_idx < RTE_MAX_MEMSEG; memseg_idx++){
/* ignore smaller memsegs as they can only get smaller */
if (ms[memseg_idx].len < maxlen)
continue;
len = ms[memseg_idx].len;
last_addr = ms[memseg_idx].addr;
/* cycle through all memzones */
for (memzone_idx = 0; memzone_idx < RTE_MAX_MEMZONE; memzone_idx++) {
/* stop when reaching last allocated memzone */
if (config->mem_config->memzone[memzone_idx].addr == NULL)
break;
/* check if the memzone is in our memseg and subtract length */
if ((config->mem_config->memzone[memzone_idx].addr >=
ms[memseg_idx].addr) &&
(config->mem_config->memzone[memzone_idx].addr <=
(RTE_PTR_ADD(ms[memseg_idx].addr,
(size_t) ms[memseg_idx].len)))) {
/* since the zones can now be aligned and occasionally skip
* some space, we should calculate the length based on
* reported length and start addresses difference.
*/
len -= (uintptr_t) RTE_PTR_SUB(
config->mem_config->memzone[memzone_idx].addr,
(uintptr_t) last_addr);
len -= config->mem_config->memzone[memzone_idx].len;
last_addr =
RTE_PTR_ADD(config->mem_config->memzone[memzone_idx].addr,
(size_t) config->mem_config->memzone[memzone_idx].len);
}
}
/* make sure we get the alignment offset */
if (len > maxlen) {
addr_offset = RTE_ALIGN_CEIL((uintptr_t) last_addr, 512) - (uintptr_t) last_addr;
maxlen = len;
}
}
maxlen -= addr_offset;
mz = rte_memzone_reserve_aligned("max_zone_aligned", 0,
SOCKET_ID_ANY, 0, 512);
if (mz == NULL){
printf("Failed to reserve a big chunk of memory\n");
rte_dump_physmem_layout();
rte_memzone_dump();
return -1;
}
if (mz->len != maxlen) {
printf("Memzone reserve with 0 size and alignment 512 did not return"
" bigest block\n");
printf("Expected size = %" PRIu64 ", actual size = %" PRIu64 "\n",
maxlen, mz->len);
rte_dump_physmem_layout();
rte_memzone_dump();
return -1;
}
return 0;
}
static int
test_memzone_aligned(void)
{
const struct rte_memzone *memzone_aligned_32;
const struct rte_memzone *memzone_aligned_128;
const struct rte_memzone *memzone_aligned_256;
const struct rte_memzone *memzone_aligned_512;
const struct rte_memzone *memzone_aligned_1024;
/* memzone that should automatically be adjusted to align on 64 bytes */
memzone_aligned_32 = rte_memzone_lookup("aligned_32");
if (memzone_aligned_32 == NULL)
memzone_aligned_32 = rte_memzone_reserve_aligned("aligned_32", 100,
SOCKET_ID_ANY, 0, 32);
/* memzone that is supposed to be aligned on a 128 byte boundary */
memzone_aligned_128 = rte_memzone_lookup("aligned_128");
if (memzone_aligned_128 == NULL)
memzone_aligned_128 = rte_memzone_reserve_aligned("aligned_128", 100,
SOCKET_ID_ANY, 0, 128);
/* memzone that is supposed to be aligned on a 256 byte boundary */
memzone_aligned_256 = rte_memzone_lookup("aligned_256");
if (memzone_aligned_256 == NULL)
memzone_aligned_256 = rte_memzone_reserve_aligned("aligned_256", 100,
SOCKET_ID_ANY, 0, 256);
/* memzone that is supposed to be aligned on a 512 byte boundary */
memzone_aligned_512 = rte_memzone_lookup("aligned_512");
if (memzone_aligned_512 == NULL)
memzone_aligned_512 = rte_memzone_reserve_aligned("aligned_512", 100,
SOCKET_ID_ANY, 0, 512);
/* memzone that is supposed to be aligned on a 1024 byte boundary */
memzone_aligned_1024 = rte_memzone_lookup("aligned_1024");
if (memzone_aligned_1024 == NULL)
memzone_aligned_1024 = rte_memzone_reserve_aligned("aligned_1024", 100,
SOCKET_ID_ANY, 0, 1024);
printf("check alignments and lengths\n");
if ((memzone_aligned_32->phys_addr & CACHE_LINE_MASK) != 0)
return -1;
if (((uintptr_t) memzone_aligned_32->addr & CACHE_LINE_MASK) != 0)
return -1;
if ((memzone_aligned_32->len & CACHE_LINE_MASK) != 0)
return -1;
if ((memzone_aligned_128->phys_addr & 127) != 0)
return -1;
if (((uintptr_t) memzone_aligned_128->addr & 127) != 0)
return -1;
if ((memzone_aligned_128->len & CACHE_LINE_MASK) != 0)
return -1;
if ((memzone_aligned_256->phys_addr & 255) != 0)
return -1;
if (((uintptr_t) memzone_aligned_256->addr & 255) != 0)
return -1;
if ((memzone_aligned_256->len & CACHE_LINE_MASK) != 0)
return -1;
if ((memzone_aligned_512->phys_addr & 511) != 0)
return -1;
if (((uintptr_t) memzone_aligned_512->addr & 511) != 0)
return -1;
if ((memzone_aligned_512->len & CACHE_LINE_MASK) != 0)
return -1;
if ((memzone_aligned_1024->phys_addr & 1023) != 0)
return -1;
if (((uintptr_t) memzone_aligned_1024->addr & 1023) != 0)
return -1;
if ((memzone_aligned_1024->len & CACHE_LINE_MASK) != 0)
return -1;
/* check that zones don't overlap */
printf("check overlapping\n");
if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len,
memzone_aligned_128->phys_addr, memzone_aligned_128->len))
return -1;
if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len,
memzone_aligned_256->phys_addr, memzone_aligned_256->len))
return -1;
if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len,
memzone_aligned_512->phys_addr, memzone_aligned_512->len))
return -1;
if (is_memory_overlap(memzone_aligned_32->phys_addr, memzone_aligned_32->len,
memzone_aligned_1024->phys_addr, memzone_aligned_1024->len))
return -1;
if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len,
memzone_aligned_256->phys_addr, memzone_aligned_256->len))
return -1;
if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len,
memzone_aligned_512->phys_addr, memzone_aligned_512->len))
return -1;
if (is_memory_overlap(memzone_aligned_128->phys_addr, memzone_aligned_128->len,
memzone_aligned_1024->phys_addr, memzone_aligned_1024->len))
return -1;
if (is_memory_overlap(memzone_aligned_256->phys_addr, memzone_aligned_256->len,
memzone_aligned_512->phys_addr, memzone_aligned_512->len))
return -1;
if (is_memory_overlap(memzone_aligned_256->phys_addr, memzone_aligned_256->len,
memzone_aligned_1024->phys_addr, memzone_aligned_1024->len))
return -1;
if (is_memory_overlap(memzone_aligned_512->phys_addr, memzone_aligned_512->len,
memzone_aligned_1024->phys_addr, memzone_aligned_1024->len))
return -1;
return 0;
}
int
test_memzone(void)
{
const struct rte_memzone *memzone1;
const struct rte_memzone *memzone2;
const struct rte_memzone *memzone3;
const struct rte_memzone *mz;
memzone1 = rte_memzone_lookup("testzone1");
if (memzone1 == NULL)
memzone1 = rte_memzone_reserve("testzone1", 100,
SOCKET_ID_ANY, 0);
memzone2 = rte_memzone_lookup("testzone2");
if (memzone2 == NULL)
memzone2 = rte_memzone_reserve("testzone2", 1000,
0, 0);
memzone3 = rte_memzone_lookup("testzone3");
if (memzone3 == NULL)
memzone3 = rte_memzone_reserve("testzone3", 1000,
1, 0);
/* memzone3 may be NULL if we don't have NUMA */
if (memzone1 == NULL || memzone2 == NULL)
return -1;
rte_memzone_dump();
/* check cache-line alignments */
printf("check alignments and lengths\n");
if ((memzone1->phys_addr & CACHE_LINE_MASK) != 0)
return -1;
if ((memzone2->phys_addr & CACHE_LINE_MASK) != 0)
return -1;
if (memzone3 != NULL && (memzone3->phys_addr & CACHE_LINE_MASK) != 0)
return -1;
if ((memzone1->len & CACHE_LINE_MASK) != 0 || memzone1->len == 0)
return -1;
if ((memzone2->len & CACHE_LINE_MASK) != 0 || memzone2->len == 0)
return -1;
if (memzone3 != NULL && ((memzone3->len & CACHE_LINE_MASK) != 0 ||
memzone3->len == 0))
return -1;
/* check that zones don't overlap */
printf("check overlapping\n");
if (is_memory_overlap(memzone1->phys_addr, memzone1->len,
memzone2->phys_addr, memzone2->len))
return -1;
if (memzone3 != NULL &&
is_memory_overlap(memzone1->phys_addr, memzone1->len,
memzone3->phys_addr, memzone3->len))
return -1;
if (memzone3 != NULL &&
is_memory_overlap(memzone2->phys_addr, memzone2->len,
memzone3->phys_addr, memzone3->len))
return -1;
printf("check socket ID\n");
/* memzone2 must be on socket id 0 and memzone3 on socket 1 */
if (memzone2->socket_id != 0)
return -1;
if (memzone3 != NULL && memzone3->socket_id != 1)
return -1;
printf("test zone lookup\n");
mz = rte_memzone_lookup("testzone1");
if (mz != memzone1)
return -1;
printf("test duplcate zone name\n");
mz = rte_memzone_reserve("testzone1", 100,
SOCKET_ID_ANY, 0);
if (mz != NULL)
return -1;
printf("test reserving memzone with bigger size than the maximum\n");
if (test_memzone_reserving_zone_size_bigger_than_the_maximum() < 0)
return -1;
printf("test reserving the largest size memzone possible\n");
if (test_memzone_reserve_max() < 0)
return -1;
printf("test memzone_reserve flags\n");
if (test_memzone_reserve_flags() < 0)
return -1;
printf("test alignment for memzone_reserve\n");
if (test_memzone_aligned() < 0)
return -1;
printf("test invalid alignment for memzone_reserve\n");
if (test_memzone_invalid_alignment() < 0)
return -1;
printf("test reserving the largest size aligned memzone possible\n");
if (test_memzone_reserve_max_aligned() < 0)
return -1;
return 0;
}

View File

@ -0,0 +1,236 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <cmdline_parse.h>
#include "test.h"
#ifndef RTE_EXEC_ENV_BAREMETAL
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <errno.h>
#include <stdarg.h>
#include <inttypes.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <sys/wait.h>
#include <rte_common.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_launch.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_errno.h>
#include <rte_branch_prediction.h>
#include <rte_atomic.h>
#include <rte_ring.h>
#include <rte_debug.h>
#include <stdarg.h>
#include <rte_log.h>
#include <rte_mempool.h>
#include <rte_hash.h>
#include <rte_fbk_hash.h>
#include <rte_lpm.h>
#include <rte_string_fns.h>
#include "process.h"
#define launch_proc(ARGV) process_dup(ARGV, \
sizeof(ARGV)/(sizeof(ARGV[0])), __func__)
/*
* This function is called in the primary i.e. main test, to spawn off secondary
* processes to run actual mp tests. Uses fork() and exec pair
*/
static int
run_secondary_instances(void)
{
int ret = 0;
char coremask[10];
/* good case, using secondary */
const char *argv1[] = {
prgname, "-c", coremask, "--proc-type=secondary"
};
/* good case, using auto */
const char *argv2[] = {
prgname, "-c", coremask, "--proc-type=auto"
};
/* bad case, using invalid type */
const char *argv3[] = {
prgname, "-c", coremask, "--proc-type=ERROR"
};
/* bad case, using invalid file prefix */
const char *argv4[] = {
prgname, "-c", coremask, "--proc-type=secondary",
"--file-prefix=ERROR"
};
rte_snprintf(coremask, sizeof(coremask), "%x", \
(1 << rte_get_master_lcore()));
ret |= launch_proc(argv1);
ret |= launch_proc(argv2);
ret |= !(launch_proc(argv3));
ret |= !(launch_proc(argv4));
return ret;
}
/*
* This function is run in the secondary instance to test that creation of
* objects fails in a secondary
*/
static int
run_object_creation_tests(void)
{
const unsigned flags = 0;
const unsigned size = 1024;
const unsigned elt_size = 64;
const unsigned cache_size = 64;
const unsigned priv_data_size = 32;
printf("### Testing object creation - expect lots of mz reserve errors!\n");
rte_errno = 0;
if (rte_memzone_reserve("test_mz", size, rte_socket_id(), flags) != NULL
|| rte_errno != E_RTE_SECONDARY){
printf("Error: unexpected return value from rte_memzone_reserve\n");
return -1;
}
printf("# Checked rte_memzone_reserve() OK\n");
rte_errno = 0;
if (rte_ring_create("test_rng", size, rte_socket_id(), flags) != NULL
|| rte_errno != E_RTE_SECONDARY){
printf("Error: unexpected return value from rte_ring_create()\n");
return -1;
}
printf("# Checked rte_ring_create() OK\n");
rte_errno = 0;
if (rte_mempool_create("test_mp", size, elt_size, cache_size,
priv_data_size, NULL, NULL, NULL, NULL,
rte_socket_id(), flags) != NULL
|| rte_errno != E_RTE_SECONDARY){
printf("Error: unexpected return value from rte_ring_create()\n");
return -1;
}
printf("# Checked rte_mempool_create() OK\n");
const struct rte_hash_parameters hash_params = { .name = "test_mp_hash" };
rte_errno=0;
if (rte_hash_create(&hash_params) != NULL
|| rte_errno != E_RTE_SECONDARY){
printf("Error: unexpected return value from rte_ring_create()\n");
return -1;
}
printf("# Checked rte_hash_create() OK\n");
const struct rte_fbk_hash_params fbk_params = { .name = "test_mp_hash" };
rte_errno=0;
if (rte_fbk_hash_create(&fbk_params) != NULL
|| rte_errno != E_RTE_SECONDARY){
printf("Error: unexpected return value from rte_ring_create()\n");
return -1;
}
printf("# Checked rte_fbk_hash_create() OK\n");
rte_errno=0;
if (rte_lpm_create("test_lpm", size, rte_socket_id(), RTE_LPM_HEAP) != NULL
|| rte_errno != E_RTE_SECONDARY){
printf("Error: unexpected return value from rte_ring_create()\n");
return -1;
}
printf("# Checked rte_lpm_create() OK\n");
/* Run a test_pci call */
if (test_pci() != 0) {
printf("PCI scan failed in secondary\n");
if (getuid() == 0) /* pci scans can fail as non-root */
return -1;
} else
printf("PCI scan succeeded in secondary\n");
return 0;
}
/* if called in a primary process, just spawns off a secondary process to
* run validation tests - which brings us right back here again...
* if called in a secondary process, this runs a series of API tests to check
* how things run in a secondary instance.
*/
int
test_mp_secondary(void)
{
if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
if (!test_pci_run) {
printf("=== Running pre-requisite test of test_pci\n");
test_pci();
printf("=== Requisite test done\n");
}
return run_secondary_instances();
}
printf("IN SECONDARY PROCESS\n");
return run_object_creation_tests();
}
#else
/* Baremetal version
* Multiprocess not applicable, so just return 0 always
*/
int
test_mp_secondary(void)
{
printf("Multi-process not applicable for baremetal\n");
return 0;
}
#endif

192
app/test/test_pci.c Normal file
View File

@ -0,0 +1,192 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_interrupts.h>
#include <rte_pci.h>
#include "test.h"
#define RTE_PCI_DEV_ID_DECL(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
#define TEST_BLACKLIST_NUM 0x100
/*
* PCI test
* ========
*
* - Register a driver with a ``devinit()`` function.
*
* - Dump all PCI devices.
*
* - Check that the ``devinit()`` function is called at least once.
*/
int test_pci_run = 0; /* value checked by the multiprocess test */
static unsigned pci_dev_count;
static unsigned driver_registered = 0;
static struct rte_pci_addr blacklist[TEST_BLACKLIST_NUM];
static int my_driver_init(struct rte_pci_driver *dr,
struct rte_pci_device *dev);
/*
* To test cases where RTE_PCI_DRV_NEED_IGB_UIO is set, and isn't set, two
* drivers are created (one with IGB devices, the other with IXGBE devices).
*/
/* IXGBE NICS + e1000 used for Qemu */
#define RTE_LIBRTE_IXGBE_PMD 1
#undef RTE_LIBRTE_IGB_PMD
struct rte_pci_id my_driver_id[] = {
#include <rte_pci_dev_ids.h>
/* this device is the e1000 of qemu for testing */
{RTE_PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x100E)},
{ .vendor_id = 0, /* sentinel */ },
};
struct rte_pci_id my_driver_id2[] = {
/* IGB NICS */
#undef RTE_LIBRTE_IXGBE_PMD
#define RTE_LIBRTE_IGB_PMD 1
#define RTE_PCI_DEV_USE_82575EB_COPPER
#include <rte_pci_dev_ids.h>
{ .vendor_id = 0, /* sentinel */ },
};
struct rte_pci_driver my_driver = {
.name = "test_driver",
.devinit = my_driver_init,
.id_table = my_driver_id,
.drv_flags = RTE_PCI_DRV_NEED_IGB_UIO,
};
struct rte_pci_driver my_driver2 = {
.name = "test_driver2",
.devinit = my_driver_init,
.id_table = my_driver_id2,
.drv_flags = 0,
};
static int
my_driver_init(__attribute__((unused)) struct rte_pci_driver *dr,
struct rte_pci_device *dev)
{
printf("My driver init called in %s\n", dr->name);
printf("%x:%x:%x.%d", dev->addr.domain, dev->addr.bus,
dev->addr.devid, dev->addr.function);
printf(" - vendor:%x device:%x\n", dev->id.vendor_id, dev->id.device_id);
pci_dev_count ++;
return 0;
}
static void
blacklist_clear(void)
{
rte_eal_pci_set_blacklist(NULL, 0);
}
static void
blacklist_all_devices(void)
{
struct rte_pci_device *dev = NULL;
unsigned idx = 0;
memset(blacklist, 0, sizeof (blacklist));
TAILQ_FOREACH(dev, &device_list, next) {
if (idx >= sizeof (blacklist) / sizeof (blacklist[0])) {
printf("Error: too many devices to blacklist");
break;
}
blacklist[idx] = dev->addr;
++idx;
}
rte_eal_pci_set_blacklist(blacklist, idx);
printf("%u devices blacklisted\n", idx);
}
int
test_pci(void)
{
printf("Dump all devices\n");
rte_eal_pci_dump();
if (driver_registered == 0) {
rte_eal_pci_register(&my_driver);
rte_eal_pci_register(&my_driver2);
driver_registered = 1;
}
pci_dev_count = 0;
printf("Scan bus\n");
rte_eal_pci_probe();
if (pci_dev_count == 0) {
printf("no device detected\n");
return -1;
}
blacklist_all_devices();
pci_dev_count = 0;
printf("Scan bus with all devices blacklisted\n");
rte_eal_pci_probe();
blacklist_clear();
if (pci_dev_count != 0) {
printf("not all devices are blacklisted\n");
return -1;
}
test_pci_run = 1;
return 0;
}

142
app/test/test_per_lcore.c Normal file
View File

@ -0,0 +1,142 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_common.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_per_lcore.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_cycles.h>
#include "test.h"
/*
* Per-lcore variables and lcore launch
* ====================================
*
* - Use ``rte_eal_mp_remote_launch()`` to call ``assign_vars()`` on
* every available lcore. In this function, a per-lcore variable is
* assigned to the lcore_id.
*
* - Use ``rte_eal_mp_remote_launch()`` to call ``display_vars()`` on
* every available lcore. The function checks that the variable is
* correctly set, or returns -1.
*
* - If at least one per-core variable was not correct, the test function
* returns -1.
*/
static RTE_DEFINE_PER_LCORE(unsigned, test) = 0x12345678;
static int
assign_vars(__attribute__((unused)) void *arg)
{
if (RTE_PER_LCORE(test) != 0x12345678)
return -1;
RTE_PER_LCORE(test) = rte_lcore_id();
return 0;
}
static int
display_vars(__attribute__((unused)) void *arg)
{
unsigned lcore_id = rte_lcore_id();
unsigned var = RTE_PER_LCORE(test);
unsigned socket_id = rte_lcore_to_socket_id(lcore_id);
printf("on socket %u, on core %u, variable is %u\n", socket_id, lcore_id, var);
if (lcore_id != var)
return -1;
RTE_PER_LCORE(test) = 0x12345678;
return 0;
}
static int
test_per_lcore_delay(__attribute__((unused)) void *arg)
{
rte_delay_ms(5000);
printf("wait 5000ms on lcore %u\n", rte_lcore_id());
return 0;
}
int
test_per_lcore(void)
{
unsigned lcore_id;
int ret;
rte_eal_mp_remote_launch(assign_vars, NULL, SKIP_MASTER);
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0)
return -1;
}
rte_eal_mp_remote_launch(display_vars, NULL, SKIP_MASTER);
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0)
return -1;
}
/* test if it could do remote launch twice at the same time or not */
ret = rte_eal_mp_remote_launch(test_per_lcore_delay, NULL, SKIP_MASTER);
if (ret < 0) {
printf("It fails to do remote launch but it should able to do\n");
return -1;
}
/* it should not be able to launch a lcore which is running */
ret = rte_eal_mp_remote_launch(test_per_lcore_delay, NULL, SKIP_MASTER);
if (ret == 0) {
printf("It does remote launch successfully but it should not at this time\n");
return -1;
}
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (rte_eal_wait_lcore(lcore_id) < 0)
return -1;
}
return 0;
}

63
app/test/test_prefetch.c Normal file
View File

@ -0,0 +1,63 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <cmdline_parse.h>
#include <rte_prefetch.h>
#include "test.h"
/*
* Prefetch test
* =============
*
* - Just test that the macro can be called and validate the compilation.
* The test always return success.
*/
int
test_prefetch(void)
{
int a;
rte_prefetch0(&a);
rte_prefetch1(&a);
rte_prefetch2(&a);
return 0;
}

987
app/test/test_ring.c Normal file
View File

@ -0,0 +1,987 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <string.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <errno.h>
#include <sys/queue.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_cycles.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_branch_prediction.h>
#include <rte_malloc.h>
#include <rte_ring.h>
#include <rte_random.h>
#include <rte_common.h>
#include <rte_errno.h>
#include <cmdline_parse.h>
#include "test.h"
/*
* Ring
* ====
*
* #. Basic tests: done on one core:
*
* - Using single producer/single consumer functions:
*
* - Enqueue one object, two objects, MAX_BULK objects
* - Dequeue one object, two objects, MAX_BULK objects
* - Check that dequeued pointers are correct
*
* - Using multi producers/multi consumers functions:
*
* - Enqueue one object, two objects, MAX_BULK objects
* - Dequeue one object, two objects, MAX_BULK objects
* - Check that dequeued pointers are correct
*
* - Test watermark and default bulk enqueue/dequeue:
*
* - Set watermark
* - Set default bulk value
* - Enqueue objects, check that -EDQUOT is returned when
* watermark is exceeded
* - Check that dequeued pointers are correct
*
* #. Check quota and watermark
*
* - Start a loop on another lcore that will enqueue and dequeue
* objects in a ring. It will monitor the value of quota (default
* bulk count) and watermark.
* - At the same time, change the quota and the watermark on the
* master lcore.
* - The slave lcore will check that bulk count changes from 4 to
* 8, and watermark changes from 16 to 32.
*
* #. Performance tests.
*
* This test is done on the following configurations:
*
* - One core enqueuing, one core dequeuing
* - One core enqueuing, other cores dequeuing
* - One core dequeuing, other cores enqueuing
* - Half of the cores enqueuing, the other half dequeuing
*
* When only one core enqueues/dequeues, the test is done with the
* SP/SC functions in addition to the MP/MC functions.
*
* The test is done with different bulk size.
*
* On each core, the test enqueues or dequeues objects during
* TIME_S seconds. The number of successes and failures are stored on
* each core, then summed and displayed.
*
* The test checks that the number of enqueues is equal to the
* number of dequeues.
*/
#define RING_SIZE 4096
#define MAX_BULK 32
#define N 65536
#define TIME_S 5
static rte_atomic32_t synchro;
static unsigned bulk_enqueue;
static unsigned bulk_dequeue;
static struct rte_ring *r;
struct test_stats {
unsigned enq_success ;
unsigned enq_quota;
unsigned enq_fail;
unsigned deq_success;
unsigned deq_fail;
} __rte_cache_aligned;
static struct test_stats test_stats[RTE_MAX_LCORE];
#define DEFINE_ENQUEUE_FUNCTION(name, enq_code) \
static int \
name(__attribute__((unused)) void *arg) \
{ \
unsigned success = 0; \
unsigned quota = 0; \
unsigned fail = 0; \
unsigned i; \
unsigned long dummy_obj; \
void *obj_table[MAX_BULK]; \
int ret; \
unsigned lcore_id = rte_lcore_id(); \
uint64_t start_cycles, end_cycles; \
uint64_t time_diff = 0, hz = rte_get_hpet_hz(); \
\
/* init dummy object table */ \
for (i = 0; i< MAX_BULK; i++) { \
dummy_obj = lcore_id + 0x1000 + i; \
obj_table[i] = (void *)dummy_obj; \
} \
\
/* wait synchro for slaves */ \
if (lcore_id != rte_get_master_lcore()) \
while (rte_atomic32_read(&synchro) == 0); \
\
start_cycles = rte_get_hpet_cycles(); \
\
/* enqueue as many object as possible */ \
while (time_diff/hz < TIME_S) { \
for (i = 0; likely(i < N); i++) { \
ret = enq_code; \
if (ret == 0) \
success++; \
else if (ret == -EDQUOT) \
quota++; \
else \
fail++; \
} \
end_cycles = rte_get_hpet_cycles(); \
time_diff = end_cycles - start_cycles; \
} \
\
/* write statistics in a shared structure */ \
test_stats[lcore_id].enq_success = success; \
test_stats[lcore_id].enq_quota = quota; \
test_stats[lcore_id].enq_fail = fail; \
\
return 0; \
}
#define DEFINE_DEQUEUE_FUNCTION(name, deq_code) \
static int \
name(__attribute__((unused)) void *arg) \
{ \
unsigned success = 0; \
unsigned fail = 0; \
unsigned i; \
void *obj_table[MAX_BULK]; \
int ret; \
unsigned lcore_id = rte_lcore_id(); \
uint64_t start_cycles, end_cycles; \
uint64_t time_diff = 0, hz = rte_get_hpet_hz(); \
\
/* wait synchro for slaves */ \
if (lcore_id != rte_get_master_lcore()) \
while (rte_atomic32_read(&synchro) == 0); \
\
start_cycles = rte_get_hpet_cycles(); \
\
/* dequeue as many object as possible */ \
while (time_diff/hz < TIME_S) { \
for (i = 0; likely(i < N); i++) { \
ret = deq_code; \
if (ret == 0) \
success++; \
else \
fail++; \
} \
end_cycles = rte_get_hpet_cycles(); \
time_diff = end_cycles - start_cycles; \
} \
\
/* write statistics in a shared structure */ \
test_stats[lcore_id].deq_success = success; \
test_stats[lcore_id].deq_fail = fail; \
\
return 0; \
}
DEFINE_ENQUEUE_FUNCTION(test_ring_per_core_sp_enqueue,
rte_ring_sp_enqueue_bulk(r, obj_table, bulk_enqueue))
DEFINE_DEQUEUE_FUNCTION(test_ring_per_core_sc_dequeue,
rte_ring_sc_dequeue_bulk(r, obj_table, bulk_dequeue))
DEFINE_ENQUEUE_FUNCTION(test_ring_per_core_mp_enqueue,
rte_ring_mp_enqueue_bulk(r, obj_table, bulk_enqueue))
DEFINE_DEQUEUE_FUNCTION(test_ring_per_core_mc_dequeue,
rte_ring_mc_dequeue_bulk(r, obj_table, bulk_dequeue))
#define TEST_RING_VERIFY(exp) \
if (!(exp)) { \
printf("error at %s:%d\tcondition " #exp " failed\n", \
__func__, __LINE__); \
rte_ring_dump(r); \
return (-1); \
}
#define TEST_RING_FULL_EMTPY_ITER 8
static int
launch_cores(unsigned enq_core_count, unsigned deq_core_count, int sp, int sc)
{
void *obj;
unsigned lcore_id;
unsigned rate, deq_remain = 0;
unsigned enq_total, deq_total;
struct test_stats sum;
int (*enq_f)(void *);
int (*deq_f)(void *);
unsigned cores = enq_core_count + deq_core_count;
int ret;
rte_atomic32_set(&synchro, 0);
printf("ring_autotest e/d_core=%u,%u e/d_bulk=%u,%u ",
enq_core_count, deq_core_count, bulk_enqueue, bulk_dequeue);
printf("sp=%d sc=%d ", sp, sc);
/* set enqueue function to be used */
if (sp)
enq_f = test_ring_per_core_sp_enqueue;
else
enq_f = test_ring_per_core_mp_enqueue;
/* set dequeue function to be used */
if (sc)
deq_f = test_ring_per_core_sc_dequeue;
else
deq_f = test_ring_per_core_mc_dequeue;
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (enq_core_count != 0) {
enq_core_count--;
rte_eal_remote_launch(enq_f, NULL, lcore_id);
}
if (deq_core_count != 1) {
deq_core_count--;
rte_eal_remote_launch(deq_f, NULL, lcore_id);
}
}
memset(test_stats, 0, sizeof(test_stats));
/* start synchro and launch test on master */
rte_atomic32_set(&synchro, 1);
ret = deq_f(NULL);
/* wait all cores */
RTE_LCORE_FOREACH_SLAVE(lcore_id) {
if (cores == 1)
break;
cores--;
if (rte_eal_wait_lcore(lcore_id) < 0)
ret = -1;
}
memset(&sum, 0, sizeof(sum));
for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
sum.enq_success += test_stats[lcore_id].enq_success;
sum.enq_quota += test_stats[lcore_id].enq_quota;
sum.enq_fail += test_stats[lcore_id].enq_fail;
sum.deq_success += test_stats[lcore_id].deq_success;
sum.deq_fail += test_stats[lcore_id].deq_fail;
}
/* empty the ring */
while (rte_ring_sc_dequeue(r, &obj) == 0)
deq_remain += 1;
if (ret < 0) {
printf("per-lcore test returned -1\n");
return -1;
}
enq_total = (sum.enq_success * bulk_enqueue) +
(sum.enq_quota * bulk_enqueue);
deq_total = (sum.deq_success * bulk_dequeue) + deq_remain;
rate = deq_total/TIME_S;
printf("rate_persec=%u\n", rate);
if (enq_total != deq_total) {
printf("invalid enq/deq_success counter: %u %u\n",
enq_total, deq_total);
return -1;
}
return 0;
}
static int
do_one_ring_test2(unsigned enq_core_count, unsigned deq_core_count,
unsigned n_enq_bulk, unsigned n_deq_bulk)
{
int sp, sc;
int do_sp, do_sc;
int ret;
bulk_enqueue = n_enq_bulk;
bulk_dequeue = n_deq_bulk;
do_sp = (enq_core_count == 1) ? 1 : 0;
do_sc = (deq_core_count == 1) ? 1 : 0;
for (sp = 0; sp <= do_sp; sp ++) {
for (sc = 0; sc <= do_sc; sc ++) {
ret = launch_cores(enq_core_count,
deq_core_count,
sp, sc);
if (ret < 0)
return -1;
}
}
return 0;
}
static int
do_one_ring_test(unsigned enq_core_count, unsigned deq_core_count)
{
unsigned bulk_enqueue_tab[] = { 1, 2, 4, 32, 0 };
unsigned bulk_dequeue_tab[] = { 1, 2, 4, 32, 0 };
unsigned *bulk_enqueue_ptr;
unsigned *bulk_dequeue_ptr;
int ret;
for (bulk_enqueue_ptr = bulk_enqueue_tab;
*bulk_enqueue_ptr;
bulk_enqueue_ptr++) {
for (bulk_dequeue_ptr = bulk_dequeue_tab;
*bulk_dequeue_ptr;
bulk_dequeue_ptr++) {
ret = do_one_ring_test2(enq_core_count, deq_core_count,
*bulk_enqueue_ptr,
*bulk_dequeue_ptr);
if (ret < 0)
return -1;
}
}
return 0;
}
static int
check_quota_and_watermark(__attribute__((unused)) void *dummy)
{
uint64_t hz = rte_get_hpet_hz();
void *obj_table[MAX_BULK];
unsigned watermark, watermark_old = 16;
uint64_t cur_time, end_time;
int64_t diff = 0;
int i, ret;
unsigned quota, quota_old = 4;
/* init the object table */
memset(obj_table, 0, sizeof(obj_table));
end_time = rte_get_hpet_cycles() + (hz * 2);
/* check that bulk and watermark are 4 and 32 (respectively) */
while (diff >= 0) {
/* read quota, the only change allowed is from 4 to 8 */
quota = rte_ring_get_bulk_count(r);
if (quota != quota_old && (quota_old != 4 || quota != 8)) {
printf("Bad quota change %u -> %u\n", quota_old,
quota);
return -1;
}
quota_old = quota;
/* add in ring until we reach watermark */
ret = 0;
for (i = 0; i < 16; i ++) {
if (ret != 0)
break;
ret = rte_ring_enqueue_bulk(r, obj_table, quota);
}
if (ret != -EDQUOT) {
printf("Cannot enqueue objects, or watermark not "
"reached (ret=%d)\n", ret);
return -1;
}
/* read watermark, the only change allowed is from 16 to 32 */
watermark = i * quota;
if (watermark != watermark_old &&
(watermark_old != 16 || watermark != 32)) {
printf("Bad watermark change %u -> %u\n", watermark_old,
watermark);
return -1;
}
watermark_old = watermark;
/* dequeue objects from ring */
while (i--) {
ret = rte_ring_dequeue_bulk(r, obj_table, quota);
if (ret != 0) {
printf("Cannot dequeue (ret=%d)\n", ret);
return -1;
}
}
cur_time = rte_get_hpet_cycles();
diff = end_time - cur_time;
}
if (watermark_old != 32 || quota_old != 8) {
printf("quota or watermark was not updated (q=%u wm=%u)\n",
quota_old, watermark_old);
return -1;
}
return 0;
}
static int
test_quota_and_watermark(void)
{
unsigned lcore_id = rte_lcore_id();
unsigned lcore_id2 = rte_get_next_lcore(lcore_id, 0, 1);
printf("Test quota and watermark live modification\n");
rte_ring_set_bulk_count(r, 4);
rte_ring_set_water_mark(r, 16);
/* launch a thread that will enqueue and dequeue, checking
* watermark and quota */
rte_eal_remote_launch(check_quota_and_watermark, NULL, lcore_id2);
rte_delay_ms(1000);
rte_ring_set_bulk_count(r, 8);
rte_ring_set_water_mark(r, 32);
rte_delay_ms(1000);
if (rte_eal_wait_lcore(lcore_id2) < 0)
return -1;
return 0;
}
/* Test for catch on invalid watermark values */
static int
test_set_watermark( void ){
unsigned count;
int setwm;
struct rte_ring *r = rte_ring_lookup("test_ring_basic_ex");
if(r == NULL){
printf( " ring lookup failed\n" );
goto error;
}
count = r->prod.size*2;
setwm = rte_ring_set_water_mark(r, count);
if (setwm != -EINVAL){
printf("Test failed to detect invalid watermark count value\n");
goto error;
}
count = 0;
setwm = rte_ring_set_water_mark(r, count);
if (r->prod.watermark != r->prod.size) {
printf("Test failed to detect invalid watermark count value\n");
goto error;
}
return 0;
error:
return -1;
}
/*
* helper routine for test_ring_basic
*/
static int
test_ring_basic_full_empty(void * const src[], void *dst[])
{
unsigned i, rand;
const unsigned rsz = RING_SIZE - 1;
printf("Basic full/empty test\n");
for (i = 0; TEST_RING_FULL_EMTPY_ITER != i; i++) {
/* random shift in the ring */
rand = RTE_MAX(rte_rand() % RING_SIZE, 1UL);
printf("%s: iteration %u, random shift: %u;\n",
__func__, i, rand);
TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
rand));
TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rand));
/* fill the ring */
TEST_RING_VERIFY(-ENOBUFS != rte_ring_enqueue_bulk(r, src,
rsz));
TEST_RING_VERIFY(0 == rte_ring_free_count(r));
TEST_RING_VERIFY(rsz == rte_ring_count(r));
TEST_RING_VERIFY(rte_ring_full(r));
TEST_RING_VERIFY(0 == rte_ring_empty(r));
/* empty the ring */
TEST_RING_VERIFY(0 == rte_ring_dequeue_bulk(r, dst, rsz));
TEST_RING_VERIFY(rsz == rte_ring_free_count(r));
TEST_RING_VERIFY(0 == rte_ring_count(r));
TEST_RING_VERIFY(0 == rte_ring_full(r));
TEST_RING_VERIFY(rte_ring_empty(r));
/* check data */
TEST_RING_VERIFY(0 == memcmp(src, dst, rsz));
rte_ring_dump(r);
}
return (0);
}
static int
test_ring_basic(void)
{
void **src = NULL, **cur_src = NULL, **dst = NULL, **cur_dst = NULL;
int ret;
unsigned i, n;
/* alloc dummy object pointers */
src = malloc(RING_SIZE*2*sizeof(void *));
if (src == NULL)
goto fail;
for (i = 0; i < RING_SIZE*2 ; i++) {
src[i] = (void *)(unsigned long)i;
}
cur_src = src;
/* alloc some room for copied objects */
dst = malloc(RING_SIZE*2*sizeof(void *));
if (dst == NULL)
goto fail;
memset(dst, 0, RING_SIZE*2*sizeof(void *));
cur_dst = dst;
printf("enqueue 1 obj\n");
ret = rte_ring_sp_enqueue_bulk(r, cur_src, 1);
cur_src += 1;
if (ret != 0)
goto fail;
printf("enqueue 2 objs\n");
ret = rte_ring_sp_enqueue_bulk(r, cur_src, 2);
cur_src += 2;
if (ret != 0)
goto fail;
printf("enqueue MAX_BULK objs\n");
ret = rte_ring_sp_enqueue_bulk(r, cur_src, MAX_BULK);
cur_src += MAX_BULK;
if (ret != 0)
goto fail;
printf("dequeue 1 obj\n");
ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 1);
cur_dst += 1;
if (ret != 0)
goto fail;
printf("dequeue 2 objs\n");
ret = rte_ring_sc_dequeue_bulk(r, cur_dst, 2);
cur_dst += 2;
if (ret != 0)
goto fail;
printf("dequeue MAX_BULK objs\n");
ret = rte_ring_sc_dequeue_bulk(r, cur_dst, MAX_BULK);
cur_dst += MAX_BULK;
if (ret != 0)
goto fail;
/* check data */
if (memcmp(src, dst, cur_dst - dst)) {
test_hexdump("src", src, cur_src - src);
test_hexdump("dst", dst, cur_dst - dst);
printf("data after dequeue is not the same\n");
goto fail;
}
cur_src = src;
cur_dst = dst;
printf("enqueue 1 obj\n");
ret = rte_ring_mp_enqueue_bulk(r, cur_src, 1);
cur_src += 1;
if (ret != 0)
goto fail;
printf("enqueue 2 objs\n");
ret = rte_ring_mp_enqueue_bulk(r, cur_src, 2);
cur_src += 2;
if (ret != 0)
goto fail;
printf("enqueue MAX_BULK objs\n");
ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
cur_src += MAX_BULK;
if (ret != 0)
goto fail;
printf("dequeue 1 obj\n");
ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 1);
cur_dst += 1;
if (ret != 0)
goto fail;
printf("dequeue 2 objs\n");
ret = rte_ring_mc_dequeue_bulk(r, cur_dst, 2);
cur_dst += 2;
if (ret != 0)
goto fail;
printf("dequeue MAX_BULK objs\n");
ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
cur_dst += MAX_BULK;
if (ret != 0)
goto fail;
/* check data */
if (memcmp(src, dst, cur_dst - dst)) {
test_hexdump("src", src, cur_src - src);
test_hexdump("dst", dst, cur_dst - dst);
printf("data after dequeue is not the same\n");
goto fail;
}
cur_src = src;
cur_dst = dst;
printf("fill and empty the ring\n");
for (i = 0; i<RING_SIZE/MAX_BULK; i++) {
ret = rte_ring_mp_enqueue_bulk(r, cur_src, MAX_BULK);
cur_src += MAX_BULK;
if (ret != 0)
goto fail;
ret = rte_ring_mc_dequeue_bulk(r, cur_dst, MAX_BULK);
cur_dst += MAX_BULK;
if (ret != 0)
goto fail;
}
/* check data */
if (memcmp(src, dst, cur_dst - dst)) {
test_hexdump("src", src, cur_src - src);
test_hexdump("dst", dst, cur_dst - dst);
printf("data after dequeue is not the same\n");
goto fail;
}
if (test_ring_basic_full_empty(src, dst) != 0)
goto fail;
cur_src = src;
cur_dst = dst;
printf("test watermark and default bulk enqueue / dequeue\n");
rte_ring_set_bulk_count(r, 16);
rte_ring_set_water_mark(r, 20);
n = rte_ring_get_bulk_count(r);
if (n != 16) {
printf("rte_ring_get_bulk_count() returned %u instead "
"of 16\n", n);
goto fail;
}
cur_src = src;
cur_dst = dst;
ret = rte_ring_enqueue_bulk(r, cur_src, n);
cur_src += 16;
if (ret != 0) {
printf("Cannot enqueue\n");
goto fail;
}
ret = rte_ring_enqueue_bulk(r, cur_src, n);
cur_src += 16;
if (ret != -EDQUOT) {
printf("Watermark not exceeded\n");
goto fail;
}
ret = rte_ring_dequeue_bulk(r, cur_dst, n);
cur_dst += 16;
if (ret != 0) {
printf("Cannot dequeue\n");
goto fail;
}
ret = rte_ring_dequeue_bulk(r, cur_dst, n);
cur_dst += 16;
if (ret != 0) {
printf("Cannot dequeue2\n");
goto fail;
}
/* check data */
if (memcmp(src, dst, cur_dst - dst)) {
test_hexdump("src", src, cur_src - src);
test_hexdump("dst", dst, cur_dst - dst);
printf("data after dequeue is not the same\n");
goto fail;
}
cur_src = src;
cur_dst = dst;
if (src)
free(src);
if (dst)
free(dst);
return 0;
fail:
if (src)
free(src);
if (dst)
free(dst);
return -1;
}
/*
* it will always fail to create ring with a wrong ring size number in this function
*/
static int
test_ring_creation_with_wrong_size(void)
{
struct rte_ring * rp = NULL;
rp = rte_ring_create("test_bad_ring_size", RING_SIZE+1, SOCKET_ID_ANY, 0);
if (NULL != rp) {
return -1;
}
return 0;
}
/*
* it tests if it would always fail to create ring with an used ring name
*/
static int
test_ring_creation_with_an_used_name(void)
{
struct rte_ring * rp;
rp = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
if (NULL != rp)
return -1;
return 0;
}
/*
* Test to if a non-power of 2 count causes the create
* function to fail correctly
*/
static int
test_create_count_odd(void)
{
struct rte_ring *r = rte_ring_create("test_ring_count",
4097, SOCKET_ID_ANY, 0 );
if(r != NULL){
return -1;
}
return 0;
}
static int
test_lookup_null(void)
{
struct rte_ring *rlp = rte_ring_lookup("ring_not_found");
if (rlp ==NULL)
if (rte_errno != ENOENT){
printf( "test failed to returnn error on null pointer\n");
return -1;
}
return 0;
}
/*
* it tests some more basic ring operations
*/
static int
test_ring_basic_ex(void)
{
int ret = -1;
unsigned i;
struct rte_ring * rp;
void **obj = NULL;
obj = (void **)rte_zmalloc("test_ring_basic_ex_malloc", (RING_SIZE * sizeof(void *)), 0);
if (obj == NULL) {
printf("test_ring_basic_ex fail to rte_malloc\n");
goto fail_test;
}
rp = rte_ring_create("test_ring_basic_ex", RING_SIZE, SOCKET_ID_ANY, 0);
if (rp == NULL) {
printf("test_ring_basic_ex fail to create ring\n");
goto fail_test;
}
if (rte_ring_lookup("test_ring_basic_ex") != rp) {
goto fail_test;
}
if (rte_ring_empty(rp) != 1) {
printf("test_ring_basic_ex ring is not empty but it should be\n");
goto fail_test;
}
printf("%u ring entries are now free\n", rte_ring_free_count(rp));
for (i = 0; i < RING_SIZE; i ++) {
rte_ring_enqueue(rp, obj[i]);
}
if (rte_ring_full(rp) != 1) {
printf("test_ring_basic_ex ring is not full but it should be\n");
goto fail_test;
}
for (i = 0; i < RING_SIZE; i ++) {
rte_ring_dequeue(rp, &obj[i]);
}
if (rte_ring_empty(rp) != 1) {
printf("test_ring_basic_ex ring is not empty but it should be\n");
goto fail_test;
}
ret = 0;
fail_test:
if (obj != NULL)
rte_free(obj);
return ret;
}
int
test_ring(void)
{
unsigned enq_core_count, deq_core_count;
/* some more basic operations */
if (test_ring_basic_ex() < 0)
return -1;
rte_atomic32_init(&synchro);
if (r == NULL)
r = rte_ring_create("test", RING_SIZE, SOCKET_ID_ANY, 0);
if (r == NULL)
return -1;
/* retrieve the ring from its name */
if (rte_ring_lookup("test") != r) {
printf("Cannot lookup ring from its name\n");
return -1;
}
/* basic operations */
if (test_ring_basic() < 0)
return -1;
/* basic operations */
if (test_quota_and_watermark() < 0)
return -1;
if ( test_set_watermark() < 0){
printf ("Test failed to detect invalid parameter\n");
return -1;
}
else
printf ( "Test detected forced bad watermark values\n");
if ( test_create_count_odd() < 0){
printf ("Test failed to detect odd count\n");
return -1;
}
else
printf ( "Test detected odd count\n");
if ( test_lookup_null() < 0){
printf ("Test failed to detect NULL ring lookup\n");
return -1;
}
else
printf ( "Test detected NULL ring lookup \n");
printf("start performance tests\n");
/* one lcore for enqueue, one for dequeue */
enq_core_count = 1;
deq_core_count = 1;
if (do_one_ring_test(enq_core_count, deq_core_count) < 0)
return -1;
/* max cores for enqueue, one for dequeue */
enq_core_count = rte_lcore_count() - 1;
deq_core_count = 1;
if (do_one_ring_test(enq_core_count, deq_core_count) < 0)
return -1;
/* max cores for dequeue, one for enqueue */
enq_core_count = 1;
deq_core_count = rte_lcore_count() - 1;
if (do_one_ring_test(enq_core_count, deq_core_count) < 0)
return -1;
/* half for enqueue and half for dequeue */
enq_core_count = rte_lcore_count() / 2;
deq_core_count = rte_lcore_count() / 2;
if (do_one_ring_test(enq_core_count, deq_core_count) < 0)
return -1;
/* test of creating ring with wrong size */
if (test_ring_creation_with_wrong_size() < 0)
return -1;
/* test of creation ring with an used name */
if (test_ring_creation_with_an_used_name() < 0)
return -1;
/* dump the ring status */
rte_ring_list_dump();
return 0;
}

135
app/test/test_rwlock.c Normal file
View File

@ -0,0 +1,135 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_common.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_per_lcore.h>
#include <rte_launch.h>
#include <rte_atomic.h>
#include <rte_rwlock.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_cycles.h>
#include "test.h"
/*
* rwlock test
* ===========
*
* - There is a global rwlock and a table of rwlocks (one per lcore).
*
* - The test function takes all of these locks and launches the
* ``test_rwlock_per_core()`` function on each core (except the master).
*
* - The function takes the global write lock, display something,
* then releases the global lock.
* - Then, it takes the per-lcore write lock, display something, and
* releases the per-core lock.
* - Finally, a read lock is taken during 100 ms, then released.
*
* - The main function unlocks the per-lcore locks sequentially and
* waits between each lock. This triggers the display of a message
* for each core, in the correct order.
*
* Then, it tries to take the global write lock and display the last
* message. The autotest script checks that the message order is correct.
*/
static rte_rwlock_t sl;
static rte_rwlock_t sl_tab[RTE_MAX_LCORE];
static int
test_rwlock_per_core(__attribute__((unused)) void *arg)
{
rte_rwlock_write_lock(&sl);
printf("Global write lock taken on core %u\n", rte_lcore_id());
rte_rwlock_write_unlock(&sl);
rte_rwlock_write_lock(&sl_tab[rte_lcore_id()]);
printf("Hello from core %u !\n", rte_lcore_id());
rte_rwlock_write_unlock(&sl_tab[rte_lcore_id()]);
rte_rwlock_read_lock(&sl);
printf("Global read lock taken on core %u\n", rte_lcore_id());
rte_delay_ms(100);
printf("Release global read lock on core %u\n", rte_lcore_id());
rte_rwlock_read_unlock(&sl);
return 0;
}
int
test_rwlock(void)
{
int i;
rte_rwlock_init(&sl);
for (i=0; i<RTE_MAX_LCORE; i++)
rte_rwlock_init(&sl_tab[i]);
rte_rwlock_write_lock(&sl);
RTE_LCORE_FOREACH_SLAVE(i) {
rte_rwlock_write_lock(&sl_tab[i]);
rte_eal_remote_launch(test_rwlock_per_core, NULL, i);
}
rte_rwlock_write_unlock(&sl);
RTE_LCORE_FOREACH_SLAVE(i) {
rte_rwlock_write_unlock(&sl_tab[i]);
rte_delay_ms(100);
}
rte_rwlock_write_lock(&sl);
/* this message should be the last message of test */
printf("Global write lock taken on master core %u\n", rte_lcore_id());
rte_rwlock_write_unlock(&sl);
rte_eal_mp_wait_lcore();
return 0;
}

318
app/test/test_spinlock.c Normal file
View File

@ -0,0 +1,318 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <unistd.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_common.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_per_lcore.h>
#include <rte_launch.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_cycles.h>
#include <rte_spinlock.h>
#include "test.h"
/*
* Spinlock test
* =============
*
* - There is a global spinlock and a table of spinlocks (one per lcore).
*
* - The test function takes all of these locks and launches the
* ``test_spinlock_per_core()`` function on each core (except the master).
*
* - The function takes the global lock, display something, then releases
* the global lock.
* - The function takes the per-lcore lock, display something, then releases
* the per-core lock.
*
* - The main function unlocks the per-lcore locks sequentially and
* waits between each lock. This triggers the display of a message
* for each core, in the correct order. The autotest script checks that
* this order is correct.
*
* - A load test is carried out, with all cores attempting to lock a single lock
* multiple times
*/
static rte_spinlock_t sl, sl_try;
static rte_spinlock_t sl_tab[RTE_MAX_LCORE];
static rte_spinlock_recursive_t slr;
static unsigned count;
static int
test_spinlock_per_core(__attribute__((unused)) void *arg)
{
rte_spinlock_lock(&sl);
printf("Global lock taken on core %u\n", rte_lcore_id());
rte_spinlock_unlock(&sl);
rte_spinlock_lock(&sl_tab[rte_lcore_id()]);
printf("Hello from core %u !\n", rte_lcore_id());
rte_spinlock_unlock(&sl_tab[rte_lcore_id()]);
return 0;
}
static int
test_spinlock_recursive_per_core(__attribute__((unused)) void *arg)
{
unsigned id = rte_lcore_id();
rte_spinlock_recursive_lock(&slr);
printf("Global recursive lock taken on core %u - count = %d\n",
id, slr.count);
rte_spinlock_recursive_lock(&slr);
printf("Global recursive lock taken on core %u - count = %d\n",
id, slr.count);
rte_spinlock_recursive_lock(&slr);
printf("Global recursive lock taken on core %u - count = %d\n",
id, slr.count);
printf("Hello from within recursive locks from core %u !\n", id);
rte_spinlock_recursive_unlock(&slr);
printf("Global recursive lock released on core %u - count = %d\n",
id, slr.count);
rte_spinlock_recursive_unlock(&slr);
printf("Global recursive lock released on core %u - count = %d\n",
id, slr.count);
rte_spinlock_recursive_unlock(&slr);
printf("Global recursive lock released on core %u - count = %d\n",
id, slr.count);
return 0;
}
static volatile int count1, count2;
static rte_spinlock_t lk = RTE_SPINLOCK_INITIALIZER;
static unsigned int max = 10000000; /* 10M */
static volatile uint64_t looptime[RTE_MAX_LCORE];
static int
load_loop_fn(__attribute__((unused)) void *dummy)
{
uint64_t end, begin;
begin = rte_get_hpet_cycles();
unsigned int i = 0;
for ( i = 0; i < max; i++) {
rte_spinlock_lock(&lk);
count1++;
rte_spinlock_unlock(&lk);
count2++;
}
end = rte_get_hpet_cycles();
looptime[rte_lcore_id()] = end - begin;
return 0;
}
static int
test_spinlock_load(void)
{
if (rte_lcore_count()<= 1) {
printf("no cores counted\n");
return -1;
}
printf ("Running %u tests.......\n", max);
printf ("Number of cores = %u\n", rte_lcore_count());
rte_eal_mp_remote_launch(load_loop_fn, NULL , CALL_MASTER);
rte_eal_mp_wait_lcore();
unsigned int k = 0;
uint64_t avgtime = 0;
RTE_LCORE_FOREACH(k) {
printf("Core [%u] time = %"PRIu64"\n", k, looptime[k]);
avgtime += looptime[k];
}
avgtime = avgtime / rte_lcore_count();
printf("Average time = %"PRIu64"\n", avgtime);
int check = 0;
check = max * rte_lcore_count();
if (count1 == check && count2 != check)
printf("Passed Load test\n");
else {
printf("Failed load test\n");
return -1;
}
return 0;
}
/*
* Use rte_spinlock_trylock() to trylock a spinlock object,
* If it could not lock the object sucessfully, it would
* return immediately and the variable of "count" would be
* increased by one per times. the value of "count" could be
* checked as the result later.
*/
static int
test_spinlock_try(__attribute__((unused)) void *arg)
{
if (rte_spinlock_trylock(&sl_try) == 0) {
rte_spinlock_lock(&sl);
count ++;
rte_spinlock_unlock(&sl);
}
return 0;
}
/*
* Test rte_eal_get_lcore_state() in addition to spinlocks
* as we have "waiting" then "running" lcores.
*/
int
test_spinlock(void)
{
int ret = 0;
int i;
/* slave cores should be waiting: print it */
RTE_LCORE_FOREACH_SLAVE(i) {
printf("lcore %d state: %d\n", i,
(int) rte_eal_get_lcore_state(i));
}
rte_spinlock_init(&sl);
rte_spinlock_init(&sl_try);
rte_spinlock_recursive_init(&slr);
for (i=0; i<RTE_MAX_LCORE; i++)
rte_spinlock_init(&sl_tab[i]);
rte_spinlock_lock(&sl);
RTE_LCORE_FOREACH_SLAVE(i) {
rte_spinlock_lock(&sl_tab[i]);
rte_eal_remote_launch(test_spinlock_per_core, NULL, i);
}
/* slave cores should be busy: print it */
RTE_LCORE_FOREACH_SLAVE(i) {
printf("lcore %d state: %d\n", i,
(int) rte_eal_get_lcore_state(i));
}
rte_spinlock_unlock(&sl);
RTE_LCORE_FOREACH_SLAVE(i) {
rte_spinlock_unlock(&sl_tab[i]);
rte_delay_ms(100);
}
rte_eal_mp_wait_lcore();
if (test_spinlock_load()<0)
return -1;
rte_spinlock_recursive_lock(&slr);
/*
* Try to acquire a lock that we already own
*/
if(!rte_spinlock_recursive_trylock(&slr)) {
printf("rte_spinlock_recursive_trylock failed on a lock that "
"we already own\n");
ret = -1;
} else
rte_spinlock_recursive_unlock(&slr);
RTE_LCORE_FOREACH_SLAVE(i) {
rte_eal_remote_launch(test_spinlock_recursive_per_core, NULL, i);
}
rte_spinlock_recursive_unlock(&slr);
rte_eal_mp_wait_lcore();
/*
* Test if it could return immediately from try-locking a locked object.
* Here it will lock the spinlock object first, then launch all the slave
* lcores to trylock the same spinlock object.
* All the slave lcores should give up try-locking a locked object and
* return immediately, and then increase the "count" initialized with zero
* by one per times.
* We can check if the "count" is finally equal to the number of all slave
* lcores to see if the behavior of try-locking a locked spinlock object
* is correct.
*/
if (rte_spinlock_trylock(&sl_try) == 0) {
return -1;
}
count = 0;
RTE_LCORE_FOREACH_SLAVE(i) {
rte_eal_remote_launch(test_spinlock_try, NULL, i);
}
rte_eal_mp_wait_lcore();
rte_spinlock_unlock(&sl_try);
if (rte_spinlock_is_locked(&sl)) {
printf("spinlock is locked but it should not be\n");
return -1;
}
rte_spinlock_lock(&sl);
if (count != ( rte_lcore_count() - 1)) {
ret = -1;
}
rte_spinlock_unlock(&sl);
/*
* Test if it can trylock recursively.
* Use rte_spinlock_recursive_trylock() to check if it can lock a spinlock
* object recursively. Here it will try to lock a spinlock object twice.
*/
if (rte_spinlock_recursive_trylock(&slr) == 0) {
printf("It failed to do the first spinlock_recursive_trylock but it should able to do\n");
return -1;
}
if (rte_spinlock_recursive_trylock(&slr) == 0) {
printf("It failed to do the second spinlock_recursive_trylock but it should able to do\n");
return -1;
}
rte_spinlock_recursive_unlock(&slr);
rte_spinlock_recursive_unlock(&slr);
return ret;
}

305
app/test/test_string_fns.c Normal file
View File

@ -0,0 +1,305 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdarg.h>
#include <stddef.h>
#include <errno.h>
#include <string.h>
#include <rte_string_fns.h>
#include <cmdline_parse.h>
#include "test.h"
#define LOG(...) do {\
fprintf(stderr, "%s() ln %d: ", __func__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
} while(0)
#define DATA_BYTE 'a'
static int
test_rte_snprintf(void)
{
/* =================================================
* First test with a string that will fit in buffer
* =================================================*/
do {
int retval;
const char source[] = "This is a string that will fit in buffer";
char buf[sizeof(source)+2]; /* make buffer big enough to fit string */
/* initialise buffer with characters so it can contain no nulls */
memset(buf, DATA_BYTE, sizeof(buf));
/* run rte_snprintf and check results */
retval = rte_snprintf(buf, sizeof(buf), "%s", source);
if (retval != sizeof(source) - 1) {
LOG("Error, retval = %d, expected = %u\n",
retval, (unsigned)sizeof(source));
return -1;
}
if (buf[retval] != '\0') {
LOG("Error, resultant is not null-terminated\n");
return -1;
}
if (memcmp(source, buf, sizeof(source)-1) != 0){
LOG("Error, corrupt data in buffer\n");
return -1;
}
} while (0);
do {
/* =================================================
* Test with a string that will get truncated
* =================================================*/
int retval;
const char source[] = "This is a long string that won't fit in buffer";
char buf[sizeof(source)/2]; /* make buffer half the size */
/* initialise buffer with characters so it can contain no nulls */
memset(buf, DATA_BYTE, sizeof(buf));
/* run rte_snprintf and check results */
retval = rte_snprintf(buf, sizeof(buf), "%s", source);
if (retval != sizeof(source) - 1) {
LOG("Error, retval = %d, expected = %u\n",
retval, (unsigned)sizeof(source));
return -1;
}
if (buf[sizeof(buf)-1] != '\0') {
LOG("Error, buffer is not null-terminated\n");
return -1;
}
if (memcmp(source, buf, sizeof(buf)-1) != 0){
LOG("Error, corrupt data in buffer\n");
return -1;
}
} while (0);
do {
/* ===========================================================
* Test using zero-size buf to check how long a buffer we need
* ===========================================================*/
int retval;
const char source[] = "This is a string";
char buf[10];
/* call with a zero-sized non-NULL buffer, should tell how big a buffer
* we need */
retval = rte_snprintf(buf, 0, "%s", source);
if (retval != sizeof(source) - 1) {
LOG("Call with 0-length buffer does not return correct size."
"Expected: %zu, got: %d\n", sizeof(source), retval);
return -1;
}
/* call with a zero-sized NULL buffer, should tell how big a buffer
* we need */
retval = rte_snprintf(NULL, 0, "%s", source);
if (retval != sizeof(source) - 1) {
LOG("Call with 0-length buffer does not return correct size."
"Expected: %zu, got: %d\n", sizeof(source), retval);
return -1;
}
} while (0);
do {
/* =================================================
* Test with invalid parameter values
* =================================================*/
const char source[] = "This is a string";
char buf[10];
/* call with buffer value set to NULL is EINVAL */
if (rte_snprintf(NULL, sizeof(buf), "%s\n", source) != -1 ||
errno != EINVAL) {
LOG("Failed to get suitable error when passing NULL buffer\n");
return -1;
}
memset(buf, DATA_BYTE, sizeof(buf));
/* call with a NULL format and zero-size should return error
* without affecting the buffer */
if (rte_snprintf(buf, 0, NULL) != -1 ||
errno != EINVAL) {
LOG("Failed to get suitable error when passing NULL buffer\n");
return -1;
}
if (buf[0] != DATA_BYTE) {
LOG("Error, zero-length buffer modified after call with NULL"
" format string\n");
return -1;
}
/* call with a NULL format should return error but also null-terminate
* the buffer */
if (rte_snprintf(buf, sizeof(buf), NULL) != -1 ||
errno != EINVAL) {
LOG("Failed to get suitable error when passing NULL buffer\n");
return -1;
}
if (buf[0] != '\0') {
LOG("Error, buffer not null-terminated after call with NULL"
" format string\n");
return -1;
}
} while (0);
LOG("%s - PASSED\n", __func__);
return 0;
}
static int
test_rte_strsplit(void)
{
int i;
do {
/* =======================================================
* split a mac address correct number of splits requested
* =======================================================*/
char test_string[] = "54:65:76:87:98:90";
char *splits[6];
LOG("Source string: '%s', to split on ':'\n", test_string);
if (rte_strsplit(test_string, sizeof(test_string),
splits, 6, ':') != 6) {
LOG("Error splitting mac address\n");
return -1;
}
for (i = 0; i < 6; i++)
LOG("Token %d = %s\n", i + 1, splits[i]);
} while (0);
do {
/* =======================================================
* split on spaces smaller number of splits requested
* =======================================================*/
char test_string[] = "54 65 76 87 98 90";
char *splits[6];
LOG("Source string: '%s', to split on ' '\n", test_string);
if (rte_strsplit(test_string, sizeof(test_string),
splits, 3, ' ') != 3) {
LOG("Error splitting mac address for max 2 splits\n");
return -1;
}
for (i = 0; i < 3; i++)
LOG("Token %d = %s\n", i + 1, splits[i]);
} while (0);
do {
/* =======================================================
* split on commas - more splits than commas requested
* =======================================================*/
char test_string[] = "a,b,c,d";
char *splits[6];
LOG("Source string: '%s', to split on ','\n", test_string);
if (rte_strsplit(test_string, sizeof(test_string),
splits, 6, ',') != 4) {
LOG("Error splitting %s on ','\n", test_string);
return -1;
}
for (i = 0; i < 4; i++)
LOG("Token %d = %s\n", i + 1, splits[i]);
} while(0);
do {
/* =======================================================
* Try splitting on non-existent character.
* =======================================================*/
char test_string[] = "a,b,c,d";
char *splits[6];
LOG("Source string: '%s', to split on ' '\n", test_string);
if (rte_strsplit(test_string, sizeof(test_string),
splits, 6, ' ') != 1) {
LOG("Error splitting %s on ' '\n", test_string);
return -1;
}
LOG("String not split\n");
} while(0);
do {
/* =======================================================
* Invalid / edge case parameter checks
* =======================================================*/
char test_string[] = "a,b,c,d";
char *splits[6];
if (rte_strsplit(NULL, 0, splits, 6, ',') >= 0
|| errno != EINVAL){
LOG("Error: rte_strsplit accepted NULL string parameter\n");
return -1;
}
if (rte_strsplit(test_string, sizeof(test_string), NULL, 0, ',') >= 0
|| errno != EINVAL){
LOG("Error: rte_strsplit accepted NULL array parameter\n");
return -1;
}
errno = 0;
if (rte_strsplit(test_string, 0, splits, 6, ',') != 0 || errno != 0) {
LOG("Error: rte_strsplit did not accept 0 length string\n");
return -1;
}
if (rte_strsplit(test_string, sizeof(test_string), splits, 0, ',') != 0
|| errno != 0) {
LOG("Error: rte_strsplit did not accept 0 length array\n");
return -1;
}
LOG("Parameter test cases passed\n");
} while(0);
LOG("%s - PASSED\n", __func__);
return 0;
}
int
test_string_fns(void)
{
if (test_rte_snprintf() < 0 ||
test_rte_strsplit() < 0)
return -1;
return 0;
}

125
app/test/test_tailq.c Normal file
View File

@ -0,0 +1,125 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <errno.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_string_fns.h>
#include <rte_tailq.h>
#include "test.h"
#define do_return(...) do { \
printf("Error at %s, line %d: ", __func__, __LINE__); \
printf(__VA_ARGS__); \
return 1; \
} while (0)
#define DEFAULT_TAILQ "dummy_q0"
static struct rte_dummy d_elem;
static int
test_tailq_create(void)
{
struct rte_dummy_head *d_head;
char name[RTE_TAILQ_NAMESIZE];
unsigned i;
/* create a first tailq and check its non-null */
d_head = RTE_TAILQ_RESERVE(DEFAULT_TAILQ, rte_dummy_head);
if (d_head == NULL)
do_return("Error allocating "DEFAULT_TAILQ"\n");
/* check we can add an item to it
*/
TAILQ_INSERT_TAIL(d_head, &d_elem, next);
/* try allocating dummy_q0 again, and check for failure */
if (RTE_TAILQ_RESERVE(DEFAULT_TAILQ, rte_dummy_head) != NULL)
do_return("Error, non-null result returned when attemption to "
"re-allocate a tailq\n");
/* now fill up the tailq slots available and check we get an error */
for (i = 1; i < RTE_MAX_TAILQ; i++){
rte_snprintf(name, sizeof(name), "dummy_q%u", i);
if ((d_head = RTE_TAILQ_RESERVE(name, rte_dummy_head)) == NULL)
break;
}
/* check that we had an error return before RTE_MAX_TAILQ */
if (i == RTE_MAX_TAILQ)
do_return("Error, we did not have a reservation failure as expected\n");
return 0;
}
static int
test_tailq_lookup(void)
{
/* run successful test - check result is found */
struct rte_dummy_head *d_head;
struct rte_dummy *d_ptr;
d_head = RTE_TAILQ_LOOKUP(DEFAULT_TAILQ, rte_dummy_head);
if (d_head == NULL)
do_return("Error with tailq lookup\n");
TAILQ_FOREACH(d_ptr, d_head, next)
if (d_ptr != &d_elem)
do_return("Error with tailq returned from lookup - "
"expected element not found\n");
/* now try a bad/error lookup */
d_head = RTE_TAILQ_LOOKUP("does_not_exist_queue", rte_dummy_head);
if (d_head != NULL)
do_return("Error, lookup does not return NULL for bad tailq name\n");
return 0;
}
int
test_tailq(void)
{
int ret = 0;
ret |= test_tailq_create();
ret |= test_tailq_lookup();
return ret;
}

363
app/test/test_timer.c Normal file
View File

@ -0,0 +1,363 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
/*
* Timer
* =====
*
* #. Stress tests.
*
* The objective of the timer stress tests is to check that there are no
* race conditions in list and status management. This test launches,
* resets and stops the timer very often on many cores at the same
* time.
*
* - Only one timer is used for this test.
* - On each core, the rte_timer_manage() function is called from the main
* loop every 3 microseconds.
* - In the main loop, the timer may be reset (randomly, with a
* probability of 0.5 %) 100 microseconds later on a random core, or
* stopped (with a probability of 0.5 % also).
* - In callback, the timer is can be reset (randomly, with a
* probability of 0.5 %) 100 microseconds later on the same core or
* on another core (same probability), or stopped (same
* probability).
*
*
* #. Basic test.
*
* This test performs basic functional checks of the timers. The test
* uses four different timers that are loaded and stopped under
* specific conditions in specific contexts.
*
* - Four timers are used for this test.
* - On each core, the rte_timer_manage() function is called from main loop
* every 3 microseconds.
*
* The autotest python script checks that the behavior is correct:
*
* - timer0
*
* - At initialization, timer0 is loaded by the master core, on master core
* in "single" mode (time = 1 second).
* - In the first 19 callbacks, timer0 is reloaded on the same core,
* then, it is explicitly stopped at the 20th call.
* - At t=25s, timer0 is reloaded once by timer2.
*
* - timer1
*
* - At initialization, timer1 is loaded by the master core, on the
* master core in "single" mode (time = 2 seconds).
* - In the first 9 callbacks, timer1 is reloaded on another
* core. After the 10th callback, timer1 is not reloaded anymore.
*
* - timer2
*
* - At initialization, timer2 is loaded by the master core, on the
* master core in "periodical" mode (time = 1 second).
* - In the callback, when t=25s, it stops timer3 and reloads timer0
* on the current core.
*
* - timer3
*
* - At initialization, timer3 is loaded by the master core, on
* another core in "periodical" mode (time = 1 second).
* - It is stopped at t=25s by timer2.
*/
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <sys/queue.h>
#include <cmdline_parse.h>
#include <rte_common.h>
#include <rte_log.h>
#include <rte_memory.h>
#include <rte_memzone.h>
#include <rte_launch.h>
#include <rte_cycles.h>
#include <rte_tailq.h>
#include <rte_eal.h>
#include <rte_per_lcore.h>
#include <rte_lcore.h>
#include <rte_atomic.h>
#include <rte_timer.h>
#include <rte_random.h>
#include "test.h"
#define TEST_DURATION_S 30 /* in seconds */
#define NB_TIMER 4
#define RTE_LOGTYPE_TESTTIMER RTE_LOGTYPE_USER3
static volatile uint64_t end_time;
struct mytimerinfo {
struct rte_timer tim;
unsigned id;
unsigned count;
};
static struct mytimerinfo mytiminfo[NB_TIMER];
static void timer_basic_cb(struct rte_timer *tim, void *arg);
static void
mytimer_reset(struct mytimerinfo *timinfo, unsigned ticks,
enum rte_timer_type type, unsigned tim_lcore,
rte_timer_cb_t fct)
{
rte_timer_reset_sync(&timinfo->tim, ticks, type, tim_lcore,
fct, timinfo);
}
/* timer callback for stress tests */
static void
timer_stress_cb(__attribute__((unused)) struct rte_timer *tim,
__attribute__((unused)) void *arg)
{
long r;
unsigned lcore_id = rte_lcore_id();
uint64_t hz = rte_get_hpet_hz();
if (rte_timer_pending(tim))
return;
r = rte_rand();
if ((r & 0xff) == 0) {
mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id,
timer_stress_cb);
}
else if ((r & 0xff) == 1) {
mytimer_reset(&mytiminfo[0], hz, SINGLE,
rte_get_next_lcore(lcore_id, 0, 1),
timer_stress_cb);
}
else if ((r & 0xff) == 2) {
rte_timer_stop(&mytiminfo[0].tim);
}
}
static int
timer_stress_main_loop(__attribute__((unused)) void *arg)
{
uint64_t hz = rte_get_hpet_hz();
unsigned lcore_id = rte_lcore_id();
uint64_t cur_time;
int64_t diff = 0;
long r;
while (diff >= 0) {
/* call the timer handler on each core */
rte_timer_manage();
/* simulate the processing of a packet
* (3 us = 6000 cycles at 2 Ghz) */
rte_delay_us(3);
/* randomly stop or reset timer */
r = rte_rand();
lcore_id = rte_get_next_lcore(lcore_id, 0, 1);
if ((r & 0xff) == 0) {
/* 100 us */
mytimer_reset(&mytiminfo[0], hz/10000, SINGLE, lcore_id,
timer_stress_cb);
}
else if ((r & 0xff) == 1) {
rte_timer_stop_sync(&mytiminfo[0].tim);
}
cur_time = rte_get_hpet_cycles();
diff = end_time - cur_time;
}
lcore_id = rte_lcore_id();
RTE_LOG(INFO, TESTTIMER, "core %u finished\n", lcore_id);
return 0;
}
/* timer callback for basic tests */
static void
timer_basic_cb(struct rte_timer *tim, void *arg)
{
struct mytimerinfo *timinfo = arg;
uint64_t hz = rte_get_hpet_hz();
unsigned lcore_id = rte_lcore_id();
uint64_t cur_time = rte_get_hpet_cycles();
if (rte_timer_pending(tim))
return;
timinfo->count ++;
RTE_LOG(INFO, TESTTIMER,
"%"PRIu64": callback id=%u count=%u on core %u\n",
cur_time, timinfo->id, timinfo->count, lcore_id);
/* reload timer 0 on same core */
if (timinfo->id == 0 && timinfo->count < 20) {
mytimer_reset(timinfo, hz, SINGLE, lcore_id, timer_basic_cb);
return;
}
/* reload timer 1 on next core */
if (timinfo->id == 1 && timinfo->count < 10) {
mytimer_reset(timinfo, hz*2, SINGLE,
rte_get_next_lcore(lcore_id, 0, 1),
timer_basic_cb);
return;
}
/* Explicitelly stop timer 0. Once stop() called, we can even
* erase the content of the structure: it is not referenced
* anymore by any code (in case of dynamic structure, it can
* be freed) */
if (timinfo->id == 0 && timinfo->count == 20) {
/* stop_sync() is not needed, because we know that the
* status of timer is only modified by this core */
rte_timer_stop(tim);
memset(tim, 0xAA, sizeof(struct rte_timer));
return;
}
/* stop timer3, and restart a new timer0 (it was removed 5
* seconds ago) for a single shot */
if (timinfo->id == 2 && timinfo->count == 25) {
rte_timer_stop_sync(&mytiminfo[3].tim);
/* need to reinit because structure was erased with 0xAA */
rte_timer_init(&mytiminfo[0].tim);
mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id,
timer_basic_cb);
}
}
static int
timer_basic_main_loop(__attribute__((unused)) void *arg)
{
uint64_t hz = rte_get_hpet_hz();
unsigned lcore_id = rte_lcore_id();
uint64_t cur_time;
int64_t diff = 0;
/* launch all timers on core 0 */
if (lcore_id == rte_get_master_lcore()) {
mytimer_reset(&mytiminfo[0], hz, SINGLE, lcore_id,
timer_basic_cb);
mytimer_reset(&mytiminfo[1], hz*2, SINGLE, lcore_id,
timer_basic_cb);
mytimer_reset(&mytiminfo[2], hz, PERIODICAL, lcore_id,
timer_basic_cb);
mytimer_reset(&mytiminfo[3], hz, PERIODICAL,
rte_get_next_lcore(lcore_id, 0, 1),
timer_basic_cb);
}
while (diff >= 0) {
/* call the timer handler on each core */
rte_timer_manage();
/* simulate the processing of a packet
* (3 us = 6000 cycles at 2 Ghz) */
rte_delay_us(3);
cur_time = rte_get_hpet_cycles();
diff = end_time - cur_time;
}
RTE_LOG(INFO, TESTTIMER, "core %u finished\n", lcore_id);
return 0;
}
int
test_timer(void)
{
unsigned i;
uint64_t cur_time;
uint64_t hz;
if (rte_lcore_count() < 2) {
printf("not enough lcores for this test\n");
return -1;
}
/* init timer */
for (i=0; i<NB_TIMER; i++) {
memset(&mytiminfo[i], 0, sizeof(struct mytimerinfo));
mytiminfo[i].id = i;
rte_timer_init(&mytiminfo[i].tim);
}
/* calculate the "end of test" time */
cur_time = rte_get_hpet_cycles();
hz = rte_get_hpet_hz();
end_time = cur_time + (hz * TEST_DURATION_S);
/* start other cores */
printf("Start timer stress tests (%d seconds)\n", TEST_DURATION_S);
rte_eal_mp_remote_launch(timer_stress_main_loop, NULL, CALL_MASTER);
rte_eal_mp_wait_lcore();
/* stop timer 0 used for stress test */
rte_timer_stop_sync(&mytiminfo[0].tim);
/* calculate the "end of test" time */
cur_time = rte_get_hpet_cycles();
hz = rte_get_hpet_hz();
end_time = cur_time + (hz * TEST_DURATION_S);
/* start other cores */
printf("Start timer basic tests (%d seconds)\n", TEST_DURATION_S);
rte_eal_mp_remote_launch(timer_basic_main_loop, NULL, CALL_MASTER);
rte_eal_mp_wait_lcore();
/* stop all timers */
for (i=0; i<NB_TIMER; i++) {
rte_timer_stop_sync(&mytiminfo[i].tim);
}
rte_timer_dump_stats();
return 0;
}

59
app/test/test_version.c Normal file
View File

@ -0,0 +1,59 @@
/*-
* BSD LICENSE
*
* Copyright(c) 2010-2012 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.
*
* version: DPDK.L.1.2.3-3
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <cmdline_parse.h>
#include <rte_common.h>
#include <rte_version.h>
#include "test.h"
int
test_version(void)
{
const char *version = rte_version();
if (version == NULL)
return -1;
printf("Version string: '%s'\n", version);
if (*version == '\0' ||
strncmp(version, RTE_VER_PREFIX, sizeof(RTE_VER_PREFIX)-1) != 0)
return -1;
return 0;
}

Some files were not shown because too many files have changed in this diff Show More