实验代码 代码结构图
prepare.sh 前置准备工作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 wget https://fast.dpdk.org/rel/dpdk-19.11.6.tar.xz tar xJf dpdk-19.11.6.tar.xz rm dpdk-19.11.6.tar.xzmv dpdk-stable-19.11.6/ dpdk2cd dpdk2meson build cd buildninja cd ../../wget http://vmx.cs.pub.ro/~vmchecker/dpdk3.zip unzip dpdk3 cd dpdk3meson build cd buildninja if [[ ! -d /mnt/huge1G ]]; then mkdir /mnt/huge1G mount -t hugetlbfs -o pagesize=1G none /mnt/huge1G fi
udp_echo.sh 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 #!/bin/bash file_prefix=cl_tx_rx pipeline=${1} interval=${2} cpufreq=${3} file_path=${4} generate_requests (){ cat ${1} | grep -A10 "received/transmitted" | grep ^[0-9] | awk -v interval=${3} -F"," 'BEGIN {i=1; printf "Interval, Number of Round Trip Requests\n"; } {if (i%interval == 0)printf "%d,%lu\n", i, $3; i++;}' > ${2} } generate_latency (){ cat ${1} | grep -A10 "received/transmitted" | grep ^[0-9] | awk -v interval=${3} -v frequency=${4} -F"," 'BEGIN {i=1; printf "Interval, Latency for the round trip in microseconds\n"; } {if (i%interval == 0)printf "%d,%0.04f\n", i, $1/(frequency * $3); i++;}' > ${2} } cl_in_file=${file_path} /${file_prefix} _${pipeline} p printf "\n" [[ -f ${cl_in_file} ]] || { printf "Inputfile ${cl_in_file} missing\n" ; exit 1; } cl_rqst_out_file=${cl_in_file} _rqstpersecond_out cl_lat_out_file=${cl_in_file} _latency_out generate_requests ${cl_in_file} ${cl_rqst_out_file} ${interval} generate_latency ${cl_in_file} ${cl_lat_out_file} ${interval} ${cpufreq}
aux dpdk 该文件夹为软链接,指向/aux/lib_src/dpdk。
dpdk2 该文件夹存放的是 19.11.6 版本的 DPDK 源码。
lib_src 该文件夹原本应该从链接下载,但链接失效,目前只能推测其中包含 19.08.2 版本的 DPDK 源码
libs unikraft 中的 libs 文件夹,用于存放库文件。
unikraft unikraft 本体代码。
server
Makefile.uk 在这个文件中,可以观察到每个测试分别引入了哪个文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 $(eval $(call addlib,apptestsuite) )ifeq ($(CONFIG_APPTESTSUITE_KERNARGS) ,y)$(eval $(call addlib_paramprefix,apptestsuite,test) )endif APPTESTSUITE_CINCLUDES-y += -I$(APPTESTSUITE_BASE) /include APPTESTSUITE_SRCS-y += $(APPTESTSUITE_BASE) /main.c EXTRA_LD_SCRIPT-y += $(APPTESTSUITE_BASE) /testsuite.ld APPTESTSUITE_CINCLUDES-$(CONFIG_APPTESTSUITE_FDT) += -I$(UK_PLAT_DRIVERS_BASE) /include APPTESTSUITE_CINCLUDES-$(CONFIG_APPTESTSUITE_FDT) += -I$(LIBKVMPLAT_BASE) /include APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_FDT) += $(APPTESTSUITE_BASE) /test_fdt/test_fdt.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_FDT) += $(APPTESTSUITE_BASE) /test_fdt/test.dts APPTESTSUITE_CINCLUDES-$(CONFIG_APPTESTSUITE_GICV2) += -I$(UK_PLAT_DRIVERS_BASE) /include APPTESTSUITE_CINCLUDES-$(CONFIG_APPTESTSUITE_GICV2) += -I$(LIBKVMPLAT_BASE) /include APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_GICV2) += $(APPTESTSUITE_BASE) /gicv2/test_gicv2.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_GICV2) += $(APPTESTSUITE_BASE) /gicv2/test.dts APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_KERNARGS) +=\ $(APPTESTSUITE_BASE) /test_libukparam/test_ukparam.c APPTESTSUITE_CFLAGS-$(CONFIG_APPTESTSUITE_KERNARGS) += \ -save-temps=obj -DUK_DEBUG APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_UC_LIBPARAM) +=\ $(APPTESTSUITE_BASE) /test_libukparam/test_ucparam.c APPTESTSUITE_CFLAGS-$(CONFIG_APPTESTSUITE_UC_LIBPARAM) += \ -I$(CONFIG_UK_BASE) /lib/uklibparam/ APPTESTSUITE_CFLAGS-$(CONFIG_APPTESTSUITE_UC_LIBPARAM) += \ -DUK_LIBPARAM_PREFIX=apptestsuite -save-temps=obj\ -I$(CONFIG_UK_BASE) /lib/uklibparam/include -DUK_DEBUG EXTRA_LD_SCRIPT-$(CONFIG_APPTESTSUITE_UC_LIBPARAM) += \ $(APPTESTSUITE_BASE) /test_libukparam/libparam.lds APPTESTSUITE_SRCS-$(CONFIG_VFSCORETEST_OPEN) += \ $(APPTESTSUITE_BASE) /test_vfscore/test_open.c APPTESTSUITE_SRCS-$(CONFIG_VFSCORETEST_STAT) += \ $(APPTESTSUITE_BASE) /test_vfscore/test_stat.c APPTESTSUITE_SRCS-$(CONFIG_VFSCORETEST_IOCTL) += \ $(APPTESTSUITE_BASE) /test_vfscore/test_ioctl.c APPTESTSUITE_SRCS-$(CONFIG_VFSCORETEST_MOUNT) += \ $(APPTESTSUITE_BASE) /test_vfscore/test_mount.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_LOCK) += \ $(APPTESTSUITE_BASE) /test_lock/test_lock.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_LDS) += \ $(APPTESTSUITE_BASE) /test_lds/test.ld APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_LDS) += \ $(APPTESTSUITE_BASE) /test_lds/lds_test.c APPTESTSUITE_CFLAGS-$(CONFIG_APPTESTSUITE_LDS) += -save-temps=obj APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_INITTAB) += \ $(APPTESTSUITE_BASE) /test_inittab/test_inittab.c APPTESTSUITE_CFLAGS-$(CONFIG_APPTESTSUITE_INITTAB) += -save-temps=obj APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_NETDEV) += $(APPTESTSUITE_BASE) /test_netdev/test_netdev.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_UK_LWIP) += $(APPTESTSUITE_BASE) /test_lwip/test_lwip.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_RING) += $(APPTESTSUITE_BASE) /test_dpdk/test_ring/test_ring.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_INIT) += $(APPTESTSUITE_BASE) /test_dpdk/test_init/init.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_MEMORY) += $(APPTESTSUITE_BASE) /test_dpdk/test_memory/test_memory.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_BASIC_FWD) += $(APPTESTSUITE_BASE) /test_dpdk/basic_forward/pktgen.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_BASIC_FWD) += $(APPTESTSUITE_BASE) /test_dpdk/basic_forward/dev.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_TXONLY) += $(APPTESTSUITE_BASE) /test_dpdk/basic_forward/txonly.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_RTT) += $(APPTESTSUITE_BASE) /test_dpdk/basic_forward/rtt.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_CLOSED_LOOP) += $(APPTESTSUITE_BASE) /test_dpdk/basic_forward/closed_loop_latency.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_RXONLY) += $(APPTESTSUITE_BASE) /test_dpdk/basic_forward/rxonly.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_CL_SERVER) += $(APPTESTSUITE_BASE) /test_dpdk/basic_forward/cl_tx_rx.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_DPDK_UDP_ECHO) += $(APPTESTSUITE_BASE) /test_dpdk/basic_forward/udp_echo.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_RAW_NETDEV) += $(APPTESTSUITE_BASE) /perf_netdev/main_nolwip.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_STRTOK_R) += \ $(APPTESTSUITE_BASE) /test_string/strtok_r.c APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_MTCPAPP_PERF) += $(APPTESTSUITE_BASE) /mtcp/apps/perf/client.c\
我们可以使用 make menuconfig
对测试选项进行选择
linux linux guest single/batch 部分测试代码
该部分通过执行脚本来启动指定的 linux 虚拟机
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 #!/bin/bash if [ $( id -u ) != 0 ]; then echo "Try to run as root..." 1>&2 exec sudo "$0 " "$@ " fi QCOW="../../aux/debian.qcow2" MEMPATH="/mnt/huge1G/test" TAPNAME="tap88" BRNAME="expbr0" TAPNAME_EXP="tap98" BRNAME_EXP="testbr0" set -xip tuntap add dev $TAPNAME mode tap ip link add $BRNAME type bridge ip link set master $BRNAME dev $TAPNAME ip link set promisc on dev $BRNAME ip link set promisc on dev $TAPNAME ip addr add 172.19.0.254/24 dev $BRNAME ip link set dev $BRNAME up ip link set dev $TAPNAME up ip link set dev enp1s0f1 down ip link add link enp1s0f1 macvtap2 type macvtap mode bridge ip link set promisc on dev enp1s0f1 ip a a 172.18.0.1/24 dev macvtap2 ip link set promisc on dev macvtap2 ip link set dev enp1s0f1 up ip link set macvtap2 up my_fd=$(cat /sys/class/net/macvtap2/ifindex) taskset -c 4,5 qemu-system-x86_64 \ -m 6G \ -cpu host,+invtsc \ -smp cpus=2 \ -enable-kvm \ -object memory-backend-file,id =mem,size=6144M,mem-path=/mnt/linux-huge,share=on -numa node,memdev=mem \ \ -netdev tap,ifname=$TAPNAME ,id =mgm0,script=no,downscript=no \ -device virtio-net-pci,netdev=mgm0 \ \ -netdev tap,fd=5,id =testtap1,vhost=on,vhostforce=on 5<>/dev/tap$my_fd \ -device virtio-net-pci,netdev=testtap1,ioeventfd=on,guest_csum=off,gso=off \ \ -hda "$QCOW " \ -display curses \ -boot c RET=$? ip link del macvtap2 ip link set dev $BRNAME down ip link set dev $TAPNAME down ip tuntap del dev $TAPNAME mode tap ip link del $BRNAME exit $RET
由于虚拟机的链接失效,无法执行测试。
linux_single linux baremetal single 部分测试代码
执行 run.sh 来调用 server.c
1 2 3 4 5 6 7 8 9 10 11 12 gcc server.c -O3 -o server sudo arp -s 172.18.0.4 a0:36:9f:52:29:D0 sudo ip a a 172.18.0.114 dev enp1s0f1 sudo ifconfig enp1s0f1 hw ether 52:54:00:12:34:57 sudo ip l set enp1s0f1 up sudo iptables -P INPUT ACCEPT sudo iptables -P OUTPUT ACCEPT sudo iptables -P FORWARD ACCEPT sudo iptables -F sudo sysctl -w net.core.rmem_max=26214400 sudo sysctl -w net.core.rmem_default=26214400 taskset -c 6 ./server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 int main () { int sockfd; char buffer[MAXLINE]; struct sockaddr_in servaddr , cliaddr ; sockfd = socket(AF_INET, SOCK_DGRAM, 0 ); assert(sockfd > 2 ); int disable = 1 ; if (setsockopt(sockfd, SOL_SOCKET, SO_NO_CHECK, (void *)&disable, sizeof (disable)) < 0 ) { perror("setsockopt failed" ); } memset (&servaddr, 0 , sizeof (servaddr)); memset (&cliaddr, 0 , sizeof (cliaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = INADDR_ANY; servaddr.sin_port = htons(PORT); assert(bind(sockfd, (const struct sockaddr *)&servaddr, sizeof (servaddr)) == 0 ); int len, ret1, ret2; init_hashmap(); len = sizeof (cliaddr); printf ("Server started \n" ); while (1 ) { ret1 = recvfrom(sockfd, (char *)buffer, MAXLINE, MSG_WAITALL, ( struct sockaddr *) &cliaddr, &len); ret2 = sendto(sockfd, (const char *)buffer, ret1, 0 , (const struct sockaddr *) &cliaddr, len); assert(ret1 >= 0 ); assert(ret2 >= 0 ); } return 0 ; }
linux_batch linux baremetal batch 部分测试代码
执行 run.sh 来调用 udpreceiver1.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 int main (int argc, const char *argv[]) { const char *listen_addr_str = "0.0.0.0:9001" ; int recv_buf_size = 4 *1024 ; int thread_num = 1 ; int reuseport = 0 ; switch (argc) { case 4 : reuseport = atoi(argv[3 ]); case 3 : thread_num = atoi(argv[2 ]); case 2 : listen_addr_str = argv[1 ]; case 1 : break ; default : FATAL("Usage: %s [listen ip:port] [fork cnt] [reuseport]" , argv[0 ]); } struct sockaddr_in addr ; int sockfd = socket(AF_INET, SOCK_DGRAM, 0 ); if (sockfd == -1 ) { perror("socket()" ); exit (EXIT_FAILURE); } addr.sin_family = AF_INET; addr.sin_addr.s_addr = (inet_addr("172.18.0.5" )); addr.sin_port = htons(9000 ); if (connect(sockfd, (struct sockaddr *) &addr, sizeof (addr)) == -1 ) { } global_sockfd = sockfd; struct net_addr listen_addr ; parse_addr(&listen_addr, listen_addr_str); int main_fd = -1 ; if (reuseport == 0 ) { fprintf (stderr , "[*] Starting udpreceiver on %s, recv buffer %iKiB\n" , addr_to_str(&listen_addr), recv_buf_size / 1024 ); main_fd = net_bind_udp(&listen_addr, 0 ); net_set_buffer_size(main_fd, recv_buf_size, 0 ); } struct state *array_of_states = calloc (thread_num, sizeof (struct state)); int t; for (t = 0 ; t < thread_num; t++) { struct state *state = &array_of_states[t]; state_init(state); if (reuseport == 0 ) { state->fd = main_fd; } else { fprintf (stderr , "[*] Starting udpreceiver on %s, recv buffer %iKiB\n" , addr_to_str(&listen_addr), recv_buf_size / 1024 ); int fd = net_bind_udp(&listen_addr, 1 ); net_set_buffer_size(fd, recv_buf_size, 0 ); state->fd = fd; } thread_spawn(thread_loop, state); } uint64_t last_pps = 0 ; uint64_t last_bps = 0 ; while (1 ) { struct timeval timeout = NSEC_TIMEVAL(MSEC_NSEC(1000UL )); while (1 ) { int r = select(0 , NULL , NULL , NULL , &timeout); if (r != 0 ) { continue ; } if (TIMEVAL_NSEC(&timeout) == 0 ) { break ; } } uint64_t now_pps = 0 , now_bps = 0 ; for (t = 0 ; t < thread_num; t++) { struct state *state = &array_of_states[t]; now_pps += __atomic_load_n(&state->pps, 0 ); now_bps += __atomic_load_n(&state->bps, 0 ); } double delta_pps = now_pps - last_pps; double delta_bps = now_bps - last_bps; last_pps = now_pps; last_bps = now_bps; printf ("%7.3fM pps %7.3fMiB / %7.3fMb\n" , delta_pps / 1000.0 / 1000.0 , delta_bps / 1024.0 / 1024.0 , delta_bps * 8.0 / 1000.0 / 1000.0 ); } return 0 ; }
linux_dpdk linux guest DPDK 部分测试代码
该部分直接使用 testpmd 程序来完成
1 2 3 4 5 6 7 sudo ../../aux/dpdk2/build/app/dpdk-testpmd -m 1024 -n 4 --proc-type=primary -- -i
unikraft_lwip unikraft guest lwip 部分测试代码
该部分直接使用 app-httpreply 作为测试程序,并引入 lib-lwip
unikraft_raw unikraft guest uknetdev 部分测试代码
该部分对应的测试文件夹为 perf_netdev
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 static int perf_netdev (void ) { struct uk_alloc *a ; struct uk_netdev *dev ; struct uk_netdev_conf dev_conf ; struct uk_netdev_rxqueue_conf rxq_conf ; struct uk_netdev_txqueue_conf txq_conf ; int devid = 0 ; int ret; a = uk_alloc_get_default(); assert(a != NULL ); dev = uk_netdev_get(devid); assert(dev != NULL ); struct uk_netdev_info info ; uk_netdev_info_get(dev, &info); assert(info.max_tx_queues); assert(info.max_rx_queues); rx_headroom = (rx_headroom < info.nb_encap_rx) ? info.nb_encap_rx : rx_headroom; tx_headroom = (tx_headroom < info.nb_encap_tx) ? info.nb_encap_tx : tx_headroom; dev_conf.nb_rx_queues = 1 ; dev_conf.nb_tx_queues = 1 ; ret = uk_netdev_configure(dev, &dev_conf); assert(ret >= 0 ); rxq_conf.a = a; rxq_conf.alloc_rxpkts = netif_alloc_rxpkts; rxq_conf.alloc_rxpkts_argp = a; #ifdef INTERRUPT_MODE rxq_conf.callback = packet_handler; rxq_conf.callback_cookie = NULL ; #ifdef CONFIG_LIBUKNETDEV_DISPATCHERTHREADS rxq_conf.s = uk_sched_get_default(); assert(rxq_conf.s); #endif #else rxq_conf.callback = NULL ; rxq_conf.callback_cookie = NULL ; #endif ret = uk_netdev_rxq_configure(dev, 0 , 0 , &rxq_conf); assert(ret >= 0 ); txq_conf.a = a; ret = uk_netdev_txq_configure(dev, 0 , 0 , &txq_conf); assert(ret >= 0 ); uint16_t mtu = uk_netdev_mtu_get(dev); assert(mtu == 1500 ); ret = uk_netdev_start(dev); #ifndef INTERRUPT_MODE ret = uk_netdev_rxq_intr_disable(dev, 0 ); assert(ret >= 0 ); #else ret = uk_netdev_rxq_intr_enable(dev, 0 ); assert(ret >= 0 ); #endif struct ether_header *eth_header ; struct iphdr *ip_hdr ; while (1 ) { #ifdef INTERRUPT_MODE uk_sched_yield(); #else packet_handler(dev, 0 , NULL ); #endif #ifdef USE_SIMPLE_QUEUE for (int i = 0 ; i < k; i++) { struct uk_netbuf *nb ; nb = queue [i]; uknetdev_output(dev, nb); #endif } return 0 ; }
奇怪的是,该文件在 Makefile.uk 中被引入
1 2 APPTESTSUITE_SRCS-$(CONFIG_APPTESTSUITE_RAW_NETDEV) += $(APPTESTSUITE_BASE) /perf_netdev/main_nolwip.c
但在 Config.uk 文件中并没有发现 CONFIG_APPTESTSUITE_RAW_NETDEV
,并且在其余的测试文件中,通常在末尾会调用 TESTSUITE_REGISTER
来将该测试函数注册,以便在 main.c 中可以顺利调用,此处并未发现该步骤。 到底跑了没 🤔
unikraft_dpdk unikraft guest DPDK 部分测试代码
推测测速相关代码位于 cl_tx_rx.c 中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 static int test_tx_rx (int argc, char *argv[]) { struct rte_mempool *mbuf_pool ; unsigned nb_ports; uint16_t portid, first_portid = 0xff ; int i; int pkt_in_flight = CONFIG_INPIPELINE; #if 0 int ret = test_app_args(argc, argv); #endif int ret = rte_eal_init(argc, argv); if (ret < 0 ) UK_CRASH("Error with EAL initialization\n" ); argc -= ret; argv += ret; nb_ports = rte_eth_dev_count_avail(); printf ("%d number of ports detected Pool Size: %d\n" , nb_ports, RTE_MBUF_DEFAULT_BUF_SIZE); mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL" , NUM_MBUFS * nb_ports, RTE_MEMPOOL_CACHE_MAX_SIZE, 0 , RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id()); RTE_ETH_FOREACH_DEV(portid) { if (first_portid == 0xff ) first_portid = portid; if (port_init(portid, mbuf_pool) != 0 ) UK_CRASH("Cannot init port %" PRIu16 "\n" , portid); } tx_pkt_setup(arg_src_ipv4_addr, arg_dst_ipv4_addr, arg_src_port, arg_dst_port); if (rte_lcore_count() > 1 ) printf ("\nWARNING: Too many lcores enabled. Only 1 used.\n" ); i = 0 ; int tx_count = 0 , total_tx_count = 0 ; int rx_count = 0 , total_rx_count = 0 ; uint64_t start_tsc = rte_rdtsc(); uint64_t curr_tsc; uint64_t latency; uint64_t j = 0 ; int cnt = CONFIG_INPIPELINE; uint64_t exp_start = start_tsc, exp_curr, dur = 0 ; #if 0 pkt_burst_transmit_cnt(first_portid, mbuf_pool, 1 , 0 ); int rc = pkt_burst_receive_arp(first_portid, mbuf_pool, 0 ); #endif pkt_stats.rxpkt_dropped[0 ] = 0 ; do { while (dur < arg_exp_end_time) { if (cnt > 0 ) { tx_count = pkt_burst_transmit_cnt(first_portid, mbuf_pool, cnt, j); pkt_stats.total_txpkts_pps[j] += tx_count; pkt_stats.txburst_itr[j]++; cnt -= tx_count; } int rc = pkt_burst_receive_cnt(first_portid, mbuf_pool, j); if (unlikely(rc == -1 )) { rx_count = 0 ; pkt_stats.rxpkt_dropped[j] += CONFIG_INPIPELINE; cnt += CONFIG_INPIPELINE; } else { rx_count = rc; pkt_stats.total_rxpkts_pps[j] += rc; cnt += rx_count; } curr_tsc = rte_rdtsc(); dur = curr_tsc - exp_start; if (curr_tsc - start_tsc > arg_stat_timer) { pkt_stats.total_rxpkts += pkt_stats.total_rxpkts_pps[j]; pkt_stats.total_txpkts += pkt_stats.total_txpkts_pps[j]; j++; if (j == arg_print_itr) { dump_stats(j); j = 0 ; } pkt_stats.total_txpkts_pps[j] = 0 ; pkt_stats.total_rxpkts_pps[j] = 0 ; pkt_stats.latency[j] = 0 ; pkt_stats.rxburst_itr[j] = 0 ; pkt_stats.txburst_itr[j] = 0 ; pkt_stats.total_txpkts_tries_pps[j] = 0 ; pkt_stats.total_txpkts_tries_dropped[j] = 0 ; pkt_stats.total_txpkts_tries_ra_pps[j] = 0 ; pkt_stats.total_txpkts_alloc_failed[j] = 0 ; pkt_stats.txpkt_xmit_cycles[j] = 0 ; pkt_stats.txpkt_gen_cycles[j] = 0 ; pkt_stats.txpkt_buf_cycles[j] = 0 ; pkt_stats.rxpkt_recv_cycles[j] = 0 ; pkt_stats.rxpkt_zrecv_cycles[j] = 0 ; pkt_stats.rxpkt_process_cycles[j] = 0 ; pkt_stats.rxpkt_buf_free[j] = 0 ; pkt_stats.rxpkt_dropped[j] = 0 ; start_tsc = rte_rdtsc(); } } exp_start = rte_rdtsc(); dur = 0 ; } while (1 ); return 0 ; }
client prepare.sh 完成 client 端编译工作的脚本
1 2 3 4 5 6 7 8 echo "Building the unikraft image with dpdk" cd unikraft/uk_test_suite/ && make fetchcd build/libukdpdkbuild/origin/rm -rf dpdk-19.08ln -s ../../../../../../aux/lib_src/dpdk/ dpdk-19.08cd ../../..make -j12 cd ../../
run_vhost.sh 启动 vhost 的脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 sudo modprobe ixgbe sudo modprobe uio_pci_generic sudo python3 ../aux/dpdk/usertools/dpdk-devbind.py --bind =uio_pci_generic ens160 sudo ../aux/dpdk2/build/app/dpdk-testpmd -l 2,3 -n 4 --vdev 'eth_vhost0,iface=vhost-net,queues=1' -- -i --txd=1024 --rxd=1024 --nb-cores=1 --eth-peer=0,52:54:00:12:34:57
unirkaft/uk_test_suit 测试代码主体部分。