[dpdk-stable] [PATCH 1/2] power: switching to unbuffered stdio for /sys file access

Radoslaw Biernacki radoslaw.biernacki at linaro.org
Mon Oct 16 15:47:07 CEST 2017


This patch fixes the bug caused by improper use of buffered
stdio file access for switching the CPU frequency and
governor. Each write operation when using buffered stdio
must be flushed out and the return code from fflush() must
be verified. In buffered mode, write() syscall return value
is is not returned by fwrite()/fputs()/fprintf().
Since with buffered approatch, fflush() need to be done
every time it is better to use unbuffered mode or not use
stdio at all (instead use plain open/write functions). To
minimize amount of changes this fix use first approach.

Signed-off-by: Radoslaw Biernacki <radoslaw.biernacki at linaro.org>
---
 lib/librte_power/rte_power_acpi_cpufreq.c | 18 +++++++++++++++++-
 1 file changed, 17 insertions(+), 1 deletion(-)

diff --git a/lib/librte_power/rte_power_acpi_cpufreq.c b/lib/librte_power/rte_power_acpi_cpufreq.c
index 01ac5ac..8bf5685 100644
--- a/lib/librte_power/rte_power_acpi_cpufreq.c
+++ b/lib/librte_power/rte_power_acpi_cpufreq.c
@@ -143,12 +143,13 @@ set_freq_internal(struct rte_power_info *pi, uint32_t idx)
 				"for setting frequency for lcore %u\n", pi->lcore_id);
 		return -1;
 	}
+	/* we use unbuffered mode so following will fail if kernel will refuse
+	 * freq setting */
 	if (fprintf(pi->f, "%u", pi->freqs[idx]) < 0) {
 		RTE_LOG(ERR, POWER, "Fail to write new frequency for "
 				"lcore %u\n", pi->lcore_id);
 		return -1;
 	}
-	fflush(pi->f);
 	pi->curr_idx = idx;
 
 	return 1;
@@ -174,6 +175,11 @@ power_set_governor_userspace(struct rte_power_info *pi)
 	f = fopen(fullpath, "rw+");
 	FOPEN_OR_ERR_RET(f, ret);
 
+	if (setvbuf(f, NULL, _IONBF, 0)) {
+		RTE_LOG(ERR, POWER, "Cannot set unbuffered mode\n");
+		goto out;
+	}
+
 	s = fgets(buf, sizeof(buf), f);
 	FOPS_OR_NULL_GOTO(s, out);
 
@@ -292,6 +298,11 @@ power_init_for_setting_freq(struct rte_power_info *pi)
 	f = fopen(fullpath, "rw+");
 	FOPEN_OR_ERR_RET(f, -1);
 
+	if (setvbuf(f, NULL, _IONBF, 0)) {
+		RTE_LOG(ERR, POWER, "Cannot set unbuffered mode\n");
+		goto out;
+	}
+
 	s = fgets(buf, sizeof(buf), f);
 	FOPS_OR_NULL_GOTO(s, out);
 
@@ -389,6 +400,11 @@ power_set_governor_original(struct rte_power_info *pi)
 	f = fopen(fullpath, "rw+");
 	FOPEN_OR_ERR_RET(f, ret);
 
+	if (setvbuf(f, NULL, _IONBF, 0)) {
+		RTE_LOG(ERR, POWER, "Cannot set unbuffered mode\n");
+		goto out;
+	}
+
 	s = fgets(buf, sizeof(buf), f);
 	FOPS_OR_NULL_GOTO(s, out);
 
-- 
2.7.4



More information about the stable mailing list