From 48ec55bd19362c5b8f7d06f7678321c3535672f4 Mon Sep 17 00:00:00 2001 From: PA4WDH Date: Sat, 20 May 2023 19:27:47 +0200 Subject: Add validation and fallback to startup --- Makefile | 2 +- cputemp2maxfreq.c | 60 +++++++++++++++++++++++++++++++++---------------------- cputemp2maxfreq.h | 17 ++++++++++++++++ failsafe.c | 33 ++++++++++++++++++++++++++++++ failsafe.h | 1 + 5 files changed, 88 insertions(+), 25 deletions(-) create mode 100644 cputemp2maxfreq.h create mode 100644 failsafe.c create mode 100644 failsafe.h 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 #include #include +#include +#include #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 +#include +#include +#include +#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(); -- cgit v1.2.3