Commit 357d1fc3 authored by Shinji Nomoto's avatar Shinji Nomoto Committed by Shuah Khan
Browse files

cpupower: Allow control of boost feature on non-x86 based systems with boost support.

The cpufreq subsystem has a generic sysfs interface for controlling boost
(/sys/devices/system/cpu/cpufreq/boost).
The sysfs interface can be used to enable boost control from the cpupower
command on non-x86 platforms as well. So, allow boost controlling
on non-x86 system if boost sysfs file exists.

The set subcommand enables/disables the boost feature using the following
syntax:
    cpupower set --boost 1
    cpupower set --boost 0

The --boost option is an alias for --turbo-boost. We provided the neutral
option name because the name "turbo boost" is specific to Intel technology.

The frequency-info subcommand displays the enabled/disabled state of
the boost feature as follows:
    boost state support:
        Active: yes (or no)

Link: https://lore.kernel.org/r/20250522061122.2149188-3-fj5851bi@fujitsu.com


Signed-off-by: default avatarShinji Nomoto <fj5851bi@fujitsu.com>
Signed-off-by: default avatarShuah Khan <skhan@linuxfoundation.org>
parent b3eaf14f
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -81,10 +81,11 @@ Refer to the AMD P-State kernel documentation for further information.
.RE

.PP
\-\-turbo\-boost, \-t
\-\-turbo\-boost, \-\-boost, \-t
.RS 4
This option is used to enable or disable the turbo boost feature on
supported Intel and AMD processors.
This option is used to enable or disable the boost feature on
supported Intel and AMD processors, and other boost supported systems.
(The --boost option is an alias for the --turbo-boost option)

This option takes as parameter either \fB1\fP to enable, or \fB0\fP to disable the feature.

+15 −1
Original line number Diff line number Diff line
@@ -128,7 +128,7 @@ static int get_boost_mode_x86(unsigned int cpu)
	/* ToDo: Make this more global */
	unsigned long pstates[MAX_HW_PSTATES] = {0,};

	ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states);
	ret = cpufreq_has_x86_boost_support(cpu, &support, &active, &b_states);
	if (ret) {
		printf(_("Error while evaluating Boost Capabilities"
				" on CPU %d -- are you root?\n"), cpu);
@@ -204,6 +204,18 @@ static int get_boost_mode_x86(unsigned int cpu)
	return 0;
}

static int get_boost_mode_generic(unsigned int cpu)
{
	bool active;

	if (!cpufreq_has_generic_boost_support(&active)) {
		printf(_("  boost state support:\n"));
		printf(_("    Active: %s\n"), active ? _("yes") : _("no"));
	}

	return 0;
}

/* --boost / -b */

static int get_boost_mode(unsigned int cpu)
@@ -214,6 +226,8 @@ static int get_boost_mode(unsigned int cpu)
	    cpupower_cpu_info.vendor == X86_VENDOR_HYGON ||
	    cpupower_cpu_info.vendor == X86_VENDOR_INTEL)
		return get_boost_mode_x86(cpu);
	else
		get_boost_mode_generic(cpu);

	freqs = cpufreq_get_boost_frequencies(cpu);
	if (freqs) {
+1 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ static struct option set_opts[] = {
	{"epp", required_argument, NULL, 'e'},
	{"amd-pstate-mode", required_argument, NULL, 'm'},
	{"turbo-boost", required_argument, NULL, 't'},
	{"boost", required_argument, NULL, 't'},
	{ },
};

+7 −7
Original line number Diff line number Diff line
@@ -103,6 +103,9 @@ extern struct cpupower_cpu_info cpupower_cpu_info;

/* cpuid and cpuinfo helpers  **************************/

int cpufreq_has_generic_boost_support(bool *active);
int cpupower_set_turbo_boost(int turbo_boost);

/* X86 ONLY ****************************************/
#if defined(__i386__) || defined(__x86_64__)

@@ -118,7 +121,6 @@ extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu);

extern int cpupower_set_epp(unsigned int cpu, char *epp);
extern int cpupower_set_amd_pstate_mode(char *mode);
extern int cpupower_set_turbo_boost(int turbo_boost);

/* Read/Write msr ****************************/

@@ -139,7 +141,7 @@ extern int decode_pstates(unsigned int cpu, int boost_states,

/* AMD HW pstate decoding **************************/

extern int cpufreq_has_boost_support(unsigned int cpu, int *support,
int cpufreq_has_x86_boost_support(unsigned int cpu, int *support,
				  int *active, int *states);

/* AMD P-State stuff **************************/
@@ -181,12 +183,10 @@ static inline int cpupower_set_epp(unsigned int cpu, char *epp)
{ return -1; };
static inline int cpupower_set_amd_pstate_mode(char *mode)
{ return -1; };
static inline int cpupower_set_turbo_boost(int turbo_boost)
{ return -1; };

/* Read/Write msr ****************************/

static inline int cpufreq_has_boost_support(unsigned int cpu, int *support,
static inline int cpufreq_has_x86_boost_support(unsigned int cpu, int *support,
						int *active, int *states)
{ return -1; }

+54 −22
Original line number Diff line number Diff line
@@ -8,14 +8,13 @@
#include "helpers/helpers.h"
#include "helpers/sysfs.h"
#include "cpufreq.h"
#include "cpupower_intern.h"

#if defined(__i386__) || defined(__x86_64__)

#include "cpupower_intern.h"

#define MSR_AMD_HWCR	0xc0010015

int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active,
int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, int *active,
				  int *states)
{
	int ret;
@@ -124,24 +123,6 @@ int cpupower_set_amd_pstate_mode(char *mode)
	return 0;
}

int cpupower_set_turbo_boost(int turbo_boost)
{
	char path[SYSFS_PATH_MAX];
	char linebuf[2] = {};

	snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost");

	if (!is_valid_path(path))
		return -1;

	snprintf(linebuf, sizeof(linebuf), "%d", turbo_boost);

	if (cpupower_write_sysfs(path, linebuf, 2) <= 0)
		return -1;

	return 0;
}

bool cpupower_amd_pstate_enabled(void)
{
	char *driver = cpufreq_get_driver(0);
@@ -160,6 +141,39 @@ bool cpupower_amd_pstate_enabled(void)

#endif /* #if defined(__i386__) || defined(__x86_64__) */

int cpufreq_has_generic_boost_support(bool *active)
{
	char path[SYSFS_PATH_MAX];
	char linebuf[2] = {};
	unsigned long val;
	char *endp;

	snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost");

	if (!is_valid_path(path))
		return -EACCES;

	if (cpupower_read_sysfs(path, linebuf, 2) <= 0)
		return -EINVAL;

	val = strtoul(linebuf, &endp, 0);
	if (endp == linebuf || errno == ERANGE)
		return -EINVAL;

	switch (val) {
	case 0:
		*active = false;
		break;
	case 1:
		*active = true;
		break;
	default:
		return -EINVAL;
	}

	return 0;
}

/* get_cpustate
 *
 * Gather the information of all online CPUs into bitmask struct
@@ -259,3 +273,21 @@ void print_speed(unsigned long speed, int no_rounding)
		}
	}
}

int cpupower_set_turbo_boost(int turbo_boost)
{
	char path[SYSFS_PATH_MAX];
	char linebuf[2] = {};

	snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost");

	if (!is_valid_path(path))
		return -1;

	snprintf(linebuf, sizeof(linebuf), "%d", turbo_boost);

	if (cpupower_write_sysfs(path, linebuf, 2) <= 0)
		return -1;

	return 0;
}