/*
 * Validate the cpus and select the frequency to set
 * Called from task cgroup cpuset code with string containing
 *  the list of cpus to be used by this step
 */
void
cpu_freq_cgroup_validate(stepd_step_rec_t *job, char *step_alloc_cores)
{
	uint16_t start  = USHRT_MAX;
	uint16_t end    = USHRT_MAX;
	uint16_t cpuidx =  0;
	char *core_range;

	debug2("cpu_freq_cgroup_validate: request value = %12d  %8x",
	       job->cpu_freq, job->cpu_freq);
	debug2("  jobid=%u, stepid=%u, tasks=%u cpu/task=%u, cpus=%u",
	       job->jobid,job->stepid,job->node_tasks,
	       job->cpus_per_task,job->cpus);
	debug2("  cpu_bind_type=%4x, cpu_bind map=%s",
	       job->cpu_bind_type, job->cpu_bind);
	debug2("  step logical cores = %s, step physical cores = %s",
	       job->step_alloc_cores, step_alloc_cores);

	if (!cpu_freq_count)
		return;

	/* set entries in cpu frequency table for this step's cpus */
	core_range = step_alloc_cores;
	while ( (cpuidx = _cpu_freq_next_cpu(&core_range, &cpuidx,
					     &start, &end)) != USHRT_MAX) {
		if (cpuidx >= cpu_freq_count) {
		    error("cpu_freq_validate: index %u exceeds cpu count %u",
			  cpuidx, cpu_freq_count);
		    return;
		}
		_cpu_freq_find_valid(job->cpu_freq, cpuidx);
	}
	cpu_freq_set(job);
	return;
}
/*
 * Validate the cpus and select the frequency to set
 * Called from task cpuset code with task launch request containing
 *  a pointer to a hex map string of the cpus to be used by this step
 */
void
cpu_freq_cpuset_validate(stepd_step_rec_t *job)
{
	int cpuidx, cpu_num;
	bitstr_t *cpus_to_set;
	bitstr_t *cpu_map;
	char *cpu_bind;
	char *cpu_str;
	char *savestr = NULL;

	debug2("cpu_freq_cpuset_validate: request = %12d  %8x",
	       job->cpu_freq, job->cpu_freq);
	debug2("  jobid=%u, stepid=%u, tasks=%u cpu/task=%u, cpus=%u",
	     job->jobid, job->stepid, job->node_tasks,
	       job->cpus_per_task,job->cpus);
	debug2("  cpu_bind_type=%4x, cpu_bind map=%s",
	       job->cpu_bind_type, job->cpu_bind);

	if (!cpu_freq_count)
		return;

	if (job->cpu_bind == NULL) {
		error("cpu_freq_cpuset_validate: cpu_bind string is null");
		return;
	}
	cpu_bind = xstrdup(job->cpu_bind);

	if ( (cpu_str = strtok_r(cpu_bind, ",", &savestr) ) == NULL) {
		error("cpu_freq_cpuset_validate: cpu_bind string invalid");
		xfree(cpu_bind);
		return;
	}

	cpu_map     = (bitstr_t *) bit_alloc(cpu_freq_count);
	cpus_to_set = (bitstr_t *) bit_alloc(cpu_freq_count);

	do {
		debug3("  cpu_str = %s", cpu_str);

		if ((job->cpu_bind_type & CPU_BIND_MAP) == CPU_BIND_MAP) {
			cpu_num = atoi(cpu_str);
			if (cpu_num >= cpu_freq_count) {
				error("cpu_freq_cpuset_validate: invalid cpu "
				      "number %d", cpu_num);
				bit_free(cpu_map);
				bit_free(cpus_to_set);
				xfree(cpu_bind);
				return;
			}
			bit_set(cpu_map, (bitoff_t)cpu_num);
		} else {
			if (bit_unfmt_hexmask(cpu_map, cpu_str) == -1) {
				error("cpu_freq_cpuset_validate: invalid cpu "
				      "mask %s", cpu_bind);
				bit_free(cpu_map);
				bit_free(cpus_to_set);
				xfree(cpu_bind);
				return;
			}
		}
		bit_or(cpus_to_set, cpu_map);
	} while ( (cpu_str = strtok_r(NULL, ",", &savestr) ) != NULL);

	for (cpuidx=0; cpuidx < cpu_freq_count; cpuidx++) {
		if (bit_test(cpus_to_set, cpuidx)) {
			_cpu_freq_find_valid(job->cpu_freq, cpuidx);
		}
	}
	cpu_freq_set(job);

	bit_free(cpu_map);
	bit_free(cpus_to_set);
	xfree(cpu_bind);
	return;
}
Example #3
0
/*
 * reset the cpus used by the process to their
 * default frequency and governor type
 */
void
cpu_freq_reset(stepd_step_rec_t *job)
{
	char path[SYSFS_PATH_MAX];
	FILE *fp;
	char value[LINE_LEN];
	unsigned int i, j;
	uint32_t def_cpu_freq;

	if ((!cpu_freq_count) || (!cpufreq))
		return;

	def_cpu_freq = slurm_get_cpu_freq_def();
	j = 0;
	for (i = 0; i < cpu_freq_count; i++) {
		bool reset_freq = false;
		bool reset_gov = false;

		if (cpufreq[i].new_frequency != 0)
			reset_freq = true;
		if (cpufreq[i].new_governor[0] != '\0')
			reset_gov = true;
		if (!reset_freq && !reset_gov)
			continue;

		cpufreq[i].new_frequency = 0;
		cpufreq[i].new_governor[0] = '\0';
		_cpu_freq_find_valid(def_cpu_freq, i);
		if (cpufreq[i].new_frequency == 0)
			cpufreq[i].new_frequency = cpufreq[i].orig_frequency;
		if (cpufreq[i].new_governor[0] == '\0') {
			strcpy(cpufreq[i].new_governor,
			       cpufreq[i].orig_governor);
		}

		if (reset_freq) {
			snprintf(path, sizeof(path),
				 PATH_TO_CPU "cpu%u/cpufreq/scaling_setspeed",
				 i);
			snprintf(value, LINE_LEN, "%u",
				 cpufreq[i].new_frequency);
			if ((fp = fopen(path, "w"))) {
				fputs(value, fp);
				fclose(fp);
			}
		}

		if (reset_gov) {
			snprintf(path, sizeof(path),
				 PATH_TO_CPU "cpu%u/cpufreq/scaling_governor",
				 i);
			if ((fp = fopen(path, "w"))) {
				fputs(cpufreq[i].new_governor, fp);
				fputc('\n', fp);
				fclose(fp);
			}
		}

		j++;
		debug3("cpu_freq_reset: CPU:%u frequency:%u governor:%s",
		       i, cpufreq[i].new_frequency,
		       cpufreq[i].new_governor);
	}
	debug("cpu_freq_reset: #cpus reset = %u", j);
}