X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest%2Ftest_kni.c;h=e47ab36e0231890a80063c2c0537a0b96b91ad91;hb=c3a90c381daa68a0ea65906ad15bc96c247ac5cd;hp=506b543a68792e8acc701f4d97644e0434cb34de;hpb=ea0c20ea95fd5d71a10757e6598ac66233ea1495;p=dpdk.git diff --git a/app/test/test_kni.c b/app/test/test_kni.c index 506b543a68..e47ab36e02 100644 --- a/app/test/test_kni.c +++ b/app/test/test_kni.c @@ -1,34 +1,5 @@ -/*- - * BSD LICENSE - * - * Copyright(c) 2010-2014 Intel Corporation. All rights reserved. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Intel Corporation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2010-2014 Intel Corporation */ #include @@ -36,12 +7,25 @@ #include #include #include +#include #include "test.h" +#if !defined(RTE_EXEC_ENV_LINUX) || !defined(RTE_LIBRTE_KNI) + +static int +test_kni(void) +{ + printf("KNI not supported, skipping test\n"); + return TEST_SKIPPED; +} + +#else + #include #include #include +#include #include #include @@ -51,12 +35,14 @@ #define PKT_BURST_SZ 32 #define MEMPOOL_CACHE_SZ PKT_BURST_SZ #define SOCKET 0 -#define NB_RXD 128 -#define NB_TXD 512 +#define NB_RXD 1024 +#define NB_TXD 1024 #define KNI_TIMEOUT_MS 5000 /* ms */ #define IFCONFIG "/sbin/ifconfig " #define TEST_KNI_PORT "test_kni_port" +#define KNI_MODULE_PATH "/sys/module/rte_kni" +#define KNI_MODULE_PARAM_LO KNI_MODULE_PATH"/parameters/lo_mode" #define KNI_TEST_MAX_PORTS 4 /* The threshold number of mbufs to be transmitted or received. */ #define KNI_NUM_MBUF_THRESHOLD 100 @@ -87,13 +73,6 @@ static const struct rte_eth_txconf tx_conf = { }; static const struct rte_eth_conf port_conf = { - .rxmode = { - .header_split = 0, - .hw_ip_checksum = 0, - .hw_vlan_filter = 0, - .jumbo_frame = 0, - .hw_strip_crc = 0, - }, .txmode = { .mq_mode = ETH_DCB_NONE, }, @@ -102,6 +81,8 @@ static const struct rte_eth_conf port_conf = { static struct rte_kni_ops kni_ops = { .change_mtu = NULL, .config_network_if = NULL, + .config_mac_address = NULL, + .config_promiscusity = NULL, }; static unsigned lcore_master, lcore_ingress, lcore_egress; @@ -132,7 +113,7 @@ test_kni_lookup_mempool(void) } /* Callback for request of changing MTU */ static int -kni_change_mtu(uint8_t port_id, unsigned new_mtu) +kni_change_mtu(uint16_t port_id, unsigned int new_mtu) { printf("Change MTU of port %d to %u\n", port_id, new_mtu); kni_pkt_mtu = new_mtu; @@ -140,6 +121,79 @@ kni_change_mtu(uint8_t port_id, unsigned new_mtu) port_id, kni_pkt_mtu); return 0; } + +static int +test_kni_link_change(void) +{ + int ret; + int pid; + + pid = fork(); + if (pid < 0) { + printf("Error: Failed to fork a process\n"); + return -1; + } + + if (pid == 0) { + printf("Starting KNI Link status change tests.\n"); + if (system(IFCONFIG TEST_KNI_PORT" up") == -1) { + ret = -1; + goto error; + } + + ret = rte_kni_update_link(test_kni_ctx, 1); + if (ret < 0) { + printf("Failed to change link state to Up ret=%d.\n", + ret); + goto error; + } + rte_delay_ms(1000); + printf("KNI: Set LINKUP, previous state=%d\n", ret); + + ret = rte_kni_update_link(test_kni_ctx, 0); + if (ret != 1) { + printf( + "Failed! Previous link state should be 1, returned %d.\n", + ret); + goto error; + } + rte_delay_ms(1000); + printf("KNI: Set LINKDOWN, previous state=%d\n", ret); + + ret = rte_kni_update_link(test_kni_ctx, 1); + if (ret != 0) { + printf( + "Failed! Previous link state should be 0, returned %d.\n", + ret); + goto error; + } + printf("KNI: Set LINKUP, previous state=%d\n", ret); + + ret = 0; + rte_delay_ms(1000); + +error: + if (system(IFCONFIG TEST_KNI_PORT" down") == -1) + ret = -1; + + printf("KNI: Link status change tests: %s.\n", + (ret == 0) ? "Passed" : "Failed"); + exit(ret); + } else { + int p_ret, status; + + while (1) { + p_ret = waitpid(pid, &status, WNOHANG); + if (p_ret != 0) { + if (WIFEXITED(status)) + return WEXITSTATUS(status); + return -1; + } + rte_delay_ms(10); + rte_kni_handle_request(test_kni_ctx); + } + } +} /** * This loop fully tests the basic functions of KNI. e.g. transmitting, * receiving to, from kernel space, and kernel requests. @@ -237,7 +291,7 @@ test_kni_allocate_lcores(void) } printf("count: %u\n", count); - return (count == 2 ? 0 : -1); + return count == 2 ? 0 : -1; } static int @@ -259,6 +313,8 @@ test_kni_register_handler_mp(void) struct rte_kni_ops ops = { .change_mtu = kni_change_mtu, .config_network_if = NULL, + .config_mac_address = NULL, + .config_promiscusity = NULL, }; if (!kni) { @@ -362,7 +418,7 @@ test_kni_register_handler_mp(void) } static int -test_kni_processing(uint8_t port_id, struct rte_mempool *mp) +test_kni_processing(uint16_t port_id, struct rte_mempool *mp) { int ret = 0; unsigned i; @@ -370,6 +426,8 @@ test_kni_processing(uint8_t port_id, struct rte_mempool *mp) struct rte_kni_conf conf; struct rte_eth_dev_info info; struct rte_kni_ops ops; + const struct rte_pci_device *pci_dev; + const struct rte_bus *bus = NULL; if (!mp) return -1; @@ -378,16 +436,27 @@ test_kni_processing(uint8_t port_id, struct rte_mempool *mp) memset(&info, 0, sizeof(info)); memset(&ops, 0, sizeof(ops)); - rte_eth_dev_info_get(port_id, &info); - conf.addr = info.pci_dev->addr; - conf.id = info.pci_dev->id; + ret = rte_eth_dev_info_get(port_id, &info); + if (ret != 0) { + printf("Error during getting device (port %u) info: %s\n", + port_id, strerror(-ret)); + return -1; + } + + if (info.device) + bus = rte_bus_find_by_device(info.device); + if (bus && !strcmp(bus->name, "pci")) { + pci_dev = RTE_DEV_TO_PCI(info.device); + conf.addr = pci_dev->addr; + conf.id = pci_dev->id; + } snprintf(conf.name, sizeof(conf.name), TEST_KNI_PORT); /* core id 1 configured for kernel thread */ conf.core_id = 1; conf.force_bind = 1; conf.mbuf_size = MAX_PACKET_SZ; - conf.group_id = (uint16_t)port_id; + conf.group_id = port_id; ops = kni_ops; ops.port_id = port_id; @@ -398,17 +467,6 @@ test_kni_processing(uint8_t port_id, struct rte_mempool *mp) printf("fail to create kni\n"); return -1; } - if (rte_kni_get_port_id(kni) != port_id) { - printf("fail to get port id\n"); - ret = -1; - goto fail_kni; - } - - if (rte_kni_info_get(RTE_MAX_ETHPORTS)) { - printf("Unexpectedly get a KNI successfully\n"); - ret = -1; - goto fail_kni; - } test_kni_ctx = kni; test_kni_processing_flag = 0; @@ -425,6 +483,10 @@ test_kni_processing(uint8_t port_id, struct rte_mempool *mp) goto fail_kni; } + ret = test_kni_link_change(); + if (ret != 0) + goto fail_kni; + rte_eal_mp_remote_launch(test_kni_loop, NULL, CALL_MASTER); RTE_LCORE_FOREACH_SLAVE(i) { if (rte_eal_wait_lcore(i) < 0) { @@ -450,12 +512,6 @@ test_kni_processing(uint8_t port_id, struct rte_mempool *mp) } test_kni_ctx = NULL; - /* test of releasing a released kni device */ - if (rte_kni_release(kni) == 0) { - printf("should not release a released kni device\n"); - return -1; - } - /* test of reusing memzone */ kni = rte_kni_alloc(mp, &conf, &ops); if (!kni) { @@ -483,12 +539,28 @@ static int test_kni(void) { int ret = -1; - uint8_t nb_ports, port_id; + uint16_t port_id; struct rte_kni *kni; struct rte_mempool *mp; struct rte_kni_conf conf; struct rte_eth_dev_info info; struct rte_kni_ops ops; + const struct rte_pci_device *pci_dev; + const struct rte_bus *bus; + FILE *fd; + DIR *dir; + char buf[16]; + + dir = opendir(KNI_MODULE_PATH); + if (!dir) { + if (errno == ENOENT) { + printf("Cannot run UT due to missing rte_kni module\n"); + return TEST_SKIPPED; + } + printf("opendir: %s", strerror(errno)); + return -1; + } + closedir(dir); /* Initialize KNI subsytem */ rte_kni_init(KNI_TEST_MAX_PORTS); @@ -504,12 +576,6 @@ test_kni(void) return -1; } - nb_ports = rte_eth_dev_count(); - if (nb_ports == 0) { - printf("no supported nic port found\n"); - return -1; - } - /* configuring port 0 for the test is enough */ port_id = 0; ret = rte_eth_dev_configure(port_id, 1, 1, &port_conf); @@ -535,21 +601,56 @@ test_kni(void) printf("fail to start port %d\n", port_id); return -1; } - rte_eth_promiscuous_enable(port_id); + ret = rte_eth_promiscuous_enable(port_id); + if (ret != 0) { + printf("fail to enable promiscuous mode for port %d: %s\n", + port_id, rte_strerror(-ret)); + return -1; + } /* basic test of kni processing */ - ret = test_kni_processing(port_id, mp); - if (ret < 0) - goto fail; + fd = fopen(KNI_MODULE_PARAM_LO, "r"); + if (fd == NULL) { + printf("fopen: %s", strerror(errno)); + return -1; + } + memset(&buf, 0, sizeof(buf)); + if (fgets(buf, sizeof(buf), fd)) { + if (!strncmp(buf, "lo_mode_fifo", strlen("lo_mode_fifo")) || + !strncmp(buf, "lo_mode_fifo_skb", + strlen("lo_mode_fifo_skb"))) { + ret = test_kni_processing(port_id, mp); + if (ret < 0) { + fclose(fd); + goto fail; + } + } else + printf("test_kni_processing skipped because of missing rte_kni module lo_mode argument\n"); + } + fclose(fd); /* test of allocating KNI with NULL mempool pointer */ memset(&info, 0, sizeof(info)); memset(&conf, 0, sizeof(conf)); memset(&ops, 0, sizeof(ops)); - rte_eth_dev_info_get(port_id, &info); - conf.addr = info.pci_dev->addr; - conf.id = info.pci_dev->id; - conf.group_id = (uint16_t)port_id; + + ret = rte_eth_dev_info_get(port_id, &info); + if (ret != 0) { + printf("Error during getting device (port %u) info: %s\n", + port_id, strerror(-ret)); + return -1; + } + + if (info.device) + bus = rte_bus_find_by_device(info.device); + else + bus = NULL; + if (bus && !strcmp(bus->name, "pci")) { + pci_dev = RTE_DEV_TO_PCI(info.device); + conf.addr = pci_dev->addr; + conf.id = pci_dev->id; + } + conf.group_id = port_id; conf.mbuf_size = MAX_PACKET_SZ; ops = kni_ops; @@ -575,10 +676,25 @@ test_kni(void) memset(&conf, 0, sizeof(conf)); memset(&info, 0, sizeof(info)); memset(&ops, 0, sizeof(ops)); - rte_eth_dev_info_get(port_id, &info); - conf.addr = info.pci_dev->addr; - conf.id = info.pci_dev->id; - conf.group_id = (uint16_t)port_id; + + ret = rte_eth_dev_info_get(port_id, &info); + if (ret != 0) { + printf("Error during getting device (port %u) info: %s\n", + port_id, strerror(-ret)); + ret = -1; + goto fail; + } + + if (info.device) + bus = rte_bus_find_by_device(info.device); + else + bus = NULL; + if (bus && !strcmp(bus->name, "pci")) { + pci_dev = RTE_DEV_TO_PCI(info.device); + conf.addr = pci_dev->addr; + conf.id = pci_dev->id; + } + conf.group_id = port_id; conf.mbuf_size = MAX_PACKET_SZ; ops = kni_ops; @@ -591,14 +707,6 @@ test_kni(void) goto fail; } - /* test of getting port id according to NULL kni context */ - if (rte_kni_get_port_id(NULL) < RTE_MAX_ETHPORTS) { - ret = -1; - printf("unexpectedly get port id successfully by NULL kni " - "pointer\n"); - goto fail; - } - /* test of releasing NULL kni context */ ret = rte_kni_release(NULL); if (ret == 0) { @@ -644,23 +752,6 @@ test_kni(void) "a never used name string\n"); goto fail; } - - /* test the interface of creating a KNI, for backward compatibility */ - memset(&ops, 0, sizeof(ops)); - ops = kni_ops; - kni = rte_kni_create(port_id, MAX_PACKET_SZ, mp, &ops); - if (!kni) { - ret = -1; - printf("Fail to create a KNI device for port %d\n", port_id); - goto fail; - } - - ret = rte_kni_release(kni); - if (ret < 0) { - printf("Fail to release a KNI device\n"); - goto fail; - } - ret = 0; fail: @@ -669,8 +760,6 @@ fail: return ret; } -static struct test_command kni_cmd = { - .command = "kni_autotest", - .callback = test_kni, -}; -REGISTER_TEST_COMMAND(kni_cmd); +#endif + +REGISTER_TEST_COMMAND(kni_autotest, test_kni);