Commit f1c35c73 authored by Len Brown's avatar Len Brown
Browse files

tools/power x86_energy_perf_policy: Version 2026.04.25



Since v2025.11.22:
	Initial SoC Slider support
	SoC Slider is an SoC-wide power/performance policy setting.
	On SoC Slider systems, EPP plays a diminished role.

Whitespace cleanup via: indent -npro -kr -i8 -ts8 -sob -l160 -ss -ncs -cp1

No functional changes

Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent 18c5b9ea
Loading
Loading
Loading
Loading
+66 −95
Original line number Diff line number Diff line
@@ -4,7 +4,7 @@
 * policy preference bias on recent X86 processors.
 */
/*
 * Copyright (c) 2010 - 2025 Intel Corporation.
 * Copyright (c) 2010 - 2026 Intel Corporation.
 * Len Brown <len.brown@intel.com>
 */

@@ -122,8 +122,7 @@ void usage(void)
	fprintf(stderr, "field: --all | --epb | --hwp-epp | --hwp-min | --hwp-max | --hwp-desired\n");
	fprintf(stderr, "other: --hwp-enable | --turbo-enable (0 | 1) | --help | --force\n");
	fprintf(stderr, "soc-slider: --soc-slider-balance # | --soc-slider-offset # | --platform-profile <name>\n");
	fprintf(stderr,
		"value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n");
	fprintf(stderr, "value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n");
	fprintf(stderr, "--hwp-window usec\n");

	fprintf(stderr, "Specify only Energy Performance BIAS (legacy usage):\n");
@@ -151,6 +150,7 @@ int ratio_2_msr_perf(int ratio)

	return msr_perf;
}

int msr_perf_2_ratio(int msr_perf)
{
	int ratio;
@@ -168,6 +168,7 @@ int msr_perf_2_ratio(int msr_perf)

	return ratio;
}

int parse_cmdline_epb(int i)
{
	if (!has_epb)
@@ -214,6 +215,7 @@ int parse_cmdline_hwp_min(int i)
	}
	return i;
}

/*
 * "power" changes hwp_max to cap.lowest
 * All others leave it at cap.highest
@@ -233,6 +235,7 @@ int parse_cmdline_hwp_max(int i)
	}
	return i;
}

/*
 * for --hwp-des, all strings leave it in autonomous mode
 * If you want to change it, you need to explicitly pick a value
@@ -284,6 +287,7 @@ int parse_cmdline_hwp_window(int i)

	return (exponent << 7) | i;
}

int parse_cmdline_hwp_epp(int i)
{
	update_hwp_epp = 1;
@@ -305,6 +309,7 @@ int parse_cmdline_hwp_epp(int i)
	}
	return i;
}

int parse_cmdline_turbo(int i)
{
	update_turbo = 1;
@@ -553,7 +558,7 @@ static int parse_cmdline_int(const char *s, int *out)

void print_version(void)
{
	printf("x86_energy_perf_policy 2025.11.22 Len Brown <lenb@kernel.org>\n");
	printf("x86_energy_perf_policy 2026.04.25 Len Brown <lenb@kernel.org>\n");
}

static int platform_profile_access(int mode)
@@ -791,8 +796,7 @@ void err_on_hypervisor(void)
	free(buffer);

	if (hypervisor)
		err(-1,
		    "not supported on this virtual machine");
		err(-1, "not supported on this virtual machine");
}

int get_msr(int cpu, int offset, unsigned long long *msr)
@@ -804,9 +808,7 @@ int get_msr(int cpu, int offset, unsigned long long *msr)
	sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu);
	fd = open(pathname, O_RDONLY);
	if (fd < 0)
		err(-1, "%s open failed, try chown or chmod +r %s, or run as root",
		   pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");

		err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");

	retval = pread(fd, msr, sizeof(*msr), offset);
	if (retval != sizeof(*msr)) {
@@ -830,8 +832,7 @@ int put_msr(int cpu, int offset, unsigned long long new_msr)
	sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu);
	fd = open(pathname, O_RDWR);
	if (fd < 0)
		err(-1, "%s open failed, try chown or chmod +r %s, or run as root",
		   pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");
		err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr");

	retval = pwrite(fd, &new_msr, sizeof(new_msr), offset);
	if (retval != sizeof(new_msr))
@@ -918,9 +919,9 @@ void print_hwp_cap(int cpu, struct msr_hwp_cap *cap, char *str)
	if (cpu != -1)
		printf("cpu%d: ", cpu);

	printf("HWP_CAP: low %d eff %d guar %d high %d\n",
		cap->lowest, cap->efficient, cap->guaranteed, cap->highest);
	printf("HWP_CAP: low %d eff %d guar %d high %d\n", cap->lowest, cap->efficient, cap->guaranteed, cap->highest);
}

void read_hwp_cap(int cpu, struct msr_hwp_cap *cap, unsigned int msr_offset)
{
	unsigned long long msr;
@@ -942,9 +943,9 @@ void print_hwp_request(int cpu, struct msr_hwp_request *h, char *str)
		printf("%s", str);

	printf("HWP_REQ: min %d max %d des %d epp %d window 0x%x (%d*10^%dus) use_pkg %d\n",
		h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp,
		h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7, h->hwp_use_pkg);
	       h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7, h->hwp_use_pkg);
}

void print_hwp_request_pkg(int pkg, struct msr_hwp_request *h, char *str)
{
	printf("pkg%d: ", pkg);
@@ -953,9 +954,9 @@ void print_hwp_request_pkg(int pkg, struct msr_hwp_request *h, char *str)
		printf("%s", str);

	printf("HWP_REQ_PKG: min %d max %d des %d epp %d window 0x%x (%d*10^%dus)\n",
		h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp,
		h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7);
	       h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7);
}

void read_hwp_request_msr(int cpu, struct msr_hwp_request *hwp_req, unsigned int msr_offset)
{
	unsigned long long msr;
@@ -976,9 +977,7 @@ void write_hwp_request_msr(int cpu, struct msr_hwp_request *hwp_req, unsigned in

	if (debug > 1)
		printf("cpu%d: requesting min %d max %d des %d epp %d window 0x%0x use_pkg %d\n",
			cpu, hwp_req->hwp_min, hwp_req->hwp_max,
			hwp_req->hwp_desired, hwp_req->hwp_epp,
			hwp_req->hwp_window, hwp_req->hwp_use_pkg);
		       cpu, hwp_req->hwp_min, hwp_req->hwp_max, hwp_req->hwp_desired, hwp_req->hwp_epp, hwp_req->hwp_window, hwp_req->hwp_use_pkg);

	msr |= HWP_MIN_PERF(ratio_2_msr_perf(hwp_req->hwp_min));
	msr |= HWP_MAX_PERF(ratio_2_msr_perf(hwp_req->hwp_max));
@@ -1125,16 +1124,12 @@ int print_pkg_msrs(int pkg)
		get_msr(first_cpu_in_pkg[pkg], MSR_HWP_INTERRUPT, &msr);
		fprintf(stderr,
			"pkg%d: MSR_HWP_INTERRUPT: 0x%08llx (Excursion_Min-%sabled, Guaranteed_Perf_Change-%sabled)\n",
		pkg, msr,
		((msr) & 0x2) ? "EN" : "Dis",
		((msr) & 0x1) ? "EN" : "Dis");
			pkg, msr, ((msr) & 0x2) ? "EN" : "Dis", ((msr) & 0x1) ? "EN" : "Dis");
	}
	get_msr(first_cpu_in_pkg[pkg], MSR_HWP_STATUS, &msr);
	fprintf(stderr,
		"pkg%d: MSR_HWP_STATUS: 0x%08llx (%sExcursion_Min, %sGuaranteed_Perf_Change)\n",
		pkg, msr,
		((msr) & 0x4) ? "" : "No-",
		((msr) & 0x1) ? "" : "No-");
		pkg, msr, ((msr) & 0x4) ? "" : "No-", ((msr) & 0x1) ? "" : "No-");

	return 0;
}
@@ -1148,6 +1143,7 @@ int ratio_2_sysfs_khz(int ratio)

	return ratio * bclk_khz;
}

/*
 * If HWP is enabled and cpufreq sysfs attribtes are present,
 * then update via sysfs. The intel_pstate driver may modify (clip)
@@ -1164,8 +1160,7 @@ void update_cpufreq_scaling_freq(int is_max, int cpu, unsigned int ratio)
	int retval;
	int khz;

	sprintf(pathname, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_%s_freq",
		cpu, is_max ? "max" : "min");
	sprintf(pathname, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_%s_freq", cpu, is_max ? "max" : "min");

	fp = fopen(pathname, "w");
	if (!fp) {
@@ -1217,19 +1212,16 @@ int verify_hwp_req_self_consistency(int cpu, struct msr_hwp_request *req)
{
	/* fail if min > max requested */
	if (req->hwp_min > req->hwp_max) {
		errx(1, "cpu%d: requested hwp-min %d > hwp_max %d",
			cpu, req->hwp_min, req->hwp_max);
		errx(1, "cpu%d: requested hwp-min %d > hwp_max %d", cpu, req->hwp_min, req->hwp_max);
	}

	/* fail if desired > max requestd */
	if (req->hwp_desired && (req->hwp_desired > req->hwp_max)) {
		errx(1, "cpu%d: requested hwp-desired %d > hwp_max %d",
			cpu, req->hwp_desired, req->hwp_max);
		errx(1, "cpu%d: requested hwp-desired %d > hwp_max %d", cpu, req->hwp_desired, req->hwp_max);
	}
	/* fail if desired < min requestd */
	if (req->hwp_desired && (req->hwp_desired < req->hwp_min)) {
		errx(1, "cpu%d: requested hwp-desired %d < requested hwp_min %d",
			cpu, req->hwp_desired, req->hwp_min);
		errx(1, "cpu%d: requested hwp-desired %d < requested hwp_min %d", cpu, req->hwp_desired, req->hwp_min);
	}

	return 0;
@@ -1239,39 +1231,30 @@ int check_hwp_request_v_hwp_capabilities(int cpu, struct msr_hwp_request *req, s
{
	if (update_hwp_max) {
		if (req->hwp_max > cap->highest)
			errx(1, "cpu%d: requested max %d > capabilities highest %d, use --force?",
				cpu, req->hwp_max, cap->highest);
			errx(1, "cpu%d: requested max %d > capabilities highest %d, use --force?", cpu, req->hwp_max, cap->highest);
		if (req->hwp_max < cap->lowest)
			errx(1, "cpu%d: requested max %d < capabilities lowest %d, use --force?",
				cpu, req->hwp_max, cap->lowest);
			errx(1, "cpu%d: requested max %d < capabilities lowest %d, use --force?", cpu, req->hwp_max, cap->lowest);
	}

	if (update_hwp_min) {
		if (req->hwp_min > cap->highest)
			errx(1, "cpu%d: requested min %d > capabilities highest %d, use --force?",
				cpu, req->hwp_min, cap->highest);
			errx(1, "cpu%d: requested min %d > capabilities highest %d, use --force?", cpu, req->hwp_min, cap->highest);
		if (req->hwp_min < cap->lowest)
			errx(1, "cpu%d: requested min %d < capabilities lowest %d, use --force?",
				cpu, req->hwp_min, cap->lowest);
			errx(1, "cpu%d: requested min %d < capabilities lowest %d, use --force?", cpu, req->hwp_min, cap->lowest);
	}

	if (update_hwp_min && update_hwp_max && (req->hwp_min > req->hwp_max))
		errx(1, "cpu%d: requested min %d > requested max %d",
			cpu, req->hwp_min, req->hwp_max);
		errx(1, "cpu%d: requested min %d > requested max %d", cpu, req->hwp_min, req->hwp_max);

	if (update_hwp_desired && req->hwp_desired) {
		if (req->hwp_desired > req->hwp_max)
			errx(1, "cpu%d: requested desired %d > requested max %d, use --force?",
				cpu, req->hwp_desired, req->hwp_max);
			errx(1, "cpu%d: requested desired %d > requested max %d, use --force?", cpu, req->hwp_desired, req->hwp_max);
		if (req->hwp_desired < req->hwp_min)
			errx(1, "cpu%d: requested desired %d < requested min %d, use --force?",
				cpu, req->hwp_desired, req->hwp_min);
			errx(1, "cpu%d: requested desired %d < requested min %d, use --force?", cpu, req->hwp_desired, req->hwp_min);
		if (req->hwp_desired < cap->lowest)
			errx(1, "cpu%d: requested desired %d < capabilities lowest %d, use --force?",
				cpu, req->hwp_desired, cap->lowest);
			errx(1, "cpu%d: requested desired %d < capabilities lowest %d, use --force?", cpu, req->hwp_desired, cap->lowest);
		if (req->hwp_desired > cap->highest)
			errx(1, "cpu%d: requested desired %d > capabilities highest %d, use --force?",
				cpu, req->hwp_desired, cap->highest);
			errx(1, "cpu%d: requested desired %d > capabilities highest %d, use --force?", cpu, req->hwp_desired, cap->highest);
	}

	return 0;
@@ -1322,6 +1305,7 @@ int update_hwp_request_msr(int cpu)
	}
	return 0;
}

int update_hwp_request_pkg_msr(int pkg)
{
	struct msr_hwp_request req;
@@ -1393,8 +1377,7 @@ int update_cpu_epb_sysfs(int cpu)
	set_epb_sysfs(cpu, new_epb);

	if (verbose)
		printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n",
			cpu, epb, (unsigned int) new_epb);
		printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n", cpu, epb, (unsigned int)new_epb);

	return 0;
}
@@ -1479,6 +1462,7 @@ int set_max_cpu_pkg_num(int cpu)

	return 0;
}

int mark_cpu_present(int cpu)
{
	CPU_SET_S(cpu, cpu_setsize, cpu_present_set);
@@ -1524,6 +1508,7 @@ void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func)(int))
		if (CPU_ISSET_S(cpu_num, set_size, cpu_set))
			func(cpu_num);
}

int for_all_cpus_in_set_and(size_t set_size, cpu_set_t *cpu_set, int (func) (int))
{
	int cpu_num;
@@ -1590,21 +1575,18 @@ int req_update_bounds_check(void)
		return 0;

	/* fail if min > max requested */
	if ((update_hwp_max && update_hwp_min) &&
	    (req_update.hwp_min > req_update.hwp_max)) {
	if ((update_hwp_max && update_hwp_min) && (req_update.hwp_min > req_update.hwp_max)) {
		printf("hwp-min %d > hwp_max %d\n", req_update.hwp_min, req_update.hwp_max);
		return -EINVAL;
	}

	/* fail if desired > max requestd */
	if (req_update.hwp_desired && update_hwp_max &&
	    (req_update.hwp_desired > req_update.hwp_max)) {
	if (req_update.hwp_desired && update_hwp_max && (req_update.hwp_desired > req_update.hwp_max)) {
		printf("hwp-desired cannot be greater than hwp_max\n");
		return -EINVAL;
	}
	/* fail if desired < min requestd */
	if (req_update.hwp_desired && update_hwp_min &&
	    (req_update.hwp_desired < req_update.hwp_min)) {
	if (req_update.hwp_desired && update_hwp_min && (req_update.hwp_desired < req_update.hwp_min)) {
		printf("hwp-desired cannot be less than hwp_min\n");
		return -EINVAL;
	}
@@ -1647,9 +1629,7 @@ void probe_dev_msr(void)
	}
}

static void get_cpuid_or_exit(unsigned int leaf,
			     unsigned int *eax, unsigned int *ebx,
			     unsigned int *ecx, unsigned int *edx)
static void get_cpuid_or_exit(unsigned int leaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx)
{
	if (!__get_cpuid(leaf, eax, ebx, ecx, edx))
		errx(1, "Processor not supported\n");
@@ -1703,8 +1683,7 @@ void parse_cpuid(void)
		genuine_intel = 1;

	if (debug)
		fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
			(char *)&ebx, (char *)&edx, (char *)&ecx);
		fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", (char *)&ebx, (char *)&edx, (char *)&ecx);

	get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx);
	family = (fms >> 8) & 0xf;
@@ -1714,23 +1693,18 @@ void parse_cpuid(void)
		model += ((fms >> 16) & 0xf) << 4;

	if (debug) {
		fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
			max_level, family, model, stepping, family, model, stepping);
		fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", max_level, family, model, stepping, family, model, stepping);
		fprintf(stderr, "CPUID(1): %s %s %s %s %s %s %s %s\n",
			ecx & (1 << 0) ? "SSE3" : "-",
			ecx & (1 << 3) ? "MONITOR" : "-",
			ecx & (1 << 7) ? "EIST" : "-",
			ecx & (1 << 8) ? "TM2" : "-",
			edx & (1 << 4) ? "TSC" : "-",
			edx & (1 << 5) ? "MSR" : "-",
			edx & (1 << 22) ? "ACPI-TM" : "-",
			edx & (1 << 29) ? "TM" : "-");
			edx & (1 << 4) ? "TSC" : "-", edx & (1 << 5) ? "MSR" : "-", edx & (1 << 22) ? "ACPI-TM" : "-", edx & (1 << 29) ? "TM" : "-");
	}

	if (!(edx & (1 << 5)))
		errx(1, "CPUID: no MSR");


	get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx);
	/* turbo_is_enabled already set */
	/* has_hwp already set */
@@ -1750,10 +1724,7 @@ void parse_cpuid(void)
			turbo_is_enabled ? "" : "No-",
			has_hwp ? "" : "No-",
			has_hwp_notify ? "" : "No-",
			has_hwp_activity_window ? "" : "No-",
			has_hwp_epp ? "" : "No-",
			has_hwp_request_pkg ? "" : "No-",
			has_epb ? "" : "No-");
			has_hwp_activity_window ? "" : "No-", has_hwp_epp ? "" : "No-", has_hwp_request_pkg ? "" : "No-", has_epb ? "" : "No-");

	return;			/* success */
}