Re: [PATCH 2/2] selftest/cpuidle: Add support for cpuidle latency measurement

2020-07-07 Thread Pratik Sampat

[..snip..]

+
+ins_mod()
+{
+    if [ ! -f "$MODULE" ]; then
+    printf "$MODULE module does not exist. Exitting\n"
+    exit 2


Please use ksft_skip code to indicate the test is being skipped.


Sure thing I'll use ksft_skip exit code instead.

+    fi
+    printf "Inserting $MODULE module\n\n"
+    insmod $MODULE
+    if [ $? != 0 ]; then
+    printf "Insmod $MODULE failed\n"
+    exit 2


This is fine since you expect to be able to load the module.


Thanks for the review.
Pratik

[..snip..]




thanks,
-- Shuah




Re: [PATCH 2/2] selftest/cpuidle: Add support for cpuidle latency measurement

2020-07-07 Thread Shuah Khan

On 7/7/20 9:29 AM, Pratik Rajesh Sampat wrote:

This patch adds support to trace IPI based and timer based wakeup
latency from idle states

Latches onto the test-cpuidle_latency kernel module using the debugfs
interface to send IPIs or schedule a timer based event, which in-turn
populates the debugfs with the latency measurements.

Currently for the IPI and timer tests; first disable all idle states
and then test for latency measurements incrementally enabling each state

Signed-off-by: Pratik Rajesh Sampat 
---
  tools/testing/selftests/Makefile   |   1 +
  tools/testing/selftests/cpuidle/Makefile   |   6 +
  tools/testing/selftests/cpuidle/cpuidle.sh | 240 +
  tools/testing/selftests/cpuidle/settings   |   1 +
  4 files changed, 248 insertions(+)
  create mode 100644 tools/testing/selftests/cpuidle/Makefile
  create mode 100755 tools/testing/selftests/cpuidle/cpuidle.sh
  create mode 100644 tools/testing/selftests/cpuidle/settings

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 1195bd85af38..ab6cf51f3518 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += capabilities
  TARGETS += cgroup
  TARGETS += clone3
  TARGETS += cpufreq
+TARGETS += cpuidle
  TARGETS += cpu-hotplug
  TARGETS += drivers/dma-buf
  TARGETS += efivarfs
diff --git a/tools/testing/selftests/cpuidle/Makefile 
b/tools/testing/selftests/cpuidle/Makefile
new file mode 100644
index ..72fd5d2e974d
--- /dev/null
+++ b/tools/testing/selftests/cpuidle/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+all:
+
+TEST_PROGS := cpuidle.sh
+
+include ../lib.mk
diff --git a/tools/testing/selftests/cpuidle/cpuidle.sh 
b/tools/testing/selftests/cpuidle/cpuidle.sh
new file mode 100755
index ..11666fe47c34
--- /dev/null
+++ b/tools/testing/selftests/cpuidle/cpuidle.sh
@@ -0,0 +1,240 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+LOG=cpuidle.log
+MODULE=/lib/modules/$(uname -r)/kernel/drivers/cpuidle/test-cpuidle_latency.ko
+
+helpme()
+{
+   printf "Usage: $0 [-h] [-todg args]
+   [-h ]
+   [-m ]
+   [-o ]
+   \n"
+   exit 2
+}
+
+parse_arguments()
+{
+   while getopts ht:m:o: arg
+   do
+   case $arg in
+   h) # --help
+   helpme
+   ;;
+   m) # --mod-file
+   MODULE=$OPTARG
+   ;;
+   o) # output log files
+   LOG=$OPTARG
+   ;;
+   \?)
+   helpme
+   ;;
+   esac
+   done
+}
+
+ins_mod()
+{
+   if [ ! -f "$MODULE" ]; then
+   printf "$MODULE module does not exist. Exitting\n"
+   exit 2


Please use ksft_skip code to indicate the test is being skipped.


+   fi
+   printf "Inserting $MODULE module\n\n"
+   insmod $MODULE
+   if [ $? != 0 ]; then
+   printf "Insmod $MODULE failed\n"
+   exit 2


This is fine since you expect to be able to load the module.


+   fi
+}
+
+compute_average()
+{
+   arr=("$@")
+   sum=0
+   size=${#arr[@]}
+   for i in "${arr[@]}"
+   do
+   sum=$((sum + i))
+   done
+   avg=$((sum/size))
+}
+
+# Disable all stop states
+disable_idle()
+{
+   for ((cpu=0; cpu 
/sys/devices/system/cpu/cpu$cpu/cpuidle/state$state/disable
+   done
+   done
+}
+
+# Enable the idle state supplied
+# $1: State to enable
+enable_state()
+{
+   for ((cpu=0; cpu /sys/devices/system/cpu/cpu$cpu/cpuidle/state$1/disable
+   done
+}
+
+# Extract latency in microseconds and convert to nanoseconds
+extract_latency()
+{
+   for ((state=0; state /dev/null &
+   yes_pid=$!
+fi
+taskset 0x1 echo $dest_cpu > 
/sys/kernel/debug/latency_test/ipi_cpu_dest
+ipi_latency=$(cat /sys/kernel/debug/latency_test/ipi_latency_ns)
+src_cpu=$(cat /sys/kernel/debug/latency_test/ipi_cpu_src)
+if [ "$1" = "baseline" ]; then
+   kill $yes_pid
+   wait $yes_pid 2>/dev/null
+fi
+}
+
+# Incrementally Enable idle states one by one and compute the latency
+run_ipi_tests()
+{
+extract_latency
+disable_idle
+declare -a avg_arr
+declare -a baseline_avg_array
+
+echo -e "--IPI Latency Test---" >> $LOG
+for ((state=0; state> $LOG
+   enable_state $state
+   printf "%s %10s %12s %12s\n" "SRC_CPU" "DEST_CPU" 
"Base_IPI_Latency(ns)" "IPI_Latency(ns)" >> $LOG
+   unset avg_arr
+   unset baseline_avg_arr
+   for ((cpu=0; cpu> $LOG
+   

[PATCH 2/2] selftest/cpuidle: Add support for cpuidle latency measurement

2020-07-07 Thread Pratik Rajesh Sampat
This patch adds support to trace IPI based and timer based wakeup
latency from idle states

Latches onto the test-cpuidle_latency kernel module using the debugfs
interface to send IPIs or schedule a timer based event, which in-turn
populates the debugfs with the latency measurements.

Currently for the IPI and timer tests; first disable all idle states
and then test for latency measurements incrementally enabling each state

Signed-off-by: Pratik Rajesh Sampat 
---
 tools/testing/selftests/Makefile   |   1 +
 tools/testing/selftests/cpuidle/Makefile   |   6 +
 tools/testing/selftests/cpuidle/cpuidle.sh | 240 +
 tools/testing/selftests/cpuidle/settings   |   1 +
 4 files changed, 248 insertions(+)
 create mode 100644 tools/testing/selftests/cpuidle/Makefile
 create mode 100755 tools/testing/selftests/cpuidle/cpuidle.sh
 create mode 100644 tools/testing/selftests/cpuidle/settings

diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 1195bd85af38..ab6cf51f3518 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -7,6 +7,7 @@ TARGETS += capabilities
 TARGETS += cgroup
 TARGETS += clone3
 TARGETS += cpufreq
+TARGETS += cpuidle
 TARGETS += cpu-hotplug
 TARGETS += drivers/dma-buf
 TARGETS += efivarfs
diff --git a/tools/testing/selftests/cpuidle/Makefile 
b/tools/testing/selftests/cpuidle/Makefile
new file mode 100644
index ..72fd5d2e974d
--- /dev/null
+++ b/tools/testing/selftests/cpuidle/Makefile
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0
+all:
+
+TEST_PROGS := cpuidle.sh
+
+include ../lib.mk
diff --git a/tools/testing/selftests/cpuidle/cpuidle.sh 
b/tools/testing/selftests/cpuidle/cpuidle.sh
new file mode 100755
index ..11666fe47c34
--- /dev/null
+++ b/tools/testing/selftests/cpuidle/cpuidle.sh
@@ -0,0 +1,240 @@
+#!/bin/bash
+# SPDX-License-Identifier: GPL-2.0
+
+LOG=cpuidle.log
+MODULE=/lib/modules/$(uname -r)/kernel/drivers/cpuidle/test-cpuidle_latency.ko
+
+helpme()
+{
+   printf "Usage: $0 [-h] [-todg args]
+   [-h ]
+   [-m ]
+   [-o ]
+   \n"
+   exit 2
+}
+
+parse_arguments()
+{
+   while getopts ht:m:o: arg
+   do
+   case $arg in
+   h) # --help
+   helpme
+   ;;
+   m) # --mod-file
+   MODULE=$OPTARG
+   ;;
+   o) # output log files
+   LOG=$OPTARG
+   ;;
+   \?)
+   helpme
+   ;;
+   esac
+   done
+}
+
+ins_mod()
+{
+   if [ ! -f "$MODULE" ]; then
+   printf "$MODULE module does not exist. Exitting\n"
+   exit 2
+   fi
+   printf "Inserting $MODULE module\n\n"
+   insmod $MODULE
+   if [ $? != 0 ]; then
+   printf "Insmod $MODULE failed\n"
+   exit 2
+   fi
+}
+
+compute_average()
+{
+   arr=("$@")
+   sum=0
+   size=${#arr[@]}
+   for i in "${arr[@]}"
+   do
+   sum=$((sum + i))
+   done
+   avg=$((sum/size))
+}
+
+# Disable all stop states
+disable_idle()
+{
+   for ((cpu=0; cpu 
/sys/devices/system/cpu/cpu$cpu/cpuidle/state$state/disable
+   done
+   done
+}
+
+# Enable the idle state supplied
+# $1: State to enable
+enable_state()
+{
+   for ((cpu=0; cpu /sys/devices/system/cpu/cpu$cpu/cpuidle/state$1/disable
+   done
+}
+
+# Extract latency in microseconds and convert to nanoseconds
+extract_latency()
+{
+   for ((state=0; state /dev/null &
+   yes_pid=$!
+fi
+taskset 0x1 echo $dest_cpu > 
/sys/kernel/debug/latency_test/ipi_cpu_dest
+ipi_latency=$(cat /sys/kernel/debug/latency_test/ipi_latency_ns)
+src_cpu=$(cat /sys/kernel/debug/latency_test/ipi_cpu_src)
+if [ "$1" = "baseline" ]; then
+   kill $yes_pid
+   wait $yes_pid 2>/dev/null
+fi
+}
+
+# Incrementally Enable idle states one by one and compute the latency
+run_ipi_tests()
+{
+extract_latency
+disable_idle
+declare -a avg_arr
+declare -a baseline_avg_array
+
+echo -e "--IPI Latency Test---" >> $LOG
+for ((state=0; state> $LOG
+   enable_state $state
+   printf "%s %10s %12s %12s\n" "SRC_CPU" "DEST_CPU" 
"Base_IPI_Latency(ns)" "IPI_Latency(ns)" >> $LOG
+   unset avg_arr
+   unset baseline_avg_arr
+   for ((cpu=0; cpu> $LOG
+   avg_arr+=($ipi_latency)
+   baseline_avg_arr+=($baseline_ipi_latency)
+   done
+   compute_average "${avg_arr[@]}"
+   local