[PATCH 07/11] cpu/cpufreq: Always check that cpufreq changes have taken

Jeremy Kerr jk at ozlabs.org
Thu May 21 09:34:27 UTC 2015


This change adds checks for cpu_set_governor and cpu_set_frequency, and
aborts (or fails) tests where this is needed.

Signed-off-by: Jeremy Kerr <jk at ozlabs.org>

---
 src/cpu/cpufreq/cpufreq.c |   80 ++++++++++++++++++++++++++++----------
 1 file changed, 61 insertions(+), 19 deletions(-)

diff --git a/src/cpu/cpufreq/cpufreq.c b/src/cpu/cpufreq/cpufreq.c
index cd55eb5..979a9e1 100644
--- a/src/cpu/cpufreq/cpufreq.c
+++ b/src/cpu/cpufreq/cpufreq.c
@@ -63,7 +63,7 @@ struct cpu {
 
 static struct cpu *cpus;
 static int num_cpus;
-static bool no_cpufreq = false;
+static bool cpufreq_settable = true;
 
 #define GET_PERFORMANCE_MAX (0)
 #define GET_PERFORMANCE_MIN (1)
@@ -83,24 +83,33 @@ static inline void cpu_mkpath(
 			cpu->sysfs_path, name);
 }
 
-static void cpu_set_governor(fwts_framework *fw, struct cpu *cpu,
+static int cpu_set_governor(fwts_framework *fw, struct cpu *cpu,
 		const char *governor)
 {
-	char path[PATH_MAX];
+	char path[PATH_MAX], *tmp;
 	int rc;
 
 	cpu_mkpath(path, sizeof(path), cpu, "scaling_governor");
 	rc = fwts_set(governor, path);
-	if (rc != FWTS_OK && !no_cpufreq) {
-		fwts_warning(fw, "Cannot set CPU governor to %s.", governor);
-		no_cpufreq = true;
-	}
+	if (rc != FWTS_OK)
+		goto out;
+
+	tmp = fwts_get(path);
+	rc = tmp && !strncmp(tmp, governor, strlen(governor))
+		? FWTS_OK : FWTS_ERROR;
+	free(tmp);
+
+out:
+	if (rc != FWTS_OK)
+		fwts_warning(fw, "Cannot set CPU %d governor to %s.",
+				cpu->idx, governor);
+	return rc;
 }
 
-static void cpu_set_frequency(fwts_framework *fw, struct cpu *cpu,
+static int cpu_set_frequency(fwts_framework *fw, struct cpu *cpu,
 		uint64_t freq_hz)
 {
-	char path[PATH_MAX];
+	char path[PATH_MAX], *tmp;
 	char buffer[64];
 	int rc;
 
@@ -108,17 +117,28 @@ static void cpu_set_frequency(fwts_framework *fw, struct cpu *cpu,
 	snprintf(buffer, sizeof(buffer), "%" PRIu64 , freq_hz);
 	rc = fwts_set(buffer, path);
 	if (rc != FWTS_OK)
-		fwts_warning(fw, "Cannot set CPU frequency to %s.", buffer);
+		goto out;
+
+	tmp = fwts_get(path);
+	rc = tmp && !strncmp(tmp, buffer, strlen(buffer))
+		? FWTS_OK : FWTS_ERROR;
+	free(tmp);
+
+out:
+	if (rc != FWTS_OK)
+		fwts_warning(fw, "Cannot set CPU %d frequency to %s.",
+				cpu->idx, buffer);
+	return rc;
 }
 
-static void cpu_set_lowest_frequency(fwts_framework *fw, struct cpu *cpu)
+static int cpu_set_lowest_frequency(fwts_framework *fw, struct cpu *cpu)
 {
-	cpu_set_frequency(fw, cpu, cpu->freqs[0].Hz);
+	return cpu_set_frequency(fw, cpu, cpu->freqs[0].Hz);
 }
 
-static void cpu_set_highest_frequency(fwts_framework *fw, struct cpu *cpu)
+static int cpu_set_highest_frequency(fwts_framework *fw, struct cpu *cpu)
 {
-	cpu_set_frequency(fw, cpu, cpu->freqs[cpu->n_freqs-1].Hz);
+	return cpu_set_frequency(fw, cpu, cpu->freqs[cpu->n_freqs-1].Hz);
 }
 
 
@@ -320,10 +340,20 @@ static int cpufreq_test_cpu_performance(fwts_framework *fw)
 
 	n_online_cpus = 0;
 
-	for (i = 0; i < num_cpus; i++) {
-		cpu_set_lowest_frequency(fw, &cpus[i]);
+
+	for (i = 0; cpufreq_settable && i < num_cpus; i++) {
 		if (cpus[i].online)
 			n_online_cpus++;
+		rc = cpu_set_lowest_frequency(fw, &cpus[i]);
+		if (rc != FWTS_OK)
+			cpufreq_settable = false;
+	}
+
+	if (!cpufreq_settable) {
+		fwts_failed(fw, LOG_LEVEL_MEDIUM,
+				"CPUFreqSetFailed",
+				"Can't set CPU frequencies");
+		return FWTS_OK;
 	}
 
 	/* then do the benchmark */
@@ -356,6 +386,11 @@ static int sw_tests_possible(fwts_framework *fw)
 	return FWTS_SKIP;
 #endif
 
+	if (!cpufreq_settable) {
+		fwts_skipped(fw, "Can't set CPU frequencies");
+		return FWTS_SKIP;
+	}
+
 	/* count the number of CPUs online now */
 	for (i = 0; i < num_cpus; i++)
 		if (cpus[i].online)
@@ -736,7 +771,7 @@ static int is_cpu_dir(const struct dirent *dir)
 static int cpufreq_init(fwts_framework *fw __attribute__((unused)))
 {
 	struct dirent **dirs;
-	int i;
+	int i, rc;
 
 	num_cpus = scandir(FWTS_CPU_PATH, &dirs, is_cpu_dir, versionsort);
 	cpus = calloc(num_cpus, sizeof(*cpus));
@@ -745,8 +780,15 @@ static int cpufreq_init(fwts_framework *fw __attribute__((unused)))
 		parse_cpu_info(&cpus[i], dirs[i]);
 
 	/* all test require a userspace governor */
-	for (i = 0; i < num_cpus; i++)
-		cpu_set_governor(fw, &cpus[i], "userspace");
+	for (i = 0; i < num_cpus; i++) {
+		rc = cpu_set_governor(fw, &cpus[i], "userspace");
+		if (rc != FWTS_OK) {
+			fwts_log_warning(fw, "Failed to intialise cpufreq "
+					"to set CPU speed");
+			cpufreq_settable = false;
+			break;
+		}
+	}
 
 	return FWTS_OK;
 }



More information about the fwts-devel mailing list