mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-12 13:55:32 +00:00
cpupower: Introduce idle-set subcommand and C-state enabling/disabling
Example: cpupower idle-set -d 3 will disable C-state 3 on all processors (set commands are active on all CPUs by default), same as: cpupower -c all idle-set -d 3 Signed-off-by: Thomas Renninger <trenn@suse.de> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
This commit is contained in:
parent
0924c369bc
commit
c4f3610eba
6 changed files with 142 additions and 9 deletions
|
@ -131,7 +131,8 @@ UTIL_OBJS = utils/helpers/amd.o utils/helpers/topology.o utils/helpers/msr.o \
|
|||
utils/idle_monitor/amd_fam14h_idle.o utils/idle_monitor/cpuidle_sysfs.o \
|
||||
utils/idle_monitor/mperf_monitor.o utils/idle_monitor/cpupower-monitor.o \
|
||||
utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \
|
||||
utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o
|
||||
utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o \
|
||||
utils/cpuidle-set.o
|
||||
|
||||
UTIL_SRC := $(UTIL_OBJS:.o=.c)
|
||||
|
||||
|
|
|
@ -110,13 +110,21 @@ May work poorly on Linux-2.6.20 through 2.6.29, as the \fBacpi-cpufreq \fP
|
|||
kernel frequency driver periodically cleared aperf/mperf registers in those
|
||||
kernels.
|
||||
|
||||
.SS "Nehalem" "SandyBridge"
|
||||
.SS "Nehalem" "SandyBridge" "HaswellExtended"
|
||||
Intel Core and Package sleep state counters.
|
||||
Threads (hyperthreaded cores) may not be able to enter deeper core states if
|
||||
its sibling is utilized.
|
||||
Deepest package sleep states may in reality show up as machine/platform wide
|
||||
sleep states and can only be entered if all cores are idle. Look up Intel
|
||||
manuals (some are provided in the References section) for further details.
|
||||
The monitors are named after the CPU family where the sleep state capabilities
|
||||
got introduced and may not match exactly the CPU name of the platform.
|
||||
For example an IvyBridge processor has sleep state capabilities which got
|
||||
introduced in Nehalem and SandyBridge processor families.
|
||||
Thus on an IvyBridge processor one will get Nehalem and SandyBridge sleep
|
||||
state monitors.
|
||||
HaswellExtended extra package sleep state capabilities are available only in a
|
||||
specific Haswell (family 0x45) and probably also other future processors.
|
||||
|
||||
.SS "Fam_12h" "Fam_14h"
|
||||
AMD laptop and desktop processor (family 12h and 14h) sleep state counters.
|
||||
|
|
|
@ -5,6 +5,7 @@ extern int cmd_set(int argc, const char **argv);
|
|||
extern int cmd_info(int argc, const char **argv);
|
||||
extern int cmd_freq_set(int argc, const char **argv);
|
||||
extern int cmd_freq_info(int argc, const char **argv);
|
||||
extern int cmd_idle_set(int argc, const char **argv);
|
||||
extern int cmd_idle_info(int argc, const char **argv);
|
||||
extern int cmd_monitor(int argc, const char **argv);
|
||||
|
||||
|
|
|
@ -48,10 +48,14 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose)
|
|||
return;
|
||||
|
||||
for (idlestate = 0; idlestate < idlestates; idlestate++) {
|
||||
int disabled = sysfs_is_idlestate_disabled(cpu, idlestate);
|
||||
/* Disabled interface not supported on older kernels */
|
||||
if (disabled < 0)
|
||||
disabled = 0;
|
||||
tmp = sysfs_get_idlestate_name(cpu, idlestate);
|
||||
if (!tmp)
|
||||
continue;
|
||||
printf("%s:\n", tmp);
|
||||
printf("%s%s:\n", tmp, (disabled) ? " (DISABLED) " : "");
|
||||
free(tmp);
|
||||
|
||||
tmp = sysfs_get_idlestate_desc(cpu, idlestate);
|
||||
|
|
118
tools/power/cpupower/utils/cpuidle-set.c
Normal file
118
tools/power/cpupower/utils/cpuidle-set.c
Normal file
|
@ -0,0 +1,118 @@
|
|||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <getopt.h>
|
||||
|
||||
#include "cpufreq.h"
|
||||
#include "helpers/helpers.h"
|
||||
#include "helpers/sysfs.h"
|
||||
|
||||
static struct option info_opts[] = {
|
||||
{ .name = "disable", .has_arg = required_argument, .flag = NULL, .val = 'd'},
|
||||
{ .name = "enable", .has_arg = required_argument, .flag = NULL, .val = 'e'},
|
||||
{ },
|
||||
};
|
||||
|
||||
|
||||
int cmd_idle_set(int argc, char **argv)
|
||||
{
|
||||
extern char *optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
int ret = 0, cont = 1, param = 0, idlestate = 0;
|
||||
unsigned int cpu = 0;
|
||||
|
||||
do {
|
||||
ret = getopt_long(argc, argv, "d:e:", info_opts, NULL);
|
||||
if (ret == -1)
|
||||
break;
|
||||
switch (ret) {
|
||||
case '?':
|
||||
param = '?';
|
||||
cont = 0;
|
||||
break;
|
||||
case 'd':
|
||||
if (param) {
|
||||
param = -1;
|
||||
cont = 0;
|
||||
break;
|
||||
}
|
||||
param = ret;
|
||||
idlestate = atoi(optarg);
|
||||
break;
|
||||
case 'e':
|
||||
if (param) {
|
||||
param = -1;
|
||||
cont = 0;
|
||||
break;
|
||||
}
|
||||
param = ret;
|
||||
idlestate = atoi(optarg);
|
||||
break;
|
||||
case -1:
|
||||
cont = 0;
|
||||
break;
|
||||
}
|
||||
} while (cont);
|
||||
|
||||
switch (param) {
|
||||
case -1:
|
||||
printf(_("You can't specify more than one "
|
||||
"output-specific argument\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
case '?':
|
||||
printf(_("invalid or unknown argument\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Default is: set all CPUs */
|
||||
if (bitmask_isallclear(cpus_chosen))
|
||||
bitmask_setall(cpus_chosen);
|
||||
|
||||
for (cpu = bitmask_first(cpus_chosen);
|
||||
cpu <= bitmask_last(cpus_chosen); cpu++) {
|
||||
|
||||
if (!bitmask_isbitset(cpus_chosen, cpu))
|
||||
continue;
|
||||
|
||||
switch (param) {
|
||||
|
||||
case 'd':
|
||||
ret = sysfs_idlestate_disable(cpu, idlestate, 1);
|
||||
if (ret == 0)
|
||||
printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
|
||||
else if (ret == -1)
|
||||
printf(_("Idlestate %u not available on CPU %u\n"),
|
||||
idlestate, cpu);
|
||||
else if (ret == -2)
|
||||
printf(_("Idlestate disabling not supported by kernel\n"));
|
||||
else
|
||||
printf(_("Idlestate %u not disabled on CPU %u\n"),
|
||||
idlestate, cpu);
|
||||
break;
|
||||
case 'e':
|
||||
ret = sysfs_idlestate_disable(cpu, idlestate, 0);
|
||||
if (ret == 0)
|
||||
printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
|
||||
else if (ret == -1)
|
||||
printf(_("Idlestate %u not available on CPU %u\n"),
|
||||
idlestate, cpu);
|
||||
else if (ret == -2)
|
||||
printf(_("Idlestate enabling not supported by kernel\n"));
|
||||
else
|
||||
printf(_("Idlestate %u not enabled on CPU %u\n"),
|
||||
idlestate, cpu);
|
||||
break;
|
||||
default:
|
||||
/* Not reachable with proper args checking */
|
||||
printf(_("Invalid or unknown argument\n"));
|
||||
exit(EXIT_FAILURE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
|
@ -17,12 +17,6 @@
|
|||
#include "helpers/helpers.h"
|
||||
#include "helpers/bitmask.h"
|
||||
|
||||
struct cmd_struct {
|
||||
const char *cmd;
|
||||
int (*main)(int, const char **);
|
||||
int needs_root;
|
||||
};
|
||||
|
||||
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||
|
||||
static int cmd_help(int argc, const char **argv);
|
||||
|
@ -43,10 +37,17 @@ int be_verbose;
|
|||
|
||||
static void print_help(void);
|
||||
|
||||
struct cmd_struct {
|
||||
const char *cmd;
|
||||
int (*main)(int, const char **);
|
||||
int needs_root;
|
||||
};
|
||||
|
||||
static struct cmd_struct commands[] = {
|
||||
{ "frequency-info", cmd_freq_info, 0 },
|
||||
{ "frequency-set", cmd_freq_set, 1 },
|
||||
{ "idle-info", cmd_idle_info, 0 },
|
||||
{ "idle-set", cmd_idle_set, 1 },
|
||||
{ "set", cmd_set, 1 },
|
||||
{ "info", cmd_info, 0 },
|
||||
{ "monitor", cmd_monitor, 0 },
|
||||
|
|
Loading…
Reference in a new issue