first public release
version 1.2.3 Signed-off-by: Intel
This commit is contained in:
parent
0c9a540ed2
commit
af75078fec
47
Makefile
Normal file
47
Makefile
Normal 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
42
app/Makefile
Normal 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
96
app/chkincs/Makefile
Normal 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
50
app/chkincs/test.c
Normal 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
90
app/chkincs/test.h
Normal 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
53
app/chkincs/test_alarm.c
Normal 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
93
app/chkincs/test_atomic.c
Normal 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;
|
||||||
|
}
|
||||||
|
|
58
app/chkincs/test_branch_prediction.c
Normal file
58
app/chkincs/test_branch_prediction.c
Normal 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;
|
||||||
|
}
|
84
app/chkincs/test_byteorder.c
Normal file
84
app/chkincs/test_byteorder.c
Normal 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
76
app/chkincs/test_common.c
Normal 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);
|
||||||
|
}
|
53
app/chkincs/test_cpuflags.c
Normal file
53
app/chkincs/test_cpuflags.c
Normal 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
63
app/chkincs/test_cycles.c
Normal 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
55
app/chkincs/test_debug.c
Normal 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
52
app/chkincs/test_eal.c
Normal 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
54
app/chkincs/test_errno.c
Normal 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
72
app/chkincs/test_ethdev.c
Normal 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
52
app/chkincs/test_ether.c
Normal 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;
|
||||||
|
}
|
53
app/chkincs/test_fbk_hash.c
Normal file
53
app/chkincs/test_fbk_hash.c
Normal 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
85
app/chkincs/test_hash.c
Normal 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;
|
||||||
|
}
|
52
app/chkincs/test_hash_crc.c
Normal file
52
app/chkincs/test_hash_crc.c
Normal 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;
|
||||||
|
}
|
53
app/chkincs/test_interrupts.c
Normal file
53
app/chkincs/test_interrupts.c
Normal 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
53
app/chkincs/test_ip.c
Normal 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
54
app/chkincs/test_jhash.c
Normal 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
68
app/chkincs/test_launch.c
Normal 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
66
app/chkincs/test_lcore.c
Normal 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
58
app/chkincs/test_log.c
Normal 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
64
app/chkincs/test_lpm.c
Normal 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
57
app/chkincs/test_malloc.c
Normal 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
110
app/chkincs/test_mbuf.c
Normal 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
58
app/chkincs/test_memcpy.c
Normal 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
65
app/chkincs/test_memory.c
Normal 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
111
app/chkincs/test_mempool.c
Normal 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;
|
||||||
|
}
|
61
app/chkincs/test_memzone.c
Normal file
61
app/chkincs/test_memzone.c
Normal 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
86
app/chkincs/test_pci.c
Normal 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;
|
||||||
|
}
|
60
app/chkincs/test_pci_dev_ids.c
Normal file
60
app/chkincs/test_pci_dev_ids.c
Normal 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;
|
||||||
|
}
|
57
app/chkincs/test_per_lcore.c
Normal file
57
app/chkincs/test_per_lcore.c
Normal 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;
|
||||||
|
}
|
58
app/chkincs/test_prefetch.c
Normal file
58
app/chkincs/test_prefetch.c
Normal 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
54
app/chkincs/test_random.c
Normal 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
97
app/chkincs/test_ring.c
Normal 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
60
app/chkincs/test_rwlock.c
Normal 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
52
app/chkincs/test_sctp.c
Normal 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;
|
||||||
|
}
|
59
app/chkincs/test_spinlock.c
Normal file
59
app/chkincs/test_spinlock.c
Normal 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;
|
||||||
|
}
|
52
app/chkincs/test_string_fns.c
Normal file
52
app/chkincs/test_string_fns.c
Normal 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
55
app/chkincs/test_tailq.c
Normal 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
52
app/chkincs/test_tcp.c
Normal 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
74
app/chkincs/test_timer.c
Normal 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
52
app/chkincs/test_udp.c
Normal 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;
|
||||||
|
}
|
52
app/chkincs/test_version.c
Normal file
52
app/chkincs/test_version.c
Normal 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
49
app/dump_cfg/Makefile
Normal 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
|
229
app/dump_cfg/dump_cfg_main.c
Normal file
229
app/dump_cfg/dump_cfg_main.c
Normal 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
63
app/test-pmd/Makefile
Normal 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
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
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
449
app/test-pmd/csumonly.c
Normal 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
657
app/test-pmd/ieee1588fwd.c
Normal 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
131
app/test-pmd/iofwd.c
Normal 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
148
app/test-pmd/macfwd.c
Normal 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],
|
||||||
|
ð_hdr->d_addr);
|
||||||
|
ether_addr_copy(&ports[fs->tx_port].eth_addr,
|
||||||
|
ð_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
646
app/test-pmd/parameters.c
Normal 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
194
app/test-pmd/rxonly.c
Normal 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=", ð_hdr->s_addr);
|
||||||
|
print_ether_addr(" - dst=", ð_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
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
413
app/test-pmd/testpmd.h
Normal 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
317
app/test-pmd/txonly.c
Normal 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],ð_hdr.d_addr);
|
||||||
|
ether_addr_copy(&ports[fs->tx_port].eth_addr, ð_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(ð_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
82
app/test/Makefile
Normal 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
664
app/test/autotest.py
Executable 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
391
app/test/commands.c
Normal 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
193
app/test/graph_mempool.py
Executable 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
201
app/test/graph_ring.py
Executable 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
89
app/test/process.h
Normal 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
153
app/test/test.c
Normal 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
85
app/test/test.h
Normal 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
258
app/test/test_alarm.c
Normal 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
381
app/test/test_atomic.c
Normal 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
97
app/test/test_byteorder.c
Normal 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
134
app/test/test_cpuflags.c
Normal 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
94
app/test/test_cycles.c
Normal 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
150
app/test/test_debug.c
Normal 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
303
app/test/test_eal_flags.c
Normal 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
110
app/test/test_errno.c
Normal 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
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
419
app/test/test_interrupts.c
Normal 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
96
app/test/test_logs.c
Normal 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
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
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
776
app/test/test_malloc.c
Normal 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
875
app/test/test_mbuf.c
Normal 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
429
app/test/test_memcpy.c
Normal 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
92
app/test/test_memory.c
Normal 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
707
app/test/test_mempool.c
Normal 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
639
app/test/test_memzone.c
Normal 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;
|
||||||
|
}
|
236
app/test/test_mp_secondary.c
Normal file
236
app/test/test_mp_secondary.c
Normal 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
192
app/test/test_pci.c
Normal 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
142
app/test/test_per_lcore.c
Normal 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
63
app/test/test_prefetch.c
Normal 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
987
app/test/test_ring.c
Normal 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
135
app/test/test_rwlock.c
Normal 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
318
app/test/test_spinlock.c
Normal 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
305
app/test/test_string_fns.c
Normal 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
125
app/test/test_tailq.c
Normal 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
363
app/test/test_timer.c
Normal 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
59
app/test/test_version.c
Normal 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
Loading…
Reference in New Issue
Block a user