#include #include #include #include #include #include #include "sysfs.h" #include "cpufreq.h" #include "debug.h" #include "cputemp2maxfreq.h" #include "failsafe.h" #include "version.h" // Valid frequencies are between 100MHz and 10GHz #define VALID_FREQ_MIN 100000 #define VALID_FREQ_MAX 10000000 // Valid temperatures are between 10 and 150 degrees #define VALID_TEMP_MIN 10000 #define VALID_TEMP_MAX 150000 struct s_cpudata cpudata; struct s_config config={"conservative",70000,"/sys/devices/virtual/thermal/thermal_zone0/temp",100000,2000000,10}; void signal_handler(int signum) { printf("Received signal %d, exiting.\n",signum); failsafe(0); } int main() { long int diff; long int newfreq; printf("Version %s, buildtime %s %s\n",version(),__DATE__,__TIME__); // Print configuration printf("Configuration:\n"); 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_freqVALID_FREQ_MAX) || (cpudata.max_freqVALID_FREQ_MAX) || (cpudata.scale_maxVALID_FREQ_MAX)) { // 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(1); } // Set signal handlers signal(SIGTERM,signal_handler); signal(SIGINT,signal_handler); signal(SIGQUIT,signal_handler); while(1) { // Get new measurements cpudata.cur_freq=sysfs_read_long_int("/sys/devices/system/cpu/cpufreq/policy0/scaling_cur_freq"); if ((cpudata.cur_freqVALID_FREQ_MAX)) { printf("Invalid current frequency reported by CPU, exiting.\n"); failsafe(1); } cpudata.cur_temp=sysfs_read_long_int(config.temp_input); if ((cpudata.cur_tempVALID_TEMP_MAX)) { printf("Invalid current tempature reported by CPU, exiting.\n"); failsafe(1); } DEBUG1_MAIN("Data: %ld %ld %ld %ld %ld\n",cpudata.cur_temp,config.max_temp,cpudata.max_freq,cpudata.scale_max,cpudata.cur_freq); // Check if we should increase if ((cpudata.cur_tempcpudata.max_freq) newfreq=cpudata.max_freq; DEBUG1_MAIN("Increase to %ld\n",newfreq); // Set new value and validate if (cpufreq_set_long_int("scaling_max_freq",newfreq,100)<0) { printf("Failed to set scaling_max_freq, exiting.\n"); failsafe(1); } cpudata.scale_max=sysfs_read_long_int("/sys/devices/system/cpu/cpufreq/policy0/scaling_max_freq"); if ((cpudata.scale_maxVALID_FREQ_MAX)) { printf("Invalid scale_max_freq reported, exiting,\n"); failsafe(1); } } // Check if we should decrease if ((cpudata.cur_temp>config.max_temp) && (cpudata.scale_max>cpudata.min_freq)) { diff=(cpudata.cur_temp-config.max_temp)/1000; newfreq=cpudata.scale_max-(config.freq_step*diff); if (newfreqVALID_FREQ_MAX)) { printf("Invalid scale_max_freq reported, exiting,\n"); failsafe(1); } } sleep(config.interval); } }