blob: 941d53871e5afbbb70cac893960d56ef19b22181 [file] [log] [blame]
#!/bin/bash
#
# core_pinning_auto.sh -- script to test vpp (debug-build) core-pinning
# -- in bare-metal, containers (docker, lxc)
#
DOCKER_CONTAINER_NAME="vpp_core_pinning"
VPP_SOCK_PATH=/run/vpp
CONTAINER_CPU_RANGE="4-7"
TEST_SUCCESS=0
TEST_FAIL=0
if [ ! $WS_ROOT ]
then
if [ ! -d "../../../vpp" ]; then
echo "VPP workspace path invalid"
echo "Please execute script from vpp/test/scripts folder.."
exit 1
fi
WS_ROOT="$(dirname $(readlink -e "../../../vpp"))/$(basename "../../../vpp")"
fi
# Get available CPU count on host machine
host_cpulist=$(cat /sys/devices/system/cpu/online)
startcpu="${host_cpulist%-*}"
endcpu="${host_cpulist#*\-}"
cpucount="$(($endcpu - $startcpu + 1))"
if [ $cpucount -lt 8 ]
then
echo "Current host machine has $cpucount CPUs"
echo "A minimum of 8 CPUs is required to run testcases, exiting.."
exit 1
fi
# Check that container 'vpp_core_pinning' does not already exist
count=$(docker ps -a | grep -c "$DOCKER_CONTAINER_NAME")
if [ $count -ne 0 ]
then
echo "Error: docker container $DOCKER_CONTAINER_NAME already exists"
echo "Remove it using 'docker stop/docker rm', then re-run test"
exit 1
fi
# Check that there is no vpp instance currently running on the machine
count=$(pgrep vpp | wc -l)
if [ $count -ne 0 ]
then
echo "Error: a vpp instance is currently running on this machine"
echo "Please stop the running instance, then re-run test"
exit 1
fi
mkdir -p $VPP_SOCK_PATH
# Function to parse main core
parse_maincore () {
main_core_args=$1
main_core_parsed=$main_core_args
if [ $main_core_args = "auto" ];
then
main_core_parsed="0"
if [ -n "$SKIP_CORE" ]
then
main_core_parsed=$(($main_core_parsed + $SKIP_CORE))
fi
if [ -n "$CONTAINER_RESTRAIN_CPUSET" ]
then
main_core_parsed=(${container_cpus[ $main_core_parsed ]})
fi
fi
echo $main_core_parsed
}
# Function to parse n workers range to an array
# e.g. "4" is parsed to ('0','1','2','3')
parse_workers_n () {
workers_n_args=$1
workers_n_parsed=()
main_core_increment="0"
skip_core_increment="0"
if [ -n "$SKIP_CORE" ]
then
skip_core_increment=$(($SKIP_CORE))
fi
for ((i=0;i<$workers_n_args;i++)); do
if [ -n "$CONTAINER_RESTRAIN_CPUSET" ]
then
if [ $(( ${container_cpus[ $(($i + $skip_core_increment)) ]})) -eq $(("$parsed_main_core")) ]
then
main_core_increment=$(($main_core_increment + 1))
fi
workers_n_parsed+=" ${container_cpus[ $(($i + $main_core_increment + $skip_core_increment)) ]}"
else
if [ $(( $skip_core_increment + $i)) -eq $(("$parsed_main_core")) ]
then
main_core_increment=$(($main_core_increment + 1))
fi
workers_n_parsed+=" $(($i + $main_core_increment + $skip_core_increment))"
fi
done
echo $workers_n_parsed
}
# Function to parse corelist range to an array
# e.g. "0,3-5,7" is parsed to ('0','3','4','5','7')
parse_corelist () {
corelist_args=$1
corelist_args=$(echo $corelist_args | grep -Po '[0-9]+-[0-9]+|[0-9]+')
corelist_parsed=()
for corelist_elt in ${corelist_args[@]};do
if [ $(echo $corelist_elt | grep -Po '[0-9]+-[0-9]+') ]
then
startcpu="${corelist_elt%-*}"
endcpu="${corelist_elt#*\-}"
cpucount="$(($endcpu - $startcpu))"
for ((i=0;i<=$cpucount;i++)); do
corelist_parsed+=" $(($i+$startcpu))"
done
elif [ $(echo $corelist_elt | grep -Po '[0-9]+') ]
then
corelist_parsed+=" ${corelist_elt}"
fi
done
echo $corelist_parsed
}
# Test VPP core pinning configuration
test_pinning_conf () {
VPP_CPU_EXTRA_OPTIONS=""
if [ -n "$CORELIST_WORKERS" ];
then
VPP_CPU_EXTRA_OPTIONS=" corelist-workers ${CORELIST_WORKERS}"
fi
if [ -n "$WORKERS_AUTO" ];
then
VPP_CPU_EXTRA_OPTIONS=" workers ${WORKERS_AUTO}"
fi
if [ -n "$SKIP_CORE" ];
then
VPP_CPU_EXTRA_OPTIONS="${VPP_CPU_EXTRA_OPTIONS} skip-cores ${SKIP_CORE}"
fi
echo "TEST - conf 'cpu {main-core ${MAIN_CORE} ${VPP_CPU_EXTRA_OPTIONS}}'"
if [ -z "$CONTAINER_RESTRAIN_CPUSET" ];
then
VPP_CONTAINER_CPUSET=""
echo "(Running vpp in container with full host cpuset $host_cpulist)"
else
VPP_CONTAINER_CPUSET="--cpuset-cpus $CONTAINER_CPU_RANGE"
echo "(Running vpp in container with limited cpuset $CONTAINER_CPU_RANGE)"
fi
(docker run -d ${VPP_CONTAINER_CPUSET} --name="$DOCKER_CONTAINER_NAME" \
-e LD_LIBRARY_PATH="/vpp/build-root/build-vpp_debug-native/vpp/lib/x86_64-linux-gnu/" -v $VPP_SOCK_PATH:$VPP_SOCK_PATH \
-v $WS_ROOT:/vpp ubuntu:22.04 sh -c "/vpp/build-root/build-vpp_debug-native/vpp/bin/vpp unix {interactive \
nodaemon cli-listen $VPP_SOCK_PATH/cli.sock} cpu {main-core ${MAIN_CORE} ${VPP_CPU_EXTRA_OPTIONS} } plugins \
{ plugin dpdk_plugin.so {disable } }" > /dev/null )
sleep 3 # wait for VPP to initialize socket
# Change access permissions on vpp cli socket
# docker exec -it "$DOCKER_CONTAINER_NAME" /bin/bash -c "chmod 777 $VPP_SOCK_PATH/cli.sock" > /dev/null
# check if vppctl can connect to vpp container instance
$WS_ROOT/build-root/build-vpp_debug-native/vpp/bin/vppctl -s $VPP_SOCK_PATH/cli.sock show threads 1> /dev/null
# get CPUs vpp instance in container is running on
taskset_vpp_cpus=($( taskset --all-tasks -pc $(pgrep vpp) | grep -e ".$" -o))
rc=$?
# parse list of user requested CPUs for vpp
requested_cpus=()
parsed_main_core=$(parse_maincore ${MAIN_CORE})
requested_cpus+=($parsed_main_core)
if [ -n "$CORELIST_WORKERS" ];
then
requested_cpus+=($(parse_corelist ${CORELIST_WORKERS}))
fi
if [ -n "$WORKERS_AUTO" ];
then
requested_cpus+=($(parse_workers_n ${WORKERS_AUTO}))
fi
# parse list of expected CPUs used by vpp
expected_cpu_mapping=()
expected_cpu_mapping=("${requested_cpus[@]}")
echo "CPUs requested by user: [${requested_cpus[@]}]"
echo "--------------------"
echo "Expected CPU Mapping: [${expected_cpu_mapping[@]}]"
echo "VPP pinning (taskset): [${taskset_vpp_cpus[@]}]"
#check if expected CPU mapping matches CPUs vpp instance in container is running on
failure_cond=""
for index in ${!taskset_vpp_cpus[@]}; do
if [ ${taskset_vpp_cpus[$index]} -ne ${expected_cpu_mapping[ $index ]} ]
then
failure_cond="t"
fi
done
if [ $rc -eq 0 ] && [ -z "$failure_cond" ]
then
echo "Test Successful"
TEST_SUCCESS=$(($TEST_SUCCESS+1))
else
echo "Test Failed"
TEST_FAIL=$(($TEST_FAIL+1))
fi
echo "=============================================="
echo " "
# Stop & destroy container instance
docker stop $DOCKER_CONTAINER_NAME &> /dev/null
docker rm -f $DOCKER_CONTAINER_NAME &> /dev/null
}
test_invalid_conf () {
if [ -n "$CORELIST_WORKERS" ];
then
VPP_CPU_EXTRA_OPTIONS=" corelist-workers ${CORELIST_WORKERS}"
fi
if [ -n "$WORKERS_AUTO" ];
then
VPP_CPU_EXTRA_OPTIONS=" workers ${WORKERS_AUTO}"
fi
if [ -n "$SKIP_CORE" ];
then
VPP_CPU_EXTRA_OPTIONS="${VPP_CPU_EXTRA_OPTIONS} skip-cores ${SKIP_CORE}"
fi
echo "TEST - conf 'cpu {main-core ${MAIN_CORE} ${VPP_CPU_EXTRA_OPTIONS}}'"
if [ -z "$CONTAINER_RESTRAIN_CPUSET" ];
then
VPP_CONTAINER_CPUSET=""
echo "(Running vpp in container with full host cpuset $host_cpulist)"
else
VPP_CONTAINER_CPUSET="--cpuset-cpus $CONTAINER_CPU_RANGE"
echo "(Running vpp in container with limited cpuset $CONTAINER_CPU_RANGE)"
fi
(docker run -d --cpuset-cpus $CONTAINER_CPU_RANGE --name="$DOCKER_CONTAINER_NAME" \
-e LD_LIBRARY_PATH="/vpp/build-root/build-vpp_debug-native/vpp/lib/x86_64-linux-gnu/" -v $VPP_SOCK_PATH:$VPP_SOCK_PATH \
-v $WS_ROOT:/vpp ubuntu:22.04 sh -c "/vpp/build-root/build-vpp_debug-native/vpp/bin/vpp unix {interactive \
nodaemon cli-listen $VPP_SOCK_PATH/cli.sock} cpu {main-core ${MAIN_CORE} ${VPP_CPU_EXTRA_OPTIONS}} plugins \
{ plugin dpdk_plugin.so {disable } }" > /dev/null)
sleep 3 # wait for vpp to initialize socket
# check if vpp launched with invalid configuration
taskset --all-tasks -pc $(pgrep vpp) &> /dev/null
rc=$?
if [ $rc -eq 1 ]
then
echo " "
echo "OK... VPP did not launch with invalid configuration"
TEST_SUCCESS=$(($TEST_SUCCESS+1))
else
echo " "
echo "Failure... VPP launched with wrong configuration"
TEST_FAIL=$(($TEST_FAIL+1))
fi
echo "=============================================="
echo " "
# Stop & destroy container instance
docker stop $DOCKER_CONTAINER_NAME &> /dev/null
docker rm -f $DOCKER_CONTAINER_NAME &> /dev/null
}
run_tests () {
container_cpus=($(parse_corelist ${CONTAINER_CPU_RANGE}))
echo "TESTING VALID CORE PINNING CONFIGURATIONS"
echo " "
WORKERS_AUTO=""
SKIP_CORE=""
CONTAINER_RESTRAIN_CPUSET=""
CORELIST_WORKERS="1-3"
MAIN_CORE="0"
test_pinning_conf
WORKERS_AUTO=""
SKIP_CORE=""
CONTAINER_RESTRAIN_CPUSET=""
CORELIST_WORKERS="0,2-3"
MAIN_CORE="1"
test_pinning_conf
WORKERS_AUTO=""
SKIP_CORE=""
CONTAINER_RESTRAIN_CPUSET=""
CORELIST_WORKERS="0-2"
MAIN_CORE="3"
test_pinning_conf
WORKERS_AUTO="2"
SKIP_CORE=""
CONTAINER_RESTRAIN_CPUSET=""
CORELIST_WORKERS=""
MAIN_CORE="auto"
test_pinning_conf
WORKERS_AUTO="3"
SKIP_CORE=""
CONTAINER_RESTRAIN_CPUSET="t"
CORELIST_WORKERS=""
MAIN_CORE="auto"
test_pinning_conf
WORKERS_AUTO="2"
SKIP_CORE="1"
CONTAINER_RESTRAIN_CPUSET="t"
CORELIST_WORKERS=""
MAIN_CORE="auto"
test_pinning_conf
WORKERS_AUTO="2"
SKIP_CORE=""
CONTAINER_RESTRAIN_CPUSET="t"
CORELIST_WORKERS=""
MAIN_CORE="5"
test_pinning_conf
echo "TESTING NON-VALID CORE PINNING CONFIGURATIONS"
echo " "
WORKERS_AUTO=""
SKIP_CORE=""
CONTAINER_RESTRAIN_CPUSET="t"
CORELIST_WORKERS="1-3"
MAIN_CORE="0"
test_invalid_conf
WORKERS_AUTO="3"
SKIP_CORE="1"
CONTAINER_RESTRAIN_CPUSET="t"
CORELIST_WORKERS=""
MAIN_CORE="auto"
test_invalid_conf
WORKERS_AUTO="5"
SKIP_CORE=""
CONTAINER_RESTRAIN_CPUSET="t"
CORELIST_WORKERS=""
MAIN_CORE="auto"
test_invalid_conf
WORKERS_AUTO=""
SKIP_CORE="4"
CONTAINER_RESTRAIN_CPUSET="t"
CORELIST_WORKERS=""
MAIN_CORE="auto"
test_invalid_conf
echo " "
echo "========================"
echo "RESULTS:"
echo "SUCCESS: $TEST_SUCCESS"
echo "FAILURE: $TEST_FAIL"
echo "========================"
echo " "
}
run_tests