aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPA4WDH2023-05-20 19:27:47 +0200
committerPA4WDH2023-05-20 19:27:47 +0200
commit48ec55bd19362c5b8f7d06f7678321c3535672f4 (patch)
tree7a8ec313dd0aea97a56697e844aa99cd6c25cf03
parentTranslate POC to C code (diff)
downloadcputemp2maxfreq-48ec55bd19362c5b8f7d06f7678321c3535672f4.tar.gz
cputemp2maxfreq-48ec55bd19362c5b8f7d06f7678321c3535672f4.tar.bz2
cputemp2maxfreq-48ec55bd19362c5b8f7d06f7678321c3535672f4.zip
Add validation and fallback to startup
-rw-r--r--Makefile2
-rw-r--r--cputemp2maxfreq.c60
-rw-r--r--cputemp2maxfreq.h17
-rw-r--r--failsafe.c33
-rw-r--r--failsafe.h1
5 files changed, 88 insertions, 25 deletions
diff --git a/Makefile b/Makefile
index 4c968ee..335d067 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-cputemp2maxfreq: debug.o sysfs.o cpufreq.o
+cputemp2maxfreq: debug.o sysfs.o cpufreq.o failsafe.o
%.o: %.c %.h debug.h
$(COMPILE.c) $(OUTPUT_OPTION) $<
diff --git a/cputemp2maxfreq.c b/cputemp2maxfreq.c
index 1760996..267c54e 100644
--- a/cputemp2maxfreq.c
+++ b/cputemp2maxfreq.c
@@ -1,26 +1,13 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
#include "sysfs.h"
#include "cpufreq.h"
#include "debug.h"
-
-struct s_cpudata {
- long int min_freq;
- long int max_freq;
- long int cur_freq;
- long int cur_temp;
- long int scale_max;
-};
-
-struct s_config {
- char *governor;
- long int max_temp;
- char *temp_input;
- long int freq_step;
- long int fallback_freq;
- unsigned int interval;
-};
+#include "cputemp2maxfreq.h"
+#include "failsafe.h"
struct s_cpudata cpudata;
struct s_config config={"conservative",70000,"/sys/devices/virtual/thermal/thermal_zone0/temp",100000,2000000,10};
@@ -29,19 +16,44 @@ int main()
{
long int diff;
long int newfreq;
-
- printf("Governor: %s\nTemp input: %s\n",config.governor,config.temp_input);
- if (cpufreq_set_str("scaling_governor",config.governor,0)!=0)
- {
- printf("Failed to set governow\n");
- exit(1);
- }
+// Print configuration
+ printf("Configuration:");
+ printf("Governor: %s\n",config.governor);
+ printf("Temperature: %ld\n",config.max_temp);
+ printf("Temp input: %s\n",config.temp_input);
+ printf("Frequency step: %ld\n",config.freq_step);
+ printf("Fallback frquency: %ld\n",config.fallback_freq);
+ printf("Interval: %d\n",config.interval);
+// Get and validate CPU data
cpudata.min_freq=sysfs_read_long_int("/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_min_freq");
cpudata.max_freq=sysfs_read_long_int("/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq");
cpudata.scale_max=sysfs_read_long_int("/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq");
+ printf("\nCPU data:\n");
+ printf("Minimum frequency: %ld\n",cpudata.min_freq);
+ printf("Maximum frequency: %ld\n",cpudata.max_freq);
+ printf("Scaling maximum frequency: %ld\n",cpudata.scale_max);
+
+ if ((cpudata.min_freq<100000) || (cpudata.min_freq>10000000) ||
+ (cpudata.max_freq<100000) || (cpudata.max_freq>10000000) ||
+ (cpudata.scale_max<100000) || (cpudata.scale_max>10000000))
+ {
+// If we have to fail now, there's not much we can do because we have no data
+ printf("Invalid CPU data, exiting.\n");
+ exit(1);
+ }
+
+// Set the governor
+ if (cpufreq_set_str("scaling_governor",config.governor,0)!=0)
+ {
+ printf("Failed to set governor, error %d (%s).\n",errno,strerror(errno));
+
+// We failed to set the governor, call the failsafe
+ failsafe();
+ }
+
while(1)
{
cpudata.cur_freq=sysfs_read_long_int("/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq");
diff --git a/cputemp2maxfreq.h b/cputemp2maxfreq.h
new file mode 100644
index 0000000..ef33fd5
--- /dev/null
+++ b/cputemp2maxfreq.h
@@ -0,0 +1,17 @@
+struct s_cpudata {
+ long int min_freq; // CPU's minimum frequency
+ long int max_freq; // CPU's maximum frequency
+ long int cur_freq; // CPU's current frequency
+ long int cur_temp; // CPU's current temperature
+ long int scale_max; // Governor's maximum scaling frequency
+};
+
+struct s_config {
+ char *governor; // The governor to use
+ long int max_temp; // The target temperature
+ char *temp_input; // Input file to read the temperature
+ long int freq_step; // Step size to increase/decrease CPU frequency
+ long int fallback_freq; // CPU frquency to set if we fail to protect hardware
+ unsigned int interval; // Time interval to check CPU temperature
+};
+
diff --git a/failsafe.c b/failsafe.c
new file mode 100644
index 0000000..5b3e7d3
--- /dev/null
+++ b/failsafe.c
@@ -0,0 +1,33 @@
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "cputemp2maxfreq.h"
+#include "cpufreq.h"
+
+extern struct s_cpudata cpudata;
+extern struct s_config config;
+
+void failsafe()
+{
+ printf("Failed to set governor, error %d (%s).\n",errno,strerror(errno));
+
+// We failed to set the governor, try to fail safe. First try the CPU minimum
+// frequency, if that doesn't work out try the fallback frequency
+ if (cpufreq_set_long_int("scaling_max_freq",cpudata.min_freq,100)==0)
+ {
+ printf("Set scaling frequency to CPU's minimum frequency.");
+ exit(1);
+ }
+ printf("Failed to set scaling frequency to CPU's minimum frequency, error: %d (%s).\n",errno,strerror(errno));
+
+ if (cpufreq_set_long_int("scaling_max_freq",config.fallback_freq,100)==0)
+ {
+ printf("Set scaling frequency to fallback frequency.");
+ exit(1);
+ }
+ printf("Failed to set scaling frequency to fallback frequency, error: %d (%s).\n",errno,strerror(errno));
+
+ printf("All safety measures failed, watch out not to fry your hardware.\n");
+ exit(1);
+}
diff --git a/failsafe.h b/failsafe.h
new file mode 100644
index 0000000..f6b0d0d
--- /dev/null
+++ b/failsafe.h
@@ -0,0 +1 @@
+void failsafe();