/* * Get current state * * IN: cpuidx - cpu to query * Return: SLURM_SUCCESS or SLURM_FAILURE */ static int _cpu_freq_current_state(int cpuidx) { uint32_t freq; /* * Getting 'previous' values using the 'scaling' values rather * than the 'cpuinfo' values. * The 'cpuinfo' values are read only. min/max seem to be raw * hardware capability. * The 'scaling' values are set by the governor */ freq = _cpu_freq_get_scaling_freq(cpuidx, "scaling_cur_freq"); if (freq == 0) return SLURM_FAILURE; cpufreq[cpuidx].org_frequency = freq; freq = _cpu_freq_get_scaling_freq(cpuidx, "scaling_min_freq"); if (freq == 0) return SLURM_FAILURE; cpufreq[cpuidx].org_min_freq = freq; freq = _cpu_freq_get_scaling_freq(cpuidx, "scaling_max_freq"); if (freq == 0) return SLURM_FAILURE; cpufreq[cpuidx].org_max_freq = freq; return _cpu_freq_get_cur_gov(cpuidx); }
/* * set one of scalling_min_freq, scaling_max_freq, scaling_setspeed * -- assume governor already set to userspace --- * */ static int _cpu_freq_set_scaling_freq(stepd_step_rec_t *job, int cpx, uint32_t freq, char* option) { char path[SYSFS_PATH_MAX]; FILE *fp; int fd, rc; uint32_t newfreq; rc = SLURM_SUCCESS; snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", cpx, option); fd = _set_cpu_owner_lock(cpx, job->jobid); if ((fp = fopen(path, "w"))) { fprintf(fp, "%u\n", freq); fclose(fp); } else { error("%s: Can not set %s: %m", __func__, option); rc = SLURM_FAILURE; } (void) close(fd); if (debug_flags & DEBUG_FLAG_CPU_FREQ) { newfreq = _cpu_freq_get_scaling_freq(cpx, option); if (newfreq != freq) { error("Failed to set freq_scaling %s to %u (org=%u)", option, freq, newfreq); } } return rc; }
/* * Get current state * * IN: cpuidx - cpu to query * Return: SLURM_SUCCESS or SLURM_FAILURE */ static int _cpu_freq_current_state(int cpuidx) { uint32_t freq; if (cpufreq[cpuidx].org_set) { /* * The current state was already loaded for this cpu. * Likely caused by stacked task plugins. Prevent * overwriting the original values so they can be * restored correctly after job completion. */ return SLURM_SUCCESS; } /* * Getting 'previous' values using the 'scaling' values rather * than the 'cpuinfo' values. * The 'cpuinfo' values are read only. min/max seem to be raw * hardware capability. * The 'scaling' values are set by the governor. * For the current frequency, use the cpuinfo_cur_freq file * since the intel_pstate driver doesn't necessarily create * the scaling_cur_freq file. */ freq = _cpu_freq_get_scaling_freq(cpuidx, "cpuinfo_cur_freq"); if (freq == 0) return SLURM_FAILURE; cpufreq[cpuidx].org_frequency = freq; freq = _cpu_freq_get_scaling_freq(cpuidx, "scaling_min_freq"); if (freq == 0) return SLURM_FAILURE; cpufreq[cpuidx].org_min_freq = freq; freq = _cpu_freq_get_scaling_freq(cpuidx, "scaling_max_freq"); if (freq == 0) return SLURM_FAILURE; cpufreq[cpuidx].org_max_freq = freq; if (_cpu_freq_get_cur_gov(cpuidx) == SLURM_SUCCESS) { cpufreq[cpuidx].org_set = true; return SLURM_SUCCESS; } else { return SLURM_FAILURE; } }