This patch provides a couple of tests for cpuidle in addition with
a small program which behaves to sollicitate the cpuidle drivers
especially when both cores needs to reach the same C-states.
The program forks as many online processors present on the system
and set the affinity to it. Then it runs, during 120 secs, small
chunks of busy loops and idle loops. When there is something wrong
with the cpuidle driver, this program often triggers the problem which
results in a kernel panic, tasks hung warning or system hang.
Signed-off-by: Daniel Lezcano <daniel.lezcano(a)linaro.org>
---
.gitignore | 5 +-
Test.mk | 11 ++-
cpuidle/cpuidle_02.sh | 37 ++++++++++
cpuidle/cpuidle_02.txt | 1 +
cpuidle/cpuidle_03.sh | 60 +++++++++++++++
cpuidle/cpuidle_03.txt | 1 +
cpuidle/cpuidle_killer.c | 180 ++++++++++++++++++++++++++++++++++++++++++++++
include/functions.sh | 8 ++
utils/Makefile | 12 +---
9 files changed, 300 insertions(+), 15 deletions(-)
create mode 100755 cpuidle/cpuidle_02.sh
create mode 100644 cpuidle/cpuidle_02.txt
create mode 100755 cpuidle/cpuidle_03.sh
create mode 100644 cpuidle/cpuidle_03.txt
create mode 100644 cpuidle/cpuidle_killer.c
diff --git a/.gitignore b/.gitignore
index c833157..e21ff87 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,7 @@
-
+.pc
+*.log
utils/cpuburn
utils/cpucycle
utils/nanosleep
+cpuidle/cpuidle_killer
+patches
diff --git a/Test.mk b/Test.mk
index a265286..a48a18c 100644
--- a/Test.mk
+++ b/Test.mk
@@ -24,8 +24,12 @@
TST=$(wildcard *.sh)
LOG=$(TST:.sh=.log)
+CFLAGS?=-g -Wall
+CC?=gcc
+SRC=$(wildcard *.c)
+EXEC=$(SRC:%.c=%)
-check: uncheck $(LOG)
+check: uncheck $(EXEC) $(LOG)
%.log: %.sh
@echo "###"
@@ -36,8 +40,9 @@ check: uncheck $(LOG)
@./$< 2> $@
clean:
- @test ! -z "$(LOG)" && rm -f $(LOG)
+ rm -f *.o $(EXEC)
-uncheck: clean
+uncheck:
+ -@test ! -z "$(LOG)" && rm -f $(LOG)
recheck: uncheck check
diff --git a/cpuidle/cpuidle_02.sh b/cpuidle/cpuidle_02.sh
new file mode 100755
index 0000000..1b155c1
--- /dev/null
+++ b/cpuidle/cpuidle_02.sh
@@ -0,0 +1,37 @@
+#!/bin/bash
+#
+# PM-QA validation test suite for the power management on Linux
+#
+# Copyright (C) 2011, Linaro Limited.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributors:
+# Daniel Lezcano <daniel.lezcano(a)linaro.org> (IBM Corporation)
+# - initial API and implementation
+#
+
+# URL : https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#cpuidl…
+
+source ../include/functions.sh
+
+CPUIDLE_KILLER=./cpuidle_killer
+
+if [ $(id -u) != 0 ]; then
+ log_skip "run as non-root"
+ exit 0
+fi
+
+check "cpuidle program runs successfully (120 secs)" "./$CPUIDLE_KILLER"
diff --git a/cpuidle/cpuidle_02.txt b/cpuidle/cpuidle_02.txt
new file mode 100644
index 0000000..3f0b1ef
--- /dev/null
+++ b/cpuidle/cpuidle_02.txt
@@ -0,0 +1 @@
+Run a cpuidle program killer
diff --git a/cpuidle/cpuidle_03.sh b/cpuidle/cpuidle_03.sh
new file mode 100755
index 0000000..22bca10
--- /dev/null
+++ b/cpuidle/cpuidle_03.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+#
+# PM-QA validation test suite for the power management on Linux
+#
+# Copyright (C) 2011, Linaro Limited.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# Contributors:
+# Daniel Lezcano <daniel.lezcano(a)linaro.org> (IBM Corporation)
+# - initial API and implementation
+#
+
+# URL : https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/QA/Scripts#cpuidl…
+
+source ../include/functions.sh
+
+CPUIDLE_KILLER=./cpuidle_killer
+
+if [ $(id -u) != 0 ]; then
+ log_skip "run as non-root"
+ exit 0
+fi
+
+restore_cpus() {
+ for_each_cpu set_online
+}
+
+check_cpuidle_kill() {
+
+ if [ "$1" = "cpu0" ]; then
+ log_skip "skipping cpu0"
+ return 0
+ fi
+
+ set_offline $1
+ check "cpuidle program runs successfully (120 secs)" "./$CPUIDLE_KILLER"
+}
+
+if [ $(id -u) != 0 ]; then
+ log_skip "run as non-root"
+ exit 0
+fi
+
+trap "restore_cpus; sigtrap" SIGHUP SIGINT SIGTERM
+
+for_each_cpu check_cpuidle_kill
+restore_cpus
diff --git a/cpuidle/cpuidle_03.txt b/cpuidle/cpuidle_03.txt
new file mode 100644
index 0000000..1bf5c02
--- /dev/null
+++ b/cpuidle/cpuidle_03.txt
@@ -0,0 +1 @@
+Run a cpuidle program killer and unplug one by one the cpus (except cpu0)
diff --git a/cpuidle/cpuidle_killer.c b/cpuidle/cpuidle_killer.c
new file mode 100644
index 0000000..67a675e
--- /dev/null
+++ b/cpuidle/cpuidle_killer.c
@@ -0,0 +1,180 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/timex.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/param.h>
+#include <sched.h>
+#include <signal.h>
+
+#define DURATION 120 /* seconds */
+#define SEC_TO_USEC(d) ((d) * 1000 * 1000)
+
+static int sigon;
+
+void sighandler(int sig)
+{
+ sigon = 1;
+}
+
+void timeout(int sig)
+{
+ printf("Test duration exceeded\n");
+ exit(1);
+}
+
+int tick_me(int nrsleeps, int delay, int cpu)
+{
+ int i;
+ cpu_set_t mask;
+ unsigned long counter = 0;
+ struct itimerval t = { };
+
+ CPU_ZERO(&mask);
+ CPU_SET(cpu, &mask);
+
+ /* stick on the specified cpu */
+ if (sched_setaffinity(getpid(), sizeof(mask), &mask)) {
+ fprintf(stderr, "sched_setaffinity (%d): %m", cpu);
+ return -1;
+ }
+
+ signal(SIGALRM, sighandler);
+
+ for (i = 0; i < nrsleeps / 2; i++) {
+ usleep(delay);
+
+ sigon = 0;
+ t.it_value.tv_sec = 0;
+ t.it_value.tv_usec = delay;
+
+ if (setitimer(ITIMER_REAL, &t, NULL)) {
+ perror("setitimer");
+ return 1;
+ }
+
+ while (!sigon)
+ counter++;
+ }
+
+ fprintf(stderr, "counter value %lu\n", counter);
+
+ return 0;
+}
+
+int isonline(int cpu)
+{
+ FILE *f;
+ char path[MAXPATHLEN];
+ int online;
+
+ if (!cpu)
+ return 1;
+
+ sprintf(path, "/sys/devices/system/cpu/cpu%d/online", cpu);
+
+ f = fopen(path, "r");
+ if (!f) {
+ perror("fopen");
+ return -1;
+ }
+
+ fscanf(f, "%d", &online);
+
+ fclose(f);
+
+ return online;
+}
+
+int main(int argc, char *argv[])
+{
+ int ret, i, nrcpus = 2;
+ int nrsleeps, delay;
+ pid_t pids[nrcpus];
+ struct timex timex = { 0 };
+
+ if (adjtimex(&timex) < 0) {
+ perror("adjtimex");
+ return 1;
+ }
+
+ fprintf(stderr, "jiffies are : %ld usecs\n", timex.tick);
+
+ nrcpus = sysconf(_SC_NPROCESSORS_CONF);
+ if (nrcpus < 0) {
+ perror("sysconf");
+ return 1;
+ }
+
+ fprintf(stderr, "found %d cpu(s)\n", nrcpus);
+
+ for (i = 0; i < nrcpus; i++) {
+
+ ret = isonline(i);
+ if (!ret) {
+ fprintf(stderr, "cpu%d is offline, ignoring\n", i);
+ continue;
+ }
+
+ pids[i] = fork();
+ if (pids[i] < 0) {
+ perror("fork");
+ return 1;
+ }
+
+ if (!pids[i]) {
+
+ struct timeval before, after;
+ long duration;
+ float deviation;
+
+ nrsleeps = SEC_TO_USEC(DURATION) / (timex.tick * 10);
+ delay = SEC_TO_USEC(DURATION) / nrsleeps;
+
+ fprintf(stderr, "duration: %d secs, #sleep: %d, delay: %d us\n",
+ DURATION, nrsleeps, delay);
+
+ gettimeofday(&before, NULL);
+ if (tick_me(nrsleeps, delay, i))
+ return 1;
+ gettimeofday(&after, NULL);
+
+ duration = SEC_TO_USEC(after.tv_sec - before.tv_sec) +
+ (after.tv_usec - before.tv_usec);
+
+ fprintf(stderr, "test duration: %f secs\n",
+ (float)(duration) / (float)SEC_TO_USEC(1));
+
+ deviation = ((float)duration - (float)SEC_TO_USEC(DURATION)) /
+ (float)SEC_TO_USEC(DURATION);
+
+ fprintf(stderr, "deviation %f\n", deviation);
+ if (deviation > 0.5) {
+ fprintf(stderr, "expected test duration too long\n");
+ return 1;
+ }
+
+ return 0;
+ }
+ }
+
+ ret = 0;
+
+ signal(SIGALRM, timeout);
+
+ alarm(DURATION + 5);
+
+ for (i = 0; i < nrcpus; i++) {
+ int status;
+
+ waitpid(pids[i], &status, 0);
+ if (status != 0) {
+ fprintf(stderr, "test for cpu %d has failed\n", i);
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
diff --git a/include/functions.sh b/include/functions.sh
index 1d06249..c39b6b7 100644
--- a/include/functions.sh
+++ b/include/functions.sh
@@ -179,6 +179,10 @@ set_online() {
local cpu=$1
local dirpath=$CPU_PATH/$cpu
+ if [ "$cpu" = "cpu0" ]; then
+ return 0
+ fi
+
echo 1 > $dirpath/online
}
@@ -186,6 +190,10 @@ set_offline() {
local cpu=$1
local dirpath=$CPU_PATH/$cpu
+ if [ "$cpu" = "cpu0" ]; then
+ return 0
+ fi
+
echo 0 > $dirpath/online
}
diff --git a/utils/Makefile b/utils/Makefile
index 6d2783f..df0b8f4 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -22,14 +22,4 @@
# - initial API and implementation
#
-CFLAGS?=-g -Wall
-CC?=gcc
-SRC=$(wildcard *.c)
-EXEC=$(SRC:%.c=%)
-
-check: $(EXEC)
-
-all: $(EXEC)
-
-clean:
- rm -f *.o $(EXEC)
+include ../Test.mk
--
1.7.5.4
Adding Guodong and Tushar to make sure that the LT trees also have
thermal management turned on for 12.04.
And cc'ing linaro-dev and the release manager. :)
/Amit
On Fri, Apr 13, 2012 at 4:47 PM, Amit Kachhap <amit.kachhap(a)linaro.org> wrote:
> Hi Andrey,
>
> Please pull the thermal management work for exynos4 and imx6 platforms
> for this month release.
>
> git://git.linaro.org/people/amitdanielk/linux.git thermal_exynos4_imx6_work
>
> since commit id 258f742635360175564e9470eb060ff4d4b984e7
>
> The necessary configs to be enabled are,
> https://wiki.linaro.org/WorkingGroups/PowerManagement/Doc/Kconfig#Thermal
>
> Thanks,
> Amit Daniel
The only thing that changed in my setup, Virtualbox,
scratchbox2, arm debian rootfs & qemu-linaro is that i
pulled a newer version than march 30th and i went from some
expected errors http://pastebin.com/QTt8S9kT to
http://pastebin.com/2SRJRvdp
not really sure where to even start tracking it down other
than comparing a last known working version, git pulled on
March 30th with one that doesn't anything since April 1st.
bst rgrds
Russell