diff --git a/pfa/Makefile b/pfa/Makefile index 5370ae0a7f98c8..77ee43464f25c2 100644 --- a/pfa/Makefile +++ b/pfa/Makefile @@ -158,6 +158,18 @@ rtval_v2recv: rbuild cptval_v2recv: cpbuild sudo ./tval_v2recv +# Used to benchmark the kernel's official driver for rtl8139 +cpbenchmark: cpbuild + sudo ./benchmark + +# Used to benchmark our C driver +cbenchmark: cbuild + sudo ./benchmark + +# Used to benchmark our rust driver +rbenchmark: rbuild + sudo ./benchmark + # Test if % is installed, recommand to use ${DEP_CMD} otherwise ${REQ_CMD_TARGETS}: check_dep_%: @which $* 2>&1 > /dev/null || (echo -e "\n(ERROR) couldn\'t find $*, considere installing all dependencies with : \n${DEP_CMD}\n" 1>&2 ; exit 1) diff --git a/pfa/benchmark b/pfa/benchmark new file mode 100755 index 00000000000000..2f0983c7c61a29 --- /dev/null +++ b/pfa/benchmark @@ -0,0 +1,42 @@ +#!/bin/sh + +BUILD_DIR=build +LINUX_PATH=.. +MAC_ADDRESS=de:ad:be:ef:ca:fe + +most_qemu_args="-kernel ${LINUX_PATH}/arch/x86_64/boot/bzImage -initrd ${BUILD_DIR}/initramfs.cpio.gz -no-reboot -nographic -device pci-testdev -netdev tap,id=mynet0 -device rtl8139,netdev=mynet0,mac=${MAC_ADDRESS}" + +# Make sure we have sudo token +sudo id > /dev/null 2>/dev/null + +spam () +{ + for _ in $(seq 1 100) + do + ./build/iperf3 -c 192.168.252.1 | tee -a .benchmark.output + sleep 0.1 + + # Check if file is not empty + if grep 'Done' .benchmark.output >/dev/null 2>&1 + then + break + fi + done +} + +exec_test () +{ + sudo qemu-system-x86_64 ${most_qemu_args} -append "console=ttyS0 panic=-1 loglevel=15 init='/init benchmark'" >/dev/null 2>&1 & + + sleep 0.5 # It's annoying to find a better way + sudo ip a add dev tap0 192.168.252.2/24 + + printf "" > .benchmark.output + + spam + wait + + echo "Benchmark done, results are in .benchmark.output" +} + +exec_test diff --git a/pfa/mk/init.sh b/pfa/mk/init.sh index 939a63784ab0bf..41b0ecff4af2b0 100644 --- a/pfa/mk/init.sh +++ b/pfa/mk/init.sh @@ -52,6 +52,11 @@ elif [ "$1" = "tval_v2recv'" ] then timeout 2 nc -lnvu -p 9999 exit 1 + +elif [ "$1" = "benchmark'" ] +then + /iperf3 -s -1 + exit 1 fi exec /bin/sh $@ diff --git a/pfa/mk/initramfs.mk b/pfa/mk/initramfs.mk index 8078ac4fef3e3a..10aeb1a5322d45 100644 --- a/pfa/mk/initramfs.mk +++ b/pfa/mk/initramfs.mk @@ -29,9 +29,9 @@ initramfs_create_root: busybox_build ${BUILD_DIR}/send_udp ${BUILD_DIR}/initramf # Begin of initramfs_root # **Make sure busybox_build as been called before**, otherwise it will not # create initramfs correctly -${BUILD_DIR}/initramfs: ${BUILD_DIR}/initramfs/send_udp +${BUILD_DIR}/initramfs: ${BUILD_DIR}/initramfs/send_udp ${BUILD_DIR}/initramfs/iperf3 @# Create usual Linux directories - mkdir -p $@/bin $@/sbin $@/etc $@/proc $@/sys $@/dev $@/usr/bin $@/usr/sbin + mkdir -p $@/bin $@/sbin $@/etc $@/proc $@/sys $@/dev $@/usr/bin $@/usr/sbin $@/tmp @# Copy busybox applets to ramfs cp -a ${BUSYBOX__INSTALL_PATH}/* $@ touch $@ diff --git a/pfa/mk/iperf.mk b/pfa/mk/iperf.mk new file mode 100644 index 00000000000000..32c816b3cdc744 --- /dev/null +++ b/pfa/mk/iperf.mk @@ -0,0 +1,97 @@ +# +# Build a x86_64 static executable of iperf3 (using musl-gcc) to embed with +# initramfs +# +# Steps: +# 1. Download the release of iperf +# 2. Extract the release archive +# 3. Download patched linux headers for musl-gcc +# 4. Create iperf config +# 5. Build the iperf/_install directory creating links to applets implemented +# by iperf +# + +# Guard to prevent including several times iperf.mk +ifndef _IPERF_MK_ +_IPERF_MK_ := "defined" + +BUILD_DIR ?= ../build + +# Defaults for linux +MUSL-GCC ?= musl-gcc +CROSS_COMPILE ?= + +# Path to _install directory +IPERF__INSTALL_PATH := $(shell pwd)/${BUILD_DIR} + +# Flags passed to make when building iperf +IPERF_FLAGS+=ARCH=x86_64 \ + CROSS_COMPILE="${CROSS_COMPILE}" \ + CC=$(MUSL-GCC) \ + CFLAGS="-Ilinux-headers-4.19.88-2/x86/include" \ + -j$(shell nproc) + + +# Prevent execution of iperf_all on include +all: + + +# Default iperf target to build +iperf_all: iperf_build + + +# Build the _install directory, creating links to all applets implemented by +# iperf +iperf_build: iperf_download_release iperf_config iperf_install + + +# Download a fixed version of iperf +iperf_download_release: ${BUILD_DIR}/iperf-3.18 + +# Begin of targets for iperf_download_release +${BUILD_DIR}/iperf-3.18: ${BUILD_DIR}/iperf-3.18.tar.gz + tar -xf $^ -C $(dir $@) + touch $@ + +${BUILD_DIR}/iperf-3.18.tar.gz: + mkdir -p $(dir $@) + wget -O "$@" https://github.com/esnet/iperf/releases/download/3.18/iperf-3.18.tar.gz + [ -f "$@" ] || (echo -E '(ERROR) wget failed, check your connexion' 1>&2 ; exit 1) +# End of targets for iperf_download_release + +iperf_config: ${BUILD_DIR}/iperf-3.18/Makefile + +# Begin of targets for iperf_config +${BUILD_DIR}/iperf-3.18/Makefile: + (cd $(dir $@); ./configure "LDFLAGS=--static" "CC=musl-gcc" --prefix=$(IPERF__INSTALL_PATH) --disable-shared --without-sctp) +# End of targets for iperf_config + + +iperf_install: ${BUILD_DIR}/iperf3 + +# Begin of targets for iperf_build_applets +# make install is phony in iperf makefile, and links applets to iperf +# executable, so we compile it only if iperf executable is more recent +${BUILD_DIR}/iperf3: ${BUILD_DIR}/iperf-3.18/src/iperf3 + @# make install creates the _install directory used to create the + @# initramfs + make install -C ${BUILD_DIR}/iperf-3.18 -j$(shell nproc) + install ${BUILD_DIR}/bin/iperf3 $@ + +${BUILD_DIR}/iperf-3.18/src/iperf3: + @# compile the executable iperf + make -C ${BUILD_DIR}/iperf-3.18 +# End of targets for iperf_build_applets + + +iperf_clean: + make clean -C ${BUILD_DIR}/iperf-3.18 + + +.PHONY: all \ + iperf_all \ + iperf_build \ + iperf_download_release \ + iperf_config \ + iperf_clean +endif # ifndef _IPERF_MK_