Message ID | 1487235157-22935-1-git-send-email-ravineet.singh@linaro.org |
---|---|
State | Superseded |
Headers | show |
On Thu, Feb 16, 2017 at 09:52:37AM +0100, Ravineet Singh wrote: > The wrapper script; odp_run_app_isolated.sh can be used to run ODP > testcases in a isolated environment. Background noise can also be > generated. > > Signed-off-by: Ravineet Singh <ravineet.singh@linaro.org> > > v2: moved task-isolation dir to odp/scripts, requested my Maxim Uvarov > v3: fixed checkpatch.pl warnings > --- > scripts/task-isolation/README | 22 ++ > scripts/task-isolation/isolate-cpu.sh | 287 +++++++++++++++++++++ > scripts/task-isolation/isolate-task.sh | 160 ++++++++++++ > .../performance/odp_run_app_isolated.sh | 108 ++++++++ > 4 files changed, 577 insertions(+) > create mode 100644 scripts/task-isolation/README > create mode 100755 scripts/task-isolation/isolate-cpu.sh > create mode 100755 scripts/task-isolation/isolate-task.sh > create mode 100755 test/linux-generic/performance/odp_run_app_isolated.sh > > diff --git a/scripts/task-isolation/README b/scripts/task-isolation/README > new file mode 100644 > index 0000000..cb02056 > --- /dev/null > +++ b/scripts/task-isolation/README > @@ -0,0 +1,22 @@ > +Helper scripts to check and set CPU isolation and execution of application in > +isolated CPU(s) > + > +Files: > +isolate-cpu.sh isolates desired CPUs > +isolate-task.sh uses isolate-cpu.sh to isolate CPUs before running > + the desired task. It also provides the possibility > + to trace kernel disturbance on the isolated CPUs. > + > +isolate-cpu.sh checks the kernel configuration and the kernel cmdline to > + determine if one or several CPUs are isolated, i.e. it checks for; > + CONFIG_NO_HZ_FULL_ALL=y", and CONFIG_RCU_NOCB_CPU_ALL=y" in the kernel config > + and rcu_nocbs,nohz_full in the kernel cmdline. > + If the desired CPU(s) are not inte the above configuration, it warns but continues > + to isolate the CPU(s) as much as possibe. The isolation is accomplished by > + - Redirecting all IRQ's away from desired isolated cores > + - Using cset (cpuset) to move all running processes and kernel threads > + away from desired isolated cores > + > +isolate-task.sh uses isolate-cpu.sh to isolate desired CPU(s). In addition > + it starts the supplied application on isolated CPU(s) and optionally traces > + the isolated CPU(s) for kernel interaction. > diff --git a/scripts/task-isolation/isolate-cpu.sh b/scripts/task-isolation/isolate-cpu.sh > new file mode 100755 > index 0000000..3eaf98a > --- /dev/null > +++ b/scripts/task-isolation/isolate-cpu.sh > @@ -0,0 +1,287 @@ > +#!/bin/bash > +# > +# Copyright (c) 2017, Linaro Limited > +# All rights reserved. > +# > +# SPDX-License-Identifier: BSD-3-Clause > +# > +# Script that passes command line arguments to odp_scheduling after, > +# optionally, isolating CPU > +# > +# This script isolates desired CPUS, i.e. > +# - Checks kernel cmdline and kernel config to determine > +# if the environment is optimised for isolated task execution; > +# - Moves CPU interrupts, kernel threads, tasks etc. away from the > +# targeted CPU. > +# *Note* CPU 0 cannot be isolated, i.e minimum 2 CPU's are required. > + > + > +print_usage() { > + echo "$0 [-h] [-a] [-c <cpu list>] [-l] [-r] [-d]" > + echo > + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" > + echo " Args:" > + echo " -h Print this message" > + echo " -a Isolate all CPUs (except CPU 0)" > + echo " -c List of CPUs to be isolated." > + echo " -l Show isolation proporties" > + echo " -r Reset isolation" > + echo " -d Show debug printouts" > + echo "" > + echo " Examples:" > + echo " Isolate all CPU(s) (except 0) " > + echo " $0 -a" > + echo > + echo " Isolate CPUs 1-3 " > + echo " $0 -c 1-3" > + echo > + echo " Isolate CPUs 1 and 4 " > + echo " $0 -c 1,4 " maybe use a here document? > +} > + > +dlog() { > + [ $DEBUG ] && echo "$*" > +} > + > +warn() { > + printf "Warning: $*\n" >&2 > +} > + > +die() { > + printf "Error: $*\n" >&2 > + exit 1 > +} > + > +get_cpu_array() { > + [ $1 ] || die "$FUNCNAME internal error!" > + > + local cpus="" > + IFS=. a=$1; IFS=, a=$a; I don't understand why IFS=. is needed... Also, shouldn't IFS be restored here? > + for str in $a; do > + if [[ $str == *[\-]* ]]; then > + str=$(echo $str| sed 's/-/../g') > + str=$(eval echo {$str}) > + fi nice! > + > + if [ "$cpus" != "" ]; then > + cpus="$cpus $str" > + else > + cpus=$str > + fi you can probably get away with cpus="$cpus $str" > + done > + > + echo $cpus > +} > + > +## > +# Check kernel config and kernel cmdline for rcu callbacs and no_hz > +# *Note* isolcpu= kernel cmdline option isolates CPUs from SMP balancing > +# If needed, this can be done via > +# cpusets/user/cpuset.sched_load_balance > +## > +check_kernel_config() { > + > + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') > + > + local configs="/proc/config.gz /boot/config-$(uname -r) /boot/config " > + dlog "Looking for Kernel configs; $configs " > + for config in $configs; do > + if [ -e $config ]; then > + dlog "Kenel configuration found:$config" > + break > + fi > + done > + > + local all_except_0="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > + if [ $config ]; then I think this will always be evaluated to true, shouldn't it be if [ -e $config ] ? or even -r $config? > + nohz_full=$(zgrep "CONFIG_NO_HZ_FULL_ALL=y" $config 2>/dev/null) \ > + && nohz_full=$all_except_0 > + else > + warn "Kernel config not found, only checking /proc/cmdline for"\ > + " isolation features." > + fi > + > + if ! [ "$nohz_full" ]; then > + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') no need to pipe: grep ... /proc/cmdline > + fi > + > + eval $(cat /proc/cmdline | grep -o 'isolcpus=[^ ]*') ditto > + if [ -z "$isolcpus" ]; then > + warn "No CPU is isolated from kernel/user threads, isolcpus= is "\ > + "not set in kernel cmdline." > + else > + gbl_isolated_cpus=$isolcpus > + export gbl_isolated_cpus > + fi > + > + if [ -z "$nohz_full" ]; then > + warn "No CPU is isolated from kernel ticks, CONFIG_NO_HZ_FULL_ALL=y" \ > + " not set in kernel, nor nohz_full= set in kernel cmdline." > + fi > + > + for i in `pgrep rcu` ; do taskset -pc 0 $i >/dev/null; done can you do this? > + > + dlog "isolcpus:$isolcpus" > + dlog "nohz_full:$nohz_full" > + #dlog "rcu_nocbs:$rcu_nocbs" > + > + return 0 > +} > + > +cpus_valid() { > + local cpus="$1" > + local isolated=$2 > + local iarray=$(get_cpu_array $isolated) > + local carray=$(get_cpu_array $cpus) > + > + for c in $carray; do > + for i in $iarray; do maybe check that the user didn't provide 0 as a CPU to isolate? > + if [ $i = $c ]; then > + yah=$i > + fi > + done > + [ -z "$yah" ] && return 1 > + done > + > + return 0 > +} > + > +check_prequesties() { > + dlog "Checking prequesties; user is root, kernel has cpuset support,"\ > + " and commads; set, zgrep, getconf are available" > + [ $UID -eq 0 ] || die "You need to be root!" > + grep -q -s cpuset /proc/filesystems || die "Kernel does not support cpuset!" > + which getconf > /dev/null 2>&1 || die "getconf command not found, please "\ > + "install getconf" > + which cset > /dev/null 2>&1 || die "cset command not found, please "\ > + "install cpuset" > + which zgrep > /dev/null 2>&1 || die "zgrep command not found, please "\ > + "install gzip" > +} > + > +shield_reset() { > + cset shield -r >/dev/null 2>&1 > + sleep 0.1 > +} > + > +shield_list() { > + sets="/cpusets/*/" > + for i in $sets ; do > + if ! [ -e $i ]; then > + continue > + fi > + printf "Domain %s cpus %s, running %d tasks\n" \ > + $(basename $i) $(cat $i/cpuset.cpus) $(cat $i/tasks | wc -l) > + done > +} > + > +shield_cpus() { > + local cpus="$1" > + > + dlog "shielding CPU:s $cpus" > + > + #Reset and create new shield > + shield_reset > + out=$(cset shield -c $cpus -k on 2>&1) || die "cset failed; $out" > + # Delay the annoying vmstat timer far away > + sysctl vm.stat_interval=120 >/dev/null > + > + # Shutdown nmi watchdog as it uses perf events > + sysctl -w kernel.watchdog=0 >/dev/null > + > + # Pin the writeback workqueue to CPU0 > + #Fixme, check that /sys/bus is mounted? > + echo 1 > /sys/bus/workqueue/devices/writeback/cpumask > + > + # Disable load balanser. balancer > + echo 0 > /cpusets/user/cpuset.sched_load_balance > + > + #Fixme, for now just send all irqs to core 0 > + for affinity in /proc/irq/*/smp_affinity; do > + dlog "redirecting $affinity" > + echo 1 > $affinity 2>/dev/null || dlog "$affinity redirection failed." > + done > + > + > + #Fixme, not implemented. > + if [ $false ]; then > + for affinity in /proc/irq/*/smp_affinity; do > + local old_mask=$(cat $affinity) > + local new_mask=$((oldmask ^ cpus )) > + echo $new_mask > $affinity > + done > + fi > +} > + > +isolate_cpus() { > + > + local cpus="$1" > + > + check_kernel_config > + > + if [ "$gbl_isolated_cpus" ]; then > + cpus_valid $cpus $gbl_isolated_cpus || > + warn "Selected CPU '$cpus' is not inside isolated cpus "\ > + "array:$gbl_isolated_cpus" > + fi > + > + dlog "Isolating CPUs $cpus" > + > + shield_cpus $cpus > + > + # Verfiy cores empty > + for c in $(get_cpu_array $cpus); do > + running=$(ps ax -o pid,psr,comm | \ > + awk -v cpu="$c" '{if($2==cpu){print $3}}') > + if [ "$running" != "" ]; then > + warn "Core $c not empty!" > + dlog "; running tasks:\n$running\n" > + fi > + done indentation (tabs used here but spaces above) > + > + return 0 > +} > + > +## > +# Script entry point > +## > +while getopts hdarlc: arguments > +do > + case $arguments in > + h) > + print_usage > + exit 0 > + ;; > + d) > + DEBUG=1 > + ;; > + a) > + ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > + ;; > + r) > + shield_reset > + exit 0 > + ;; > + l) > + shield_list > + exit 0 > + ;; > + c) > + [ "$ISOL_CPUS" ] || ISOL_CPUS=$OPTARG > + ;; > + *) > + print_usage > + exit 1 > + ;; > + esac > +done > +#Remove all flags > +shift $((OPTIND-1)) > + > +if ! [ $ISOL_CPUS ]; then > + print_usage > + exit 1 > +fi > + > +check_prequesties > +isolate_cpus $ISOL_CPUS || die "isolate_cpus failed." isolate_cpus() always retuns success... > diff --git a/scripts/task-isolation/isolate-task.sh b/scripts/task-isolation/isolate-task.sh > new file mode 100755 > index 0000000..3e588bc > --- /dev/null > +++ b/scripts/task-isolation/isolate-task.sh > @@ -0,0 +1,160 @@ > +#!/bin/bash > +# > +# Copyright (c) 2017, Linaro Limited > +# All rights reserved. > +# > +# SPDX-License-Identifier: BSD-3-Clause > +# > +# Script that passes command line arguments to odp_scheduling after, > +# optionally, isolating CPU > +# > +# This script isolates a task on desired CPUs and > +# optionally creates background noise. > + > +print_usage() { > + echo "$0 [-c <cpu list>] [-d] [-h] [-n] <application arg1, arg2, ...>" > + echo > + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" > + echo " and run an application on isolated CPUs" > + echo " Args:" > + echo " -c List of CPUs to be isolated" > + echo " -d Show debug printouts" > + echo " -h Print this message" > + echo " -n Create background noise (stress)" > + echo "" > + echo "All CPU's, except CPU 0, are isolated unless '-c' specified" > + echo " Examples:" > + echo " Isolate CPU 1,2 and run application in the same." > + echo " $0 -n -c 1,2 /some/path/application" > + echo > + echo " Isolate all possible CPUs and run applicatipon" > + echo " $0 /path/application" > +} > + > +dlog() { > + [ $DEBUG ] && echo "$*" > +} > + > +die() { > + printf "Error: $*\n" >&2 > + exit 1 > +} > + > +trap cleanup INT EXIT > + > +cleanup(){ > + local pids=$(pgrep $MY_STRESS 2>/dev/null) > + local base=$(dirname $0) > + > + $base/isolate-cpu.sh -r > + [ "$pids" != "" ] && kill -9 $pids >/dev/null 2>&1 > + kill -9 $CHILD >/dev/null 2>&1 > + rm -f $MY_STRESS_PATH > +} > + > +wait_app_started () { > + local child=$1 > + local ltasks=0 > + > + while true; do > + sleep 0.01 > + kill -0 $child 2>/dev/null || break > + tasks=$(ls /proc/$child/task | wc -l) > + [ $tasks -eq $ltasks ] && break > + ltasks=$tasks > + done > + dlog "app started, # threads:$ltasks" > +} > + > +create_noise() { > + local mpath=$1 > + local nr=$(grep processor /proc/cpuinfo | wc -l) > + > + ln -sf $(which stress) $mpath || die "ln failed" > + $mpath -c $nr 2>&1 >/dev/null & > + disown $! > +} > + > +isolate_cpu(){ > + local cpus=$1 > + local base=$(dirname $0) > + $base/isolate-cpu.sh -c $cpus || die "$0 failed" > +} > + > +run_application() { > + local app="$1" > + > + dlog "Starting application: $app" > + $app& > + child=$! > + CHILD=$child > + > + echo $child >> /cpusets/user/tasks > + if [ $? -ne 0 ]; then > + kill -9 $child > + die "Failed to isolate task..." > + fi > + > + wait_app_started $child > + wait $child > +} > + > +check_prequesties() { > + local base=$(dirname $0) > + > + [ -e $base/isolate-cpu.sh ] || die "$base/isolate-cpu.sh not found!" > + [ $UID -eq 0 ] || die "You need to be root!" > + which stress > /dev/null 2>&1 || die "stress command not found, "\ > + "please install stress" > +} > + > +## > +# Script entry point > +## > + > +ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > + > +while getopts hdnc: arguments > +do > + case $arguments in > + h) > + print_usage > + exit 0 > + ;; > + d) > + DEBUG=1 > + ;; > + n) > + NOISE=1 > + ;; > + c) > + ISOL_CPUS=$OPTARG > + ;; > + *) > + print_usage > + exit 1 > + ;; > + esac > +done > +# Remove all flags > +shift $((OPTIND-1)) > + > +if ! [ "$1" ]; then > + print_usage > + exit 1 > +fi > + > +#Isolate and optionally create noise > +command="$*" > +set -- $command > + > +check_prequesties > + > +MY_STRESS=stress-by-$$ > +MY_STRESS_PATH=/tmp/$MY_STRESS > + > +isolate_cpu $ISOL_CPUS || die "isolate cpu failed!" > +[ -z $NOISE ] || create_noise $MY_STRESS_PATH > +run_application "$command" > + > +exit $? > diff --git a/test/linux-generic/performance/odp_run_app_isolated.sh b/test/linux-generic/performance/odp_run_app_isolated.sh > new file mode 100755 > index 0000000..3bed0a7 > --- /dev/null > +++ b/test/linux-generic/performance/odp_run_app_isolated.sh there is a mix of spaces and tabs for indentation in this script > @@ -0,0 +1,108 @@ > +#!/bin/sh > +# > +# Copyright (c) 2017, Linaro Limited > +# All rights reserved. > +# > +# SPDX-License-Identifier: BSD-3-Clause > +# > + > + > +TEST_DIR="${TEST_DIR:-$(dirname $0)}" > +PERFORMANCE="$TEST_DIR/../../common_plat/performance" > +ISOL_DIR="${TEST_DIR}/../../../scripts/task-isolation" > +APPLICATION="${PERFORMANCE}/odp_pktio_perf${EXEEXT}" > +APPLICATION_ARGS="" > +APPLICATION_BASE="$(basename ${APPLICATION})" > + > +cleanup(){ > + pids=$(pgrep stress 2>/dev/null) > + [ "$pids" != "" ] && kill -9 $pids > +} > + > +print_usage() { > + echo "$0 [-i] [-n] [-h] [<application> <application args>]" > + echo > + echo " Run an application with or without isolation and background noise" > + echo " Flags:" > + echo " -h Print this message" > + echo " -i Isolate CPU prior to running application." > + echo " -n Create background noise (stress)" > + echo "" > + echo " <application> targeted application" > + echo " <args> targeted application arguments" > + echo " *Note* Default application is ${APPLICATION_BASE}" > + echo "" > + echo " Example:" > + echo " Isolate CPU, create background noise and run ${APPLICATION_BASE}:" > + echo " $0 -i -n" > + echo > + echo " Run ${APPLICATION_BASE}, w/o isolation but with background noise:" > + echo " $0 -n" > + echo > + echo " Run Myapp, without isolation but with background noise:" > + echo " $0 -n Myapp -s ome args" > +} > + > +run() { > + local isolate=$1 > + local noise=$2 > + if [ ${isolate} -eq 1 ]; then > + [ ${noise} -eq 1 ] && noise_par="-n" > + echo Running ${APPLICATION_BASE} with isolation and background noise > + echo ===================================================== > + $ISOL_DIR/isolate-task.sh ${noise_par} ${APPLICATION} \ > + ${APPLICATION_ARGS} || exit 1 > + #reset isolation > + $ISOL_DIR/isolate-cpu.sh -r > + else > + echo Running ${APPLICATION_BASE} without isolation > + echo ===================================================== > + if [ ${noise} -eq 1 ]; then > + local nr=$(grep processor /proc/cpuinfo | wc -l) > + echo " Creating background noise..." > + stress -c $nr 2>&1 >/dev/null & > + fi > + ${APPLICATION} ${APPLICATION_ARGS} || exit 2 > + fi > +} > + > +trap cleanup INT EXIT > +ISOLATE=0 > +NOISE=0 > +while getopts hni arguments > +do > + case $arguments in > + h) > + print_usage > + exit 0 > + ;; > + n) > + NOISE=1 > + $(which stress > /dev/null 2>&1) > + ret=$? > + if [ ${ret} -ne 0 ]; then or: if ! $(which stress > /dev/null 2>&1); then > + echo "'stress' not found, bailing" >&2 > + exit 3 > + fi > + ;; > + i) > + ISOLATE=1 > + ;; > + *) > + print_usage > + exit 1 > + ;; > + esac > +done > +#Remove flags > +shift $((OPTIND-1)) > + > +if [ $# -gt 0 ]; then > + APPLICATION="$1" > + shift > +fi > +[ $# -gt 0 ] && APPLICATION_ARGS=$* > + > +run ${ISOLATE} ${NOISE} > + > +exit $? not needed, the script will exit with the exit value of the last command executed. > -- > 2.7.4 >
interesting if checpatch is ok, git am warns on spaces in intent: git am -s /tmp/11/\[PATCH\ v3\]\ validation\:\ A\ wrapper\ script\ to\ run\ test\ isolated..eml Applying: validation: A wrapper script to run test isolated. .git/rebase-apply/patch:24: indent with spaces. the desired task. It also provides the possibility .git/rebase-apply/patch:25: indent with spaces. to trace kernel disturbance on the isolated CPUs. .git/rebase-apply/patch:106: indent with spaces. if [[ $str == *[\-]* ]]; then .git/rebase-apply/patch:107: indent with spaces. str=$(echo $str| sed 's/-/../g') .git/rebase-apply/patch:108: indent with spaces. str=$(eval echo {$str}) warning: squelched 88 whitespace errors warning: 93 lines add whitespace errors. 17:08 /opt/Linaro/odp3.git (master)$git format-patch HEAD^ 0001-validation-A-wrapper-script-to-run-test-isolated.patch 17:09 /opt/Linaro/odp3.git (master)$perl ./scripts/checkpatch.pl 0001-validation-A-wrapper-script-to-run-test-isolated.patch total: 0 errors, 0 warnings, 0 checks, 577 lines checked NOTE: Ignored message types: BIT_MACRO COMPARISON_TO_NULL DEPRECATED_VARIABLE NEW_TYPEDEFS SPLIT_STRING SSCANF_TO_KSTRTO 0001-validation-A-wrapper-script-to-run-test-isolated.patch has no obvious style problems and is ready for submission. On 02/16/17 13:42, Josep Puigdemont wrote: > On Thu, Feb 16, 2017 at 09:52:37AM +0100, Ravineet Singh wrote: >> The wrapper script; odp_run_app_isolated.sh can be used to run ODP >> testcases in a isolated environment. Background noise can also be >> generated. >> >> Signed-off-by: Ravineet Singh <ravineet.singh@linaro.org> >> >> v2: moved task-isolation dir to odp/scripts, requested my Maxim Uvarov >> v3: fixed checkpatch.pl warnings >> --- >> scripts/task-isolation/README | 22 ++ >> scripts/task-isolation/isolate-cpu.sh | 287 +++++++++++++++++++++ >> scripts/task-isolation/isolate-task.sh | 160 ++++++++++++ >> .../performance/odp_run_app_isolated.sh | 108 ++++++++ >> 4 files changed, 577 insertions(+) >> create mode 100644 scripts/task-isolation/README >> create mode 100755 scripts/task-isolation/isolate-cpu.sh >> create mode 100755 scripts/task-isolation/isolate-task.sh >> create mode 100755 test/linux-generic/performance/odp_run_app_isolated.sh >> >> diff --git a/scripts/task-isolation/README b/scripts/task-isolation/README >> new file mode 100644 >> index 0000000..cb02056 >> --- /dev/null >> +++ b/scripts/task-isolation/README >> @@ -0,0 +1,22 @@ >> +Helper scripts to check and set CPU isolation and execution of application in >> +isolated CPU(s) >> + >> +Files: >> +isolate-cpu.sh isolates desired CPUs >> +isolate-task.sh uses isolate-cpu.sh to isolate CPUs before running >> + the desired task. It also provides the possibility >> + to trace kernel disturbance on the isolated CPUs. >> + >> +isolate-cpu.sh checks the kernel configuration and the kernel cmdline to >> + determine if one or several CPUs are isolated, i.e. it checks for; >> + CONFIG_NO_HZ_FULL_ALL=y", and CONFIG_RCU_NOCB_CPU_ALL=y" in the kernel config >> + and rcu_nocbs,nohz_full in the kernel cmdline. >> + If the desired CPU(s) are not inte the above configuration, it warns but continues >> + to isolate the CPU(s) as much as possibe. The isolation is accomplished by >> + - Redirecting all IRQ's away from desired isolated cores >> + - Using cset (cpuset) to move all running processes and kernel threads >> + away from desired isolated cores >> + >> +isolate-task.sh uses isolate-cpu.sh to isolate desired CPU(s). In addition >> + it starts the supplied application on isolated CPU(s) and optionally traces >> + the isolated CPU(s) for kernel interaction. >> diff --git a/scripts/task-isolation/isolate-cpu.sh b/scripts/task-isolation/isolate-cpu.sh >> new file mode 100755 >> index 0000000..3eaf98a >> --- /dev/null >> +++ b/scripts/task-isolation/isolate-cpu.sh >> @@ -0,0 +1,287 @@ >> +#!/bin/bash >> +# >> +# Copyright (c) 2017, Linaro Limited >> +# All rights reserved. >> +# >> +# SPDX-License-Identifier: BSD-3-Clause >> +# >> +# Script that passes command line arguments to odp_scheduling after, >> +# optionally, isolating CPU >> +# >> +# This script isolates desired CPUS, i.e. >> +# - Checks kernel cmdline and kernel config to determine >> +# if the environment is optimised for isolated task execution; >> +# - Moves CPU interrupts, kernel threads, tasks etc. away from the >> +# targeted CPU. >> +# *Note* CPU 0 cannot be isolated, i.e minimum 2 CPU's are required. >> + >> + >> +print_usage() { >> + echo "$0 [-h] [-a] [-c <cpu list>] [-l] [-r] [-d]" >> + echo >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" >> + echo " Args:" >> + echo " -h Print this message" >> + echo " -a Isolate all CPUs (except CPU 0)" >> + echo " -c List of CPUs to be isolated." >> + echo " -l Show isolation proporties" >> + echo " -r Reset isolation" >> + echo " -d Show debug printouts" >> + echo "" >> + echo " Examples:" >> + echo " Isolate all CPU(s) (except 0) " >> + echo " $0 -a" >> + echo >> + echo " Isolate CPUs 1-3 " >> + echo " $0 -c 1-3" >> + echo >> + echo " Isolate CPUs 1 and 4 " >> + echo " $0 -c 1,4 " > > maybe use a here document? > >> +} >> + >> +dlog() { >> + [ $DEBUG ] && echo "$*" >> +} >> + >> +warn() { >> + printf "Warning: $*\n" >&2 >> +} >> + >> +die() { >> + printf "Error: $*\n" >&2 >> + exit 1 >> +} >> + >> +get_cpu_array() { >> + [ $1 ] || die "$FUNCNAME internal error!" >> + >> + local cpus="" >> + IFS=. a=$1; IFS=, a=$a; > > I don't understand why IFS=. is needed... > Also, shouldn't IFS be restored here? > >> + for str in $a; do >> + if [[ $str == *[\-]* ]]; then >> + str=$(echo $str| sed 's/-/../g') >> + str=$(eval echo {$str}) >> + fi > > nice! > >> + >> + if [ "$cpus" != "" ]; then >> + cpus="$cpus $str" >> + else >> + cpus=$str >> + fi > > you can probably get away with cpus="$cpus $str" > >> + done >> + >> + echo $cpus >> +} >> + >> +## >> +# Check kernel config and kernel cmdline for rcu callbacs and no_hz >> +# *Note* isolcpu= kernel cmdline option isolates CPUs from SMP balancing >> +# If needed, this can be done via >> +# cpusets/user/cpuset.sched_load_balance >> +## >> +check_kernel_config() { >> + >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') >> + >> + local configs="/proc/config.gz /boot/config-$(uname -r) /boot/config " >> + dlog "Looking for Kernel configs; $configs " >> + for config in $configs; do >> + if [ -e $config ]; then >> + dlog "Kenel configuration found:$config" >> + break >> + fi >> + done >> + >> + local all_except_0="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" >> + if [ $config ]; then > > I think this will always be evaluated to true, shouldn't it be > if [ -e $config ] ? or even -r $config? > >> + nohz_full=$(zgrep "CONFIG_NO_HZ_FULL_ALL=y" $config 2>/dev/null) \ >> + && nohz_full=$all_except_0 >> + else >> + warn "Kernel config not found, only checking /proc/cmdline for"\ >> + " isolation features." >> + fi >> + >> + if ! [ "$nohz_full" ]; then >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') > > no need to pipe: grep ... /proc/cmdline > >> + fi >> + >> + eval $(cat /proc/cmdline | grep -o 'isolcpus=[^ ]*') > > ditto > >> + if [ -z "$isolcpus" ]; then >> + warn "No CPU is isolated from kernel/user threads, isolcpus= is "\ >> + "not set in kernel cmdline." >> + else >> + gbl_isolated_cpus=$isolcpus >> + export gbl_isolated_cpus >> + fi >> + >> + if [ -z "$nohz_full" ]; then >> + warn "No CPU is isolated from kernel ticks, CONFIG_NO_HZ_FULL_ALL=y" \ >> + " not set in kernel, nor nohz_full= set in kernel cmdline." >> + fi >> + >> + for i in `pgrep rcu` ; do taskset -pc 0 $i >/dev/null; done > > can you do this? > >> + >> + dlog "isolcpus:$isolcpus" >> + dlog "nohz_full:$nohz_full" >> + #dlog "rcu_nocbs:$rcu_nocbs" >> + >> + return 0 >> +} >> + >> +cpus_valid() { >> + local cpus="$1" >> + local isolated=$2 >> + local iarray=$(get_cpu_array $isolated) >> + local carray=$(get_cpu_array $cpus) >> + >> + for c in $carray; do >> + for i in $iarray; do > > maybe check that the user didn't provide 0 as a CPU to isolate? > >> + if [ $i = $c ]; then >> + yah=$i >> + fi >> + done >> + [ -z "$yah" ] && return 1 >> + done >> + >> + return 0 >> +} >> + >> +check_prequesties() { >> + dlog "Checking prequesties; user is root, kernel has cpuset support,"\ >> + " and commads; set, zgrep, getconf are available" >> + [ $UID -eq 0 ] || die "You need to be root!" >> + grep -q -s cpuset /proc/filesystems || die "Kernel does not support cpuset!" >> + which getconf > /dev/null 2>&1 || die "getconf command not found, please "\ >> + "install getconf" >> + which cset > /dev/null 2>&1 || die "cset command not found, please "\ >> + "install cpuset" >> + which zgrep > /dev/null 2>&1 || die "zgrep command not found, please "\ >> + "install gzip" >> +} >> + >> +shield_reset() { >> + cset shield -r >/dev/null 2>&1 >> + sleep 0.1 >> +} >> + >> +shield_list() { >> + sets="/cpusets/*/" >> + for i in $sets ; do >> + if ! [ -e $i ]; then >> + continue >> + fi >> + printf "Domain %s cpus %s, running %d tasks\n" \ >> + $(basename $i) $(cat $i/cpuset.cpus) $(cat $i/tasks | wc -l) >> + done >> +} >> + >> +shield_cpus() { >> + local cpus="$1" >> + >> + dlog "shielding CPU:s $cpus" >> + >> + #Reset and create new shield >> + shield_reset >> + out=$(cset shield -c $cpus -k on 2>&1) || die "cset failed; $out" >> + # Delay the annoying vmstat timer far away >> + sysctl vm.stat_interval=120 >/dev/null >> + >> + # Shutdown nmi watchdog as it uses perf events >> + sysctl -w kernel.watchdog=0 >/dev/null >> + >> + # Pin the writeback workqueue to CPU0 >> + #Fixme, check that /sys/bus is mounted? >> + echo 1 > /sys/bus/workqueue/devices/writeback/cpumask >> + >> + # Disable load balanser. > > balancer > >> + echo 0 > /cpusets/user/cpuset.sched_load_balance >> + >> + #Fixme, for now just send all irqs to core 0 >> + for affinity in /proc/irq/*/smp_affinity; do >> + dlog "redirecting $affinity" >> + echo 1 > $affinity 2>/dev/null || dlog "$affinity redirection failed." >> + done >> + >> + >> + #Fixme, not implemented. >> + if [ $false ]; then >> + for affinity in /proc/irq/*/smp_affinity; do >> + local old_mask=$(cat $affinity) >> + local new_mask=$((oldmask ^ cpus )) >> + echo $new_mask > $affinity >> + done >> + fi >> +} >> + >> +isolate_cpus() { >> + >> + local cpus="$1" >> + >> + check_kernel_config >> + >> + if [ "$gbl_isolated_cpus" ]; then >> + cpus_valid $cpus $gbl_isolated_cpus || >> + warn "Selected CPU '$cpus' is not inside isolated cpus "\ >> + "array:$gbl_isolated_cpus" >> + fi >> + >> + dlog "Isolating CPUs $cpus" >> + >> + shield_cpus $cpus >> + >> + # Verfiy cores empty >> + for c in $(get_cpu_array $cpus); do >> + running=$(ps ax -o pid,psr,comm | \ >> + awk -v cpu="$c" '{if($2==cpu){print $3}}') >> + if [ "$running" != "" ]; then >> + warn "Core $c not empty!" >> + dlog "; running tasks:\n$running\n" >> + fi >> + done > > indentation (tabs used here but spaces above) > >> + >> + return 0 >> +} >> + >> +## >> +# Script entry point >> +## >> +while getopts hdarlc: arguments >> +do >> + case $arguments in >> + h) >> + print_usage >> + exit 0 >> + ;; >> + d) >> + DEBUG=1 >> + ;; >> + a) >> + ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" >> + ;; >> + r) >> + shield_reset >> + exit 0 >> + ;; >> + l) >> + shield_list >> + exit 0 >> + ;; >> + c) >> + [ "$ISOL_CPUS" ] || ISOL_CPUS=$OPTARG >> + ;; >> + *) >> + print_usage >> + exit 1 >> + ;; >> + esac >> +done >> +#Remove all flags >> +shift $((OPTIND-1)) >> + >> +if ! [ $ISOL_CPUS ]; then >> + print_usage >> + exit 1 >> +fi >> + >> +check_prequesties >> +isolate_cpus $ISOL_CPUS || die "isolate_cpus failed." > > isolate_cpus() always retuns success... > >> diff --git a/scripts/task-isolation/isolate-task.sh b/scripts/task-isolation/isolate-task.sh >> new file mode 100755 >> index 0000000..3e588bc >> --- /dev/null >> +++ b/scripts/task-isolation/isolate-task.sh >> @@ -0,0 +1,160 @@ >> +#!/bin/bash >> +# >> +# Copyright (c) 2017, Linaro Limited >> +# All rights reserved. >> +# >> +# SPDX-License-Identifier: BSD-3-Clause >> +# >> +# Script that passes command line arguments to odp_scheduling after, >> +# optionally, isolating CPU >> +# >> +# This script isolates a task on desired CPUs and >> +# optionally creates background noise. >> + >> +print_usage() { >> + echo "$0 [-c <cpu list>] [-d] [-h] [-n] <application arg1, arg2, ...>" >> + echo >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" >> + echo " and run an application on isolated CPUs" >> + echo " Args:" >> + echo " -c List of CPUs to be isolated" >> + echo " -d Show debug printouts" >> + echo " -h Print this message" >> + echo " -n Create background noise (stress)" >> + echo "" >> + echo "All CPU's, except CPU 0, are isolated unless '-c' specified" >> + echo " Examples:" >> + echo " Isolate CPU 1,2 and run application in the same." >> + echo " $0 -n -c 1,2 /some/path/application" >> + echo >> + echo " Isolate all possible CPUs and run applicatipon" >> + echo " $0 /path/application" >> +} >> + >> +dlog() { >> + [ $DEBUG ] && echo "$*" >> +} >> + >> +die() { >> + printf "Error: $*\n" >&2 >> + exit 1 >> +} >> + >> +trap cleanup INT EXIT >> + >> +cleanup(){ >> + local pids=$(pgrep $MY_STRESS 2>/dev/null) >> + local base=$(dirname $0) >> + >> + $base/isolate-cpu.sh -r >> + [ "$pids" != "" ] && kill -9 $pids >/dev/null 2>&1 >> + kill -9 $CHILD >/dev/null 2>&1 >> + rm -f $MY_STRESS_PATH >> +} >> + >> +wait_app_started () { >> + local child=$1 >> + local ltasks=0 >> + >> + while true; do >> + sleep 0.01 >> + kill -0 $child 2>/dev/null || break >> + tasks=$(ls /proc/$child/task | wc -l) >> + [ $tasks -eq $ltasks ] && break >> + ltasks=$tasks >> + done >> + dlog "app started, # threads:$ltasks" >> +} >> + >> +create_noise() { >> + local mpath=$1 >> + local nr=$(grep processor /proc/cpuinfo | wc -l) >> + >> + ln -sf $(which stress) $mpath || die "ln failed" >> + $mpath -c $nr 2>&1 >/dev/null & >> + disown $! >> +} >> + >> +isolate_cpu(){ >> + local cpus=$1 >> + local base=$(dirname $0) >> + $base/isolate-cpu.sh -c $cpus || die "$0 failed" >> +} >> + >> +run_application() { >> + local app="$1" >> + >> + dlog "Starting application: $app" >> + $app& >> + child=$! >> + CHILD=$child >> + >> + echo $child >> /cpusets/user/tasks >> + if [ $? -ne 0 ]; then >> + kill -9 $child >> + die "Failed to isolate task..." >> + fi >> + >> + wait_app_started $child >> + wait $child >> +} >> + >> +check_prequesties() { >> + local base=$(dirname $0) >> + >> + [ -e $base/isolate-cpu.sh ] || die "$base/isolate-cpu.sh not found!" >> + [ $UID -eq 0 ] || die "You need to be root!" >> + which stress > /dev/null 2>&1 || die "stress command not found, "\ >> + "please install stress" >> +} >> + >> +## >> +# Script entry point >> +## >> + >> +ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" >> + >> +while getopts hdnc: arguments >> +do >> + case $arguments in >> + h) >> + print_usage >> + exit 0 >> + ;; >> + d) >> + DEBUG=1 >> + ;; >> + n) >> + NOISE=1 >> + ;; >> + c) >> + ISOL_CPUS=$OPTARG >> + ;; >> + *) >> + print_usage >> + exit 1 >> + ;; >> + esac >> +done >> +# Remove all flags >> +shift $((OPTIND-1)) >> + >> +if ! [ "$1" ]; then >> + print_usage >> + exit 1 >> +fi >> + >> +#Isolate and optionally create noise >> +command="$*" >> +set -- $command >> + >> +check_prequesties >> + >> +MY_STRESS=stress-by-$$ >> +MY_STRESS_PATH=/tmp/$MY_STRESS >> + >> +isolate_cpu $ISOL_CPUS || die "isolate cpu failed!" >> +[ -z $NOISE ] || create_noise $MY_STRESS_PATH >> +run_application "$command" >> + >> +exit $? >> diff --git a/test/linux-generic/performance/odp_run_app_isolated.sh b/test/linux-generic/performance/odp_run_app_isolated.sh >> new file mode 100755 >> index 0000000..3bed0a7 >> --- /dev/null >> +++ b/test/linux-generic/performance/odp_run_app_isolated.sh > > there is a mix of spaces and tabs for indentation in this script > >> @@ -0,0 +1,108 @@ >> +#!/bin/sh >> +# >> +# Copyright (c) 2017, Linaro Limited >> +# All rights reserved. >> +# >> +# SPDX-License-Identifier: BSD-3-Clause >> +# >> + >> + >> +TEST_DIR="${TEST_DIR:-$(dirname $0)}" >> +PERFORMANCE="$TEST_DIR/../../common_plat/performance" >> +ISOL_DIR="${TEST_DIR}/../../../scripts/task-isolation" >> +APPLICATION="${PERFORMANCE}/odp_pktio_perf${EXEEXT}" >> +APPLICATION_ARGS="" >> +APPLICATION_BASE="$(basename ${APPLICATION})" >> + >> +cleanup(){ >> + pids=$(pgrep stress 2>/dev/null) >> + [ "$pids" != "" ] && kill -9 $pids >> +} >> + >> +print_usage() { >> + echo "$0 [-i] [-n] [-h] [<application> <application args>]" >> + echo >> + echo " Run an application with or without isolation and background noise" >> + echo " Flags:" >> + echo " -h Print this message" >> + echo " -i Isolate CPU prior to running application." >> + echo " -n Create background noise (stress)" >> + echo "" >> + echo " <application> targeted application" >> + echo " <args> targeted application arguments" >> + echo " *Note* Default application is ${APPLICATION_BASE}" >> + echo "" >> + echo " Example:" >> + echo " Isolate CPU, create background noise and run ${APPLICATION_BASE}:" >> + echo " $0 -i -n" >> + echo >> + echo " Run ${APPLICATION_BASE}, w/o isolation but with background noise:" >> + echo " $0 -n" >> + echo >> + echo " Run Myapp, without isolation but with background noise:" >> + echo " $0 -n Myapp -s ome args" >> +} >> + >> +run() { >> + local isolate=$1 >> + local noise=$2 >> + if [ ${isolate} -eq 1 ]; then >> + [ ${noise} -eq 1 ] && noise_par="-n" >> + echo Running ${APPLICATION_BASE} with isolation and background noise >> + echo ===================================================== >> + $ISOL_DIR/isolate-task.sh ${noise_par} ${APPLICATION} \ >> + ${APPLICATION_ARGS} || exit 1 >> + #reset isolation >> + $ISOL_DIR/isolate-cpu.sh -r >> + else >> + echo Running ${APPLICATION_BASE} without isolation >> + echo ===================================================== >> + if [ ${noise} -eq 1 ]; then >> + local nr=$(grep processor /proc/cpuinfo | wc -l) >> + echo " Creating background noise..." >> + stress -c $nr 2>&1 >/dev/null & >> + fi >> + ${APPLICATION} ${APPLICATION_ARGS} || exit 2 >> + fi >> +} >> + >> +trap cleanup INT EXIT >> +ISOLATE=0 >> +NOISE=0 >> +while getopts hni arguments >> +do >> + case $arguments in >> + h) >> + print_usage >> + exit 0 >> + ;; >> + n) >> + NOISE=1 >> + $(which stress > /dev/null 2>&1) >> + ret=$? >> + if [ ${ret} -ne 0 ]; then > > or: > if ! $(which stress > /dev/null 2>&1); then > >> + echo "'stress' not found, bailing" >&2 >> + exit 3 >> + fi >> + ;; >> + i) >> + ISOLATE=1 >> + ;; >> + *) >> + print_usage >> + exit 1 >> + ;; >> + esac >> +done >> +#Remove flags >> +shift $((OPTIND-1)) >> + >> +if [ $# -gt 0 ]; then >> + APPLICATION="$1" >> + shift >> +fi >> +[ $# -gt 0 ] && APPLICATION_ARGS=$* >> + >> +run ${ISOLATE} ${NOISE} >> + >> +exit $? > > not needed, the script will exit with the exit value of the last > command executed. > >> -- >> 2.7.4 >>
checkpatch is designed for the kernel C code so we have to use some judgment, as for git there are cases it makes no sence On 17 February 2017 at 09:10, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > interesting if checpatch is ok, git am warns on spaces in intent: > > > git am -s /tmp/11/\[PATCH\ v3\]\ validation\:\ A\ wrapper\ script\ to\ > run\ test\ isolated..eml > Applying: validation: A wrapper script to run test isolated. > .git/rebase-apply/patch:24: indent with spaces. > the desired task. It also provides the possibility > This is Human text in a readme file, do we want or need to enforce tabs here ? > .git/rebase-apply/patch:25: indent with spaces. > to trace kernel disturbance on the isolated CPUs. > .git/rebase-apply/patch:106: indent with spaces. > if [[ $str == *[\-]* ]]; then > .git/rebase-apply/patch:107: indent with spaces. > str=$(echo $str| sed 's/-/../g') > .git/rebase-apply/patch:108: indent with spaces. > str=$(eval echo {$str}) > warning: squelched 88 whitespace errors > warning: 93 lines add whitespace errors. > 17:08 /opt/Linaro/odp3.git (master)$git format-patch HEAD^ > 0001-validation-A-wrapper-script-to-run-test-isolated.patch > 17:09 /opt/Linaro/odp3.git (master)$perl ./scripts/checkpatch.pl > 0001-validation-A-wrapper-script-to-run-test-isolated.patch > total: 0 errors, 0 warnings, 0 checks, 577 lines checked > > NOTE: Ignored message types: BIT_MACRO COMPARISON_TO_NULL > DEPRECATED_VARIABLE NEW_TYPEDEFS SPLIT_STRING SSCANF_TO_KSTRTO > > 0001-validation-A-wrapper-script-to-run-test-isolated.patch has no > obvious style problems and is ready for submission. > > > > On 02/16/17 13:42, Josep Puigdemont wrote: > > On Thu, Feb 16, 2017 at 09:52:37AM +0100, Ravineet Singh wrote: > >> The wrapper script; odp_run_app_isolated.sh can be used to run ODP > >> testcases in a isolated environment. Background noise can also be > >> generated. > >> > >> Signed-off-by: Ravineet Singh <ravineet.singh@linaro.org> > >> > >> v2: moved task-isolation dir to odp/scripts, requested my Maxim Uvarov > >> v3: fixed checkpatch.pl warnings > >> --- > >> scripts/task-isolation/README | 22 ++ > >> scripts/task-isolation/isolate-cpu.sh | 287 > +++++++++++++++++++++ > >> scripts/task-isolation/isolate-task.sh | 160 ++++++++++++ > >> .../performance/odp_run_app_isolated.sh | 108 ++++++++ > >> 4 files changed, 577 insertions(+) > >> create mode 100644 scripts/task-isolation/README > >> create mode 100755 scripts/task-isolation/isolate-cpu.sh > >> create mode 100755 scripts/task-isolation/isolate-task.sh > >> create mode 100755 test/linux-generic/performance/odp_run_app_ > isolated.sh > >> > >> diff --git a/scripts/task-isolation/README b/scripts/task-isolation/ > README > >> new file mode 100644 > >> index 0000000..cb02056 > >> --- /dev/null > >> +++ b/scripts/task-isolation/README > >> @@ -0,0 +1,22 @@ > >> +Helper scripts to check and set CPU isolation and execution of > application in > >> +isolated CPU(s) > >> + > >> +Files: > >> +isolate-cpu.sh isolates desired CPUs > >> +isolate-task.sh uses isolate-cpu.sh to isolate CPUs before running > >> + the desired task. It also provides the possibility > >> + to trace kernel disturbance on the isolated CPUs. > >> + > >> +isolate-cpu.sh checks the kernel configuration and the kernel cmdline > to > >> + determine if one or several CPUs are isolated, i.e. it checks for; > >> + CONFIG_NO_HZ_FULL_ALL=y", and CONFIG_RCU_NOCB_CPU_ALL=y" in the > kernel config > >> + and rcu_nocbs,nohz_full in the kernel cmdline. > >> + If the desired CPU(s) are not inte the above configuration, it warns > but continues > >> + to isolate the CPU(s) as much as possibe. The isolation is > accomplished by > >> + - Redirecting all IRQ's away from desired isolated cores > >> + - Using cset (cpuset) to move all running processes and kernel threads > >> + away from desired isolated cores > >> + > >> +isolate-task.sh uses isolate-cpu.sh to isolate desired CPU(s). In > addition > >> + it starts the supplied application on isolated CPU(s) and optionally > traces > >> + the isolated CPU(s) for kernel interaction. > >> diff --git a/scripts/task-isolation/isolate-cpu.sh > b/scripts/task-isolation/isolate-cpu.sh > >> new file mode 100755 > >> index 0000000..3eaf98a > >> --- /dev/null > >> +++ b/scripts/task-isolation/isolate-cpu.sh > >> @@ -0,0 +1,287 @@ > >> +#!/bin/bash > >> +# > >> +# Copyright (c) 2017, Linaro Limited > >> +# All rights reserved. > >> +# > >> +# SPDX-License-Identifier: BSD-3-Clause > >> +# > >> +# Script that passes command line arguments to odp_scheduling after, > >> +# optionally, isolating CPU > >> +# > >> +# This script isolates desired CPUS, i.e. > >> +# - Checks kernel cmdline and kernel config to determine > >> +# if the environment is optimised for isolated task execution; > >> +# - Moves CPU interrupts, kernel threads, tasks etc. away from the > >> +# targeted CPU. > >> +# *Note* CPU 0 cannot be isolated, i.e minimum 2 CPU's are required. > >> + > >> + > >> +print_usage() { > >> + echo "$0 [-h] [-a] [-c <cpu list>] [-l] [-r] [-d]" > >> + echo > >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" > >> + echo " Args:" > >> + echo " -h Print this message" > >> + echo " -a Isolate all CPUs (except CPU 0)" > >> + echo " -c List of CPUs to be isolated." > >> + echo " -l Show isolation proporties" > >> + echo " -r Reset isolation" > >> + echo " -d Show debug printouts" > >> + echo "" > >> + echo " Examples:" > >> + echo " Isolate all CPU(s) (except 0) " > >> + echo " $0 -a" > >> + echo > >> + echo " Isolate CPUs 1-3 " > >> + echo " $0 -c 1-3" > >> + echo > >> + echo " Isolate CPUs 1 and 4 " > >> + echo " $0 -c 1,4 " > > > > maybe use a here document? > > > >> +} > >> + > >> +dlog() { > >> + [ $DEBUG ] && echo "$*" > >> +} > >> + > >> +warn() { > >> + printf "Warning: $*\n" >&2 > >> +} > >> + > >> +die() { > >> + printf "Error: $*\n" >&2 > >> + exit 1 > >> +} > >> + > >> +get_cpu_array() { > >> + [ $1 ] || die "$FUNCNAME internal error!" > >> + > >> + local cpus="" > >> + IFS=. a=$1; IFS=, a=$a; > > > > I don't understand why IFS=. is needed... > > Also, shouldn't IFS be restored here? > > > >> + for str in $a; do > >> + if [[ $str == *[\-]* ]]; then > >> + str=$(echo $str| sed 's/-/../g') > >> + str=$(eval echo {$str}) > >> + fi > > > > nice! > > > >> + > >> + if [ "$cpus" != "" ]; then > >> + cpus="$cpus $str" > >> + else > >> + cpus=$str > >> + fi > > > > you can probably get away with cpus="$cpus $str" > > > >> + done > >> + > >> + echo $cpus > >> +} > >> + > >> +## > >> +# Check kernel config and kernel cmdline for rcu callbacs and no_hz > >> +# *Note* isolcpu= kernel cmdline option isolates CPUs from SMP > balancing > >> +# If needed, this can be done via > >> +# cpusets/user/cpuset.sched_load_balance > >> +## > >> +check_kernel_config() { > >> + > >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') > >> + > >> + local configs="/proc/config.gz /boot/config-$(uname -r) > /boot/config " > >> + dlog "Looking for Kernel configs; $configs " > >> + for config in $configs; do > >> + if [ -e $config ]; then > >> + dlog "Kenel configuration found:$config" > >> + break > >> + fi > >> + done > >> + > >> + local all_except_0="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > >> + if [ $config ]; then > > > > I think this will always be evaluated to true, shouldn't it be > > if [ -e $config ] ? or even -r $config? > > > >> + nohz_full=$(zgrep "CONFIG_NO_HZ_FULL_ALL=y" $config > 2>/dev/null) \ > >> + && nohz_full=$all_except_0 > >> + else > >> + warn "Kernel config not found, only checking /proc/cmdline > for"\ > >> + " isolation features." > >> + fi > >> + > >> + if ! [ "$nohz_full" ]; then > >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') > > > > no need to pipe: grep ... /proc/cmdline > > > >> + fi > >> + > >> + eval $(cat /proc/cmdline | grep -o 'isolcpus=[^ ]*') > > > > ditto > > > >> + if [ -z "$isolcpus" ]; then > >> + warn "No CPU is isolated from kernel/user threads, isolcpus= > is "\ > >> + "not set in kernel cmdline." > >> + else > >> + gbl_isolated_cpus=$isolcpus > >> + export gbl_isolated_cpus > >> + fi > >> + > >> + if [ -z "$nohz_full" ]; then > >> + warn "No CPU is isolated from kernel ticks, > CONFIG_NO_HZ_FULL_ALL=y" \ > >> + " not set in kernel, nor nohz_full= set in kernel cmdline." > >> + fi > >> + > >> + for i in `pgrep rcu` ; do taskset -pc 0 $i >/dev/null; done > > > > can you do this? > > > >> + > >> + dlog "isolcpus:$isolcpus" > >> + dlog "nohz_full:$nohz_full" > >> + #dlog "rcu_nocbs:$rcu_nocbs" > >> + > >> + return 0 > >> +} > >> + > >> +cpus_valid() { > >> + local cpus="$1" > >> + local isolated=$2 > >> + local iarray=$(get_cpu_array $isolated) > >> + local carray=$(get_cpu_array $cpus) > >> + > >> + for c in $carray; do > >> + for i in $iarray; do > > > > maybe check that the user didn't provide 0 as a CPU to isolate? > > > >> + if [ $i = $c ]; then > >> + yah=$i > >> + fi > >> + done > >> + [ -z "$yah" ] && return 1 > >> + done > >> + > >> + return 0 > >> +} > >> + > >> +check_prequesties() { > >> + dlog "Checking prequesties; user is root, kernel has cpuset > support,"\ > >> + " and commads; set, zgrep, getconf are available" > >> + [ $UID -eq 0 ] || die "You need to be root!" > >> + grep -q -s cpuset /proc/filesystems || die "Kernel does not > support cpuset!" > >> + which getconf > /dev/null 2>&1 || die "getconf command not found, > please "\ > >> + "install getconf" > >> + which cset > /dev/null 2>&1 || die "cset command not found, please > "\ > >> + "install cpuset" > >> + which zgrep > /dev/null 2>&1 || die "zgrep command not found, > please "\ > >> + "install gzip" > >> +} > >> + > >> +shield_reset() { > >> + cset shield -r >/dev/null 2>&1 > >> + sleep 0.1 > >> +} > >> + > >> +shield_list() { > >> + sets="/cpusets/*/" > >> + for i in $sets ; do > >> + if ! [ -e $i ]; then > >> + continue > >> + fi > >> + printf "Domain %s cpus %s, running %d tasks\n" \ > >> + $(basename $i) $(cat $i/cpuset.cpus) $(cat $i/tasks | wc -l) > >> + done > >> +} > >> + > >> +shield_cpus() { > >> + local cpus="$1" > >> + > >> + dlog "shielding CPU:s $cpus" > >> + > >> + #Reset and create new shield > >> + shield_reset > >> + out=$(cset shield -c $cpus -k on 2>&1) || die "cset failed; $out" > >> + # Delay the annoying vmstat timer far away > >> + sysctl vm.stat_interval=120 >/dev/null > >> + > >> + # Shutdown nmi watchdog as it uses perf events > >> + sysctl -w kernel.watchdog=0 >/dev/null > >> + > >> + # Pin the writeback workqueue to CPU0 > >> + #Fixme, check that /sys/bus is mounted? > >> + echo 1 > /sys/bus/workqueue/devices/writeback/cpumask > >> + > >> + # Disable load balanser. > > > > balancer > > > >> + echo 0 > /cpusets/user/cpuset.sched_load_balance > >> + > >> + #Fixme, for now just send all irqs to core 0 > >> + for affinity in /proc/irq/*/smp_affinity; do > >> + dlog "redirecting $affinity" > >> + echo 1 > $affinity 2>/dev/null || dlog "$affinity redirection > failed." > >> + done > >> + > >> + > >> + #Fixme, not implemented. > >> + if [ $false ]; then > >> + for affinity in /proc/irq/*/smp_affinity; do > >> + local old_mask=$(cat $affinity) > >> + local new_mask=$((oldmask ^ cpus )) > >> + echo $new_mask > $affinity > >> + done > >> + fi > >> +} > >> + > >> +isolate_cpus() { > >> + > >> + local cpus="$1" > >> + > >> + check_kernel_config > >> + > >> + if [ "$gbl_isolated_cpus" ]; then > >> + cpus_valid $cpus $gbl_isolated_cpus || > >> + warn "Selected CPU '$cpus' is not inside isolated cpus "\ > >> + "array:$gbl_isolated_cpus" > >> + fi > >> + > >> + dlog "Isolating CPUs $cpus" > >> + > >> + shield_cpus $cpus > >> + > >> + # Verfiy cores empty > >> + for c in $(get_cpu_array $cpus); do > >> + running=$(ps ax -o pid,psr,comm | \ > >> + awk -v cpu="$c" '{if($2==cpu){print $3}}') > >> + if [ "$running" != "" ]; then > >> + warn "Core $c not empty!" > >> + dlog "; running tasks:\n$running\n" > >> + fi > >> + done > > > > indentation (tabs used here but spaces above) > > > >> + > >> + return 0 > >> +} > >> + > >> +## > >> +# Script entry point > >> +## > >> +while getopts hdarlc: arguments > >> +do > >> + case $arguments in > >> + h) > >> + print_usage > >> + exit 0 > >> + ;; > >> + d) > >> + DEBUG=1 > >> + ;; > >> + a) > >> + ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > >> + ;; > >> + r) > >> + shield_reset > >> + exit 0 > >> + ;; > >> + l) > >> + shield_list > >> + exit 0 > >> + ;; > >> + c) > >> + [ "$ISOL_CPUS" ] || ISOL_CPUS=$OPTARG > >> + ;; > >> + *) > >> + print_usage > >> + exit 1 > >> + ;; > >> + esac > >> +done > >> +#Remove all flags > >> +shift $((OPTIND-1)) > >> + > >> +if ! [ $ISOL_CPUS ]; then > >> + print_usage > >> + exit 1 > >> +fi > >> + > >> +check_prequesties > >> +isolate_cpus $ISOL_CPUS || die "isolate_cpus failed." > > > > isolate_cpus() always retuns success... > > > >> diff --git a/scripts/task-isolation/isolate-task.sh > b/scripts/task-isolation/isolate-task.sh > >> new file mode 100755 > >> index 0000000..3e588bc > >> --- /dev/null > >> +++ b/scripts/task-isolation/isolate-task.sh > >> @@ -0,0 +1,160 @@ > >> +#!/bin/bash > >> +# > >> +# Copyright (c) 2017, Linaro Limited > >> +# All rights reserved. > >> +# > >> +# SPDX-License-Identifier: BSD-3-Clause > >> +# > >> +# Script that passes command line arguments to odp_scheduling after, > >> +# optionally, isolating CPU > >> +# > >> +# This script isolates a task on desired CPUs and > >> +# optionally creates background noise. > >> + > >> +print_usage() { > >> + echo "$0 [-c <cpu list>] [-d] [-h] [-n] <application arg1, arg2, > ...>" > >> + echo > >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" > >> + echo " and run an application on isolated CPUs" > >> + echo " Args:" > >> + echo " -c List of CPUs to be isolated" > >> + echo " -d Show debug printouts" > >> + echo " -h Print this message" > >> + echo " -n Create background noise (stress)" > >> + echo "" > >> + echo "All CPU's, except CPU 0, are isolated unless '-c' specified" > >> + echo " Examples:" > >> + echo " Isolate CPU 1,2 and run application in the same." > >> + echo " $0 -n -c 1,2 /some/path/application" > >> + echo > >> + echo " Isolate all possible CPUs and run applicatipon" > >> + echo " $0 /path/application" > >> +} > >> + > >> +dlog() { > >> + [ $DEBUG ] && echo "$*" > >> +} > >> + > >> +die() { > >> + printf "Error: $*\n" >&2 > >> + exit 1 > >> +} > >> + > >> +trap cleanup INT EXIT > >> + > >> +cleanup(){ > >> + local pids=$(pgrep $MY_STRESS 2>/dev/null) > >> + local base=$(dirname $0) > >> + > >> + $base/isolate-cpu.sh -r > >> + [ "$pids" != "" ] && kill -9 $pids >/dev/null 2>&1 > >> + kill -9 $CHILD >/dev/null 2>&1 > >> + rm -f $MY_STRESS_PATH > >> +} > >> + > >> +wait_app_started () { > >> + local child=$1 > >> + local ltasks=0 > >> + > >> + while true; do > >> + sleep 0.01 > >> + kill -0 $child 2>/dev/null || break > >> + tasks=$(ls /proc/$child/task | wc -l) > >> + [ $tasks -eq $ltasks ] && break > >> + ltasks=$tasks > >> + done > >> + dlog "app started, # threads:$ltasks" > >> +} > >> + > >> +create_noise() { > >> + local mpath=$1 > >> + local nr=$(grep processor /proc/cpuinfo | wc -l) > >> + > >> + ln -sf $(which stress) $mpath || die "ln failed" > >> + $mpath -c $nr 2>&1 >/dev/null & > >> + disown $! > >> +} > >> + > >> +isolate_cpu(){ > >> + local cpus=$1 > >> + local base=$(dirname $0) > >> + $base/isolate-cpu.sh -c $cpus || die "$0 failed" > >> +} > >> + > >> +run_application() { > >> + local app="$1" > >> + > >> + dlog "Starting application: $app" > >> + $app& > >> + child=$! > >> + CHILD=$child > >> + > >> + echo $child >> /cpusets/user/tasks > >> + if [ $? -ne 0 ]; then > >> + kill -9 $child > >> + die "Failed to isolate task..." > >> + fi > >> + > >> + wait_app_started $child > >> + wait $child > >> +} > >> + > >> +check_prequesties() { > >> + local base=$(dirname $0) > >> + > >> + [ -e $base/isolate-cpu.sh ] || die "$base/isolate-cpu.sh not > found!" > >> + [ $UID -eq 0 ] || die "You need to be root!" > >> + which stress > /dev/null 2>&1 || die "stress command not found, "\ > >> + "please install stress" > >> +} > >> + > >> +## > >> +# Script entry point > >> +## > >> + > >> +ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > >> + > >> +while getopts hdnc: arguments > >> +do > >> + case $arguments in > >> + h) > >> + print_usage > >> + exit 0 > >> + ;; > >> + d) > >> + DEBUG=1 > >> + ;; > >> + n) > >> + NOISE=1 > >> + ;; > >> + c) > >> + ISOL_CPUS=$OPTARG > >> + ;; > >> + *) > >> + print_usage > >> + exit 1 > >> + ;; > >> + esac > >> +done > >> +# Remove all flags > >> +shift $((OPTIND-1)) > >> + > >> +if ! [ "$1" ]; then > >> + print_usage > >> + exit 1 > >> +fi > >> + > >> +#Isolate and optionally create noise > >> +command="$*" > >> +set -- $command > >> + > >> +check_prequesties > >> + > >> +MY_STRESS=stress-by-$$ > >> +MY_STRESS_PATH=/tmp/$MY_STRESS > >> + > >> +isolate_cpu $ISOL_CPUS || die "isolate cpu failed!" > >> +[ -z $NOISE ] || create_noise $MY_STRESS_PATH > >> +run_application "$command" > >> + > >> +exit $? > >> diff --git a/test/linux-generic/performance/odp_run_app_isolated.sh > b/test/linux-generic/performance/odp_run_app_isolated.sh > >> new file mode 100755 > >> index 0000000..3bed0a7 > >> --- /dev/null > >> +++ b/test/linux-generic/performance/odp_run_app_isolated.sh > > > > there is a mix of spaces and tabs for indentation in this script > > > >> @@ -0,0 +1,108 @@ > >> +#!/bin/sh > >> +# > >> +# Copyright (c) 2017, Linaro Limited > >> +# All rights reserved. > >> +# > >> +# SPDX-License-Identifier: BSD-3-Clause > >> +# > >> + > >> + > >> +TEST_DIR="${TEST_DIR:-$(dirname $0)}" > >> +PERFORMANCE="$TEST_DIR/../../common_plat/performance" > >> +ISOL_DIR="${TEST_DIR}/../../../scripts/task-isolation" > >> +APPLICATION="${PERFORMANCE}/odp_pktio_perf${EXEEXT}" > >> +APPLICATION_ARGS="" > >> +APPLICATION_BASE="$(basename ${APPLICATION})" > >> + > >> +cleanup(){ > >> + pids=$(pgrep stress 2>/dev/null) > >> + [ "$pids" != "" ] && kill -9 $pids > >> +} > >> + > >> +print_usage() { > >> + echo "$0 [-i] [-n] [-h] [<application> <application args>]" > >> + echo > >> + echo " Run an application with or without isolation and background > noise" > >> + echo " Flags:" > >> + echo " -h Print this message" > >> + echo " -i Isolate CPU prior to running application." > >> + echo " -n Create background noise (stress)" > >> + echo "" > >> + echo " <application> targeted application" > >> + echo " <args> targeted application arguments" > >> + echo " *Note* Default application is ${APPLICATION_BASE}" > >> + echo "" > >> + echo " Example:" > >> + echo " Isolate CPU, create background noise and run > ${APPLICATION_BASE}:" > >> + echo " $0 -i -n" > >> + echo > >> + echo " Run ${APPLICATION_BASE}, w/o isolation but with background > noise:" > >> + echo " $0 -n" > >> + echo > >> + echo " Run Myapp, without isolation but with background noise:" > >> + echo " $0 -n Myapp -s ome args" > >> +} > >> + > >> +run() { > >> + local isolate=$1 > >> + local noise=$2 > >> + if [ ${isolate} -eq 1 ]; then > >> + [ ${noise} -eq 1 ] && noise_par="-n" > >> + echo Running ${APPLICATION_BASE} with isolation and background > noise > >> + echo ===================================================== > >> + $ISOL_DIR/isolate-task.sh ${noise_par} ${APPLICATION} \ > >> + ${APPLICATION_ARGS} || exit 1 > >> + #reset isolation > >> + $ISOL_DIR/isolate-cpu.sh -r > >> + else > >> + echo Running ${APPLICATION_BASE} without isolation > >> + echo ===================================================== > >> + if [ ${noise} -eq 1 ]; then > >> + local nr=$(grep processor /proc/cpuinfo | wc -l) > >> + echo " Creating background noise..." > >> + stress -c $nr 2>&1 >/dev/null & > >> + fi > >> + ${APPLICATION} ${APPLICATION_ARGS} || exit 2 > >> + fi > >> +} > >> + > >> +trap cleanup INT EXIT > >> +ISOLATE=0 > >> +NOISE=0 > >> +while getopts hni arguments > >> +do > >> + case $arguments in > >> + h) > >> + print_usage > >> + exit 0 > >> + ;; > >> + n) > >> + NOISE=1 > >> + $(which stress > /dev/null 2>&1) > >> + ret=$? > >> + if [ ${ret} -ne 0 ]; then > > > > or: > > if ! $(which stress > /dev/null 2>&1); then > > > >> + echo "'stress' not found, bailing" >&2 > >> + exit 3 > >> + fi > >> + ;; > >> + i) > >> + ISOLATE=1 > >> + ;; > >> + *) > >> + print_usage > >> + exit 1 > >> + ;; > >> + esac > >> +done > >> +#Remove flags > >> +shift $((OPTIND-1)) > >> + > >> +if [ $# -gt 0 ]; then > >> + APPLICATION="$1" > >> + shift > >> +fi > >> +[ $# -gt 0 ] && APPLICATION_ARGS=$* > >> + > >> +run ${ISOLATE} ${NOISE} > >> + > >> +exit $? > > > > not needed, the script will exit with the exit value of the last > > command executed. > > > >> -- > >> 2.7.4 > >> > > -- Mike Holmes Program Manager - Linaro Networking Group Linaro.org <http://www.linaro.org/> *│ *Open source software for ARM SoCs "Work should be fun and collaborative, the rest follows"
My bash does not understand that syntax: [ $UID -eq 0 ] || die "You need to be root!" + [ -eq 0 ] ./scripts/task-isolation/isolate-cpu.sh: 152: [: -eq: unexpected operator On 02/17/17 17:34, Mike Holmes wrote: > checkpatch is designed for the kernel C code so we have to use some > judgment, as for git there are cases it makes no sence > > On 17 February 2017 at 09:10, Maxim Uvarov <maxim.uvarov@linaro.org > <mailto:maxim.uvarov@linaro.org>> wrote: > > interesting if checpatch is ok, git am warns on spaces in intent: > > > git am -s /tmp/11/\[PATCH\ v3\]\ validation\:\ A\ wrapper\ script\ to\ > run\ test\ isolated..eml > Applying: validation: A wrapper script to run test isolated. > .git/rebase-apply/patch:24: indent with spaces. > the desired task. It also provides the possibility > > > This is Human text in a readme file, do we want or need to enforce tabs > here ? > > > > .git/rebase-apply/patch:25: indent with spaces. > to trace kernel disturbance on the isolated CPUs. > .git/rebase-apply/patch:106: indent with spaces. > if [[ $str == *[\-]* ]]; then > .git/rebase-apply/patch:107: indent with spaces. > str=$(echo $str| sed 's/-/../g') > .git/rebase-apply/patch:108: indent with spaces. > str=$(eval echo {$str}) > warning: squelched 88 whitespace errors > warning: 93 lines add whitespace errors. > 17:08 /opt/Linaro/odp3.git (master)$git format-patch HEAD^ > 0001-validation-A-wrapper-script-to-run-test-isolated.patch > 17:09 /opt/Linaro/odp3.git (master)$perl ./scripts/checkpatch.pl > <http://checkpatch.pl> > 0001-validation-A-wrapper-script-to-run-test-isolated.patch > total: 0 errors, 0 warnings, 0 checks, 577 lines checked > > NOTE: Ignored message types: BIT_MACRO COMPARISON_TO_NULL > DEPRECATED_VARIABLE NEW_TYPEDEFS SPLIT_STRING SSCANF_TO_KSTRTO > > 0001-validation-A-wrapper-script-to-run-test-isolated.patch has no > obvious style problems and is ready for submission. > > > > On 02/16/17 13:42, Josep Puigdemont wrote: > > On Thu, Feb 16, 2017 at 09:52:37AM +0100, Ravineet Singh wrote: > >> The wrapper script; odp_run_app_isolated.sh can be used to run ODP > >> testcases in a isolated environment. Background noise can also be > >> generated. > >> > >> Signed-off-by: Ravineet Singh <ravineet.singh@linaro.org > <mailto:ravineet.singh@linaro.org>> > >> > >> v2: moved task-isolation dir to odp/scripts, requested my Maxim > Uvarov > >> v3: fixed checkpatch.pl <http://checkpatch.pl> warnings > >> --- > >> scripts/task-isolation/README | 22 ++ > >> scripts/task-isolation/isolate-cpu.sh | 287 > +++++++++++++++++++++ > >> scripts/task-isolation/isolate-task.sh | 160 > ++++++++++++ > >> .../performance/odp_run_app_isolated.sh | 108 ++++++++ > >> 4 files changed, 577 insertions(+) > >> create mode 100644 scripts/task-isolation/README > >> create mode 100755 scripts/task-isolation/isolate-cpu.sh > >> create mode 100755 scripts/task-isolation/isolate-task.sh > >> create mode 100755 > test/linux-generic/performance/odp_run_app_isolated.sh > >> > >> diff --git a/scripts/task-isolation/README > b/scripts/task-isolation/README > >> new file mode 100644 > >> index 0000000..cb02056 > >> --- /dev/null > >> +++ b/scripts/task-isolation/README > >> @@ -0,0 +1,22 @@ > >> +Helper scripts to check and set CPU isolation and execution of > application in > >> +isolated CPU(s) > >> + > >> +Files: > >> +isolate-cpu.sh isolates desired CPUs > >> +isolate-task.sh uses isolate-cpu.sh to isolate CPUs before > running > >> + the desired task. It also provides the > possibility > >> + to trace kernel disturbance on the isolated > CPUs. > >> + > >> +isolate-cpu.sh checks the kernel configuration and the kernel > cmdline to > >> + determine if one or several CPUs are isolated, i.e. it checks for; > >> + CONFIG_NO_HZ_FULL_ALL=y", and CONFIG_RCU_NOCB_CPU_ALL=y" in the > kernel config > >> + and rcu_nocbs,nohz_full in the kernel cmdline. > >> + If the desired CPU(s) are not inte the above configuration, it > warns but continues > >> + to isolate the CPU(s) as much as possibe. The isolation is > accomplished by > >> + - Redirecting all IRQ's away from desired isolated cores > >> + - Using cset (cpuset) to move all running processes and kernel > threads > >> + away from desired isolated cores > >> + > >> +isolate-task.sh uses isolate-cpu.sh to isolate desired CPU(s). > In addition > >> + it starts the supplied application on isolated CPU(s) and > optionally traces > >> + the isolated CPU(s) for kernel interaction. > >> diff --git a/scripts/task-isolation/isolate-cpu.sh > b/scripts/task-isolation/isolate-cpu.sh > >> new file mode 100755 > >> index 0000000..3eaf98a > >> --- /dev/null > >> +++ b/scripts/task-isolation/isolate-cpu.sh > >> @@ -0,0 +1,287 @@ > >> +#!/bin/bash > >> +# > >> +# Copyright (c) 2017, Linaro Limited > >> +# All rights reserved. > >> +# > >> +# SPDX-License-Identifier: BSD-3-Clause > >> +# > >> +# Script that passes command line arguments to odp_scheduling after, > >> +# optionally, isolating CPU > >> +# > >> +# This script isolates desired CPUS, i.e. > >> +# - Checks kernel cmdline and kernel config to determine > >> +# if the environment is optimised for isolated task execution; > >> +# - Moves CPU interrupts, kernel threads, tasks etc. away from the > >> +# targeted CPU. > >> +# *Note* CPU 0 cannot be isolated, i.e minimum 2 CPU's are required. > >> + > >> + > >> +print_usage() { > >> + echo "$0 [-h] [-a] [-c <cpu list>] [-l] [-r] [-d]" > >> + echo > >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" > >> + echo " Args:" > >> + echo " -h Print this message" > >> + echo " -a Isolate all CPUs (except CPU 0)" > >> + echo " -c List of CPUs to be isolated." > >> + echo " -l Show isolation proporties" > >> + echo " -r Reset isolation" > >> + echo " -d Show debug printouts" > >> + echo "" > >> + echo " Examples:" > >> + echo " Isolate all CPU(s) (except 0) " > >> + echo " $0 -a" > >> + echo > >> + echo " Isolate CPUs 1-3 " > >> + echo " $0 -c 1-3" > >> + echo > >> + echo " Isolate CPUs 1 and 4 " > >> + echo " $0 -c 1,4 " > > > > maybe use a here document? > > > >> +} > >> + > >> +dlog() { > >> + [ $DEBUG ] && echo "$*" > >> +} > >> + > >> +warn() { > >> + printf "Warning: $*\n" >&2 > >> +} > >> + > >> +die() { > >> + printf "Error: $*\n" >&2 > >> + exit 1 > >> +} > >> + > >> +get_cpu_array() { > >> + [ $1 ] || die "$FUNCNAME internal error!" > >> + > >> + local cpus="" > >> + IFS=. a=$1; IFS=, a=$a; > > > > I don't understand why IFS=. is needed... > > Also, shouldn't IFS be restored here? > > > >> + for str in $a; do > >> + if [[ $str == *[\-]* ]]; then > >> + str=$(echo $str| sed 's/-/../g') > >> + str=$(eval echo {$str}) > >> + fi > > > > nice! > > > >> + > >> + if [ "$cpus" != "" ]; then > >> + cpus="$cpus $str" > >> + else > >> + cpus=$str > >> + fi > > > > you can probably get away with cpus="$cpus $str" > > > >> + done > >> + > >> + echo $cpus > >> +} > >> + > >> +## > >> +# Check kernel config and kernel cmdline for rcu callbacs and no_hz > >> +# *Note* isolcpu= kernel cmdline option isolates CPUs from SMP > balancing > >> +# If needed, this can be done via > >> +# cpusets/user/cpuset.sched_load_balance > >> +## > >> +check_kernel_config() { > >> + > >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') > >> + > >> + local configs="/proc/config.gz /boot/config-$(uname -r) > /boot/config " > >> + dlog "Looking for Kernel configs; $configs " > >> + for config in $configs; do > >> + if [ -e $config ]; then > >> + dlog "Kenel configuration found:$config" > >> + break > >> + fi > >> + done > >> + > >> + local all_except_0="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > >> + if [ $config ]; then > > > > I think this will always be evaluated to true, shouldn't it be > > if [ -e $config ] ? or even -r $config? > > > >> + nohz_full=$(zgrep "CONFIG_NO_HZ_FULL_ALL=y" $config > 2>/dev/null) \ > >> + && nohz_full=$all_except_0 > >> + else > >> + warn "Kernel config not found, only checking > /proc/cmdline for"\ > >> + " isolation features." > >> + fi > >> + > >> + if ! [ "$nohz_full" ]; then > >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') > > > > no need to pipe: grep ... /proc/cmdline > > > >> + fi > >> + > >> + eval $(cat /proc/cmdline | grep -o 'isolcpus=[^ ]*') > > > > ditto > > > >> + if [ -z "$isolcpus" ]; then > >> + warn "No CPU is isolated from kernel/user threads, > isolcpus= is "\ > >> + "not set in kernel cmdline." > >> + else > >> + gbl_isolated_cpus=$isolcpus > >> + export gbl_isolated_cpus > >> + fi > >> + > >> + if [ -z "$nohz_full" ]; then > >> + warn "No CPU is isolated from kernel ticks, > CONFIG_NO_HZ_FULL_ALL=y" \ > >> + " not set in kernel, nor nohz_full= set in kernel > cmdline." > >> + fi > >> + > >> + for i in `pgrep rcu` ; do taskset -pc 0 $i >/dev/null; done > > > > can you do this? > > > >> + > >> + dlog "isolcpus:$isolcpus" > >> + dlog "nohz_full:$nohz_full" > >> + #dlog "rcu_nocbs:$rcu_nocbs" > >> + > >> + return 0 > >> +} > >> + > >> +cpus_valid() { > >> + local cpus="$1" > >> + local isolated=$2 > >> + local iarray=$(get_cpu_array $isolated) > >> + local carray=$(get_cpu_array $cpus) > >> + > >> + for c in $carray; do > >> + for i in $iarray; do > > > > maybe check that the user didn't provide 0 as a CPU to isolate? > > > >> + if [ $i = $c ]; then > >> + yah=$i > >> + fi > >> + done > >> + [ -z "$yah" ] && return 1 > >> + done > >> + > >> + return 0 > >> +} > >> + > >> +check_prequesties() { > >> + dlog "Checking prequesties; user is root, kernel has cpuset > support,"\ > >> + " and commads; set, zgrep, getconf are available" > >> + [ $UID -eq 0 ] || die "You need to be root!" > >> + grep -q -s cpuset /proc/filesystems || die "Kernel does not > support cpuset!" > >> + which getconf > /dev/null 2>&1 || die "getconf command not > found, please "\ > >> + "install getconf" > >> + which cset > /dev/null 2>&1 || die "cset command not found, > please "\ > >> + "install cpuset" > >> + which zgrep > /dev/null 2>&1 || die "zgrep command not > found, please "\ > >> + "install gzip" > >> +} > >> + > >> +shield_reset() { > >> + cset shield -r >/dev/null 2>&1 > >> + sleep 0.1 > >> +} > >> + > >> +shield_list() { > >> + sets="/cpusets/*/" > >> + for i in $sets ; do > >> + if ! [ -e $i ]; then > >> + continue > >> + fi > >> + printf "Domain %s cpus %s, running %d tasks\n" \ > >> + $(basename $i) $(cat $i/cpuset.cpus) $(cat $i/tasks | > wc -l) > >> + done > >> +} > >> + > >> +shield_cpus() { > >> + local cpus="$1" > >> + > >> + dlog "shielding CPU:s $cpus" > >> + > >> + #Reset and create new shield > >> + shield_reset > >> + out=$(cset shield -c $cpus -k on 2>&1) || die "cset failed; > $out" > >> + # Delay the annoying vmstat timer far away > >> + sysctl vm.stat_interval=120 >/dev/null > >> + > >> + # Shutdown nmi watchdog as it uses perf events > >> + sysctl -w kernel.watchdog=0 >/dev/null > >> + > >> + # Pin the writeback workqueue to CPU0 > >> + #Fixme, check that /sys/bus is mounted? > >> + echo 1 > /sys/bus/workqueue/devices/writeback/cpumask > >> + > >> + # Disable load balanser. > > > > balancer > > > >> + echo 0 > /cpusets/user/cpuset.sched_load_balance > >> + > >> + #Fixme, for now just send all irqs to core 0 > >> + for affinity in /proc/irq/*/smp_affinity; do > >> + dlog "redirecting $affinity" > >> + echo 1 > $affinity 2>/dev/null || dlog "$affinity > redirection failed." > >> + done > >> + > >> + > >> + #Fixme, not implemented. > >> + if [ $false ]; then > >> + for affinity in /proc/irq/*/smp_affinity; do > >> + local old_mask=$(cat $affinity) > >> + local new_mask=$((oldmask ^ cpus )) > >> + echo $new_mask > $affinity > >> + done > >> + fi > >> +} > >> + > >> +isolate_cpus() { > >> + > >> + local cpus="$1" > >> + > >> + check_kernel_config > >> + > >> + if [ "$gbl_isolated_cpus" ]; then > >> + cpus_valid $cpus $gbl_isolated_cpus || > >> + warn "Selected CPU '$cpus' is not inside isolated > cpus "\ > >> + "array:$gbl_isolated_cpus" > >> + fi > >> + > >> + dlog "Isolating CPUs $cpus" > >> + > >> + shield_cpus $cpus > >> + > >> + # Verfiy cores empty > >> + for c in $(get_cpu_array $cpus); do > >> + running=$(ps ax -o pid,psr,comm | \ > >> + awk -v cpu="$c" '{if($2==cpu){print $3}}') > >> + if [ "$running" != "" ]; then > >> + warn "Core $c not empty!" > >> + dlog "; running tasks:\n$running\n" > >> + fi > >> + done > > > > indentation (tabs used here but spaces above) > > > >> + > >> + return 0 > >> +} > >> + > >> +## > >> +# Script entry point > >> +## > >> +while getopts hdarlc: arguments > >> +do > >> + case $arguments in > >> + h) > >> + print_usage > >> + exit 0 > >> + ;; > >> + d) > >> + DEBUG=1 > >> + ;; > >> + a) > >> + ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > >> + ;; > >> + r) > >> + shield_reset > >> + exit 0 > >> + ;; > >> + l) > >> + shield_list > >> + exit 0 > >> + ;; > >> + c) > >> + [ "$ISOL_CPUS" ] || ISOL_CPUS=$OPTARG > >> + ;; > >> + *) > >> + print_usage > >> + exit 1 > >> + ;; > >> + esac > >> +done > >> +#Remove all flags > >> +shift $((OPTIND-1)) > >> + > >> +if ! [ $ISOL_CPUS ]; then > >> + print_usage > >> + exit 1 > >> +fi > >> + > >> +check_prequesties > >> +isolate_cpus $ISOL_CPUS || die "isolate_cpus failed." > > > > isolate_cpus() always retuns success... > > > >> diff --git a/scripts/task-isolation/isolate-task.sh > b/scripts/task-isolation/isolate-task.sh > >> new file mode 100755 > >> index 0000000..3e588bc > >> --- /dev/null > >> +++ b/scripts/task-isolation/isolate-task.sh > >> @@ -0,0 +1,160 @@ > >> +#!/bin/bash > >> +# > >> +# Copyright (c) 2017, Linaro Limited > >> +# All rights reserved. > >> +# > >> +# SPDX-License-Identifier: BSD-3-Clause > >> +# > >> +# Script that passes command line arguments to odp_scheduling after, > >> +# optionally, isolating CPU > >> +# > >> +# This script isolates a task on desired CPUs and > >> +# optionally creates background noise. > >> + > >> +print_usage() { > >> + echo "$0 [-c <cpu list>] [-d] [-h] [-n] <application arg1, > arg2, ...>" > >> + echo > >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" > >> + echo " and run an application on isolated CPUs" > >> + echo " Args:" > >> + echo " -c List of CPUs to be isolated" > >> + echo " -d Show debug printouts" > >> + echo " -h Print this message" > >> + echo " -n Create background noise (stress)" > >> + echo "" > >> + echo "All CPU's, except CPU 0, are isolated unless '-c' > specified" > >> + echo " Examples:" > >> + echo " Isolate CPU 1,2 and run application in the same." > >> + echo " $0 -n -c 1,2 /some/path/application" > >> + echo > >> + echo " Isolate all possible CPUs and run applicatipon" > >> + echo " $0 /path/application" > >> +} > >> + > >> +dlog() { > >> + [ $DEBUG ] && echo "$*" > >> +} > >> + > >> +die() { > >> + printf "Error: $*\n" >&2 > >> + exit 1 > >> +} > >> + > >> +trap cleanup INT EXIT > >> + > >> +cleanup(){ > >> + local pids=$(pgrep $MY_STRESS 2>/dev/null) > >> + local base=$(dirname $0) > >> + > >> + $base/isolate-cpu.sh -r > >> + [ "$pids" != "" ] && kill -9 $pids >/dev/null 2>&1 > >> + kill -9 $CHILD >/dev/null 2>&1 > >> + rm -f $MY_STRESS_PATH > >> +} > >> + > >> +wait_app_started () { > >> + local child=$1 > >> + local ltasks=0 > >> + > >> + while true; do > >> + sleep 0.01 > >> + kill -0 $child 2>/dev/null || break > >> + tasks=$(ls /proc/$child/task | wc -l) > >> + [ $tasks -eq $ltasks ] && break > >> + ltasks=$tasks > >> + done > >> + dlog "app started, # threads:$ltasks" > >> +} > >> + > >> +create_noise() { > >> + local mpath=$1 > >> + local nr=$(grep processor /proc/cpuinfo | wc -l) > >> + > >> + ln -sf $(which stress) $mpath || die "ln failed" > >> + $mpath -c $nr 2>&1 >/dev/null & > >> + disown $! > >> +} > >> + > >> +isolate_cpu(){ > >> + local cpus=$1 > >> + local base=$(dirname $0) > >> + $base/isolate-cpu.sh -c $cpus || die "$0 failed" > >> +} > >> + > >> +run_application() { > >> + local app="$1" > >> + > >> + dlog "Starting application: $app" > >> + $app& > >> + child=$! > >> + CHILD=$child > >> + > >> + echo $child >> /cpusets/user/tasks > >> + if [ $? -ne 0 ]; then > >> + kill -9 $child > >> + die "Failed to isolate task..." > >> + fi > >> + > >> + wait_app_started $child > >> + wait $child > >> +} > >> + > >> +check_prequesties() { > >> + local base=$(dirname $0) > >> + > >> + [ -e $base/isolate-cpu.sh ] || die "$base/isolate-cpu.sh not > found!" > >> + [ $UID -eq 0 ] || die "You need to be root!" > >> + which stress > /dev/null 2>&1 || die "stress command not > found, "\ > >> + "please install stress" > >> +} > >> + > >> +## > >> +# Script entry point > >> +## > >> + > >> +ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > >> + > >> +while getopts hdnc: arguments > >> +do > >> + case $arguments in > >> + h) > >> + print_usage > >> + exit 0 > >> + ;; > >> + d) > >> + DEBUG=1 > >> + ;; > >> + n) > >> + NOISE=1 > >> + ;; > >> + c) > >> + ISOL_CPUS=$OPTARG > >> + ;; > >> + *) > >> + print_usage > >> + exit 1 > >> + ;; > >> + esac > >> +done > >> +# Remove all flags > >> +shift $((OPTIND-1)) > >> + > >> +if ! [ "$1" ]; then > >> + print_usage > >> + exit 1 > >> +fi > >> + > >> +#Isolate and optionally create noise > >> +command="$*" > >> +set -- $command > >> + > >> +check_prequesties > >> + > >> +MY_STRESS=stress-by-$$ > >> +MY_STRESS_PATH=/tmp/$MY_STRESS > >> + > >> +isolate_cpu $ISOL_CPUS || die "isolate cpu failed!" > >> +[ -z $NOISE ] || create_noise $MY_STRESS_PATH > >> +run_application "$command" > >> + > >> +exit $? > >> diff --git > a/test/linux-generic/performance/odp_run_app_isolated.sh > b/test/linux-generic/performance/odp_run_app_isolated.sh > >> new file mode 100755 > >> index 0000000..3bed0a7 > >> --- /dev/null > >> +++ b/test/linux-generic/performance/odp_run_app_isolated.sh > > > > there is a mix of spaces and tabs for indentation in this script > > > >> @@ -0,0 +1,108 @@ > >> +#!/bin/sh > >> +# > >> +# Copyright (c) 2017, Linaro Limited > >> +# All rights reserved. > >> +# > >> +# SPDX-License-Identifier: BSD-3-Clause > >> +# > >> + > >> + > >> +TEST_DIR="${TEST_DIR:-$(dirname $0)}" > >> +PERFORMANCE="$TEST_DIR/../../common_plat/performance" > >> +ISOL_DIR="${TEST_DIR}/../../../scripts/task-isolation" > >> +APPLICATION="${PERFORMANCE}/odp_pktio_perf${EXEEXT}" > >> +APPLICATION_ARGS="" > >> +APPLICATION_BASE="$(basename ${APPLICATION})" > >> + > >> +cleanup(){ > >> + pids=$(pgrep stress 2>/dev/null) > >> + [ "$pids" != "" ] && kill -9 $pids > >> +} > >> + > >> +print_usage() { > >> + echo "$0 [-i] [-n] [-h] [<application> <application args>]" > >> + echo > >> + echo " Run an application with or without isolation and > background noise" > >> + echo " Flags:" > >> + echo " -h Print this message" > >> + echo " -i Isolate CPU prior to running application." > >> + echo " -n Create background noise (stress)" > >> + echo "" > >> + echo " <application> targeted application" > >> + echo " <args> targeted application arguments" > >> + echo " *Note* Default application is ${APPLICATION_BASE}" > >> + echo "" > >> + echo " Example:" > >> + echo " Isolate CPU, create background noise and run > ${APPLICATION_BASE}:" > >> + echo " $0 -i -n" > >> + echo > >> + echo " Run ${APPLICATION_BASE}, w/o isolation but with > background noise:" > >> + echo " $0 -n" > >> + echo > >> + echo " Run Myapp, without isolation but with background noise:" > >> + echo " $0 -n Myapp -s ome args" > >> +} > >> + > >> +run() { > >> + local isolate=$1 > >> + local noise=$2 > >> + if [ ${isolate} -eq 1 ]; then > >> + [ ${noise} -eq 1 ] && noise_par="-n" > >> + echo Running ${APPLICATION_BASE} with isolation and > background noise > >> + echo ===================================================== > >> + $ISOL_DIR/isolate-task.sh ${noise_par} ${APPLICATION} \ > >> + ${APPLICATION_ARGS} || exit 1 > >> + #reset isolation > >> + $ISOL_DIR/isolate-cpu.sh -r > >> + else > >> + echo Running ${APPLICATION_BASE} without isolation > >> + echo ===================================================== > >> + if [ ${noise} -eq 1 ]; then > >> + local nr=$(grep processor /proc/cpuinfo | wc -l) > >> + echo " Creating background noise..." > >> + stress -c $nr 2>&1 >/dev/null & > >> + fi > >> + ${APPLICATION} ${APPLICATION_ARGS} || exit 2 > >> + fi > >> +} > >> + > >> +trap cleanup INT EXIT > >> +ISOLATE=0 > >> +NOISE=0 > >> +while getopts hni arguments > >> +do > >> + case $arguments in > >> + h) > >> + print_usage > >> + exit 0 > >> + ;; > >> + n) > >> + NOISE=1 > >> + $(which stress > /dev/null 2>&1) > >> + ret=$? > >> + if [ ${ret} -ne 0 ]; then > > > > or: > > if ! $(which stress > /dev/null 2>&1); then > > > >> + echo "'stress' not found, bailing" >&2 > >> + exit 3 > >> + fi > >> + ;; > >> + i) > >> + ISOLATE=1 > >> + ;; > >> + *) > >> + print_usage > >> + exit 1 > >> + ;; > >> + esac > >> +done > >> +#Remove flags > >> +shift $((OPTIND-1)) > >> + > >> +if [ $# -gt 0 ]; then > >> + APPLICATION="$1" > >> + shift > >> +fi > >> +[ $# -gt 0 ] && APPLICATION_ARGS=$* > >> + > >> +run ${ISOLATE} ${NOISE} > >> + > >> +exit $? > > > > not needed, the script will exit with the exit value of the last > > command executed. > > > >> -- > >> 2.7.4 > >> > > > > > -- > Mike Holmes > Program Manager - Linaro Networking Group > Linaro.org <http://www.linaro.org/>* **│ *Open source software for ARM SoCs > "Work should be fun and collaborative, the rest follows" > > __ > >
I'm trying to run it on Ubuntu 14.04.4. But some problems there. Any hints where to look? + out=cset: --> failed to create shield, hint: do other cpusets exist? cset: **> attempt to create already existing set: "/user" + die cset failed; cset: --> failed to create shield, hint: do other cpusets exist? cset: **> attempt to create already existing set: "/user" + printf Error: cset failed; cset: --> failed to create shield, hint: do other cpusets exist? cset: **> attempt to create already existing set: "/user"\n Error: cset failed; cset: --> failed to create shield, hint: do other cpusets exist? cset: **> attempt to create already existing set: "/user" + exit 1 LinuLinux maxim-Aspire-VN7-791 4.10.0-rc8+ #33 SMP Fri Feb 17 17:38:29 MSK 2017 x86_64 x86_64 x86_64 GNU/Linux x maxim-Aspire-VN7-791 4.10.0-rc8+ #33 SMP Fri Feb 17 17:38:29 MSK 2017 x86_64 x86_64 x86_64 GNU/Linux BOOT_IMAGBOOT_IMAGE=/boot/vmlinuz-4.10.0-rc8+ root=UUID=55d0fa87-5df1-47a7-af19-0f7d64a107ea ro quiet pciehp.pciehp_force=1 pciehp.pciehp_poll=1 elevator=noop isolcpus=1-7E=/boot/vmlinuz-4.10.0-rc8+ root=UUID=55d0fa87-5df1-47a7-af19-0f7d64a107ea ro quiet pciehp.pciehp_force=1 pciehp.pciehp_poll=1 elevator=noop isolcpus=1-7 On 02/17/17 17:34, Mike Holmes wrote: > checkpatch is designed for the kernel C code so we have to use some > judgment, as for git there are cases it makes no sence > > On 17 February 2017 at 09:10, Maxim Uvarov <maxim.uvarov@linaro.org > <mailto:maxim.uvarov@linaro.org>> wrote: > > interesting if checpatch is ok, git am warns on spaces in intent: > > > git am -s /tmp/11/\[PATCH\ v3\]\ validation\:\ A\ wrapper\ script\ to\ > run\ test\ isolated..eml > Applying: validation: A wrapper script to run test isolated. > .git/rebase-apply/patch:24: indent with spaces. > the desired task. It also provides the possibility > > > This is Human text in a readme file, do we want or need to enforce tabs > here ? > > > > .git/rebase-apply/patch:25: indent with spaces. > to trace kernel disturbance on the isolated CPUs. > .git/rebase-apply/patch:106: indent with spaces. > if [[ $str == *[\-]* ]]; then > .git/rebase-apply/patch:107: indent with spaces. > str=$(echo $str| sed 's/-/../g') > .git/rebase-apply/patch:108: indent with spaces. > str=$(eval echo {$str}) > warning: squelched 88 whitespace errors > warning: 93 lines add whitespace errors. > 17:08 /opt/Linaro/odp3.git (master)$git format-patch HEAD^ > 0001-validation-A-wrapper-script-to-run-test-isolated.patch > 17:09 /opt/Linaro/odp3.git (master)$perl ./scripts/checkpatch.pl > <http://checkpatch.pl> > 0001-validation-A-wrapper-script-to-run-test-isolated.patch > total: 0 errors, 0 warnings, 0 checks, 577 lines checked > > NOTE: Ignored message types: BIT_MACRO COMPARISON_TO_NULL > DEPRECATED_VARIABLE NEW_TYPEDEFS SPLIT_STRING SSCANF_TO_KSTRTO > > 0001-validation-A-wrapper-script-to-run-test-isolated.patch has no > obvious style problems and is ready for submission. > > > > On 02/16/17 13:42, Josep Puigdemont wrote: > > On Thu, Feb 16, 2017 at 09:52:37AM +0100, Ravineet Singh wrote: > >> The wrapper script; odp_run_app_isolated.sh can be used to run ODP > >> testcases in a isolated environment. Background noise can also be > >> generated. > >> > >> Signed-off-by: Ravineet Singh <ravineet.singh@linaro.org > <mailto:ravineet.singh@linaro.org>> > >> > >> v2: moved task-isolation dir to odp/scripts, requested my Maxim > Uvarov > >> v3: fixed checkpatch.pl <http://checkpatch.pl> warnings > >> --- > >> scripts/task-isolation/README | 22 ++ > >> scripts/task-isolation/isolate-cpu.sh | 287 > +++++++++++++++++++++ > >> scripts/task-isolation/isolate-task.sh | 160 > ++++++++++++ > >> .../performance/odp_run_app_isolated.sh | 108 ++++++++ > >> 4 files changed, 577 insertions(+) > >> create mode 100644 scripts/task-isolation/README > >> create mode 100755 scripts/task-isolation/isolate-cpu.sh > >> create mode 100755 scripts/task-isolation/isolate-task.sh > >> create mode 100755 > test/linux-generic/performance/odp_run_app_isolated.sh > >> > >> diff --git a/scripts/task-isolation/README > b/scripts/task-isolation/README > >> new file mode 100644 > >> index 0000000..cb02056 > >> --- /dev/null > >> +++ b/scripts/task-isolation/README > >> @@ -0,0 +1,22 @@ > >> +Helper scripts to check and set CPU isolation and execution of > application in > >> +isolated CPU(s) > >> + > >> +Files: > >> +isolate-cpu.sh isolates desired CPUs > >> +isolate-task.sh uses isolate-cpu.sh to isolate CPUs before > running > >> + the desired task. It also provides the > possibility > >> + to trace kernel disturbance on the isolated > CPUs. > >> + > >> +isolate-cpu.sh checks the kernel configuration and the kernel > cmdline to > >> + determine if one or several CPUs are isolated, i.e. it checks for; > >> + CONFIG_NO_HZ_FULL_ALL=y", and CONFIG_RCU_NOCB_CPU_ALL=y" in the > kernel config > >> + and rcu_nocbs,nohz_full in the kernel cmdline. > >> + If the desired CPU(s) are not inte the above configuration, it > warns but continues > >> + to isolate the CPU(s) as much as possibe. The isolation is > accomplished by > >> + - Redirecting all IRQ's away from desired isolated cores > >> + - Using cset (cpuset) to move all running processes and kernel > threads > >> + away from desired isolated cores > >> + > >> +isolate-task.sh uses isolate-cpu.sh to isolate desired CPU(s). > In addition > >> + it starts the supplied application on isolated CPU(s) and > optionally traces > >> + the isolated CPU(s) for kernel interaction. > >> diff --git a/scripts/task-isolation/isolate-cpu.sh > b/scripts/task-isolation/isolate-cpu.sh > >> new file mode 100755 > >> index 0000000..3eaf98a > >> --- /dev/null > >> +++ b/scripts/task-isolation/isolate-cpu.sh > >> @@ -0,0 +1,287 @@ > >> +#!/bin/bash > >> +# > >> +# Copyright (c) 2017, Linaro Limited > >> +# All rights reserved. > >> +# > >> +# SPDX-License-Identifier: BSD-3-Clause > >> +# > >> +# Script that passes command line arguments to odp_scheduling after, > >> +# optionally, isolating CPU > >> +# > >> +# This script isolates desired CPUS, i.e. > >> +# - Checks kernel cmdline and kernel config to determine > >> +# if the environment is optimised for isolated task execution; > >> +# - Moves CPU interrupts, kernel threads, tasks etc. away from the > >> +# targeted CPU. > >> +# *Note* CPU 0 cannot be isolated, i.e minimum 2 CPU's are required. > >> + > >> + > >> +print_usage() { > >> + echo "$0 [-h] [-a] [-c <cpu list>] [-l] [-r] [-d]" > >> + echo > >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" > >> + echo " Args:" > >> + echo " -h Print this message" > >> + echo " -a Isolate all CPUs (except CPU 0)" > >> + echo " -c List of CPUs to be isolated." > >> + echo " -l Show isolation proporties" > >> + echo " -r Reset isolation" > >> + echo " -d Show debug printouts" > >> + echo "" > >> + echo " Examples:" > >> + echo " Isolate all CPU(s) (except 0) " > >> + echo " $0 -a" > >> + echo > >> + echo " Isolate CPUs 1-3 " > >> + echo " $0 -c 1-3" > >> + echo > >> + echo " Isolate CPUs 1 and 4 " > >> + echo " $0 -c 1,4 " > > > > maybe use a here document? > > > >> +} > >> + > >> +dlog() { > >> + [ $DEBUG ] && echo "$*" > >> +} > >> + > >> +warn() { > >> + printf "Warning: $*\n" >&2 > >> +} > >> + > >> +die() { > >> + printf "Error: $*\n" >&2 > >> + exit 1 > >> +} > >> + > >> +get_cpu_array() { > >> + [ $1 ] || die "$FUNCNAME internal error!" > >> + > >> + local cpus="" > >> + IFS=. a=$1; IFS=, a=$a; > > > > I don't understand why IFS=. is needed... > > Also, shouldn't IFS be restored here? > > > >> + for str in $a; do > >> + if [[ $str == *[\-]* ]]; then > >> + str=$(echo $str| sed 's/-/../g') > >> + str=$(eval echo {$str}) > >> + fi > > > > nice! > > > >> + > >> + if [ "$cpus" != "" ]; then > >> + cpus="$cpus $str" > >> + else > >> + cpus=$str > >> + fi > > > > you can probably get away with cpus="$cpus $str" > > > >> + done > >> + > >> + echo $cpus > >> +} > >> + > >> +## > >> +# Check kernel config and kernel cmdline for rcu callbacs and no_hz > >> +# *Note* isolcpu= kernel cmdline option isolates CPUs from SMP > balancing > >> +# If needed, this can be done via > >> +# cpusets/user/cpuset.sched_load_balance > >> +## > >> +check_kernel_config() { > >> + > >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') > >> + > >> + local configs="/proc/config.gz /boot/config-$(uname -r) > /boot/config " > >> + dlog "Looking for Kernel configs; $configs " > >> + for config in $configs; do > >> + if [ -e $config ]; then > >> + dlog "Kenel configuration found:$config" > >> + break > >> + fi > >> + done > >> + > >> + local all_except_0="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > >> + if [ $config ]; then > > > > I think this will always be evaluated to true, shouldn't it be > > if [ -e $config ] ? or even -r $config? > > > >> + nohz_full=$(zgrep "CONFIG_NO_HZ_FULL_ALL=y" $config > 2>/dev/null) \ > >> + && nohz_full=$all_except_0 > >> + else > >> + warn "Kernel config not found, only checking > /proc/cmdline for"\ > >> + " isolation features." > >> + fi > >> + > >> + if ! [ "$nohz_full" ]; then > >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') > > > > no need to pipe: grep ... /proc/cmdline > > > >> + fi > >> + > >> + eval $(cat /proc/cmdline | grep -o 'isolcpus=[^ ]*') > > > > ditto > > > >> + if [ -z "$isolcpus" ]; then > >> + warn "No CPU is isolated from kernel/user threads, > isolcpus= is "\ > >> + "not set in kernel cmdline." > >> + else > >> + gbl_isolated_cpus=$isolcpus > >> + export gbl_isolated_cpus > >> + fi > >> + > >> + if [ -z "$nohz_full" ]; then > >> + warn "No CPU is isolated from kernel ticks, > CONFIG_NO_HZ_FULL_ALL=y" \ > >> + " not set in kernel, nor nohz_full= set in kernel > cmdline." > >> + fi > >> + > >> + for i in `pgrep rcu` ; do taskset -pc 0 $i >/dev/null; done > > > > can you do this? > > > >> + > >> + dlog "isolcpus:$isolcpus" > >> + dlog "nohz_full:$nohz_full" > >> + #dlog "rcu_nocbs:$rcu_nocbs" > >> + > >> + return 0 > >> +} > >> + > >> +cpus_valid() { > >> + local cpus="$1" > >> + local isolated=$2 > >> + local iarray=$(get_cpu_array $isolated) > >> + local carray=$(get_cpu_array $cpus) > >> + > >> + for c in $carray; do > >> + for i in $iarray; do > > > > maybe check that the user didn't provide 0 as a CPU to isolate? > > > >> + if [ $i = $c ]; then > >> + yah=$i > >> + fi > >> + done > >> + [ -z "$yah" ] && return 1 > >> + done > >> + > >> + return 0 > >> +} > >> + > >> +check_prequesties() { > >> + dlog "Checking prequesties; user is root, kernel has cpuset > support,"\ > >> + " and commads; set, zgrep, getconf are available" > >> + [ $UID -eq 0 ] || die "You need to be root!" > >> + grep -q -s cpuset /proc/filesystems || die "Kernel does not > support cpuset!" > >> + which getconf > /dev/null 2>&1 || die "getconf command not > found, please "\ > >> + "install getconf" > >> + which cset > /dev/null 2>&1 || die "cset command not found, > please "\ > >> + "install cpuset" > >> + which zgrep > /dev/null 2>&1 || die "zgrep command not > found, please "\ > >> + "install gzip" > >> +} > >> + > >> +shield_reset() { > >> + cset shield -r >/dev/null 2>&1 > >> + sleep 0.1 > >> +} > >> + > >> +shield_list() { > >> + sets="/cpusets/*/" > >> + for i in $sets ; do > >> + if ! [ -e $i ]; then > >> + continue > >> + fi > >> + printf "Domain %s cpus %s, running %d tasks\n" \ > >> + $(basename $i) $(cat $i/cpuset.cpus) $(cat $i/tasks | > wc -l) > >> + done > >> +} > >> + > >> +shield_cpus() { > >> + local cpus="$1" > >> + > >> + dlog "shielding CPU:s $cpus" > >> + > >> + #Reset and create new shield > >> + shield_reset > >> + out=$(cset shield -c $cpus -k on 2>&1) || die "cset failed; > $out" > >> + # Delay the annoying vmstat timer far away > >> + sysctl vm.stat_interval=120 >/dev/null > >> + > >> + # Shutdown nmi watchdog as it uses perf events > >> + sysctl -w kernel.watchdog=0 >/dev/null > >> + > >> + # Pin the writeback workqueue to CPU0 > >> + #Fixme, check that /sys/bus is mounted? > >> + echo 1 > /sys/bus/workqueue/devices/writeback/cpumask > >> + > >> + # Disable load balanser. > > > > balancer > > > >> + echo 0 > /cpusets/user/cpuset.sched_load_balance > >> + > >> + #Fixme, for now just send all irqs to core 0 > >> + for affinity in /proc/irq/*/smp_affinity; do > >> + dlog "redirecting $affinity" > >> + echo 1 > $affinity 2>/dev/null || dlog "$affinity > redirection failed." > >> + done > >> + > >> + > >> + #Fixme, not implemented. > >> + if [ $false ]; then > >> + for affinity in /proc/irq/*/smp_affinity; do > >> + local old_mask=$(cat $affinity) > >> + local new_mask=$((oldmask ^ cpus )) > >> + echo $new_mask > $affinity > >> + done > >> + fi > >> +} > >> + > >> +isolate_cpus() { > >> + > >> + local cpus="$1" > >> + > >> + check_kernel_config > >> + > >> + if [ "$gbl_isolated_cpus" ]; then > >> + cpus_valid $cpus $gbl_isolated_cpus || > >> + warn "Selected CPU '$cpus' is not inside isolated > cpus "\ > >> + "array:$gbl_isolated_cpus" > >> + fi > >> + > >> + dlog "Isolating CPUs $cpus" > >> + > >> + shield_cpus $cpus > >> + > >> + # Verfiy cores empty > >> + for c in $(get_cpu_array $cpus); do > >> + running=$(ps ax -o pid,psr,comm | \ > >> + awk -v cpu="$c" '{if($2==cpu){print $3}}') > >> + if [ "$running" != "" ]; then > >> + warn "Core $c not empty!" > >> + dlog "; running tasks:\n$running\n" > >> + fi > >> + done > > > > indentation (tabs used here but spaces above) > > > >> + > >> + return 0 > >> +} > >> + > >> +## > >> +# Script entry point > >> +## > >> +while getopts hdarlc: arguments > >> +do > >> + case $arguments in > >> + h) > >> + print_usage > >> + exit 0 > >> + ;; > >> + d) > >> + DEBUG=1 > >> + ;; > >> + a) > >> + ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > >> + ;; > >> + r) > >> + shield_reset > >> + exit 0 > >> + ;; > >> + l) > >> + shield_list > >> + exit 0 > >> + ;; > >> + c) > >> + [ "$ISOL_CPUS" ] || ISOL_CPUS=$OPTARG > >> + ;; > >> + *) > >> + print_usage > >> + exit 1 > >> + ;; > >> + esac > >> +done > >> +#Remove all flags > >> +shift $((OPTIND-1)) > >> + > >> +if ! [ $ISOL_CPUS ]; then > >> + print_usage > >> + exit 1 > >> +fi > >> + > >> +check_prequesties > >> +isolate_cpus $ISOL_CPUS || die "isolate_cpus failed." > > > > isolate_cpus() always retuns success... > > > >> diff --git a/scripts/task-isolation/isolate-task.sh > b/scripts/task-isolation/isolate-task.sh > >> new file mode 100755 > >> index 0000000..3e588bc > >> --- /dev/null > >> +++ b/scripts/task-isolation/isolate-task.sh > >> @@ -0,0 +1,160 @@ > >> +#!/bin/bash > >> +# > >> +# Copyright (c) 2017, Linaro Limited > >> +# All rights reserved. > >> +# > >> +# SPDX-License-Identifier: BSD-3-Clause > >> +# > >> +# Script that passes command line arguments to odp_scheduling after, > >> +# optionally, isolating CPU > >> +# > >> +# This script isolates a task on desired CPUs and > >> +# optionally creates background noise. > >> + > >> +print_usage() { > >> + echo "$0 [-c <cpu list>] [-d] [-h] [-n] <application arg1, > arg2, ...>" > >> + echo > >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" > >> + echo " and run an application on isolated CPUs" > >> + echo " Args:" > >> + echo " -c List of CPUs to be isolated" > >> + echo " -d Show debug printouts" > >> + echo " -h Print this message" > >> + echo " -n Create background noise (stress)" > >> + echo "" > >> + echo "All CPU's, except CPU 0, are isolated unless '-c' > specified" > >> + echo " Examples:" > >> + echo " Isolate CPU 1,2 and run application in the same." > >> + echo " $0 -n -c 1,2 /some/path/application" > >> + echo > >> + echo " Isolate all possible CPUs and run applicatipon" > >> + echo " $0 /path/application" > >> +} > >> + > >> +dlog() { > >> + [ $DEBUG ] && echo "$*" > >> +} > >> + > >> +die() { > >> + printf "Error: $*\n" >&2 > >> + exit 1 > >> +} > >> + > >> +trap cleanup INT EXIT > >> + > >> +cleanup(){ > >> + local pids=$(pgrep $MY_STRESS 2>/dev/null) > >> + local base=$(dirname $0) > >> + > >> + $base/isolate-cpu.sh -r > >> + [ "$pids" != "" ] && kill -9 $pids >/dev/null 2>&1 > >> + kill -9 $CHILD >/dev/null 2>&1 > >> + rm -f $MY_STRESS_PATH > >> +} > >> + > >> +wait_app_started () { > >> + local child=$1 > >> + local ltasks=0 > >> + > >> + while true; do > >> + sleep 0.01 > >> + kill -0 $child 2>/dev/null || break > >> + tasks=$(ls /proc/$child/task | wc -l) > >> + [ $tasks -eq $ltasks ] && break > >> + ltasks=$tasks > >> + done > >> + dlog "app started, # threads:$ltasks" > >> +} > >> + > >> +create_noise() { > >> + local mpath=$1 > >> + local nr=$(grep processor /proc/cpuinfo | wc -l) > >> + > >> + ln -sf $(which stress) $mpath || die "ln failed" > >> + $mpath -c $nr 2>&1 >/dev/null & > >> + disown $! > >> +} > >> + > >> +isolate_cpu(){ > >> + local cpus=$1 > >> + local base=$(dirname $0) > >> + $base/isolate-cpu.sh -c $cpus || die "$0 failed" > >> +} > >> + > >> +run_application() { > >> + local app="$1" > >> + > >> + dlog "Starting application: $app" > >> + $app& > >> + child=$! > >> + CHILD=$child > >> + > >> + echo $child >> /cpusets/user/tasks > >> + if [ $? -ne 0 ]; then > >> + kill -9 $child > >> + die "Failed to isolate task..." > >> + fi > >> + > >> + wait_app_started $child > >> + wait $child > >> +} > >> + > >> +check_prequesties() { > >> + local base=$(dirname $0) > >> + > >> + [ -e $base/isolate-cpu.sh ] || die "$base/isolate-cpu.sh not > found!" > >> + [ $UID -eq 0 ] || die "You need to be root!" > >> + which stress > /dev/null 2>&1 || die "stress command not > found, "\ > >> + "please install stress" > >> +} > >> + > >> +## > >> +# Script entry point > >> +## > >> + > >> +ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" > >> + > >> +while getopts hdnc: arguments > >> +do > >> + case $arguments in > >> + h) > >> + print_usage > >> + exit 0 > >> + ;; > >> + d) > >> + DEBUG=1 > >> + ;; > >> + n) > >> + NOISE=1 > >> + ;; > >> + c) > >> + ISOL_CPUS=$OPTARG > >> + ;; > >> + *) > >> + print_usage > >> + exit 1 > >> + ;; > >> + esac > >> +done > >> +# Remove all flags > >> +shift $((OPTIND-1)) > >> + > >> +if ! [ "$1" ]; then > >> + print_usage > >> + exit 1 > >> +fi > >> + > >> +#Isolate and optionally create noise > >> +command="$*" > >> +set -- $command > >> + > >> +check_prequesties > >> + > >> +MY_STRESS=stress-by-$$ > >> +MY_STRESS_PATH=/tmp/$MY_STRESS > >> + > >> +isolate_cpu $ISOL_CPUS || die "isolate cpu failed!" > >> +[ -z $NOISE ] || create_noise $MY_STRESS_PATH > >> +run_application "$command" > >> + > >> +exit $? > >> diff --git > a/test/linux-generic/performance/odp_run_app_isolated.sh > b/test/linux-generic/performance/odp_run_app_isolated.sh > >> new file mode 100755 > >> index 0000000..3bed0a7 > >> --- /dev/null > >> +++ b/test/linux-generic/performance/odp_run_app_isolated.sh > > > > there is a mix of spaces and tabs for indentation in this script > > > >> @@ -0,0 +1,108 @@ > >> +#!/bin/sh > >> +# > >> +# Copyright (c) 2017, Linaro Limited > >> +# All rights reserved. > >> +# > >> +# SPDX-License-Identifier: BSD-3-Clause > >> +# > >> + > >> + > >> +TEST_DIR="${TEST_DIR:-$(dirname $0)}" > >> +PERFORMANCE="$TEST_DIR/../../common_plat/performance" > >> +ISOL_DIR="${TEST_DIR}/../../../scripts/task-isolation" > >> +APPLICATION="${PERFORMANCE}/odp_pktio_perf${EXEEXT}" > >> +APPLICATION_ARGS="" > >> +APPLICATION_BASE="$(basename ${APPLICATION})" > >> + > >> +cleanup(){ > >> + pids=$(pgrep stress 2>/dev/null) > >> + [ "$pids" != "" ] && kill -9 $pids > >> +} > >> + > >> +print_usage() { > >> + echo "$0 [-i] [-n] [-h] [<application> <application args>]" > >> + echo > >> + echo " Run an application with or without isolation and > background noise" > >> + echo " Flags:" > >> + echo " -h Print this message" > >> + echo " -i Isolate CPU prior to running application." > >> + echo " -n Create background noise (stress)" > >> + echo "" > >> + echo " <application> targeted application" > >> + echo " <args> targeted application arguments" > >> + echo " *Note* Default application is ${APPLICATION_BASE}" > >> + echo "" > >> + echo " Example:" > >> + echo " Isolate CPU, create background noise and run > ${APPLICATION_BASE}:" > >> + echo " $0 -i -n" > >> + echo > >> + echo " Run ${APPLICATION_BASE}, w/o isolation but with > background noise:" > >> + echo " $0 -n" > >> + echo > >> + echo " Run Myapp, without isolation but with background noise:" > >> + echo " $0 -n Myapp -s ome args" > >> +} > >> + > >> +run() { > >> + local isolate=$1 > >> + local noise=$2 > >> + if [ ${isolate} -eq 1 ]; then > >> + [ ${noise} -eq 1 ] && noise_par="-n" > >> + echo Running ${APPLICATION_BASE} with isolation and > background noise > >> + echo ===================================================== > >> + $ISOL_DIR/isolate-task.sh ${noise_par} ${APPLICATION} \ > >> + ${APPLICATION_ARGS} || exit 1 > >> + #reset isolation > >> + $ISOL_DIR/isolate-cpu.sh -r > >> + else > >> + echo Running ${APPLICATION_BASE} without isolation > >> + echo ===================================================== > >> + if [ ${noise} -eq 1 ]; then > >> + local nr=$(grep processor /proc/cpuinfo | wc -l) > >> + echo " Creating background noise..." > >> + stress -c $nr 2>&1 >/dev/null & > >> + fi > >> + ${APPLICATION} ${APPLICATION_ARGS} || exit 2 > >> + fi > >> +} > >> + > >> +trap cleanup INT EXIT > >> +ISOLATE=0 > >> +NOISE=0 > >> +while getopts hni arguments > >> +do > >> + case $arguments in > >> + h) > >> + print_usage > >> + exit 0 > >> + ;; > >> + n) > >> + NOISE=1 > >> + $(which stress > /dev/null 2>&1) > >> + ret=$? > >> + if [ ${ret} -ne 0 ]; then > > > > or: > > if ! $(which stress > /dev/null 2>&1); then > > > >> + echo "'stress' not found, bailing" >&2 > >> + exit 3 > >> + fi > >> + ;; > >> + i) > >> + ISOLATE=1 > >> + ;; > >> + *) > >> + print_usage > >> + exit 1 > >> + ;; > >> + esac > >> +done > >> +#Remove flags > >> +shift $((OPTIND-1)) > >> + > >> +if [ $# -gt 0 ]; then > >> + APPLICATION="$1" > >> + shift > >> +fi > >> +[ $# -gt 0 ] && APPLICATION_ARGS=$* > >> + > >> +run ${ISOLATE} ${NOISE} > >> + > >> +exit $? > > > > not needed, the script will exit with the exit value of the last > > command executed. > > > >> -- > >> 2.7.4 > >> > > > > > -- > Mike Holmes > Program Manager - Linaro Networking Group > Linaro.org <http://www.linaro.org/>* **│ *Open source software for ARM SoCs > "Work should be fun and collaborative, the rest follows" > > __ > >
Looks like you have cset shield active on the system, unclear to me why. Could you just retry after a ' cset shield -r' , i.e. reset the shield. On 17 February 2017 at 19:56, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: > I'm trying to run it on Ubuntu 14.04.4. > But some problems there. Any hints where to look? > > + out=cset: --> failed to create shield, hint: do other cpusets exist? > cset: **> attempt to create already existing set: "/user" > + die cset failed; cset: --> failed to create shield, hint: do other > cpusets exist? > cset: **> attempt to create already existing set: "/user" > + printf Error: cset failed; cset: --> failed to create shield, hint: do > other cpusets exist? > cset: **> attempt to create already existing set: "/user"\n > Error: cset failed; cset: --> failed to create shield, hint: do other > cpusets exist? > cset: **> attempt to create already existing set: "/user" > + exit 1 > > LinuLinux maxim-Aspire-VN7-791 4.10.0-rc8+ #33 SMP Fri Feb 17 17:38:29 > MSK 2017 x86_64 x86_64 x86_64 GNU/Linux > x maxim-Aspire-VN7-791 4.10.0-rc8+ #33 SMP Fri Feb 17 17:38:29 MSK 2017 > x86_64 x86_64 x86_64 GNU/Linux > > BOOT_IMAGBOOT_IMAGE=/boot/vmlinuz-4.10.0-rc8+ > root=UUID=55d0fa87-5df1-47a7-af19-0f7d64a107ea ro quiet > pciehp.pciehp_force=1 pciehp.pciehp_poll=1 elevator=noop > isolcpus=1-7E=/boot/vmlinuz-4.10.0-rc8+ > root=UUID=55d0fa87-5df1-47a7-af19-0f7d64a107ea ro quiet > pciehp.pciehp_force=1 pciehp.pciehp_poll=1 elevator=noop isolcpus=1-7 > > > On 02/17/17 17:34, Mike Holmes wrote: >> checkpatch is designed for the kernel C code so we have to use some >> judgment, as for git there are cases it makes no sence >> >> On 17 February 2017 at 09:10, Maxim Uvarov <maxim.uvarov@linaro.org >> <mailto:maxim.uvarov@linaro.org>> wrote: >> >> interesting if checpatch is ok, git am warns on spaces in intent: >> >> >> git am -s /tmp/11/\[PATCH\ v3\]\ validation\:\ A\ wrapper\ script\ to\ >> run\ test\ isolated..eml >> Applying: validation: A wrapper script to run test isolated. >> .git/rebase-apply/patch:24: indent with spaces. >> the desired task. It also provides the possibility >> >> >> This is Human text in a readme file, do we want or need to enforce tabs >> here ? >> >> >> >> .git/rebase-apply/patch:25: indent with spaces. >> to trace kernel disturbance on the isolated CPUs. >> .git/rebase-apply/patch:106: indent with spaces. >> if [[ $str == *[\-]* ]]; then >> .git/rebase-apply/patch:107: indent with spaces. >> str=$(echo $str| sed 's/-/../g') >> .git/rebase-apply/patch:108: indent with spaces. >> str=$(eval echo {$str}) >> warning: squelched 88 whitespace errors >> warning: 93 lines add whitespace errors. >> 17:08 /opt/Linaro/odp3.git (master)$git format-patch HEAD^ >> 0001-validation-A-wrapper-script-to-run-test-isolated.patch >> 17:09 /opt/Linaro/odp3.git (master)$perl ./scripts/checkpatch.pl >> <http://checkpatch.pl> >> 0001-validation-A-wrapper-script-to-run-test-isolated.patch >> total: 0 errors, 0 warnings, 0 checks, 577 lines checked >> >> NOTE: Ignored message types: BIT_MACRO COMPARISON_TO_NULL >> DEPRECATED_VARIABLE NEW_TYPEDEFS SPLIT_STRING SSCANF_TO_KSTRTO >> >> 0001-validation-A-wrapper-script-to-run-test-isolated.patch has no >> obvious style problems and is ready for submission. >> >> >> >> On 02/16/17 13:42, Josep Puigdemont wrote: >> > On Thu, Feb 16, 2017 at 09:52:37AM +0100, Ravineet Singh wrote: >> >> The wrapper script; odp_run_app_isolated.sh can be used to run ODP >> >> testcases in a isolated environment. Background noise can also be >> >> generated. >> >> >> >> Signed-off-by: Ravineet Singh <ravineet.singh@linaro.org >> <mailto:ravineet.singh@linaro.org>> >> >> >> >> v2: moved task-isolation dir to odp/scripts, requested my Maxim >> Uvarov >> >> v3: fixed checkpatch.pl <http://checkpatch.pl> warnings >> >> --- >> >> scripts/task-isolation/README | 22 ++ >> >> scripts/task-isolation/isolate-cpu.sh | 287 >> +++++++++++++++++++++ >> >> scripts/task-isolation/isolate-task.sh | 160 >> ++++++++++++ >> >> .../performance/odp_run_app_isolated.sh | 108 ++++++++ >> >> 4 files changed, 577 insertions(+) >> >> create mode 100644 scripts/task-isolation/README >> >> create mode 100755 scripts/task-isolation/isolate-cpu.sh >> >> create mode 100755 scripts/task-isolation/isolate-task.sh >> >> create mode 100755 >> test/linux-generic/performance/odp_run_app_isolated.sh >> >> >> >> diff --git a/scripts/task-isolation/README >> b/scripts/task-isolation/README >> >> new file mode 100644 >> >> index 0000000..cb02056 >> >> --- /dev/null >> >> +++ b/scripts/task-isolation/README >> >> @@ -0,0 +1,22 @@ >> >> +Helper scripts to check and set CPU isolation and execution of >> application in >> >> +isolated CPU(s) >> >> + >> >> +Files: >> >> +isolate-cpu.sh isolates desired CPUs >> >> +isolate-task.sh uses isolate-cpu.sh to isolate CPUs before >> running >> >> + the desired task. It also provides the >> possibility >> >> + to trace kernel disturbance on the isolated >> CPUs. >> >> + >> >> +isolate-cpu.sh checks the kernel configuration and the kernel >> cmdline to >> >> + determine if one or several CPUs are isolated, i.e. it checks for; >> >> + CONFIG_NO_HZ_FULL_ALL=y", and CONFIG_RCU_NOCB_CPU_ALL=y" in the >> kernel config >> >> + and rcu_nocbs,nohz_full in the kernel cmdline. >> >> + If the desired CPU(s) are not inte the above configuration, it >> warns but continues >> >> + to isolate the CPU(s) as much as possibe. The isolation is >> accomplished by >> >> + - Redirecting all IRQ's away from desired isolated cores >> >> + - Using cset (cpuset) to move all running processes and kernel >> threads >> >> + away from desired isolated cores >> >> + >> >> +isolate-task.sh uses isolate-cpu.sh to isolate desired CPU(s). >> In addition >> >> + it starts the supplied application on isolated CPU(s) and >> optionally traces >> >> + the isolated CPU(s) for kernel interaction. >> >> diff --git a/scripts/task-isolation/isolate-cpu.sh >> b/scripts/task-isolation/isolate-cpu.sh >> >> new file mode 100755 >> >> index 0000000..3eaf98a >> >> --- /dev/null >> >> +++ b/scripts/task-isolation/isolate-cpu.sh >> >> @@ -0,0 +1,287 @@ >> >> +#!/bin/bash >> >> +# >> >> +# Copyright (c) 2017, Linaro Limited >> >> +# All rights reserved. >> >> +# >> >> +# SPDX-License-Identifier: BSD-3-Clause >> >> +# >> >> +# Script that passes command line arguments to odp_scheduling after, >> >> +# optionally, isolating CPU >> >> +# >> >> +# This script isolates desired CPUS, i.e. >> >> +# - Checks kernel cmdline and kernel config to determine >> >> +# if the environment is optimised for isolated task execution; >> >> +# - Moves CPU interrupts, kernel threads, tasks etc. away from the >> >> +# targeted CPU. >> >> +# *Note* CPU 0 cannot be isolated, i.e minimum 2 CPU's are required. >> >> + >> >> + >> >> +print_usage() { >> >> + echo "$0 [-h] [-a] [-c <cpu list>] [-l] [-r] [-d]" >> >> + echo >> >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" >> >> + echo " Args:" >> >> + echo " -h Print this message" >> >> + echo " -a Isolate all CPUs (except CPU 0)" >> >> + echo " -c List of CPUs to be isolated." >> >> + echo " -l Show isolation proporties" >> >> + echo " -r Reset isolation" >> >> + echo " -d Show debug printouts" >> >> + echo "" >> >> + echo " Examples:" >> >> + echo " Isolate all CPU(s) (except 0) " >> >> + echo " $0 -a" >> >> + echo >> >> + echo " Isolate CPUs 1-3 " >> >> + echo " $0 -c 1-3" >> >> + echo >> >> + echo " Isolate CPUs 1 and 4 " >> >> + echo " $0 -c 1,4 " >> > >> > maybe use a here document? >> > >> >> +} >> >> + >> >> +dlog() { >> >> + [ $DEBUG ] && echo "$*" >> >> +} >> >> + >> >> +warn() { >> >> + printf "Warning: $*\n" >&2 >> >> +} >> >> + >> >> +die() { >> >> + printf "Error: $*\n" >&2 >> >> + exit 1 >> >> +} >> >> + >> >> +get_cpu_array() { >> >> + [ $1 ] || die "$FUNCNAME internal error!" >> >> + >> >> + local cpus="" >> >> + IFS=. a=$1; IFS=, a=$a; >> > >> > I don't understand why IFS=. is needed... >> > Also, shouldn't IFS be restored here? >> > >> >> + for str in $a; do >> >> + if [[ $str == *[\-]* ]]; then >> >> + str=$(echo $str| sed 's/-/../g') >> >> + str=$(eval echo {$str}) >> >> + fi >> > >> > nice! >> > >> >> + >> >> + if [ "$cpus" != "" ]; then >> >> + cpus="$cpus $str" >> >> + else >> >> + cpus=$str >> >> + fi >> > >> > you can probably get away with cpus="$cpus $str" >> > >> >> + done >> >> + >> >> + echo $cpus >> >> +} >> >> + >> >> +## >> >> +# Check kernel config and kernel cmdline for rcu callbacs and no_hz >> >> +# *Note* isolcpu= kernel cmdline option isolates CPUs from SMP >> balancing >> >> +# If needed, this can be done via >> >> +# cpusets/user/cpuset.sched_load_balance >> >> +## >> >> +check_kernel_config() { >> >> + >> >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') >> >> + >> >> + local configs="/proc/config.gz /boot/config-$(uname -r) >> /boot/config " >> >> + dlog "Looking for Kernel configs; $configs " >> >> + for config in $configs; do >> >> + if [ -e $config ]; then >> >> + dlog "Kenel configuration found:$config" >> >> + break >> >> + fi >> >> + done >> >> + >> >> + local all_except_0="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" >> >> + if [ $config ]; then >> > >> > I think this will always be evaluated to true, shouldn't it be >> > if [ -e $config ] ? or even -r $config? >> > >> >> + nohz_full=$(zgrep "CONFIG_NO_HZ_FULL_ALL=y" $config >> 2>/dev/null) \ >> >> + && nohz_full=$all_except_0 >> >> + else >> >> + warn "Kernel config not found, only checking >> /proc/cmdline for"\ >> >> + " isolation features." >> >> + fi >> >> + >> >> + if ! [ "$nohz_full" ]; then >> >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') >> > >> > no need to pipe: grep ... /proc/cmdline >> > >> >> + fi >> >> + >> >> + eval $(cat /proc/cmdline | grep -o 'isolcpus=[^ ]*') >> > >> > ditto >> > >> >> + if [ -z "$isolcpus" ]; then >> >> + warn "No CPU is isolated from kernel/user threads, >> isolcpus= is "\ >> >> + "not set in kernel cmdline." >> >> + else >> >> + gbl_isolated_cpus=$isolcpus >> >> + export gbl_isolated_cpus >> >> + fi >> >> + >> >> + if [ -z "$nohz_full" ]; then >> >> + warn "No CPU is isolated from kernel ticks, >> CONFIG_NO_HZ_FULL_ALL=y" \ >> >> + " not set in kernel, nor nohz_full= set in kernel >> cmdline." >> >> + fi >> >> + >> >> + for i in `pgrep rcu` ; do taskset -pc 0 $i >/dev/null; done >> > >> > can you do this? >> > >> >> + >> >> + dlog "isolcpus:$isolcpus" >> >> + dlog "nohz_full:$nohz_full" >> >> + #dlog "rcu_nocbs:$rcu_nocbs" >> >> + >> >> + return 0 >> >> +} >> >> + >> >> +cpus_valid() { >> >> + local cpus="$1" >> >> + local isolated=$2 >> >> + local iarray=$(get_cpu_array $isolated) >> >> + local carray=$(get_cpu_array $cpus) >> >> + >> >> + for c in $carray; do >> >> + for i in $iarray; do >> > >> > maybe check that the user didn't provide 0 as a CPU to isolate? >> > >> >> + if [ $i = $c ]; then >> >> + yah=$i >> >> + fi >> >> + done >> >> + [ -z "$yah" ] && return 1 >> >> + done >> >> + >> >> + return 0 >> >> +} >> >> + >> >> +check_prequesties() { >> >> + dlog "Checking prequesties; user is root, kernel has cpuset >> support,"\ >> >> + " and commads; set, zgrep, getconf are available" >> >> + [ $UID -eq 0 ] || die "You need to be root!" >> >> + grep -q -s cpuset /proc/filesystems || die "Kernel does not >> support cpuset!" >> >> + which getconf > /dev/null 2>&1 || die "getconf command not >> found, please "\ >> >> + "install getconf" >> >> + which cset > /dev/null 2>&1 || die "cset command not found, >> please "\ >> >> + "install cpuset" >> >> + which zgrep > /dev/null 2>&1 || die "zgrep command not >> found, please "\ >> >> + "install gzip" >> >> +} >> >> + >> >> +shield_reset() { >> >> + cset shield -r >/dev/null 2>&1 >> >> + sleep 0.1 >> >> +} >> >> + >> >> +shield_list() { >> >> + sets="/cpusets/*/" >> >> + for i in $sets ; do >> >> + if ! [ -e $i ]; then >> >> + continue >> >> + fi >> >> + printf "Domain %s cpus %s, running %d tasks\n" \ >> >> + $(basename $i) $(cat $i/cpuset.cpus) $(cat $i/tasks | >> wc -l) >> >> + done >> >> +} >> >> + >> >> +shield_cpus() { >> >> + local cpus="$1" >> >> + >> >> + dlog "shielding CPU:s $cpus" >> >> + >> >> + #Reset and create new shield >> >> + shield_reset >> >> + out=$(cset shield -c $cpus -k on 2>&1) || die "cset failed; >> $out" >> >> + # Delay the annoying vmstat timer far away >> >> + sysctl vm.stat_interval=120 >/dev/null >> >> + >> >> + # Shutdown nmi watchdog as it uses perf events >> >> + sysctl -w kernel.watchdog=0 >/dev/null >> >> + >> >> + # Pin the writeback workqueue to CPU0 >> >> + #Fixme, check that /sys/bus is mounted? >> >> + echo 1 > /sys/bus/workqueue/devices/writeback/cpumask >> >> + >> >> + # Disable load balanser. >> > >> > balancer >> > >> >> + echo 0 > /cpusets/user/cpuset.sched_load_balance >> >> + >> >> + #Fixme, for now just send all irqs to core 0 >> >> + for affinity in /proc/irq/*/smp_affinity; do >> >> + dlog "redirecting $affinity" >> >> + echo 1 > $affinity 2>/dev/null || dlog "$affinity >> redirection failed." >> >> + done >> >> + >> >> + >> >> + #Fixme, not implemented. >> >> + if [ $false ]; then >> >> + for affinity in /proc/irq/*/smp_affinity; do >> >> + local old_mask=$(cat $affinity) >> >> + local new_mask=$((oldmask ^ cpus )) >> >> + echo $new_mask > $affinity >> >> + done >> >> + fi >> >> +} >> >> + >> >> +isolate_cpus() { >> >> + >> >> + local cpus="$1" >> >> + >> >> + check_kernel_config >> >> + >> >> + if [ "$gbl_isolated_cpus" ]; then >> >> + cpus_valid $cpus $gbl_isolated_cpus || >> >> + warn "Selected CPU '$cpus' is not inside isolated >> cpus "\ >> >> + "array:$gbl_isolated_cpus" >> >> + fi >> >> + >> >> + dlog "Isolating CPUs $cpus" >> >> + >> >> + shield_cpus $cpus >> >> + >> >> + # Verfiy cores empty >> >> + for c in $(get_cpu_array $cpus); do >> >> + running=$(ps ax -o pid,psr,comm | \ >> >> + awk -v cpu="$c" '{if($2==cpu){print $3}}') >> >> + if [ "$running" != "" ]; then >> >> + warn "Core $c not empty!" >> >> + dlog "; running tasks:\n$running\n" >> >> + fi >> >> + done >> > >> > indentation (tabs used here but spaces above) >> > >> >> + >> >> + return 0 >> >> +} >> >> + >> >> +## >> >> +# Script entry point >> >> +## >> >> +while getopts hdarlc: arguments >> >> +do >> >> + case $arguments in >> >> + h) >> >> + print_usage >> >> + exit 0 >> >> + ;; >> >> + d) >> >> + DEBUG=1 >> >> + ;; >> >> + a) >> >> + ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" >> >> + ;; >> >> + r) >> >> + shield_reset >> >> + exit 0 >> >> + ;; >> >> + l) >> >> + shield_list >> >> + exit 0 >> >> + ;; >> >> + c) >> >> + [ "$ISOL_CPUS" ] || ISOL_CPUS=$OPTARG >> >> + ;; >> >> + *) >> >> + print_usage >> >> + exit 1 >> >> + ;; >> >> + esac >> >> +done >> >> +#Remove all flags >> >> +shift $((OPTIND-1)) >> >> + >> >> +if ! [ $ISOL_CPUS ]; then >> >> + print_usage >> >> + exit 1 >> >> +fi >> >> + >> >> +check_prequesties >> >> +isolate_cpus $ISOL_CPUS || die "isolate_cpus failed." >> > >> > isolate_cpus() always retuns success... >> > >> >> diff --git a/scripts/task-isolation/isolate-task.sh >> b/scripts/task-isolation/isolate-task.sh >> >> new file mode 100755 >> >> index 0000000..3e588bc >> >> --- /dev/null >> >> +++ b/scripts/task-isolation/isolate-task.sh >> >> @@ -0,0 +1,160 @@ >> >> +#!/bin/bash >> >> +# >> >> +# Copyright (c) 2017, Linaro Limited >> >> +# All rights reserved. >> >> +# >> >> +# SPDX-License-Identifier: BSD-3-Clause >> >> +# >> >> +# Script that passes command line arguments to odp_scheduling after, >> >> +# optionally, isolating CPU >> >> +# >> >> +# This script isolates a task on desired CPUs and >> >> +# optionally creates background noise. >> >> + >> >> +print_usage() { >> >> + echo "$0 [-c <cpu list>] [-d] [-h] [-n] <application arg1, >> arg2, ...>" >> >> + echo >> >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" >> >> + echo " and run an application on isolated CPUs" >> >> + echo " Args:" >> >> + echo " -c List of CPUs to be isolated" >> >> + echo " -d Show debug printouts" >> >> + echo " -h Print this message" >> >> + echo " -n Create background noise (stress)" >> >> + echo "" >> >> + echo "All CPU's, except CPU 0, are isolated unless '-c' >> specified" >> >> + echo " Examples:" >> >> + echo " Isolate CPU 1,2 and run application in the same." >> >> + echo " $0 -n -c 1,2 /some/path/application" >> >> + echo >> >> + echo " Isolate all possible CPUs and run applicatipon" >> >> + echo " $0 /path/application" >> >> +} >> >> + >> >> +dlog() { >> >> + [ $DEBUG ] && echo "$*" >> >> +} >> >> + >> >> +die() { >> >> + printf "Error: $*\n" >&2 >> >> + exit 1 >> >> +} >> >> + >> >> +trap cleanup INT EXIT >> >> + >> >> +cleanup(){ >> >> + local pids=$(pgrep $MY_STRESS 2>/dev/null) >> >> + local base=$(dirname $0) >> >> + >> >> + $base/isolate-cpu.sh -r >> >> + [ "$pids" != "" ] && kill -9 $pids >/dev/null 2>&1 >> >> + kill -9 $CHILD >/dev/null 2>&1 >> >> + rm -f $MY_STRESS_PATH >> >> +} >> >> + >> >> +wait_app_started () { >> >> + local child=$1 >> >> + local ltasks=0 >> >> + >> >> + while true; do >> >> + sleep 0.01 >> >> + kill -0 $child 2>/dev/null || break >> >> + tasks=$(ls /proc/$child/task | wc -l) >> >> + [ $tasks -eq $ltasks ] && break >> >> + ltasks=$tasks >> >> + done >> >> + dlog "app started, # threads:$ltasks" >> >> +} >> >> + >> >> +create_noise() { >> >> + local mpath=$1 >> >> + local nr=$(grep processor /proc/cpuinfo | wc -l) >> >> + >> >> + ln -sf $(which stress) $mpath || die "ln failed" >> >> + $mpath -c $nr 2>&1 >/dev/null & >> >> + disown $! >> >> +} >> >> + >> >> +isolate_cpu(){ >> >> + local cpus=$1 >> >> + local base=$(dirname $0) >> >> + $base/isolate-cpu.sh -c $cpus || die "$0 failed" >> >> +} >> >> + >> >> +run_application() { >> >> + local app="$1" >> >> + >> >> + dlog "Starting application: $app" >> >> + $app& >> >> + child=$! >> >> + CHILD=$child >> >> + >> >> + echo $child >> /cpusets/user/tasks >> >> + if [ $? -ne 0 ]; then >> >> + kill -9 $child >> >> + die "Failed to isolate task..." >> >> + fi >> >> + >> >> + wait_app_started $child >> >> + wait $child >> >> +} >> >> + >> >> +check_prequesties() { >> >> + local base=$(dirname $0) >> >> + >> >> + [ -e $base/isolate-cpu.sh ] || die "$base/isolate-cpu.sh not >> found!" >> >> + [ $UID -eq 0 ] || die "You need to be root!" >> >> + which stress > /dev/null 2>&1 || die "stress command not >> found, "\ >> >> + "please install stress" >> >> +} >> >> + >> >> +## >> >> +# Script entry point >> >> +## >> >> + >> >> +ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" >> >> + >> >> +while getopts hdnc: arguments >> >> +do >> >> + case $arguments in >> >> + h) >> >> + print_usage >> >> + exit 0 >> >> + ;; >> >> + d) >> >> + DEBUG=1 >> >> + ;; >> >> + n) >> >> + NOISE=1 >> >> + ;; >> >> + c) >> >> + ISOL_CPUS=$OPTARG >> >> + ;; >> >> + *) >> >> + print_usage >> >> + exit 1 >> >> + ;; >> >> + esac >> >> +done >> >> +# Remove all flags >> >> +shift $((OPTIND-1)) >> >> + >> >> +if ! [ "$1" ]; then >> >> + print_usage >> >> + exit 1 >> >> +fi >> >> + >> >> +#Isolate and optionally create noise >> >> +command="$*" >> >> +set -- $command >> >> + >> >> +check_prequesties >> >> + >> >> +MY_STRESS=stress-by-$$ >> >> +MY_STRESS_PATH=/tmp/$MY_STRESS >> >> + >> >> +isolate_cpu $ISOL_CPUS || die "isolate cpu failed!" >> >> +[ -z $NOISE ] || create_noise $MY_STRESS_PATH >> >> +run_application "$command" >> >> + >> >> +exit $? >> >> diff --git >> a/test/linux-generic/performance/odp_run_app_isolated.sh >> b/test/linux-generic/performance/odp_run_app_isolated.sh >> >> new file mode 100755 >> >> index 0000000..3bed0a7 >> >> --- /dev/null >> >> +++ b/test/linux-generic/performance/odp_run_app_isolated.sh >> > >> > there is a mix of spaces and tabs for indentation in this script >> > >> >> @@ -0,0 +1,108 @@ >> >> +#!/bin/sh >> >> +# >> >> +# Copyright (c) 2017, Linaro Limited >> >> +# All rights reserved. >> >> +# >> >> +# SPDX-License-Identifier: BSD-3-Clause >> >> +# >> >> + >> >> + >> >> +TEST_DIR="${TEST_DIR:-$(dirname $0)}" >> >> +PERFORMANCE="$TEST_DIR/../../common_plat/performance" >> >> +ISOL_DIR="${TEST_DIR}/../../../scripts/task-isolation" >> >> +APPLICATION="${PERFORMANCE}/odp_pktio_perf${EXEEXT}" >> >> +APPLICATION_ARGS="" >> >> +APPLICATION_BASE="$(basename ${APPLICATION})" >> >> + >> >> +cleanup(){ >> >> + pids=$(pgrep stress 2>/dev/null) >> >> + [ "$pids" != "" ] && kill -9 $pids >> >> +} >> >> + >> >> +print_usage() { >> >> + echo "$0 [-i] [-n] [-h] [<application> <application args>]" >> >> + echo >> >> + echo " Run an application with or without isolation and >> background noise" >> >> + echo " Flags:" >> >> + echo " -h Print this message" >> >> + echo " -i Isolate CPU prior to running application." >> >> + echo " -n Create background noise (stress)" >> >> + echo "" >> >> + echo " <application> targeted application" >> >> + echo " <args> targeted application arguments" >> >> + echo " *Note* Default application is ${APPLICATION_BASE}" >> >> + echo "" >> >> + echo " Example:" >> >> + echo " Isolate CPU, create background noise and run >> ${APPLICATION_BASE}:" >> >> + echo " $0 -i -n" >> >> + echo >> >> + echo " Run ${APPLICATION_BASE}, w/o isolation but with >> background noise:" >> >> + echo " $0 -n" >> >> + echo >> >> + echo " Run Myapp, without isolation but with background noise:" >> >> + echo " $0 -n Myapp -s ome args" >> >> +} >> >> + >> >> +run() { >> >> + local isolate=$1 >> >> + local noise=$2 >> >> + if [ ${isolate} -eq 1 ]; then >> >> + [ ${noise} -eq 1 ] && noise_par="-n" >> >> + echo Running ${APPLICATION_BASE} with isolation and >> background noise >> >> + echo ===================================================== >> >> + $ISOL_DIR/isolate-task.sh ${noise_par} ${APPLICATION} \ >> >> + ${APPLICATION_ARGS} || exit 1 >> >> + #reset isolation >> >> + $ISOL_DIR/isolate-cpu.sh -r >> >> + else >> >> + echo Running ${APPLICATION_BASE} without isolation >> >> + echo ===================================================== >> >> + if [ ${noise} -eq 1 ]; then >> >> + local nr=$(grep processor /proc/cpuinfo | wc -l) >> >> + echo " Creating background noise..." >> >> + stress -c $nr 2>&1 >/dev/null & >> >> + fi >> >> + ${APPLICATION} ${APPLICATION_ARGS} || exit 2 >> >> + fi >> >> +} >> >> + >> >> +trap cleanup INT EXIT >> >> +ISOLATE=0 >> >> +NOISE=0 >> >> +while getopts hni arguments >> >> +do >> >> + case $arguments in >> >> + h) >> >> + print_usage >> >> + exit 0 >> >> + ;; >> >> + n) >> >> + NOISE=1 >> >> + $(which stress > /dev/null 2>&1) >> >> + ret=$? >> >> + if [ ${ret} -ne 0 ]; then >> > >> > or: >> > if ! $(which stress > /dev/null 2>&1); then >> > >> >> + echo "'stress' not found, bailing" >&2 >> >> + exit 3 >> >> + fi >> >> + ;; >> >> + i) >> >> + ISOLATE=1 >> >> + ;; >> >> + *) >> >> + print_usage >> >> + exit 1 >> >> + ;; >> >> + esac >> >> +done >> >> +#Remove flags >> >> +shift $((OPTIND-1)) >> >> + >> >> +if [ $# -gt 0 ]; then >> >> + APPLICATION="$1" >> >> + shift >> >> +fi >> >> +[ $# -gt 0 ] && APPLICATION_ARGS=$* >> >> + >> >> +run ${ISOLATE} ${NOISE} >> >> + >> >> +exit $? >> > >> > not needed, the script will exit with the exit value of the last >> > command executed. >> > >> >> -- >> >> 2.7.4 >> >> >> >> >> >> >> -- >> Mike Holmes >> Program Manager - Linaro Networking Group >> Linaro.org <http://www.linaro.org/>* **│ *Open source software for ARM SoCs >> "Work should be fun and collaborative, the rest follows" >> >> __ >> >> > -- Regards Ravineet
On 02/18/17 23:07, Ravineet Singh wrote: > Looks like you have cset shield active on the system, unclear to me why. > Could you just retry after a ' cset shield -r' , i.e. reset the shield. > root:17:22 /opt/Linaro/odp3.git (master)$cset shield -r cset: --> deactivating/reseting shielding cset: **> shielding not active on system root:17:23 /opt/Linaro/odp3.git (master)$./scripts/task-isolation/isolate-cpu.sh -a Error: cset failed; cset: --> failed to create shield, hint: do other cpusets exist? cset: **> attempt to create already existing set: "/user > On 17 February 2017 at 19:56, Maxim Uvarov <maxim.uvarov@linaro.org> wrote: >> I'm trying to run it on Ubuntu 14.04.4. >> But some problems there. Any hints where to look? >> >> + out=cset: --> failed to create shield, hint: do other cpusets exist? >> cset: **> attempt to create already existing set: "/user" >> + die cset failed; cset: --> failed to create shield, hint: do other >> cpusets exist? >> cset: **> attempt to create already existing set: "/user" >> + printf Error: cset failed; cset: --> failed to create shield, hint: do >> other cpusets exist? >> cset: **> attempt to create already existing set: "/user"\n >> Error: cset failed; cset: --> failed to create shield, hint: do other >> cpusets exist? >> cset: **> attempt to create already existing set: "/user" >> + exit 1 >> >> LinuLinux maxim-Aspire-VN7-791 4.10.0-rc8+ #33 SMP Fri Feb 17 17:38:29 >> MSK 2017 x86_64 x86_64 x86_64 GNU/Linux >> x maxim-Aspire-VN7-791 4.10.0-rc8+ #33 SMP Fri Feb 17 17:38:29 MSK 2017 >> x86_64 x86_64 x86_64 GNU/Linux >> >> BOOT_IMAGBOOT_IMAGE=/boot/vmlinuz-4.10.0-rc8+ >> root=UUID=55d0fa87-5df1-47a7-af19-0f7d64a107ea ro quiet >> pciehp.pciehp_force=1 pciehp.pciehp_poll=1 elevator=noop >> isolcpus=1-7E=/boot/vmlinuz-4.10.0-rc8+ >> root=UUID=55d0fa87-5df1-47a7-af19-0f7d64a107ea ro quiet >> pciehp.pciehp_force=1 pciehp.pciehp_poll=1 elevator=noop isolcpus=1-7 >> >> >> On 02/17/17 17:34, Mike Holmes wrote: >>> checkpatch is designed for the kernel C code so we have to use some >>> judgment, as for git there are cases it makes no sence >>> >>> On 17 February 2017 at 09:10, Maxim Uvarov <maxim.uvarov@linaro.org >>> <mailto:maxim.uvarov@linaro.org>> wrote: >>> >>> interesting if checpatch is ok, git am warns on spaces in intent: >>> >>> >>> git am -s /tmp/11/\[PATCH\ v3\]\ validation\:\ A\ wrapper\ script\ to\ >>> run\ test\ isolated..eml >>> Applying: validation: A wrapper script to run test isolated. >>> .git/rebase-apply/patch:24: indent with spaces. >>> the desired task. It also provides the possibility >>> >>> >>> This is Human text in a readme file, do we want or need to enforce tabs >>> here ? >>> >>> >>> >>> .git/rebase-apply/patch:25: indent with spaces. >>> to trace kernel disturbance on the isolated CPUs. >>> .git/rebase-apply/patch:106: indent with spaces. >>> if [[ $str == *[\-]* ]]; then >>> .git/rebase-apply/patch:107: indent with spaces. >>> str=$(echo $str| sed 's/-/../g') >>> .git/rebase-apply/patch:108: indent with spaces. >>> str=$(eval echo {$str}) >>> warning: squelched 88 whitespace errors >>> warning: 93 lines add whitespace errors. >>> 17:08 /opt/Linaro/odp3.git (master)$git format-patch HEAD^ >>> 0001-validation-A-wrapper-script-to-run-test-isolated.patch >>> 17:09 /opt/Linaro/odp3.git (master)$perl ./scripts/checkpatch.pl >>> <http://checkpatch.pl> >>> 0001-validation-A-wrapper-script-to-run-test-isolated.patch >>> total: 0 errors, 0 warnings, 0 checks, 577 lines checked >>> >>> NOTE: Ignored message types: BIT_MACRO COMPARISON_TO_NULL >>> DEPRECATED_VARIABLE NEW_TYPEDEFS SPLIT_STRING SSCANF_TO_KSTRTO >>> >>> 0001-validation-A-wrapper-script-to-run-test-isolated.patch has no >>> obvious style problems and is ready for submission. >>> >>> >>> >>> On 02/16/17 13:42, Josep Puigdemont wrote: >>> > On Thu, Feb 16, 2017 at 09:52:37AM +0100, Ravineet Singh wrote: >>> >> The wrapper script; odp_run_app_isolated.sh can be used to run ODP >>> >> testcases in a isolated environment. Background noise can also be >>> >> generated. >>> >> >>> >> Signed-off-by: Ravineet Singh <ravineet.singh@linaro.org >>> <mailto:ravineet.singh@linaro.org>> >>> >> >>> >> v2: moved task-isolation dir to odp/scripts, requested my Maxim >>> Uvarov >>> >> v3: fixed checkpatch.pl <http://checkpatch.pl> warnings >>> >> --- >>> >> scripts/task-isolation/README | 22 ++ >>> >> scripts/task-isolation/isolate-cpu.sh | 287 >>> +++++++++++++++++++++ >>> >> scripts/task-isolation/isolate-task.sh | 160 >>> ++++++++++++ >>> >> .../performance/odp_run_app_isolated.sh | 108 ++++++++ >>> >> 4 files changed, 577 insertions(+) >>> >> create mode 100644 scripts/task-isolation/README >>> >> create mode 100755 scripts/task-isolation/isolate-cpu.sh >>> >> create mode 100755 scripts/task-isolation/isolate-task.sh >>> >> create mode 100755 >>> test/linux-generic/performance/odp_run_app_isolated.sh >>> >> >>> >> diff --git a/scripts/task-isolation/README >>> b/scripts/task-isolation/README >>> >> new file mode 100644 >>> >> index 0000000..cb02056 >>> >> --- /dev/null >>> >> +++ b/scripts/task-isolation/README >>> >> @@ -0,0 +1,22 @@ >>> >> +Helper scripts to check and set CPU isolation and execution of >>> application in >>> >> +isolated CPU(s) >>> >> + >>> >> +Files: >>> >> +isolate-cpu.sh isolates desired CPUs >>> >> +isolate-task.sh uses isolate-cpu.sh to isolate CPUs before >>> running >>> >> + the desired task. It also provides the >>> possibility >>> >> + to trace kernel disturbance on the isolated >>> CPUs. >>> >> + >>> >> +isolate-cpu.sh checks the kernel configuration and the kernel >>> cmdline to >>> >> + determine if one or several CPUs are isolated, i.e. it checks for; >>> >> + CONFIG_NO_HZ_FULL_ALL=y", and CONFIG_RCU_NOCB_CPU_ALL=y" in the >>> kernel config >>> >> + and rcu_nocbs,nohz_full in the kernel cmdline. >>> >> + If the desired CPU(s) are not inte the above configuration, it >>> warns but continues >>> >> + to isolate the CPU(s) as much as possibe. The isolation is >>> accomplished by >>> >> + - Redirecting all IRQ's away from desired isolated cores >>> >> + - Using cset (cpuset) to move all running processes and kernel >>> threads >>> >> + away from desired isolated cores >>> >> + >>> >> +isolate-task.sh uses isolate-cpu.sh to isolate desired CPU(s). >>> In addition >>> >> + it starts the supplied application on isolated CPU(s) and >>> optionally traces >>> >> + the isolated CPU(s) for kernel interaction. >>> >> diff --git a/scripts/task-isolation/isolate-cpu.sh >>> b/scripts/task-isolation/isolate-cpu.sh >>> >> new file mode 100755 >>> >> index 0000000..3eaf98a >>> >> --- /dev/null >>> >> +++ b/scripts/task-isolation/isolate-cpu.sh >>> >> @@ -0,0 +1,287 @@ >>> >> +#!/bin/bash >>> >> +# >>> >> +# Copyright (c) 2017, Linaro Limited >>> >> +# All rights reserved. >>> >> +# >>> >> +# SPDX-License-Identifier: BSD-3-Clause >>> >> +# >>> >> +# Script that passes command line arguments to odp_scheduling after, >>> >> +# optionally, isolating CPU >>> >> +# >>> >> +# This script isolates desired CPUS, i.e. >>> >> +# - Checks kernel cmdline and kernel config to determine >>> >> +# if the environment is optimised for isolated task execution; >>> >> +# - Moves CPU interrupts, kernel threads, tasks etc. away from the >>> >> +# targeted CPU. >>> >> +# *Note* CPU 0 cannot be isolated, i.e minimum 2 CPU's are required. >>> >> + >>> >> + >>> >> +print_usage() { >>> >> + echo "$0 [-h] [-a] [-c <cpu list>] [-l] [-r] [-d]" >>> >> + echo >>> >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" >>> >> + echo " Args:" >>> >> + echo " -h Print this message" >>> >> + echo " -a Isolate all CPUs (except CPU 0)" >>> >> + echo " -c List of CPUs to be isolated." >>> >> + echo " -l Show isolation proporties" >>> >> + echo " -r Reset isolation" >>> >> + echo " -d Show debug printouts" >>> >> + echo "" >>> >> + echo " Examples:" >>> >> + echo " Isolate all CPU(s) (except 0) " >>> >> + echo " $0 -a" >>> >> + echo >>> >> + echo " Isolate CPUs 1-3 " >>> >> + echo " $0 -c 1-3" >>> >> + echo >>> >> + echo " Isolate CPUs 1 and 4 " >>> >> + echo " $0 -c 1,4 " >>> > >>> > maybe use a here document? >>> > >>> >> +} >>> >> + >>> >> +dlog() { >>> >> + [ $DEBUG ] && echo "$*" >>> >> +} >>> >> + >>> >> +warn() { >>> >> + printf "Warning: $*\n" >&2 >>> >> +} >>> >> + >>> >> +die() { >>> >> + printf "Error: $*\n" >&2 >>> >> + exit 1 >>> >> +} >>> >> + >>> >> +get_cpu_array() { >>> >> + [ $1 ] || die "$FUNCNAME internal error!" >>> >> + >>> >> + local cpus="" >>> >> + IFS=. a=$1; IFS=, a=$a; >>> > >>> > I don't understand why IFS=. is needed... >>> > Also, shouldn't IFS be restored here? >>> > >>> >> + for str in $a; do >>> >> + if [[ $str == *[\-]* ]]; then >>> >> + str=$(echo $str| sed 's/-/../g') >>> >> + str=$(eval echo {$str}) >>> >> + fi >>> > >>> > nice! >>> > >>> >> + >>> >> + if [ "$cpus" != "" ]; then >>> >> + cpus="$cpus $str" >>> >> + else >>> >> + cpus=$str >>> >> + fi >>> > >>> > you can probably get away with cpus="$cpus $str" >>> > >>> >> + done >>> >> + >>> >> + echo $cpus >>> >> +} >>> >> + >>> >> +## >>> >> +# Check kernel config and kernel cmdline for rcu callbacs and no_hz >>> >> +# *Note* isolcpu= kernel cmdline option isolates CPUs from SMP >>> balancing >>> >> +# If needed, this can be done via >>> >> +# cpusets/user/cpuset.sched_load_balance >>> >> +## >>> >> +check_kernel_config() { >>> >> + >>> >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') >>> >> + >>> >> + local configs="/proc/config.gz /boot/config-$(uname -r) >>> /boot/config " >>> >> + dlog "Looking for Kernel configs; $configs " >>> >> + for config in $configs; do >>> >> + if [ -e $config ]; then >>> >> + dlog "Kenel configuration found:$config" >>> >> + break >>> >> + fi >>> >> + done >>> >> + >>> >> + local all_except_0="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" >>> >> + if [ $config ]; then >>> > >>> > I think this will always be evaluated to true, shouldn't it be >>> > if [ -e $config ] ? or even -r $config? >>> > >>> >> + nohz_full=$(zgrep "CONFIG_NO_HZ_FULL_ALL=y" $config >>> 2>/dev/null) \ >>> >> + && nohz_full=$all_except_0 >>> >> + else >>> >> + warn "Kernel config not found, only checking >>> /proc/cmdline for"\ >>> >> + " isolation features." >>> >> + fi >>> >> + >>> >> + if ! [ "$nohz_full" ]; then >>> >> + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') >>> > >>> > no need to pipe: grep ... /proc/cmdline >>> > >>> >> + fi >>> >> + >>> >> + eval $(cat /proc/cmdline | grep -o 'isolcpus=[^ ]*') >>> > >>> > ditto >>> > >>> >> + if [ -z "$isolcpus" ]; then >>> >> + warn "No CPU is isolated from kernel/user threads, >>> isolcpus= is "\ >>> >> + "not set in kernel cmdline." >>> >> + else >>> >> + gbl_isolated_cpus=$isolcpus >>> >> + export gbl_isolated_cpus >>> >> + fi >>> >> + >>> >> + if [ -z "$nohz_full" ]; then >>> >> + warn "No CPU is isolated from kernel ticks, >>> CONFIG_NO_HZ_FULL_ALL=y" \ >>> >> + " not set in kernel, nor nohz_full= set in kernel >>> cmdline." >>> >> + fi >>> >> + >>> >> + for i in `pgrep rcu` ; do taskset -pc 0 $i >/dev/null; done >>> > >>> > can you do this? >>> > >>> >> + >>> >> + dlog "isolcpus:$isolcpus" >>> >> + dlog "nohz_full:$nohz_full" >>> >> + #dlog "rcu_nocbs:$rcu_nocbs" >>> >> + >>> >> + return 0 >>> >> +} >>> >> + >>> >> +cpus_valid() { >>> >> + local cpus="$1" >>> >> + local isolated=$2 >>> >> + local iarray=$(get_cpu_array $isolated) >>> >> + local carray=$(get_cpu_array $cpus) >>> >> + >>> >> + for c in $carray; do >>> >> + for i in $iarray; do >>> > >>> > maybe check that the user didn't provide 0 as a CPU to isolate? >>> > >>> >> + if [ $i = $c ]; then >>> >> + yah=$i >>> >> + fi >>> >> + done >>> >> + [ -z "$yah" ] && return 1 >>> >> + done >>> >> + >>> >> + return 0 >>> >> +} >>> >> + >>> >> +check_prequesties() { >>> >> + dlog "Checking prequesties; user is root, kernel has cpuset >>> support,"\ >>> >> + " and commads; set, zgrep, getconf are available" >>> >> + [ $UID -eq 0 ] || die "You need to be root!" >>> >> + grep -q -s cpuset /proc/filesystems || die "Kernel does not >>> support cpuset!" >>> >> + which getconf > /dev/null 2>&1 || die "getconf command not >>> found, please "\ >>> >> + "install getconf" >>> >> + which cset > /dev/null 2>&1 || die "cset command not found, >>> please "\ >>> >> + "install cpuset" >>> >> + which zgrep > /dev/null 2>&1 || die "zgrep command not >>> found, please "\ >>> >> + "install gzip" >>> >> +} >>> >> + >>> >> +shield_reset() { >>> >> + cset shield -r >/dev/null 2>&1 >>> >> + sleep 0.1 >>> >> +} >>> >> + >>> >> +shield_list() { >>> >> + sets="/cpusets/*/" >>> >> + for i in $sets ; do >>> >> + if ! [ -e $i ]; then >>> >> + continue >>> >> + fi >>> >> + printf "Domain %s cpus %s, running %d tasks\n" \ >>> >> + $(basename $i) $(cat $i/cpuset.cpus) $(cat $i/tasks | >>> wc -l) >>> >> + done >>> >> +} >>> >> + >>> >> +shield_cpus() { >>> >> + local cpus="$1" >>> >> + >>> >> + dlog "shielding CPU:s $cpus" >>> >> + >>> >> + #Reset and create new shield >>> >> + shield_reset >>> >> + out=$(cset shield -c $cpus -k on 2>&1) || die "cset failed; >>> $out" >>> >> + # Delay the annoying vmstat timer far away >>> >> + sysctl vm.stat_interval=120 >/dev/null >>> >> + >>> >> + # Shutdown nmi watchdog as it uses perf events >>> >> + sysctl -w kernel.watchdog=0 >/dev/null >>> >> + >>> >> + # Pin the writeback workqueue to CPU0 >>> >> + #Fixme, check that /sys/bus is mounted? >>> >> + echo 1 > /sys/bus/workqueue/devices/writeback/cpumask >>> >> + >>> >> + # Disable load balanser. >>> > >>> > balancer >>> > >>> >> + echo 0 > /cpusets/user/cpuset.sched_load_balance >>> >> + >>> >> + #Fixme, for now just send all irqs to core 0 >>> >> + for affinity in /proc/irq/*/smp_affinity; do >>> >> + dlog "redirecting $affinity" >>> >> + echo 1 > $affinity 2>/dev/null || dlog "$affinity >>> redirection failed." >>> >> + done >>> >> + >>> >> + >>> >> + #Fixme, not implemented. >>> >> + if [ $false ]; then >>> >> + for affinity in /proc/irq/*/smp_affinity; do >>> >> + local old_mask=$(cat $affinity) >>> >> + local new_mask=$((oldmask ^ cpus )) >>> >> + echo $new_mask > $affinity >>> >> + done >>> >> + fi >>> >> +} >>> >> + >>> >> +isolate_cpus() { >>> >> + >>> >> + local cpus="$1" >>> >> + >>> >> + check_kernel_config >>> >> + >>> >> + if [ "$gbl_isolated_cpus" ]; then >>> >> + cpus_valid $cpus $gbl_isolated_cpus || >>> >> + warn "Selected CPU '$cpus' is not inside isolated >>> cpus "\ >>> >> + "array:$gbl_isolated_cpus" >>> >> + fi >>> >> + >>> >> + dlog "Isolating CPUs $cpus" >>> >> + >>> >> + shield_cpus $cpus >>> >> + >>> >> + # Verfiy cores empty >>> >> + for c in $(get_cpu_array $cpus); do >>> >> + running=$(ps ax -o pid,psr,comm | \ >>> >> + awk -v cpu="$c" '{if($2==cpu){print $3}}') >>> >> + if [ "$running" != "" ]; then >>> >> + warn "Core $c not empty!" >>> >> + dlog "; running tasks:\n$running\n" >>> >> + fi >>> >> + done >>> > >>> > indentation (tabs used here but spaces above) >>> > >>> >> + >>> >> + return 0 >>> >> +} >>> >> + >>> >> +## >>> >> +# Script entry point >>> >> +## >>> >> +while getopts hdarlc: arguments >>> >> +do >>> >> + case $arguments in >>> >> + h) >>> >> + print_usage >>> >> + exit 0 >>> >> + ;; >>> >> + d) >>> >> + DEBUG=1 >>> >> + ;; >>> >> + a) >>> >> + ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" >>> >> + ;; >>> >> + r) >>> >> + shield_reset >>> >> + exit 0 >>> >> + ;; >>> >> + l) >>> >> + shield_list >>> >> + exit 0 >>> >> + ;; >>> >> + c) >>> >> + [ "$ISOL_CPUS" ] || ISOL_CPUS=$OPTARG >>> >> + ;; >>> >> + *) >>> >> + print_usage >>> >> + exit 1 >>> >> + ;; >>> >> + esac >>> >> +done >>> >> +#Remove all flags >>> >> +shift $((OPTIND-1)) >>> >> + >>> >> +if ! [ $ISOL_CPUS ]; then >>> >> + print_usage >>> >> + exit 1 >>> >> +fi >>> >> + >>> >> +check_prequesties >>> >> +isolate_cpus $ISOL_CPUS || die "isolate_cpus failed." >>> > >>> > isolate_cpus() always retuns success... >>> > >>> >> diff --git a/scripts/task-isolation/isolate-task.sh >>> b/scripts/task-isolation/isolate-task.sh >>> >> new file mode 100755 >>> >> index 0000000..3e588bc >>> >> --- /dev/null >>> >> +++ b/scripts/task-isolation/isolate-task.sh >>> >> @@ -0,0 +1,160 @@ >>> >> +#!/bin/bash >>> >> +# >>> >> +# Copyright (c) 2017, Linaro Limited >>> >> +# All rights reserved. >>> >> +# >>> >> +# SPDX-License-Identifier: BSD-3-Clause >>> >> +# >>> >> +# Script that passes command line arguments to odp_scheduling after, >>> >> +# optionally, isolating CPU >>> >> +# >>> >> +# This script isolates a task on desired CPUs and >>> >> +# optionally creates background noise. >>> >> + >>> >> +print_usage() { >>> >> + echo "$0 [-c <cpu list>] [-d] [-h] [-n] <application arg1, >>> arg2, ...>" >>> >> + echo >>> >> + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" >>> >> + echo " and run an application on isolated CPUs" >>> >> + echo " Args:" >>> >> + echo " -c List of CPUs to be isolated" >>> >> + echo " -d Show debug printouts" >>> >> + echo " -h Print this message" >>> >> + echo " -n Create background noise (stress)" >>> >> + echo "" >>> >> + echo "All CPU's, except CPU 0, are isolated unless '-c' >>> specified" >>> >> + echo " Examples:" >>> >> + echo " Isolate CPU 1,2 and run application in the same." >>> >> + echo " $0 -n -c 1,2 /some/path/application" >>> >> + echo >>> >> + echo " Isolate all possible CPUs and run applicatipon" >>> >> + echo " $0 /path/application" >>> >> +} >>> >> + >>> >> +dlog() { >>> >> + [ $DEBUG ] && echo "$*" >>> >> +} >>> >> + >>> >> +die() { >>> >> + printf "Error: $*\n" >&2 >>> >> + exit 1 >>> >> +} >>> >> + >>> >> +trap cleanup INT EXIT >>> >> + >>> >> +cleanup(){ >>> >> + local pids=$(pgrep $MY_STRESS 2>/dev/null) >>> >> + local base=$(dirname $0) >>> >> + >>> >> + $base/isolate-cpu.sh -r >>> >> + [ "$pids" != "" ] && kill -9 $pids >/dev/null 2>&1 >>> >> + kill -9 $CHILD >/dev/null 2>&1 >>> >> + rm -f $MY_STRESS_PATH >>> >> +} >>> >> + >>> >> +wait_app_started () { >>> >> + local child=$1 >>> >> + local ltasks=0 >>> >> + >>> >> + while true; do >>> >> + sleep 0.01 >>> >> + kill -0 $child 2>/dev/null || break >>> >> + tasks=$(ls /proc/$child/task | wc -l) >>> >> + [ $tasks -eq $ltasks ] && break >>> >> + ltasks=$tasks >>> >> + done >>> >> + dlog "app started, # threads:$ltasks" >>> >> +} >>> >> + >>> >> +create_noise() { >>> >> + local mpath=$1 >>> >> + local nr=$(grep processor /proc/cpuinfo | wc -l) >>> >> + >>> >> + ln -sf $(which stress) $mpath || die "ln failed" >>> >> + $mpath -c $nr 2>&1 >/dev/null & >>> >> + disown $! >>> >> +} >>> >> + >>> >> +isolate_cpu(){ >>> >> + local cpus=$1 >>> >> + local base=$(dirname $0) >>> >> + $base/isolate-cpu.sh -c $cpus || die "$0 failed" >>> >> +} >>> >> + >>> >> +run_application() { >>> >> + local app="$1" >>> >> + >>> >> + dlog "Starting application: $app" >>> >> + $app& >>> >> + child=$! >>> >> + CHILD=$child >>> >> + >>> >> + echo $child >> /cpusets/user/tasks >>> >> + if [ $? -ne 0 ]; then >>> >> + kill -9 $child >>> >> + die "Failed to isolate task..." >>> >> + fi >>> >> + >>> >> + wait_app_started $child >>> >> + wait $child >>> >> +} >>> >> + >>> >> +check_prequesties() { >>> >> + local base=$(dirname $0) >>> >> + >>> >> + [ -e $base/isolate-cpu.sh ] || die "$base/isolate-cpu.sh not >>> found!" >>> >> + [ $UID -eq 0 ] || die "You need to be root!" >>> >> + which stress > /dev/null 2>&1 || die "stress command not >>> found, "\ >>> >> + "please install stress" >>> >> +} >>> >> + >>> >> +## >>> >> +# Script entry point >>> >> +## >>> >> + >>> >> +ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" >>> >> + >>> >> +while getopts hdnc: arguments >>> >> +do >>> >> + case $arguments in >>> >> + h) >>> >> + print_usage >>> >> + exit 0 >>> >> + ;; >>> >> + d) >>> >> + DEBUG=1 >>> >> + ;; >>> >> + n) >>> >> + NOISE=1 >>> >> + ;; >>> >> + c) >>> >> + ISOL_CPUS=$OPTARG >>> >> + ;; >>> >> + *) >>> >> + print_usage >>> >> + exit 1 >>> >> + ;; >>> >> + esac >>> >> +done >>> >> +# Remove all flags >>> >> +shift $((OPTIND-1)) >>> >> + >>> >> +if ! [ "$1" ]; then >>> >> + print_usage >>> >> + exit 1 >>> >> +fi >>> >> + >>> >> +#Isolate and optionally create noise >>> >> +command="$*" >>> >> +set -- $command >>> >> + >>> >> +check_prequesties >>> >> + >>> >> +MY_STRESS=stress-by-$$ >>> >> +MY_STRESS_PATH=/tmp/$MY_STRESS >>> >> + >>> >> +isolate_cpu $ISOL_CPUS || die "isolate cpu failed!" >>> >> +[ -z $NOISE ] || create_noise $MY_STRESS_PATH >>> >> +run_application "$command" >>> >> + >>> >> +exit $? >>> >> diff --git >>> a/test/linux-generic/performance/odp_run_app_isolated.sh >>> b/test/linux-generic/performance/odp_run_app_isolated.sh >>> >> new file mode 100755 >>> >> index 0000000..3bed0a7 >>> >> --- /dev/null >>> >> +++ b/test/linux-generic/performance/odp_run_app_isolated.sh >>> > >>> > there is a mix of spaces and tabs for indentation in this script >>> > >>> >> @@ -0,0 +1,108 @@ >>> >> +#!/bin/sh >>> >> +# >>> >> +# Copyright (c) 2017, Linaro Limited >>> >> +# All rights reserved. >>> >> +# >>> >> +# SPDX-License-Identifier: BSD-3-Clause >>> >> +# >>> >> + >>> >> + >>> >> +TEST_DIR="${TEST_DIR:-$(dirname $0)}" >>> >> +PERFORMANCE="$TEST_DIR/../../common_plat/performance" >>> >> +ISOL_DIR="${TEST_DIR}/../../../scripts/task-isolation" >>> >> +APPLICATION="${PERFORMANCE}/odp_pktio_perf${EXEEXT}" >>> >> +APPLICATION_ARGS="" >>> >> +APPLICATION_BASE="$(basename ${APPLICATION})" >>> >> + >>> >> +cleanup(){ >>> >> + pids=$(pgrep stress 2>/dev/null) >>> >> + [ "$pids" != "" ] && kill -9 $pids >>> >> +} >>> >> + >>> >> +print_usage() { >>> >> + echo "$0 [-i] [-n] [-h] [<application> <application args>]" >>> >> + echo >>> >> + echo " Run an application with or without isolation and >>> background noise" >>> >> + echo " Flags:" >>> >> + echo " -h Print this message" >>> >> + echo " -i Isolate CPU prior to running application." >>> >> + echo " -n Create background noise (stress)" >>> >> + echo "" >>> >> + echo " <application> targeted application" >>> >> + echo " <args> targeted application arguments" >>> >> + echo " *Note* Default application is ${APPLICATION_BASE}" >>> >> + echo "" >>> >> + echo " Example:" >>> >> + echo " Isolate CPU, create background noise and run >>> ${APPLICATION_BASE}:" >>> >> + echo " $0 -i -n" >>> >> + echo >>> >> + echo " Run ${APPLICATION_BASE}, w/o isolation but with >>> background noise:" >>> >> + echo " $0 -n" >>> >> + echo >>> >> + echo " Run Myapp, without isolation but with background noise:" >>> >> + echo " $0 -n Myapp -s ome args" >>> >> +} >>> >> + >>> >> +run() { >>> >> + local isolate=$1 >>> >> + local noise=$2 >>> >> + if [ ${isolate} -eq 1 ]; then >>> >> + [ ${noise} -eq 1 ] && noise_par="-n" >>> >> + echo Running ${APPLICATION_BASE} with isolation and >>> background noise >>> >> + echo ===================================================== >>> >> + $ISOL_DIR/isolate-task.sh ${noise_par} ${APPLICATION} \ >>> >> + ${APPLICATION_ARGS} || exit 1 >>> >> + #reset isolation >>> >> + $ISOL_DIR/isolate-cpu.sh -r >>> >> + else >>> >> + echo Running ${APPLICATION_BASE} without isolation >>> >> + echo ===================================================== >>> >> + if [ ${noise} -eq 1 ]; then >>> >> + local nr=$(grep processor /proc/cpuinfo | wc -l) >>> >> + echo " Creating background noise..." >>> >> + stress -c $nr 2>&1 >/dev/null & >>> >> + fi >>> >> + ${APPLICATION} ${APPLICATION_ARGS} || exit 2 >>> >> + fi >>> >> +} >>> >> + >>> >> +trap cleanup INT EXIT >>> >> +ISOLATE=0 >>> >> +NOISE=0 >>> >> +while getopts hni arguments >>> >> +do >>> >> + case $arguments in >>> >> + h) >>> >> + print_usage >>> >> + exit 0 >>> >> + ;; >>> >> + n) >>> >> + NOISE=1 >>> >> + $(which stress > /dev/null 2>&1) >>> >> + ret=$? >>> >> + if [ ${ret} -ne 0 ]; then >>> > >>> > or: >>> > if ! $(which stress > /dev/null 2>&1); then >>> > >>> >> + echo "'stress' not found, bailing" >&2 >>> >> + exit 3 >>> >> + fi >>> >> + ;; >>> >> + i) >>> >> + ISOLATE=1 >>> >> + ;; >>> >> + *) >>> >> + print_usage >>> >> + exit 1 >>> >> + ;; >>> >> + esac >>> >> +done >>> >> +#Remove flags >>> >> +shift $((OPTIND-1)) >>> >> + >>> >> +if [ $# -gt 0 ]; then >>> >> + APPLICATION="$1" >>> >> + shift >>> >> +fi >>> >> +[ $# -gt 0 ] && APPLICATION_ARGS=$* >>> >> + >>> >> +run ${ISOLATE} ${NOISE} >>> >> + >>> >> +exit $? >>> > >>> > not needed, the script will exit with the exit value of the last >>> > command executed. >>> > >>> >> -- >>> >> 2.7.4 >>> >> >>> >>> >>> >>> >>> -- >>> Mike Holmes >>> Program Manager - Linaro Networking Group >>> Linaro.org <http://www.linaro.org/>* **│ *Open source software for ARM SoCs >>> "Work should be fun and collaborative, the rest follows" >>> >>> __ >>> >>> >> > > >
diff --git a/scripts/task-isolation/README b/scripts/task-isolation/README new file mode 100644 index 0000000..cb02056 --- /dev/null +++ b/scripts/task-isolation/README @@ -0,0 +1,22 @@ +Helper scripts to check and set CPU isolation and execution of application in +isolated CPU(s) + +Files: +isolate-cpu.sh isolates desired CPUs +isolate-task.sh uses isolate-cpu.sh to isolate CPUs before running + the desired task. It also provides the possibility + to trace kernel disturbance on the isolated CPUs. + +isolate-cpu.sh checks the kernel configuration and the kernel cmdline to + determine if one or several CPUs are isolated, i.e. it checks for; + CONFIG_NO_HZ_FULL_ALL=y", and CONFIG_RCU_NOCB_CPU_ALL=y" in the kernel config + and rcu_nocbs,nohz_full in the kernel cmdline. + If the desired CPU(s) are not inte the above configuration, it warns but continues + to isolate the CPU(s) as much as possibe. The isolation is accomplished by + - Redirecting all IRQ's away from desired isolated cores + - Using cset (cpuset) to move all running processes and kernel threads + away from desired isolated cores + +isolate-task.sh uses isolate-cpu.sh to isolate desired CPU(s). In addition + it starts the supplied application on isolated CPU(s) and optionally traces + the isolated CPU(s) for kernel interaction. diff --git a/scripts/task-isolation/isolate-cpu.sh b/scripts/task-isolation/isolate-cpu.sh new file mode 100755 index 0000000..3eaf98a --- /dev/null +++ b/scripts/task-isolation/isolate-cpu.sh @@ -0,0 +1,287 @@ +#!/bin/bash +# +# Copyright (c) 2017, Linaro Limited +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# Script that passes command line arguments to odp_scheduling after, +# optionally, isolating CPU +# +# This script isolates desired CPUS, i.e. +# - Checks kernel cmdline and kernel config to determine +# if the environment is optimised for isolated task execution; +# - Moves CPU interrupts, kernel threads, tasks etc. away from the +# targeted CPU. +# *Note* CPU 0 cannot be isolated, i.e minimum 2 CPU's are required. + + +print_usage() { + echo "$0 [-h] [-a] [-c <cpu list>] [-l] [-r] [-d]" + echo + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" + echo " Args:" + echo " -h Print this message" + echo " -a Isolate all CPUs (except CPU 0)" + echo " -c List of CPUs to be isolated." + echo " -l Show isolation proporties" + echo " -r Reset isolation" + echo " -d Show debug printouts" + echo "" + echo " Examples:" + echo " Isolate all CPU(s) (except 0) " + echo " $0 -a" + echo + echo " Isolate CPUs 1-3 " + echo " $0 -c 1-3" + echo + echo " Isolate CPUs 1 and 4 " + echo " $0 -c 1,4 " +} + +dlog() { + [ $DEBUG ] && echo "$*" +} + +warn() { + printf "Warning: $*\n" >&2 +} + +die() { + printf "Error: $*\n" >&2 + exit 1 +} + +get_cpu_array() { + [ $1 ] || die "$FUNCNAME internal error!" + + local cpus="" + IFS=. a=$1; IFS=, a=$a; + for str in $a; do + if [[ $str == *[\-]* ]]; then + str=$(echo $str| sed 's/-/../g') + str=$(eval echo {$str}) + fi + + if [ "$cpus" != "" ]; then + cpus="$cpus $str" + else + cpus=$str + fi + done + + echo $cpus +} + +## +# Check kernel config and kernel cmdline for rcu callbacs and no_hz +# *Note* isolcpu= kernel cmdline option isolates CPUs from SMP balancing +# If needed, this can be done via +# cpusets/user/cpuset.sched_load_balance +## +check_kernel_config() { + + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') + + local configs="/proc/config.gz /boot/config-$(uname -r) /boot/config " + dlog "Looking for Kernel configs; $configs " + for config in $configs; do + if [ -e $config ]; then + dlog "Kenel configuration found:$config" + break + fi + done + + local all_except_0="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" + if [ $config ]; then + nohz_full=$(zgrep "CONFIG_NO_HZ_FULL_ALL=y" $config 2>/dev/null) \ + && nohz_full=$all_except_0 + else + warn "Kernel config not found, only checking /proc/cmdline for"\ + " isolation features." + fi + + if ! [ "$nohz_full" ]; then + eval $(cat /proc/cmdline | grep -o 'nohz_full=[^ ]*') + fi + + eval $(cat /proc/cmdline | grep -o 'isolcpus=[^ ]*') + if [ -z "$isolcpus" ]; then + warn "No CPU is isolated from kernel/user threads, isolcpus= is "\ + "not set in kernel cmdline." + else + gbl_isolated_cpus=$isolcpus + export gbl_isolated_cpus + fi + + if [ -z "$nohz_full" ]; then + warn "No CPU is isolated from kernel ticks, CONFIG_NO_HZ_FULL_ALL=y" \ + " not set in kernel, nor nohz_full= set in kernel cmdline." + fi + + for i in `pgrep rcu` ; do taskset -pc 0 $i >/dev/null; done + + dlog "isolcpus:$isolcpus" + dlog "nohz_full:$nohz_full" + #dlog "rcu_nocbs:$rcu_nocbs" + + return 0 +} + +cpus_valid() { + local cpus="$1" + local isolated=$2 + local iarray=$(get_cpu_array $isolated) + local carray=$(get_cpu_array $cpus) + + for c in $carray; do + for i in $iarray; do + if [ $i = $c ]; then + yah=$i + fi + done + [ -z "$yah" ] && return 1 + done + + return 0 +} + +check_prequesties() { + dlog "Checking prequesties; user is root, kernel has cpuset support,"\ + " and commads; set, zgrep, getconf are available" + [ $UID -eq 0 ] || die "You need to be root!" + grep -q -s cpuset /proc/filesystems || die "Kernel does not support cpuset!" + which getconf > /dev/null 2>&1 || die "getconf command not found, please "\ + "install getconf" + which cset > /dev/null 2>&1 || die "cset command not found, please "\ + "install cpuset" + which zgrep > /dev/null 2>&1 || die "zgrep command not found, please "\ + "install gzip" +} + +shield_reset() { + cset shield -r >/dev/null 2>&1 + sleep 0.1 +} + +shield_list() { + sets="/cpusets/*/" + for i in $sets ; do + if ! [ -e $i ]; then + continue + fi + printf "Domain %s cpus %s, running %d tasks\n" \ + $(basename $i) $(cat $i/cpuset.cpus) $(cat $i/tasks | wc -l) + done +} + +shield_cpus() { + local cpus="$1" + + dlog "shielding CPU:s $cpus" + + #Reset and create new shield + shield_reset + out=$(cset shield -c $cpus -k on 2>&1) || die "cset failed; $out" + # Delay the annoying vmstat timer far away + sysctl vm.stat_interval=120 >/dev/null + + # Shutdown nmi watchdog as it uses perf events + sysctl -w kernel.watchdog=0 >/dev/null + + # Pin the writeback workqueue to CPU0 + #Fixme, check that /sys/bus is mounted? + echo 1 > /sys/bus/workqueue/devices/writeback/cpumask + + # Disable load balanser. + echo 0 > /cpusets/user/cpuset.sched_load_balance + + #Fixme, for now just send all irqs to core 0 + for affinity in /proc/irq/*/smp_affinity; do + dlog "redirecting $affinity" + echo 1 > $affinity 2>/dev/null || dlog "$affinity redirection failed." + done + + + #Fixme, not implemented. + if [ $false ]; then + for affinity in /proc/irq/*/smp_affinity; do + local old_mask=$(cat $affinity) + local new_mask=$((oldmask ^ cpus )) + echo $new_mask > $affinity + done + fi +} + +isolate_cpus() { + + local cpus="$1" + + check_kernel_config + + if [ "$gbl_isolated_cpus" ]; then + cpus_valid $cpus $gbl_isolated_cpus || + warn "Selected CPU '$cpus' is not inside isolated cpus "\ + "array:$gbl_isolated_cpus" + fi + + dlog "Isolating CPUs $cpus" + + shield_cpus $cpus + + # Verfiy cores empty + for c in $(get_cpu_array $cpus); do + running=$(ps ax -o pid,psr,comm | \ + awk -v cpu="$c" '{if($2==cpu){print $3}}') + if [ "$running" != "" ]; then + warn "Core $c not empty!" + dlog "; running tasks:\n$running\n" + fi + done + + return 0 +} + +## +# Script entry point +## +while getopts hdarlc: arguments +do + case $arguments in + h) + print_usage + exit 0 + ;; + d) + DEBUG=1 + ;; + a) + ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" + ;; + r) + shield_reset + exit 0 + ;; + l) + shield_list + exit 0 + ;; + c) + [ "$ISOL_CPUS" ] || ISOL_CPUS=$OPTARG + ;; + *) + print_usage + exit 1 + ;; + esac +done +#Remove all flags +shift $((OPTIND-1)) + +if ! [ $ISOL_CPUS ]; then + print_usage + exit 1 +fi + +check_prequesties +isolate_cpus $ISOL_CPUS || die "isolate_cpus failed." diff --git a/scripts/task-isolation/isolate-task.sh b/scripts/task-isolation/isolate-task.sh new file mode 100755 index 0000000..3e588bc --- /dev/null +++ b/scripts/task-isolation/isolate-task.sh @@ -0,0 +1,160 @@ +#!/bin/bash +# +# Copyright (c) 2017, Linaro Limited +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# +# Script that passes command line arguments to odp_scheduling after, +# optionally, isolating CPU +# +# This script isolates a task on desired CPUs and +# optionally creates background noise. + +print_usage() { + echo "$0 [-c <cpu list>] [-d] [-h] [-n] <application arg1, arg2, ...>" + echo + echo " Isolate CPU(s) from other tasks, kernel threads and IRQs" + echo " and run an application on isolated CPUs" + echo " Args:" + echo " -c List of CPUs to be isolated" + echo " -d Show debug printouts" + echo " -h Print this message" + echo " -n Create background noise (stress)" + echo "" + echo "All CPU's, except CPU 0, are isolated unless '-c' specified" + echo " Examples:" + echo " Isolate CPU 1,2 and run application in the same." + echo " $0 -n -c 1,2 /some/path/application" + echo + echo " Isolate all possible CPUs and run applicatipon" + echo " $0 /path/application" +} + +dlog() { + [ $DEBUG ] && echo "$*" +} + +die() { + printf "Error: $*\n" >&2 + exit 1 +} + +trap cleanup INT EXIT + +cleanup(){ + local pids=$(pgrep $MY_STRESS 2>/dev/null) + local base=$(dirname $0) + + $base/isolate-cpu.sh -r + [ "$pids" != "" ] && kill -9 $pids >/dev/null 2>&1 + kill -9 $CHILD >/dev/null 2>&1 + rm -f $MY_STRESS_PATH +} + +wait_app_started () { + local child=$1 + local ltasks=0 + + while true; do + sleep 0.01 + kill -0 $child 2>/dev/null || break + tasks=$(ls /proc/$child/task | wc -l) + [ $tasks -eq $ltasks ] && break + ltasks=$tasks + done + dlog "app started, # threads:$ltasks" +} + +create_noise() { + local mpath=$1 + local nr=$(grep processor /proc/cpuinfo | wc -l) + + ln -sf $(which stress) $mpath || die "ln failed" + $mpath -c $nr 2>&1 >/dev/null & + disown $! +} + +isolate_cpu(){ + local cpus=$1 + local base=$(dirname $0) + $base/isolate-cpu.sh -c $cpus || die "$0 failed" +} + +run_application() { + local app="$1" + + dlog "Starting application: $app" + $app& + child=$! + CHILD=$child + + echo $child >> /cpusets/user/tasks + if [ $? -ne 0 ]; then + kill -9 $child + die "Failed to isolate task..." + fi + + wait_app_started $child + wait $child +} + +check_prequesties() { + local base=$(dirname $0) + + [ -e $base/isolate-cpu.sh ] || die "$base/isolate-cpu.sh not found!" + [ $UID -eq 0 ] || die "You need to be root!" + which stress > /dev/null 2>&1 || die "stress command not found, "\ + "please install stress" +} + +## +# Script entry point +## + +ISOL_CPUS="1-$(($(getconf _NPROCESSORS_ONLN) - 1))" + +while getopts hdnc: arguments +do + case $arguments in + h) + print_usage + exit 0 + ;; + d) + DEBUG=1 + ;; + n) + NOISE=1 + ;; + c) + ISOL_CPUS=$OPTARG + ;; + *) + print_usage + exit 1 + ;; + esac +done +# Remove all flags +shift $((OPTIND-1)) + +if ! [ "$1" ]; then + print_usage + exit 1 +fi + +#Isolate and optionally create noise +command="$*" +set -- $command + +check_prequesties + +MY_STRESS=stress-by-$$ +MY_STRESS_PATH=/tmp/$MY_STRESS + +isolate_cpu $ISOL_CPUS || die "isolate cpu failed!" +[ -z $NOISE ] || create_noise $MY_STRESS_PATH +run_application "$command" + +exit $? diff --git a/test/linux-generic/performance/odp_run_app_isolated.sh b/test/linux-generic/performance/odp_run_app_isolated.sh new file mode 100755 index 0000000..3bed0a7 --- /dev/null +++ b/test/linux-generic/performance/odp_run_app_isolated.sh @@ -0,0 +1,108 @@ +#!/bin/sh +# +# Copyright (c) 2017, Linaro Limited +# All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + + +TEST_DIR="${TEST_DIR:-$(dirname $0)}" +PERFORMANCE="$TEST_DIR/../../common_plat/performance" +ISOL_DIR="${TEST_DIR}/../../../scripts/task-isolation" +APPLICATION="${PERFORMANCE}/odp_pktio_perf${EXEEXT}" +APPLICATION_ARGS="" +APPLICATION_BASE="$(basename ${APPLICATION})" + +cleanup(){ + pids=$(pgrep stress 2>/dev/null) + [ "$pids" != "" ] && kill -9 $pids +} + +print_usage() { + echo "$0 [-i] [-n] [-h] [<application> <application args>]" + echo + echo " Run an application with or without isolation and background noise" + echo " Flags:" + echo " -h Print this message" + echo " -i Isolate CPU prior to running application." + echo " -n Create background noise (stress)" + echo "" + echo " <application> targeted application" + echo " <args> targeted application arguments" + echo " *Note* Default application is ${APPLICATION_BASE}" + echo "" + echo " Example:" + echo " Isolate CPU, create background noise and run ${APPLICATION_BASE}:" + echo " $0 -i -n" + echo + echo " Run ${APPLICATION_BASE}, w/o isolation but with background noise:" + echo " $0 -n" + echo + echo " Run Myapp, without isolation but with background noise:" + echo " $0 -n Myapp -s ome args" +} + +run() { + local isolate=$1 + local noise=$2 + if [ ${isolate} -eq 1 ]; then + [ ${noise} -eq 1 ] && noise_par="-n" + echo Running ${APPLICATION_BASE} with isolation and background noise + echo ===================================================== + $ISOL_DIR/isolate-task.sh ${noise_par} ${APPLICATION} \ + ${APPLICATION_ARGS} || exit 1 + #reset isolation + $ISOL_DIR/isolate-cpu.sh -r + else + echo Running ${APPLICATION_BASE} without isolation + echo ===================================================== + if [ ${noise} -eq 1 ]; then + local nr=$(grep processor /proc/cpuinfo | wc -l) + echo " Creating background noise..." + stress -c $nr 2>&1 >/dev/null & + fi + ${APPLICATION} ${APPLICATION_ARGS} || exit 2 + fi +} + +trap cleanup INT EXIT +ISOLATE=0 +NOISE=0 +while getopts hni arguments +do + case $arguments in + h) + print_usage + exit 0 + ;; + n) + NOISE=1 + $(which stress > /dev/null 2>&1) + ret=$? + if [ ${ret} -ne 0 ]; then + echo "'stress' not found, bailing" >&2 + exit 3 + fi + ;; + i) + ISOLATE=1 + ;; + *) + print_usage + exit 1 + ;; + esac +done +#Remove flags +shift $((OPTIND-1)) + +if [ $# -gt 0 ]; then + APPLICATION="$1" + shift +fi +[ $# -gt 0 ] && APPLICATION_ARGS=$* + +run ${ISOLATE} ${NOISE} + +exit $?
The wrapper script; odp_run_app_isolated.sh can be used to run ODP testcases in a isolated environment. Background noise can also be generated. Signed-off-by: Ravineet Singh <ravineet.singh@linaro.org> v2: moved task-isolation dir to odp/scripts, requested my Maxim Uvarov v3: fixed checkpatch.pl warnings --- scripts/task-isolation/README | 22 ++ scripts/task-isolation/isolate-cpu.sh | 287 +++++++++++++++++++++ scripts/task-isolation/isolate-task.sh | 160 ++++++++++++ .../performance/odp_run_app_isolated.sh | 108 ++++++++ 4 files changed, 577 insertions(+) create mode 100644 scripts/task-isolation/README create mode 100755 scripts/task-isolation/isolate-cpu.sh create mode 100755 scripts/task-isolation/isolate-task.sh create mode 100755 test/linux-generic/performance/odp_run_app_isolated.sh -- 2.7.4