diff options
Diffstat (limited to 'tools/power/cpupower')
31 files changed, 1991 insertions, 85 deletions
diff --git a/tools/power/cpupower/.gitignore b/tools/power/cpupower/.gitignore index 7677329c42a6..5113d5a7aee0 100644 --- a/tools/power/cpupower/.gitignore +++ b/tools/power/cpupower/.gitignore @@ -27,3 +27,6 @@ debug/i386/intel_gsic debug/i386/powernow-k8-decode debug/x86_64/centrino-decode debug/x86_64/powernow-k8-decode + +# Clang's compilation database file +compile_commands.json diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index b53753dee02f..be8dfac14076 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile @@ -2,6 +2,7 @@ # Makefile for cpupower # # Copyright (C) 2005,2006 Dominik Brodowski <linux@dominikbrodowski.net> +# Copyright (C) 2025 Francesco Poli <invernomuto@paranoici.org> # # Based largely on the Makefile for udev by: # @@ -52,12 +53,15 @@ DESTDIR ?= # and _should_ modify the PACKAGE_BUGREPORT definition VERSION:= $(shell ./utils/version-gen.sh) -LIB_MAJ= 0.0.1 -LIB_MIN= 1 +LIB_FIX= 1 +LIB_MIN= 0 +LIB_MAJ= 1 +LIB_VER= $(LIB_MAJ).$(LIB_MIN).$(LIB_FIX) + PACKAGE = cpupower PACKAGE_BUGREPORT = linux-pm@vger.kernel.org -LANGUAGES = de fr it cs pt ka +LANGUAGES = de fr it cs pt ka zh_CN # Directory definitions. These are default and most probably @@ -67,6 +71,8 @@ LANGUAGES = de fr it cs pt ka bindir ?= /usr/bin sbindir ?= /usr/sbin mandir ?= /usr/man +libdir ?= /usr/lib +libexecdir ?= /usr/libexec includedir ?= /usr/include localedir ?= /usr/share/locale docdir ?= /usr/share/doc/packages/cpupower @@ -79,29 +85,29 @@ CP = cp -fpR INSTALL = /usr/bin/install -c INSTALL_PROGRAM = ${INSTALL} INSTALL_DATA = ${INSTALL} -m 644 +SETPERM_DATA = chmod 644 #bash completion scripts get sourced and so they should be rw only. INSTALL_SCRIPT = ${INSTALL} -m 644 # If you are running a cross compiler, you may want to set this # to something more interesting, like "arm-linux-". If you want # to compile vs uClibc, that can be done here as well. -CROSS = #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- +CROSS ?= #/usr/i386-linux-uclibc/usr/bin/i386-uclibc- +ifneq ($(CROSS), ) CC = $(CROSS)gcc LD = $(CROSS)gcc AR = $(CROSS)ar STRIP = $(CROSS)strip RANLIB = $(CROSS)ranlib -HOSTCC = gcc -MKDIR = mkdir - -# 64bit library detection -include ../../scripts/Makefile.arch - -ifeq ($(IS_64_BIT), 1) -libdir ?= /usr/lib64 else -libdir ?= /usr/lib +CC ?= $(CROSS)gcc +LD ?= $(CROSS)gcc +AR ?= $(CROSS)ar +STRIP ?= $(CROSS)strip +RANLIB ?= $(CROSS)ranlib endif +HOSTCC = gcc +MKDIR = mkdir # Now we set up the build system # @@ -200,14 +206,14 @@ $(OUTPUT)lib/%.o: $(LIB_SRC) $(LIB_HEADERS) $(ECHO) " CC " $@ $(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c -$(OUTPUT)libcpupower.so.$(LIB_MAJ): $(LIB_OBJS) +$(OUTPUT)libcpupower.so.$(LIB_VER): $(LIB_OBJS) $(ECHO) " LD " $@ $(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \ - -Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS) + -Wl,-soname,libcpupower.so.$(LIB_MAJ) $(LIB_OBJS) @ln -sf $(@F) $(OUTPUT)libcpupower.so - @ln -sf $(@F) $(OUTPUT)libcpupower.so.$(LIB_MIN) + @ln -sf $(@F) $(OUTPUT)libcpupower.so.$(LIB_MAJ) -libcpupower: $(OUTPUT)libcpupower.so.$(LIB_MAJ) +libcpupower: $(OUTPUT)libcpupower.so.$(LIB_VER) # Let all .o files depend on its .c file and all headers # Might be worth to put this into utils/Makefile at some point of time @@ -217,7 +223,7 @@ $(OUTPUT)%.o: %.c $(ECHO) " CC " $@ $(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c -$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ) +$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_VER) $(ECHO) " CC " $@ ifeq ($(strip $(STATIC)),true) $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lrt -lpci -L$(OUTPUT) -o $@ @@ -226,17 +232,28 @@ else endif $(QUIET) $(STRIPCMD) $@ +ifeq (, $(shell which xgettext)) +$(warning "Install xgettext to extract translatable strings.") +else $(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC) $(ECHO) " GETTEXT " $@ $(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \ --keyword=_ --keyword=N_ $(UTIL_SRC) -p $(@D) -o $(@F) +endif +ifeq (, $(shell which msgfmt)) +$(warning "Install msgfmt to generate binary message catalogs.") +else $(OUTPUT)po/%.gmo: po/%.po $(ECHO) " MSGFMT " $@ $(QUIET) msgfmt -o $@ po/$*.po +endif create-gmo: ${GMO_FILES} +ifeq (, $(shell which msgmerge)) +$(warning "Install msgmerge to merge translations.") +else update-po: $(OUTPUT)po/$(PACKAGE).pot $(ECHO) " MSGMRG " $@ $(QUIET) @for HLANG in $(LANGUAGES); do \ @@ -249,8 +266,9 @@ update-po: $(OUTPUT)po/$(PACKAGE).pot rm -f $(OUTPUT)po/$$HLANG.new.po; \ fi; \ done; +endif -compile-bench: $(OUTPUT)libcpupower.so.$(LIB_MAJ) +compile-bench: $(OUTPUT)libcpupower.so.$(LIB_VER) @V=$(V) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) # we compile into subdirectories. if the target directory is not the @@ -287,6 +305,13 @@ install-tools: $(OUTPUT)cpupower $(INSTALL_PROGRAM) $(OUTPUT)cpupower $(DESTDIR)${bindir} $(INSTALL) -d $(DESTDIR)${bash_completion_dir} $(INSTALL_SCRIPT) cpupower-completion.sh '$(DESTDIR)${bash_completion_dir}/cpupower' + $(INSTALL) -d $(DESTDIR)${confdir} + $(INSTALL_DATA) cpupower-service.conf '$(DESTDIR)${confdir}' + $(INSTALL) -d $(DESTDIR)${libexecdir} + $(INSTALL_PROGRAM) cpupower.sh '$(DESTDIR)${libexecdir}/cpupower' + $(INSTALL) -d $(DESTDIR)${libdir}/systemd/system + sed 's|___CDIR___|${confdir}|; s|___LDIR___|${libexecdir}|' cpupower.service.in > '$(DESTDIR)${libdir}/systemd/system/cpupower.service' + $(SETPERM_DATA) '$(DESTDIR)${libdir}/systemd/system/cpupower.service' install-man: $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1 @@ -321,6 +346,9 @@ uninstall: - rm -f $(DESTDIR)${includedir}/cpufreq.h - rm -f $(DESTDIR)${includedir}/cpuidle.h - rm -f $(DESTDIR)${bindir}/utils/cpupower + - rm -f $(DESTDIR)${confdir}cpupower-service.conf + - rm -f $(DESTDIR)${libexecdir}/cpupower + - rm -f $(DESTDIR)${libdir}/systemd/system/cpupower.service - rm -f $(DESTDIR)${mandir}/man1/cpupower.1 - rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1 - rm -f $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1 @@ -332,4 +360,39 @@ uninstall: rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \ done; -.PHONY: all utils libcpupower update-po create-gmo install-lib install-tools install-man install-gmo install uninstall clean +help: + @echo 'Building targets:' + @echo ' all - Default target. Could be omitted. Put build artifacts' + @echo ' to "O" cmdline option dir (default: current dir)' + @echo ' install - Install previously built project files from the output' + @echo ' dir defined by "O" cmdline option (default: current dir)' + @echo ' to the install dir defined by "DESTDIR" cmdline or' + @echo ' Makefile config block option (default: "")' + @echo ' install-lib - Install previously built library binary from the output' + @echo ' dir defined by "O" cmdline option (default: current dir)' + @echo ' and library headers from "lib/" for userspace to the install' + @echo ' dir defined by "DESTDIR" cmdline (default: "")' + @echo ' install-tools - Install previously built "cpupower" util from the output' + @echo ' dir defined by "O" cmdline option (default: current dir) and' + @echo ' "cpupower-completion.sh" script from the src dir to the' + @echo ' install dir defined by "DESTDIR" cmdline or Makefile' + @echo ' config block option (default: "")' + @echo ' install-man - Install man pages from the "man" src subdir to the' + @echo ' install dir defined by "DESTDIR" cmdline or Makefile' + @echo ' config block option (default: "")' + @echo ' install-gmo - Install previously built language files from the output' + @echo ' dir defined by "O" cmdline option (default: current dir)' + @echo ' to the install dir defined by "DESTDIR" cmdline or Makefile' + @echo ' config block option (default: "")' + @echo ' install-bench - Install previously built "cpufreq-bench" util files from the' + @echo ' output dir defined by "O" cmdline option (default: current dir)' + @echo ' to the install dir defined by "DESTDIR" cmdline or Makefile' + @echo ' config block option (default: "")' + @echo '' + @echo 'Cleaning targets:' + @echo ' clean - Clean build artifacts from the dir defined by "O" cmdline' + @echo ' option (default: current dir)' + @echo ' uninstall - Remove previously installed files from the dir defined by "DESTDIR"' + @echo ' cmdline or Makefile config block option (default: "")' + +.PHONY: all utils libcpupower update-po create-gmo install-lib install-tools install-man install-gmo install uninstall clean help diff --git a/tools/power/cpupower/README b/tools/power/cpupower/README index 1c68f47663b2..9de449469568 100644 --- a/tools/power/cpupower/README +++ b/tools/power/cpupower/README @@ -22,16 +22,184 @@ interfaces [depending on configuration, see below]. compilation and installation ---------------------------- -make -su -make install - -should suffice on most systems. It builds libcpupower to put in -/usr/lib; cpupower, cpufreq-bench_plot.sh to put in /usr/bin; and -cpufreq-bench to put in /usr/sbin. If you want to set up the paths -differently and/or want to configure the package to your specific -needs, you need to open "Makefile" with an editor of your choice and -edit the block marked CONFIGURATION. +There are 2 output directories - one for the build output and another for +the installation of the build results, that is the utility, library, +man pages, etc... + +default directory +----------------- + +In the case of default directory, build and install process requires no +additional parameters: + +build +----- + +$ make + +The output directory for the 'make' command is the current directory and +its subdirs in the kernel tree: +tools/power/cpupower + +install +------- + +$ sudo make install + +'make install' command puts targets to default system dirs: + +----------------------------------------------------------------------- +| Installing file | System dir | +----------------------------------------------------------------------- +| libcpupower | /usr/lib | +----------------------------------------------------------------------- +| cpupower | /usr/bin | +----------------------------------------------------------------------- +| cpufreq-bench_plot.sh | /usr/bin | +----------------------------------------------------------------------- +| man pages | /usr/man | +----------------------------------------------------------------------- +| systemd service | /usr/lib/systemd/system | +----------------------------------------------------------------------- +| systemd support script | /usr/libexec | +----------------------------------------------------------------------- + +To put it in other words it makes build results available system-wide, +enabling any user to simply start using it without any additional steps + +custom directory +---------------- + +There are 2 make's command-line variables 'O' and 'DESTDIR' that setup +appropriate dirs: +'O' - build directory +'DESTDIR' - installation directory. This variable could also be setup in +the 'CONFIGURATION' block of the "Makefile" + +build +----- + +$ make O=<your_custom_build_catalog> + +Example: +$ make O=/home/hedin/prj/cpupower/build + +install +------- + +$ make O=<your_custom_build_catalog> DESTDIR=<your_custom_install_catalog> + +Example: +$ make O=/home/hedin/prj/cpupower/build DESTDIR=/home/hedin/prj/cpupower \ +> install + +Notice that both variables 'O' and 'DESTDIR' have been provided. The reason +is that the build results are saved in the custom output dir defined by 'O' +variable. So, this dir is the source for the installation step. If only +'DESTDIR' were provided then the 'install' target would assume that the +build directory is the current one, build everything there and install +from the current dir. + +The files will be installed to the following dirs: + +----------------------------------------------------------------------- +| Installing file | System dir | +----------------------------------------------------------------------- +| libcpupower | ${DESTDIR}/usr/lib | +----------------------------------------------------------------------- +| cpupower | ${DESTDIR}/usr/bin | +----------------------------------------------------------------------- +| cpufreq-bench_plot.sh | ${DESTDIR}/usr/bin | +----------------------------------------------------------------------- +| man pages | ${DESTDIR}/usr/man | +----------------------------------------------------------------------- +| systemd service | ${DESTDIR}/usr/lib/systemd/system | +----------------------------------------------------------------------- +| systemd support script | ${DESTDIR}/usr/libexec | +----------------------------------------------------------------------- + +If you look at the table for the default 'make' output dirs you will +notice that the only difference with the non-default case is the +${DESTDIR} prefix. So, the structure of the output dirs remains the same +regardles of the root output directory. + + +clean and uninstall +------------------- + +'clean' target is intended for cleanup the build catalog from build results +'uninstall' target is intended for removing installed files from the +installation directory + +default directory +----------------- + +This case is a straightforward one: +$ make clean +$ make uninstall + +custom directory +---------------- + +Use 'O' command line variable to remove previously built files from the +build dir: +$ make O=<your_custom_build_catalog> clean + +Example: +$ make O=/home/hedin/prj/cpupower/build clean + +Use 'DESTDIR' command line variable to uninstall previously installed files +from the given dir: +$ make DESTDIR=<your_custom_install_catalog> + +Example: +make DESTDIR=/home/hedin/prj/cpupower uninstall + + +running the tool +---------------- + +default directory +----------------- + +$ sudo cpupower + +custom directory +---------------- + +When it comes to run the utility from the custom build catalog things +become a little bit complicated as 'just run' approach doesn't work. +Assuming that the current dir is '<your_custom_install_catalog>/usr', +issuing the following command: + +$ sudo ./bin/cpupower +will produce the following error output: +./bin/cpupower: error while loading shared libraries: libcpupower.so.1: +cannot open shared object file: No such file or directory + +The issue is that binary cannot find the 'libcpupower' library. So, we +shall point to the lib dir: +sudo LD_LIBRARY_PATH=lib64/ ./bin/cpupower + +systemd service +--------------- + +A systemd service is also provided to run the cpupower utility at boot with +settings read from a configuration file. + +If you want systemd to find the new service after the installation, the service +unit must have been installed in one of the system unit search path directories +(such as '/usr/lib/systemd/system/', which is the default location) and (unless +you are willing to wait for the next reboot) you need to issue the following +command: + +$ sudo systemctl daemon-reload + +If you want to enable this systemd service, edit '/etc/cpupower-service.conf' +(uncommenting at least one of the options, depending on your preferences) +and then issue the following command: + +$ sudo systemctl enable --now cpupower.service THANKS diff --git a/tools/power/cpupower/bench/Makefile b/tools/power/cpupower/bench/Makefile index a4b902f9e1c4..34e5894476eb 100644 --- a/tools/power/cpupower/bench/Makefile +++ b/tools/power/cpupower/bench/Makefile @@ -1,4 +1,9 @@ # SPDX-License-Identifier: GPL-2.0 +ifeq ($(MAKELEVEL),0) +$(error This Makefile is not intended to be run standalone, but only as a part \ +of the main one in the parent dir) +endif + OUTPUT := ./ ifeq ("$(origin O)", "command line") ifneq ($(O),) diff --git a/tools/power/cpupower/bench/parse.c b/tools/power/cpupower/bench/parse.c index e63dc11fa3a5..bd67c758b33a 100644 --- a/tools/power/cpupower/bench/parse.c +++ b/tools/power/cpupower/bench/parse.c @@ -4,6 +4,7 @@ * Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de> */ +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <stdarg.h> @@ -120,6 +121,10 @@ out_dir: struct config *prepare_default_config() { struct config *config = malloc(sizeof(struct config)); + if (!config) { + perror("malloc"); + return NULL; + } dprintf("loading defaults\n"); @@ -165,8 +170,8 @@ int prepare_config(const char *path, struct config *config) configfile = fopen(path, "r"); if (configfile == NULL) { - perror("fopen"); - fprintf(stderr, "error: unable to read configfile\n"); + fprintf(stderr, "error: unable to read configfile: %s, %s\n", + path, strerror(errno)); free(config); return 1; } diff --git a/tools/power/cpupower/bindings/python/.gitignore b/tools/power/cpupower/bindings/python/.gitignore new file mode 100644 index 000000000000..51cbb8799c44 --- /dev/null +++ b/tools/power/cpupower/bindings/python/.gitignore @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-only +__pycache__/ +raw_pylibcpupower_wrap.c +*.o +*.so +*.py +!test_raw_pylibcpupower.py diff --git a/tools/power/cpupower/bindings/python/Makefile b/tools/power/cpupower/bindings/python/Makefile new file mode 100644 index 000000000000..81db39a03efb --- /dev/null +++ b/tools/power/cpupower/bindings/python/Makefile @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Makefile for libcpupower's Python bindings +# +# This Makefile expects you have already run `make install-lib` in the lib +# directory for the bindings to be created. + +CC := gcc +HAVE_SWIG := $(shell if which swig >/dev/null 2>&1; then echo 1; else echo 0; fi) +HAVE_PYCONFIG := $(shell if which python-config >/dev/null 2>&1; then echo 1; else echo 0; fi) + +PY_INCLUDE = $(firstword $(shell python-config --includes)) +INSTALL_DIR = $(shell python3 -c "import site; print(site.getsitepackages()[0])") + +all: _raw_pylibcpupower.so + +_raw_pylibcpupower.so: raw_pylibcpupower_wrap.o + $(CC) -shared -lcpupower raw_pylibcpupower_wrap.o -o _raw_pylibcpupower.so + +raw_pylibcpupower_wrap.o: raw_pylibcpupower_wrap.c + $(CC) -fPIC -c raw_pylibcpupower_wrap.c $(PY_INCLUDE) + +raw_pylibcpupower_wrap.c: raw_pylibcpupower.swg +ifeq ($(HAVE_SWIG),0) + $(error "swig was not found. Make sure you have it installed and in the PATH to generate the bindings.") +else ifeq ($(HAVE_PYCONFIG),0) + $(error "python-config was not found. Make sure you have it installed and in the PATH to generate the bindings.") +endif + swig -python raw_pylibcpupower.swg + +# Only installs the Python bindings +install: _raw_pylibcpupower.so + install -D _raw_pylibcpupower.so $(INSTALL_DIR)/_raw_pylibcpupower.so + install -D raw_pylibcpupower.py $(INSTALL_DIR)/raw_pylibcpupower.py + +uninstall: + rm -f $(INSTALL_DIR)/_raw_pylibcpupower.so + rm -f $(INSTALL_DIR)/raw_pylibcpupower.py + +# Will only clean the bindings folder; will not clean the actual cpupower folder +clean: + rm -f raw_pylibcpupower.py raw_pylibcpupower_wrap.c raw_pylibcpupower_wrap.o _raw_pylibcpupower.so diff --git a/tools/power/cpupower/bindings/python/README b/tools/power/cpupower/bindings/python/README new file mode 100644 index 000000000000..2a4896b648b7 --- /dev/null +++ b/tools/power/cpupower/bindings/python/README @@ -0,0 +1,87 @@ +This folder contains the necessary files to build the Python bindings for +libcpupower (aside from the libcpupower object files). + + +requirements +------------ + +* If you are building completely from upstream; please install libcpupower by +running `make install-lib` within the cpupower directory. This installs the +libcpupower.so file and symlinks needed. Otherwise, please make sure a symlink +to libcpupower.so exists in your library path from your distribution's +packages. +* The SWIG program must be installed. +* The Python's development libraries must be installed. + +Please check that your version of SWIG is compatible with the version of Python +installed on your machine by checking the SWIG changelog on their website. +https://swig.org/ + +Note that while SWIG itself is GPL v3+ licensed; the resulting output, +the bindings code: is permissively licensed + the license of libcpupower's +library files. For these bindings that means GPL v2. + +Please see https://swig.org/legal.html and the discussion [1] for more details. + +[1] +https://lore.kernel.org/linux-pm/Zqv9BOjxLAgyNP5B@hatbackup/ + + +build +----- + +Install SWIG and the Python development files provided by your distribution. + +Build the object files for libcpupower by running make in the cpupower +directory. + +Return to the directory this README is in to run: + +$ make + + +testing +------- + +Please verify the _raw_pylibcpupower.so and raw_pylibcpupower.py files have +been created. + +To run the test script: + +$ python test_raw_pylibcpupower.py + + +developing/using the bindings directly +-------------------------------------- + +You need to add the Python bindings directory to your $PYTHONPATH. + +You would set the path in the Bash terminal or in the Bash profile: + +PYTHONPATH=~/linux/tools/power/cpupower/bindings/python:$PYTHONPATH + +This allows you to set a specific repo of the bindings to use. + + +installing/uninstalling +----------------------- + +Python uses a system specific site-packages folder to look up modules to import +by default. You do not need to install cpupower to use the SWIG bindings. + +You can install and uninstall the bindings to the site-packages with: + +sudo make install + +sudo make uninstall + + +credits +------- + +Original Bindings Author: +John B. Wyatt IV +jwyatt@redhat.com +sageofredondo@gmail.com + +Copyright (C) 2024 Red Hat diff --git a/tools/power/cpupower/bindings/python/raw_pylibcpupower.swg b/tools/power/cpupower/bindings/python/raw_pylibcpupower.swg new file mode 100644 index 000000000000..d82af6fa93c3 --- /dev/null +++ b/tools/power/cpupower/bindings/python/raw_pylibcpupower.swg @@ -0,0 +1,252 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +%module raw_pylibcpupower +%{ +#include "../../lib/cpupower_intern.h" +#include "../../lib/acpi_cppc.h" +#include "../../lib/cpufreq.h" +#include "../../lib/cpuidle.h" +#include "../../lib/cpupower.h" +#include "../../lib/powercap.h" +%} + +/* + * cpupower_intern.h + */ + +#define PATH_TO_CPU "/sys/devices/system/cpu/" +#define MAX_LINE_LEN 4096 +#define SYSFS_PATH_MAX 255 + +int is_valid_path(const char *path); + +unsigned int cpupower_read_sysfs(const char *path, char *buf, size_t buflen); + +unsigned int cpupower_write_sysfs(const char *path, char *buf, size_t buflen); + +/* + * acpi_cppc.h + */ + +enum acpi_cppc_value { + HIGHEST_PERF, + LOWEST_PERF, + NOMINAL_PERF, + LOWEST_NONLINEAR_PERF, + LOWEST_FREQ, + NOMINAL_FREQ, + REFERENCE_PERF, + WRAPAROUND_TIME, + MAX_CPPC_VALUE_FILES +}; + +unsigned long acpi_cppc_get_data(unsigned int cpu, + enum acpi_cppc_value which); + +/* + * cpufreq.h + */ + +struct cpufreq_policy { + unsigned long min; + unsigned long max; + char *governor; +}; + +struct cpufreq_available_governors { + char *governor; + struct cpufreq_available_governors *next; + struct cpufreq_available_governors *first; +}; + +struct cpufreq_available_frequencies { + unsigned long frequency; + struct cpufreq_available_frequencies *next; + struct cpufreq_available_frequencies *first; +}; + + +struct cpufreq_affected_cpus { + unsigned int cpu; + struct cpufreq_affected_cpus *next; + struct cpufreq_affected_cpus *first; +}; + +struct cpufreq_stats { + unsigned long frequency; + unsigned long long time_in_state; + struct cpufreq_stats *next; + struct cpufreq_stats *first; +}; + +unsigned long cpufreq_get_freq_kernel(unsigned int cpu); + +unsigned long cpufreq_get_freq_hardware(unsigned int cpu); + +#define cpufreq_get(cpu) cpufreq_get_freq_kernel(cpu); + +unsigned long cpufreq_get_transition_latency(unsigned int cpu); + +int cpufreq_get_hardware_limits(unsigned int cpu, + unsigned long *min, + unsigned long *max); + +char *cpufreq_get_driver(unsigned int cpu); + +void cpufreq_put_driver(char *ptr); + +struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu); + +void cpufreq_put_policy(struct cpufreq_policy *policy); + +struct cpufreq_available_governors +*cpufreq_get_available_governors(unsigned int cpu); + +void cpufreq_put_available_governors( + struct cpufreq_available_governors *first); + +struct cpufreq_available_frequencies +*cpufreq_get_available_frequencies(unsigned int cpu); + +void cpufreq_put_available_frequencies( + struct cpufreq_available_frequencies *first); + +struct cpufreq_available_frequencies +*cpufreq_get_boost_frequencies(unsigned int cpu); + +void cpufreq_put_boost_frequencies( + struct cpufreq_available_frequencies *first); + +struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned + int cpu); + +void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *first); + +struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned + int cpu); + +void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *first); + +struct cpufreq_stats *cpufreq_get_stats(unsigned int cpu, + unsigned long long *total_time); + +void cpufreq_put_stats(struct cpufreq_stats *stats); + +unsigned long cpufreq_get_transitions(unsigned int cpu); + +char *cpufreq_get_energy_performance_preference(unsigned int cpu); +void cpufreq_put_energy_performance_preference(char *ptr); + +int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy); + +int cpufreq_modify_policy_min(unsigned int cpu, unsigned long min_freq); + +int cpufreq_modify_policy_max(unsigned int cpu, unsigned long max_freq); + +int cpufreq_modify_policy_governor(unsigned int cpu, char *governor); + +int cpufreq_set_frequency(unsigned int cpu, + unsigned long target_frequency); + +unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu, + const char **table, + unsigned int index, + unsigned int size); + +/* + * cpuidle.h + */ + +int cpuidle_is_state_disabled(unsigned int cpu, + unsigned int idlestate); +int cpuidle_state_disable(unsigned int cpu, unsigned int idlestate, + unsigned int disable); +unsigned long cpuidle_state_latency(unsigned int cpu, + unsigned int idlestate); +unsigned long cpuidle_state_residency(unsigned int cpu, + unsigned int idlestate); +unsigned long cpuidle_state_usage(unsigned int cpu, + unsigned int idlestate); +unsigned long long cpuidle_state_time(unsigned int cpu, + unsigned int idlestate); +char *cpuidle_state_name(unsigned int cpu, + unsigned int idlestate); +char *cpuidle_state_desc(unsigned int cpu, + unsigned int idlestate); +unsigned int cpuidle_state_count(unsigned int cpu); + +char *cpuidle_get_governor(void); + +char *cpuidle_get_driver(void); + +/* + * cpupower.h + */ + +struct cpupower_topology { + /* Amount of CPU cores, packages and threads per core in the system */ + unsigned int cores; + unsigned int pkgs; + unsigned int threads; /* per core */ + + /* Array gets mallocated with cores entries, holding per core info */ + struct cpuid_core_info *core_info; +}; + +struct cpuid_core_info { + int pkg; + int core; + int cpu; + + /* flags */ + unsigned int is_online:1; +}; + +int get_cpu_topology(struct cpupower_topology *cpu_top); + +void cpu_topology_release(struct cpupower_topology cpu_top); + +int cpupower_is_cpu_online(unsigned int cpu); + +/* + * powercap.h + */ + +struct powercap_zone { + char name[MAX_LINE_LEN]; + /* + * sys_name relative to PATH_TO_POWERCAP, + * do not forget the / in between + */ + char sys_name[SYSFS_PATH_MAX]; + int tree_depth; + struct powercap_zone *parent; + struct powercap_zone *children[POWERCAP_MAX_CHILD_ZONES]; + /* More possible caps or attributes to be added? */ + uint32_t has_power_uw:1, + has_energy_uj:1; + +}; + +int powercap_walk_zones(struct powercap_zone *zone, + int (*f)(struct powercap_zone *zone)); + +struct powercap_zone *powercap_init_zones(void); + +int powercap_get_enabled(int *mode); + +int powercap_set_enabled(int mode); + +int powercap_get_driver(char *driver, int buflen); + +int powercap_get_max_energy_range_uj(struct powercap_zone *zone, uint64_t *val); + +int powercap_get_energy_uj(struct powercap_zone *zone, uint64_t *val); + +int powercap_get_max_power_range_uw(struct powercap_zone *zone, uint64_t *val); + +int powercap_get_power_uw(struct powercap_zone *zone, uint64_t *val); + +int powercap_zone_get_enabled(struct powercap_zone *zone, int *mode); + +int powercap_zone_set_enabled(struct powercap_zone *zone, int mode); diff --git a/tools/power/cpupower/bindings/python/test_raw_pylibcpupower.py b/tools/power/cpupower/bindings/python/test_raw_pylibcpupower.py new file mode 100755 index 000000000000..ca5aa46c9b20 --- /dev/null +++ b/tools/power/cpupower/bindings/python/test_raw_pylibcpupower.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-only + +import raw_pylibcpupower as p + +# Simple function call + +""" +Get cstate count +""" +cpu_cstates_count = p.cpuidle_state_count(0) +if cpu_cstates_count > -1: + print(f"CPU 0 has {cpu_cstates_count} c-states") +else: + print(f"cstate count error: return code: {cpu_cstates_count}") + +""" +Disable cstate (will fail if the above returns is under 1, ex: a virtual machine) +""" +cstate_disabled = p.cpuidle_state_disable(0, 0, 1) + +match cstate_disabled: + case 0: + print(f"CPU state disabled") + case -1: + print(f"Idlestate not available") + case -2: + print(f"Disabling is not supported by the kernel") + case -3: + print(f"No write access to disable/enable C-states: try using sudo") + case _: + print(f"Not documented: {cstate_disabled}") + +""" +Test cstate is disabled +""" +is_cstate_disabled = p.cpuidle_is_state_disabled(0, 0) + +match is_cstate_disabled: + case 1: + print(f"CPU is disabled") + case 0: + print(f"CPU is enabled") + case -1: + print(f"Idlestate not available") + case -2: + print(f"Disabling is not supported by kernel") + case _: + print(f"Not documented: {is_cstate_disabled}") + +# Pointer example + +topo = p.cpupower_topology() +total_cpus = p.get_cpu_topology(topo) +if total_cpus > 0: + print(f"Number of total cpus: {total_cpus} and number of cores: {topo.cores}") +else: + print(f"Error: could not get cpu topology") diff --git a/tools/power/cpupower/cpupower-service.conf b/tools/power/cpupower/cpupower-service.conf new file mode 100644 index 000000000000..02eabe8e3614 --- /dev/null +++ b/tools/power/cpupower/cpupower-service.conf @@ -0,0 +1,32 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2012, Sébastien Luttringer +# Copyright (C) 2024-2025, Francesco Poli <invernomuto@paranoici.org> + +# Configuration file for cpupower.service systemd service unit +# +# Edit this file (uncommenting at least one of the options, depending on +# your preferences) and then enable cpupower.service, if you want cpupower +# to run at boot with these settings. + +# --- CPU clock frequency --- + +# Define CPU governor +# Valid governors: ondemand, performance, powersave, conservative, userspace +#GOVERNOR='ondemand' + +# Limit frequency range +# Valid suffixes: Hz, kHz (default), MHz, GHz, THz +#MIN_FREQ="2.25GHz" +#MAX_FREQ="3GHz" + +# Set a specific frequency +# Requires userspace governor to be available. +# If this option is set, all the previous frequency options are ignored +#FREQ= + +# --- CPU policy --- + +# Set a register on supported Intel processore which allows software to convey +# its policy for the relative importance of performance versus energy savings to +# the processor. See man CPUPOWER-SET(1) for additional details +#PERF_BIAS= diff --git a/tools/power/cpupower/cpupower.service.in b/tools/power/cpupower/cpupower.service.in new file mode 100644 index 000000000000..fbd5b8c14270 --- /dev/null +++ b/tools/power/cpupower/cpupower.service.in @@ -0,0 +1,16 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2012-2020, Sébastien Luttringer +# Copyright (C) 2024-2025, Francesco Poli <invernomuto@paranoici.org> + +[Unit] +Description=Apply cpupower configuration +ConditionVirtualization=!container + +[Service] +Type=oneshot +EnvironmentFile=-___CDIR___cpupower-service.conf +ExecStart=___LDIR___/cpupower +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/tools/power/cpupower/cpupower.sh b/tools/power/cpupower/cpupower.sh new file mode 100644 index 000000000000..a37dd4cfdb2b --- /dev/null +++ b/tools/power/cpupower/cpupower.sh @@ -0,0 +1,26 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2012, Sébastien Luttringer +# Copyright (C) 2024, Francesco Poli <invernomuto@paranoici.org> + +ESTATUS=0 + +# apply CPU clock frequency options +if test -n "$FREQ" +then + cpupower frequency-set -f "$FREQ" > /dev/null || ESTATUS=1 +elif test -n "${GOVERNOR}${MIN_FREQ}${MAX_FREQ}" +then + cpupower frequency-set \ + ${GOVERNOR:+ -g "$GOVERNOR"} \ + ${MIN_FREQ:+ -d "$MIN_FREQ"} ${MAX_FREQ:+ -u "$MAX_FREQ"} \ + > /dev/null || ESTATUS=1 +fi + +# apply CPU policy options +if test -n "$PERF_BIAS" +then + cpupower set -b "$PERF_BIAS" > /dev/null || ESTATUS=1 +fi + +exit $ESTATUS diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c index 1516d23c17c9..8dda3db2dff0 100644 --- a/tools/power/cpupower/lib/cpufreq.c +++ b/tools/power/cpupower/lib/cpufreq.c @@ -102,6 +102,10 @@ unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu, if (len == 0) return 0; + if (!strcmp(linebuf, "enabled\n")) + return 1; + if (!strcmp(linebuf, "disabled\n")) + return 0; value = strtoul(linebuf, &endp, 0); if (endp == linebuf || errno == ERANGE) @@ -123,12 +127,14 @@ static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, enum cpufreq_string { SCALING_DRIVER, SCALING_GOVERNOR, + ENERGY_PERFORMANCE_PREFERENCE, MAX_CPUFREQ_STRING_FILES }; static const char *cpufreq_string_files[MAX_CPUFREQ_STRING_FILES] = { [SCALING_DRIVER] = "scaling_driver", [SCALING_GOVERNOR] = "scaling_governor", + [ENERGY_PERFORMANCE_PREFERENCE] = "energy_performance_preference", }; @@ -203,6 +209,18 @@ unsigned long cpufreq_get_transition_latency(unsigned int cpu) return sysfs_cpufreq_get_one_value(cpu, CPUINFO_LATENCY); } +char *cpufreq_get_energy_performance_preference(unsigned int cpu) +{ + return sysfs_cpufreq_get_one_string(cpu, ENERGY_PERFORMANCE_PREFERENCE); +} + +void cpufreq_put_energy_performance_preference(char *ptr) +{ + if (!ptr) + return; + free(ptr); +} + int cpufreq_get_hardware_limits(unsigned int cpu, unsigned long *min, unsigned long *max) diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h index 2f3c84035806..bfc617311ebd 100644 --- a/tools/power/cpupower/lib/cpufreq.h +++ b/tools/power/cpupower/lib/cpufreq.h @@ -68,6 +68,14 @@ unsigned long cpufreq_get_freq_hardware(unsigned int cpu); unsigned long cpufreq_get_transition_latency(unsigned int cpu); +/* determine energy performance preference + * + * returns NULL on failure, else the string that represents the energy performance + * preference requested. + */ +char *cpufreq_get_energy_performance_preference(unsigned int cpu); +void cpufreq_put_energy_performance_preference(char *ptr); + /* determine hardware CPU frequency limits * * These may be limited further by thermal, energy or other diff --git a/tools/power/cpupower/lib/cpuidle.c b/tools/power/cpupower/lib/cpuidle.c index 479c5971aa6d..0ecac009273c 100644 --- a/tools/power/cpupower/lib/cpuidle.c +++ b/tools/power/cpupower/lib/cpuidle.c @@ -116,6 +116,7 @@ enum idlestate_value { IDLESTATE_USAGE, IDLESTATE_POWER, IDLESTATE_LATENCY, + IDLESTATE_RESIDENCY, IDLESTATE_TIME, IDLESTATE_DISABLE, MAX_IDLESTATE_VALUE_FILES @@ -125,6 +126,7 @@ static const char *idlestate_value_files[MAX_IDLESTATE_VALUE_FILES] = { [IDLESTATE_USAGE] = "usage", [IDLESTATE_POWER] = "power", [IDLESTATE_LATENCY] = "latency", + [IDLESTATE_RESIDENCY] = "residency", [IDLESTATE_TIME] = "time", [IDLESTATE_DISABLE] = "disable", }; @@ -254,6 +256,12 @@ unsigned long cpuidle_state_latency(unsigned int cpu, return cpuidle_state_get_one_value(cpu, idlestate, IDLESTATE_LATENCY); } +unsigned long cpuidle_state_residency(unsigned int cpu, + unsigned int idlestate) +{ + return cpuidle_state_get_one_value(cpu, idlestate, IDLESTATE_RESIDENCY); +} + unsigned long cpuidle_state_usage(unsigned int cpu, unsigned int idlestate) { diff --git a/tools/power/cpupower/lib/cpuidle.h b/tools/power/cpupower/lib/cpuidle.h index 2e10fead2e1e..2ab404d40259 100644 --- a/tools/power/cpupower/lib/cpuidle.h +++ b/tools/power/cpupower/lib/cpuidle.h @@ -8,6 +8,8 @@ int cpuidle_state_disable(unsigned int cpu, unsigned int idlestate, unsigned int disable); unsigned long cpuidle_state_latency(unsigned int cpu, unsigned int idlestate); +unsigned long cpuidle_state_residency(unsigned int cpu, + unsigned int idlestate); unsigned long cpuidle_state_usage(unsigned int cpu, unsigned int idlestate); unsigned long long cpuidle_state_time(unsigned int cpu, diff --git a/tools/power/cpupower/lib/cpupower.c b/tools/power/cpupower/lib/cpupower.c index 7a2ef691b20e..ce8dfb8e46ab 100644 --- a/tools/power/cpupower/lib/cpupower.c +++ b/tools/power/cpupower/lib/cpupower.c @@ -10,6 +10,7 @@ #include <stdio.h> #include <errno.h> #include <stdlib.h> +#include <string.h> #include "cpupower.h" #include "cpupower_intern.h" @@ -150,15 +151,25 @@ static int __compare(const void *t1, const void *t2) return 0; } +static int __compare_core_cpu_list(const void *t1, const void *t2) +{ + struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1; + struct cpuid_core_info *top2 = (struct cpuid_core_info *)t2; + + return strcmp(top1->core_cpu_list, top2->core_cpu_list); +} + /* * Returns amount of cpus, negative on error, cpu_top must be * passed to cpu_topology_release to free resources * - * Array is sorted after ->pkg, ->core, then ->cpu + * Array is sorted after ->cpu_smt_list ->pkg, ->core */ int get_cpu_topology(struct cpupower_topology *cpu_top) { int cpu, last_pkg, cpus = sysconf(_SC_NPROCESSORS_CONF); + char path[SYSFS_PATH_MAX]; + char *last_cpu_list; cpu_top->core_info = malloc(sizeof(struct cpuid_core_info) * cpus); if (cpu_top->core_info == NULL) @@ -183,6 +194,34 @@ int get_cpu_topology(struct cpupower_topology *cpu_top) cpu_top->core_info[cpu].core = -1; continue; } + if (cpu_top->core_info[cpu].core == -1) { + strncpy(cpu_top->core_info[cpu].core_cpu_list, "-1", CPULIST_BUFFER); + continue; + } + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s", + cpu, "core_cpus_list"); + if (cpupower_read_sysfs( + path, + cpu_top->core_info[cpu].core_cpu_list, + CPULIST_BUFFER) < 1) { + printf("Warning CPU%u has a 0 size core_cpus_list string", cpu); + } + } + + /* Count the number of distinct cpu lists to get the physical core + * count. + */ + qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info), + __compare_core_cpu_list); + + last_cpu_list = cpu_top->core_info[0].core_cpu_list; + cpu_top->cores = 1; + for (cpu = 1; cpu < cpus; cpu++) { + if (strcmp(cpu_top->core_info[cpu].core_cpu_list, last_cpu_list) != 0 && + cpu_top->core_info[cpu].pkg != -1) { + last_cpu_list = cpu_top->core_info[cpu].core_cpu_list; + cpu_top->cores++; + } } qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info), @@ -203,13 +242,6 @@ int get_cpu_topology(struct cpupower_topology *cpu_top) if (!(cpu_top->core_info[0].pkg == -1)) cpu_top->pkgs++; - /* Intel's cores count is not consecutively numbered, there may - * be a core_id of 3, but none of 2. Assume there always is 0 - * Get amount of cores by counting duplicates in a package - for (cpu = 0; cpu_top->core_info[cpu].pkg = 0 && cpu < cpus; cpu++) { - if (cpu_top->core_info[cpu].core == 0) - cpu_top->cores++; - */ return cpus; } diff --git a/tools/power/cpupower/lib/cpupower.h b/tools/power/cpupower/lib/cpupower.h index e4e4292eacec..2e67a080f203 100644 --- a/tools/power/cpupower/lib/cpupower.h +++ b/tools/power/cpupower/lib/cpupower.h @@ -2,6 +2,8 @@ #ifndef __CPUPOWER_CPUPOWER_H__ #define __CPUPOWER_CPUPOWER_H__ +#define CPULIST_BUFFER 5 + struct cpupower_topology { /* Amount of CPU cores, packages and threads per core in the system */ unsigned int cores; @@ -16,6 +18,7 @@ struct cpuid_core_info { int pkg; int core; int cpu; + char core_cpu_list[CPULIST_BUFFER]; /* flags */ unsigned int is_online:1; diff --git a/tools/power/cpupower/lib/powercap.c b/tools/power/cpupower/lib/powercap.c index a7a59c6bacda..94a0c69e55ef 100644 --- a/tools/power/cpupower/lib/powercap.c +++ b/tools/power/cpupower/lib/powercap.c @@ -78,6 +78,14 @@ int powercap_get_enabled(int *mode) } /* + * TODO: implement function. Returns dummy 0 for now. + */ +int powercap_set_enabled(int mode) +{ + return 0; +} + +/* * Hardcoded, because rapl is the only powercap implementation - * this needs to get more generic if more powercap implementations * should show up diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1 index 8ee737eefa5c..89af019f8dc4 100644 --- a/tools/power/cpupower/man/cpupower-monitor.1 +++ b/tools/power/cpupower/man/cpupower-monitor.1 @@ -81,11 +81,6 @@ Measure idle and frequency characteristics of an arbitrary command/workload. The executable \fBcommand\fP is forked and upon its exit, statistics gathered since it was forked are displayed. .RE -.PP -\-v -.RS 4 -Increase verbosity if the binary was compiled with the DEBUG option set. -.RE .SH MONITOR DESCRIPTIONS .SS "Idle_Stats" @@ -172,9 +167,11 @@ displayed. "BIOS and Kernel Developer’s Guide (BKDG) for AMD Family 14h Processors" https://support.amd.com/us/Processor_TechDocs/43170.pdf -"Intel® Turbo Boost Technology -in Intel® Core™ Microarchitecture (Nehalem) Based Processors" -http://download.intel.com/design/processor/applnots/320354.pdf +"What Is Intel® Turbo Boost Technology?" +https://www.intel.com/content/www/us/en/gaming/resources/turbo-boost.html + +"Power Management - Technology Overview" +https://cdrdv2.intel.com/v1/dl/getContent/637748 "Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3B: System Programming Guide" diff --git a/tools/power/cpupower/man/cpupower-set.1 b/tools/power/cpupower/man/cpupower-set.1 index 2bcc696f4496..500653ef98c7 100644 --- a/tools/power/cpupower/man/cpupower-set.1 +++ b/tools/power/cpupower/man/cpupower-set.1 @@ -3,7 +3,7 @@ cpupower\-set \- Set processor power related kernel or hardware configurations .SH SYNOPSIS .ft B -.B cpupower set [ \-b VAL ] +.B cpupower set [ \-b VAL | \-e POLICY | \-m MODE | \-t BOOL ] .SH DESCRIPTION @@ -19,7 +19,7 @@ described in the Options sections. Use \fBcpupower info \fP to read out current settings and whether they are supported on the system at all. -.SH Options +.SH OPTIONS .PP \-\-perf-bias, \-b .RS 4 @@ -56,6 +56,40 @@ Use \fBcpupower -c all info -b\fP to verify. This options needs the msr kernel driver (CONFIG_X86_MSR) loaded. .RE +.PP +\-\-epp, \-e +.RS 4 +Sets the energy performance policy preference on supported Intel or AMD +processors which use the Intel or AMD P-State cpufreq driver respectively. + +Available policies can be found with +\fBcat /sys/devices/system/cpu/cpufreq/policy0/energy_performance_available_preferences\fP : +.RS 4 +default performance balance_performance balance_power power +.RE + +.RE + +.PP +\-\-amd\-pstate\-mode, \-m +.RS 4 +Sets the AMD P-State mode for supported AMD processors. +Available modes are "active", "guided" or "passive". + +Refer to the AMD P-State kernel documentation for further information. + +.RE + +.PP +\-\-turbo\-boost, \-t +.RS 4 +This option is used to enable or disable the turbo boost feature on +supported Intel and AMD processors. + +This option takes as parameter either \fB1\fP to enable, or \fB0\fP to disable the feature. + +.RE + .SH "SEE ALSO" cpupower-info(1), cpupower-monitor(1), powertop(1) .PP diff --git a/tools/power/cpupower/po/zh_CN.po b/tools/power/cpupower/po/zh_CN.po new file mode 100644 index 000000000000..0489abffb702 --- /dev/null +++ b/tools/power/cpupower/po/zh_CN.po @@ -0,0 +1,942 @@ +# Chinese Simplified translations for cpufrequtils package +# Copyright (C) 2004 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the cpufrequtils package. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: cpufrequtils 006\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-03-08 17:03+0100\n" +"PO-Revision-Date: 2024-05-22 15:36+0000\n" +"Last-Translator: Kieran Moy <kfatyuip@gmail.com>\n" +"Language-Team: NONE\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 3.4.2\n" + +#: utils/idle_monitor/nhm_idle.c:36 +msgid "Processor Core C3" +msgstr "处理器 Core C3" + +#: utils/idle_monitor/nhm_idle.c:43 +msgid "Processor Core C6" +msgstr "处理器 Core C6" + +#: utils/idle_monitor/nhm_idle.c:51 +msgid "Processor Package C3" +msgstr "处理器套件 C3" + +#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70 +msgid "Processor Package C6" +msgstr "处理器套件 C6" + +#: utils/idle_monitor/snb_idle.c:33 +msgid "Processor Core C7" +msgstr "处理器 Core C7" + +#: utils/idle_monitor/snb_idle.c:40 +msgid "Processor Package C2" +msgstr "处理器套件 C2" + +#: utils/idle_monitor/snb_idle.c:47 +msgid "Processor Package C7" +msgstr "处理器套件 C7" + +#: utils/idle_monitor/amd_fam14h_idle.c:56 +msgid "Package in sleep state (PC1 or deeper)" +msgstr "Package in sleep state (PC1 或更深)" + +#: utils/idle_monitor/amd_fam14h_idle.c:63 +msgid "Processor Package C1" +msgstr "处理器套件 C1" + +#: utils/idle_monitor/amd_fam14h_idle.c:77 +msgid "North Bridge P1 boolean counter (returns 0 or 1)" +msgstr "北桥 P1 布尔计数器(返回 0 或 1)" + +#: utils/idle_monitor/mperf_monitor.c:35 +msgid "Processor Core not idle" +msgstr "处理器 Core不空闲" + +#: utils/idle_monitor/mperf_monitor.c:42 +msgid "Processor Core in an idle state" +msgstr "处理器 Core处于空闲状态" + +#: utils/idle_monitor/mperf_monitor.c:50 +msgid "Average Frequency (including boost) in MHz" +msgstr "平均频率(包括增加频率),单位 MHz" + +#: utils/idle_monitor/cpupower-monitor.c:66 +#, c-format +msgid "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" +"cpupower monitor:[-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i " +"interval_sec | -c command...]\n" + +#: utils/idle_monitor/cpupower-monitor.c:69 +#, c-format +msgid "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" +"cpupower monitor:[-v] [-h] [ [-t] | [-l] | [-m <mon1>,[<mon2>] ] ] [-i " +"interval_sec | -c command...]\n" + +#: utils/idle_monitor/cpupower-monitor.c:71 +#, c-format +msgid "\t -v: be more verbose\n" +msgstr "-v:更详细\n" + +#: utils/idle_monitor/cpupower-monitor.c:73 +#, c-format +msgid "\t -h: print this help\n" +msgstr "-h:打印此帮助\n" + +#: utils/idle_monitor/cpupower-monitor.c:74 +#, c-format +msgid "\t -i: time interval to measure for in seconds (default 1)\n" +msgstr "-i:测量的时间间隔(以秒为单位)(默认 1)\n" + +#: utils/idle_monitor/cpupower-monitor.c:75 +#, c-format +msgid "\t -t: show CPU topology/hierarchy\n" +msgstr "-t:显示CPU拓扑/层次结构\n" + +#: utils/idle_monitor/cpupower-monitor.c:76 +#, c-format +msgid "\t -l: list available CPU sleep monitors (for use with -m)\n" +msgstr "-l:列出可用的 CPU 睡眠监视器(与 -m 一起使用)\n" + +#: utils/idle_monitor/cpupower-monitor.c:77 +#, c-format +msgid "\t -m: show specific CPU sleep monitors only (in same order)\n" +msgstr "-m:仅显示特定的CPU睡眠监视器(按相同顺序)\n" + +#: utils/idle_monitor/cpupower-monitor.c:79 +#, c-format +msgid "" +"only one of: -t, -l, -m are allowed\n" +"If none of them is passed," +msgstr "" +"仅允许以下之一:-t、-l、-m\n" +"如果都没有通过的话" + +#: utils/idle_monitor/cpupower-monitor.c:80 +#, c-format +msgid " all supported monitors are shown\n" +msgstr " 显示所有支持的显示器\n" + +#: utils/idle_monitor/cpupower-monitor.c:197 +#, c-format +msgid "Monitor %s, Counter %s has no count function. Implementation error\n" +msgstr "监视器 %s、计数器 %s 无计数功能。 执行错误\n" + +#: utils/idle_monitor/cpupower-monitor.c:207 +#, c-format +msgid " *is offline\n" +msgstr " *离线\n" + +#: utils/idle_monitor/cpupower-monitor.c:236 +#, c-format +msgid "%s: max monitor name length (%d) exceeded\n" +msgstr "%s:超出最大监视器名称长度 (%d)\n" + +#: utils/idle_monitor/cpupower-monitor.c:250 +#, c-format +msgid "No matching monitor found in %s, try -l option\n" +msgstr "在 %s 中找不到匹配的监视器,请尝试 -l 选项\n" + +#: utils/idle_monitor/cpupower-monitor.c:266 +#, c-format +msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n" +msgstr "监视器“%s”(%d 状态)- 可能会在 %u 秒后溢出\n" + +#: utils/idle_monitor/cpupower-monitor.c:319 +#, c-format +msgid "%s took %.5f seconds and exited with status %d\n" +msgstr "%s 用了 %.5f 秒并退出,状态为 %d\n" + +#: utils/idle_monitor/cpupower-monitor.c:406 +#, c-format +msgid "Cannot read number of available processors\n" +msgstr "无法读取可用处理器的数量\n" + +#: utils/idle_monitor/cpupower-monitor.c:417 +#, c-format +msgid "Available monitor %s needs root access\n" +msgstr "可用监视器 %s 需要 root 访问权限\n" + +#: utils/idle_monitor/cpupower-monitor.c:428 +#, c-format +msgid "No HW Cstate monitors found\n" +msgstr "未找到 HW Cstate 监视器\n" + +#: utils/cpupower.c:78 +#, c-format +msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n" +msgstr "cpupower [ -c cpulist ] subcommand [ARGS]\n" + +#: utils/cpupower.c:79 +#, c-format +msgid "cpupower --version\n" +msgstr "cpupower --version\n" + +#: utils/cpupower.c:80 +#, c-format +msgid "Supported subcommands are:\n" +msgstr "支持的子命令有:\n" + +#: utils/cpupower.c:83 +#, c-format +msgid "" +"\n" +"Some subcommands can make use of the -c cpulist option.\n" +msgstr "" +"\n" +"某些子命令可以使用 -c cpulist 选项。\n" + +#: utils/cpupower.c:84 +#, c-format +msgid "Look at the general cpupower manpage how to use it\n" +msgstr "看看一般的cpupower manpage如何使用它\n" + +#: utils/cpupower.c:85 +#, c-format +msgid "and read up the subcommand's manpage whether it is supported.\n" +msgstr "并阅读子命令的manpage是否受支持。\n" + +#: utils/cpupower.c:86 +#, c-format +msgid "" +"\n" +"Use cpupower help subcommand for getting help for above subcommands.\n" +msgstr "" +"\n" +"使用 cpupower help subcommand获取上述子命令的帮助。\n" + +#: utils/cpupower.c:91 +#, c-format +msgid "Report errors and bugs to %s, please.\n" +msgstr "请向 %s 报告错误和错误。\n" + +#: utils/cpupower.c:114 +#, c-format +msgid "Error parsing cpu list\n" +msgstr "解析cpu列表时出错\n" + +#: utils/cpupower.c:172 +#, c-format +msgid "Subcommand %s needs root privileges\n" +msgstr "子命令 %s 需要 root 权限\n" + +#: utils/cpufreq-info.c:31 +#, c-format +msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n" +msgstr "无法计算 CPU 数量(%s:%s),假设为 1\n" + +#: utils/cpufreq-info.c:63 +#, c-format +msgid "" +" minimum CPU frequency - maximum CPU frequency - governor\n" +msgstr "最低 CPU 频率 - 最高 CPU 频率 - 调速器\n" + +#: utils/cpufreq-info.c:151 +#, c-format +msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n" +msgstr "评估 CPU %d 上的 Boost 功能时出错 - 您是 root 吗?\n" + +#. P state changes via MSR are identified via cpuid 80000007 +#. on Intel and AMD, but we assume boost capable machines can do that +#. if (cpuid_eax(0x80000000) >= 0x80000007 +#. && (cpuid_edx(0x80000007) & (1 << 7))) +#. +#: utils/cpufreq-info.c:161 +#, c-format +msgid " boost state support: \n" +msgstr " 升压状态支持:\n" + +#: utils/cpufreq-info.c:163 +#, c-format +msgid " Supported: %s\n" +msgstr " 支持:%s\n" + +#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164 +msgid "yes" +msgstr "是" + +#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164 +msgid "no" +msgstr "不是" + +#: utils/cpufreq-info.c:164 +#, c-format +msgid " Active: %s\n" +msgstr " 活跃:%s\n" + +#: utils/cpufreq-info.c:177 +#, c-format +msgid " Boost States: %d\n" +msgstr " 提升状态:%d\n" + +#: utils/cpufreq-info.c:178 +#, c-format +msgid " Total States: %d\n" +msgstr " 状态总数:%d\n" + +#: utils/cpufreq-info.c:181 +#, c-format +msgid " Pstate-Pb%d: %luMHz (boost state)\n" +msgstr " Pstate-Pb%d:%luMHz(升压状态)\n" + +#: utils/cpufreq-info.c:184 +#, c-format +msgid " Pstate-P%d: %luMHz\n" +msgstr " Pstate-P%d:%luMHz\n" + +#: utils/cpufreq-info.c:211 +#, c-format +msgid " no or unknown cpufreq driver is active on this CPU\n" +msgstr " 该 CPU 上没有或未知的 cpufreq 驱动程序处于活动状态\n" + +#: utils/cpufreq-info.c:213 +#, c-format +msgid " driver: %s\n" +msgstr " 驱动程序:%s\n" + +#: utils/cpufreq-info.c:219 +#, c-format +msgid " CPUs which run at the same hardware frequency: " +msgstr " 以相同硬件频率运行的 CPU:" + +#: utils/cpufreq-info.c:230 +#, c-format +msgid " CPUs which need to have their frequency coordinated by software: " +msgstr " 需要通过软件协调频率的 CPU:" + +#: utils/cpufreq-info.c:241 +#, c-format +msgid " maximum transition latency: " +msgstr " 最大转换延迟:" + +#: utils/cpufreq-info.c:247 +#, c-format +msgid " hardware limits: " +msgstr " 硬件限制:" + +#: utils/cpufreq-info.c:256 +#, c-format +msgid " available frequency steps: " +msgstr " 可用频率范围:" + +#: utils/cpufreq-info.c:269 +#, c-format +msgid " available cpufreq governors: " +msgstr " 可用的cpufreq调节器:" + +#: utils/cpufreq-info.c:280 +#, c-format +msgid " current policy: frequency should be within " +msgstr " 当前政策:频率应在" + +#: utils/cpufreq-info.c:282 +#, c-format +msgid " and " +msgstr "和" + +#: utils/cpufreq-info.c:286 +#, c-format +msgid "" +"The governor \"%s\" may decide which speed to use\n" +" within this range.\n" +msgstr "" +"调速器“%s”可以决定使用哪种速度\n" +" 在这个范围内。\n" + +#: utils/cpufreq-info.c:293 +#, c-format +msgid " current CPU frequency is " +msgstr " 当前CPU频率是" + +#: utils/cpufreq-info.c:296 +#, c-format +msgid " (asserted by call to hardware)" +msgstr " (通过调用硬件来断言)" + +#: utils/cpufreq-info.c:304 +#, c-format +msgid " cpufreq stats: " +msgstr " cpu频率统计:" + +#: utils/cpufreq-info.c:472 +#, c-format +msgid "Usage: cpupower freqinfo [options]\n" +msgstr "用法:cpupower freqinfo [选项]\n" + +#: utils/cpufreq-info.c:473 utils/cpufreq-set.c:26 utils/cpupower-set.c:23 +#: utils/cpupower-info.c:22 utils/cpuidle-info.c:148 +#, c-format +msgid "Options:\n" +msgstr "选项:\n" + +#: utils/cpufreq-info.c:474 +#, c-format +msgid " -e, --debug Prints out debug information [default]\n" +msgstr " -e, --debug 打印出调试信息[默认]\n" + +#: utils/cpufreq-info.c:475 +#, c-format +msgid "" +" -f, --freq Get frequency the CPU currently runs at, according\n" +" to the cpufreq core *\n" +msgstr "" +" -f, --freq 获取CPU当前运行的频率,根据\n" +" 到 cpufreq 核心 *\n" + +#: utils/cpufreq-info.c:477 +#, c-format +msgid "" +" -w, --hwfreq Get frequency the CPU currently runs at, by reading\n" +" it from hardware (only available to root) *\n" +msgstr "" +" -w, --hwfreq 通过读取获取CPU当前运行的频率\n" +" 它来自硬件(仅适用于root)*\n" + +#: utils/cpufreq-info.c:479 +#, c-format +msgid "" +" -l, --hwlimits Determine the minimum and maximum CPU frequency " +"allowed *\n" +msgstr " -l, --hwlimits 确定允许的最小和最大 CPU 频率 *\n" + +#: utils/cpufreq-info.c:480 +#, c-format +msgid " -d, --driver Determines the used cpufreq kernel driver *\n" +msgstr " -d, --driver 确定使用的 cpufreq 内核驱动程序 *\n" + +#: utils/cpufreq-info.c:481 +#, c-format +msgid " -p, --policy Gets the currently used cpufreq policy *\n" +msgstr " -p, --policy 获取当前使用的cpufreq策略 *\n" + +#: utils/cpufreq-info.c:482 +#, c-format +msgid " -g, --governors Determines available cpufreq governors *\n" +msgstr " -g, --governors 确定可用的 cpufreq 调节器 *\n" + +#: utils/cpufreq-info.c:483 +#, c-format +msgid "" +" -r, --related-cpus Determines which CPUs run at the same hardware " +"frequency *\n" +msgstr " -r, --lated-cpus 确定哪些 CPU 以相同的硬件频率运行 *\n" + +#: utils/cpufreq-info.c:484 +#, c-format +msgid "" +" -a, --affected-cpus Determines which CPUs need to have their frequency\n" +" coordinated by software *\n" +msgstr "" +" -a, --affected-cpus 确定哪些 CPU 需要其频率\n" +" 由软件协调*\n" + +#: utils/cpufreq-info.c:486 +#, c-format +msgid " -s, --stats Shows cpufreq statistics if available\n" +msgstr " -s, --stats 显示 cpufreq 统计信息(如果有)\n" + +#: utils/cpufreq-info.c:487 +#, c-format +msgid "" +" -y, --latency Determines the maximum latency on CPU frequency " +"changes *\n" +msgstr " -y, --latency 确定 CPU 频率变化的最大延迟*\n" + +#: utils/cpufreq-info.c:488 +#, c-format +msgid " -b, --boost Checks for turbo or boost modes *\n" +msgstr " -b, --boost 检查 Turbo 或 boost 模式 *\n" + +#: utils/cpufreq-info.c:489 +#, c-format +msgid "" +" -o, --proc Prints out information like provided by the /proc/" +"cpufreq\n" +" interface in 2.4. and early 2.6. kernels\n" +msgstr "" +" -o, --proc 打印 /proc/cpufreq 提供的信息\n" +" 2.4 中的接口。 以及 2.6 之前的内核。\n" + +#: utils/cpufreq-info.c:491 +#, c-format +msgid "" +" -m, --human human-readable output for the -f, -w, -s and -y " +"parameters\n" +msgstr " -m, -- human -f, -w, -s 和 -y 参数的人类可读输出\n" + +#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152 +#, c-format +msgid " -h, --help Prints out this screen\n" +msgstr " -h, --help 打印此屏幕\n" + +#: utils/cpufreq-info.c:495 +#, c-format +msgid "" +"If no argument or only the -c, --cpu parameter is given, debug output " +"about\n" +"cpufreq is printed which is useful e.g. for reporting bugs.\n" +msgstr "" +"screen如果没有参数或仅给出了 -c, --cpu 参数,则调试输出有关\n" +"cpufreq 被打印出来,这很有用,例如 用于报告错误。\n" + +#: utils/cpufreq-info.c:497 +#, c-format +msgid "" +"For the arguments marked with *, omitting the -c or --cpu argument is\n" +"equivalent to setting it to zero\n" +msgstr "" +"对于标有 * 的参数,省略 -c 或 --cpu 参数是\n" +"相当于将其设置为零\n" + +#: utils/cpufreq-info.c:580 +#, c-format +msgid "" +"The argument passed to this tool can't be combined with passing a --cpu " +"argument\n" +msgstr "传递给此工具的参数不能与传递 --cpu 参数结合使用\n" + +#: utils/cpufreq-info.c:596 +#, c-format +msgid "" +"You can't specify more than one --cpu parameter and/or\n" +"more than one output-specific argument\n" +msgstr "" +"您不能指定多个 --cpu 参数和/或\n" +"多个特定于输出的参数\n" + +#: utils/cpufreq-info.c:600 utils/cpufreq-set.c:82 utils/cpupower-set.c:42 +#: utils/cpupower-info.c:42 utils/cpuidle-info.c:213 +#, c-format +msgid "invalid or unknown argument\n" +msgstr "无效或未知的参数\n" + +#: utils/cpufreq-info.c:617 +#, c-format +msgid "couldn't analyze CPU %d as it doesn't seem to be present\n" +msgstr "无法分析 CPU %d,因为它似乎不存在\n" + +#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142 +#, c-format +msgid "analyzing CPU %d:\n" +msgstr "分析 CPU %d:\n" + +#: utils/cpufreq-set.c:25 +#, c-format +msgid "Usage: cpupower frequency-set [options]\n" +msgstr "用法:cpupower frequency-set [选项]\n" + +#: utils/cpufreq-set.c:27 +#, c-format +msgid "" +" -d FREQ, --min FREQ new minimum CPU frequency the governor may " +"select\n" +msgstr " -d FREQ, --min FREQ 调控器可以选择的新的最小 CPU 频率\n" + +#: utils/cpufreq-set.c:28 +#, c-format +msgid "" +" -u FREQ, --max FREQ new maximum CPU frequency the governor may " +"select\n" +msgstr " -u FREQ, --max FREQ 调控器可以选择的新的最大 CPU 频率\n" + +#: utils/cpufreq-set.c:29 +#, c-format +msgid " -g GOV, --governor GOV new cpufreq governor\n" +msgstr " -g GOV, --governor GOV 新的 cpufreq 调节器\n" + +#: utils/cpufreq-set.c:30 +#, c-format +msgid "" +" -f FREQ, --freq FREQ specific frequency to be set. Requires " +"userspace\n" +" governor to be available and loaded\n" +msgstr "" +" -f FREQ, --freq FREQ 要设置的特定频率。 需要用户空间\n" +" 调速器可用并已加载\n" + +#: utils/cpufreq-set.c:32 +#, c-format +msgid " -r, --related Switches all hardware-related CPUs\n" +msgstr " -r, --related 切换所有与硬件相关的CPU\n" + +#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27 +#, c-format +msgid " -h, --help Prints out this screen\n" +msgstr " -h, --help 打印此屏幕\n" + +#: utils/cpufreq-set.c:35 +#, c-format +msgid "" +"Notes:\n" +"1. Omitting the -c or --cpu argument is equivalent to setting it to " +"\"all\"\n" +msgstr "" +"注意:\n" +"1.省略-c或--cpu参数相当于将其设置为“all”\n" + +#: utils/cpufreq-set.c:37 +#, c-format +msgid "" +"2. The -f FREQ, --freq FREQ parameter cannot be combined with any other " +"parameter\n" +" except the -c CPU, --cpu CPU parameter\n" +"3. FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz\n" +" by postfixing the value with the wanted unit name, without any space\n" +" (FREQuency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000).\n" +msgstr "" +"2. -f FREQ、--freq FREQ参数不能与任何其他参数组合使用\n" +" 除了 -c CPU、--cpu CPU 参数\n" +"3. 频率可以以 Hz、kHz(默认)、MHz、GHz 或 THz 为单位传递\n" +" 通过在值后面添加所需的单位名称,不带任何空格\n" +" (以 kHz 为单位的频率 =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000)。\n" + +#: utils/cpufreq-set.c:57 +#, c-format +msgid "" +"Error setting new values. Common errors:\n" +"- Do you have proper administration rights? (super-user?)\n" +"- Is the governor you requested available and modprobed?\n" +"- Trying to set an invalid policy?\n" +"- Trying to set a specific frequency, but userspace governor is not " +"available,\n" +" for example because of hardware which cannot be set to a specific " +"frequency\n" +" or because the userspace governor isn't loaded?\n" +msgstr "" +"设置新值时出错。 常见错误:\n" +"- 您有适当的管理权吗? (超级用户?)\n" +"- 您请求的调控器是否可用并已进行 modprobed?\n" +"- 尝试设置无效的策略?\n" +"- 尝试设置特定频率,但用户空间调控器不可用,\n" +" 例如由于硬件无法设置为特定频率\n" +" 或者因为用户空间调控器未加载?\n" + +#: utils/cpufreq-set.c:170 +#, c-format +msgid "wrong, unknown or unhandled CPU?\n" +msgstr "错误、未知或未处理的CPU?\n" + +#: utils/cpufreq-set.c:302 +#, c-format +msgid "" +"the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n" +"-g/--governor parameters\n" +msgstr "" +"-f/--freq 参数不能与 -d/--min、-u/--max 或\n" +"-g/--调速器参数\n" + +#: utils/cpufreq-set.c:308 +#, c-format +msgid "" +"At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n" +"-g/--governor must be passed\n" +msgstr "" +"-f/--freq、-d/--min、-u/--max 和 -f/--freq 中的至少一个参数\n" +"-g/--governor 必须通过\n" + +#: utils/cpufreq-set.c:347 +#, c-format +msgid "Setting cpu: %d\n" +msgstr "设置CPU:%d\n" + +#: utils/cpupower-set.c:22 +#, c-format +msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" +msgstr "用法: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" + +#: utils/cpupower-set.c:24 +#, c-format +msgid "" +" -b, --perf-bias [VAL] Sets CPU's power vs performance policy on some\n" +" Intel models [0-15], see manpage for details\n" +msgstr "" +" -b, --perf-bias [VAL] 设置 CPU 的功耗与性能策略\n" +" Intel 型号 [0-15],请参阅manpage了解详细信息\n" + +#: utils/cpupower-set.c:26 +#, c-format +msgid "" +" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n" +msgstr " -m, --sched-mc [VAL] 设置内核的多核调度程序策略。\n" + +#: utils/cpupower-set.c:27 +#, c-format +msgid "" +" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler " +"policy.\n" +msgstr " -s, --sched-smt [VAL] 设置内核的线程同级调度程序策略。\n" + +#: utils/cpupower-set.c:80 +#, c-format +msgid "--perf-bias param out of range [0-%d]\n" +msgstr "--perf-bias 参数超出范围 [0-%d]\n" + +#: utils/cpupower-set.c:91 +#, c-format +msgid "--sched-mc param out of range [0-%d]\n" +msgstr "--sched-mc 参数超出范围 [0-%d]\n" + +#: utils/cpupower-set.c:102 +#, c-format +msgid "--sched-smt param out of range [0-%d]\n" +msgstr "--sched-smt 参数超出范围 [0-%d]\n" + +#: utils/cpupower-set.c:121 +#, c-format +msgid "Error setting sched-mc %s\n" +msgstr "设置 sched-mc %s 时出错\n" + +#: utils/cpupower-set.c:127 +#, c-format +msgid "Error setting sched-smt %s\n" +msgstr "设置 sched-smt %s 时出错\n" + +#: utils/cpupower-set.c:146 +#, c-format +msgid "Error setting perf-bias value on CPU %d\n" +msgstr "在 CPU %d 上设置性能偏差值时出错\n" + +#: utils/cpupower-info.c:21 +#, c-format +msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n" +msgstr "用法:cpupower info [-b][-m][-s]\n" + +#: utils/cpupower-info.c:23 +#, c-format +msgid "" +" -b, --perf-bias Gets CPU's power vs performance policy on some\n" +" Intel models [0-15], see manpage for details\n" +msgstr "" +" -b, --perf-bias 获取 CPU 在某些方面的功耗与性能策略\n" +" Intel 型号 [0-15],请参阅联机帮助页了解详细信" +"息\n" + +#: utils/cpupower-info.c:25 +#, c-format +msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n" +msgstr " -m, --sched-mc 获取内核的多核调度程序策略。\n" + +#: utils/cpupower-info.c:26 +#, c-format +msgid "" +" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n" +msgstr " -s, --sched-smt 获取内核的线程同级调度程序策略。\n" + +#: utils/cpupower-info.c:28 +#, c-format +msgid "" +"\n" +"Passing no option will show all info, by default only on core 0\n" +msgstr "" +"\n" +"不传递任何选项将显示所有信息,默认情况下仅在核心 0 上\n" + +#: utils/cpupower-info.c:102 +#, c-format +msgid "System's multi core scheduler setting: " +msgstr "系统的多核调度器设置:" + +#. if sysfs file is missing it's: errno == ENOENT +#: utils/cpupower-info.c:105 utils/cpupower-info.c:114 +#, c-format +msgid "not supported\n" +msgstr "不支持\n" + +#: utils/cpupower-info.c:111 +#, c-format +msgid "System's thread sibling scheduler setting: " +msgstr "系统的线程兄调度程序设置:" + +#: utils/cpupower-info.c:126 +#, c-format +msgid "Intel's performance bias setting needs root privileges\n" +msgstr "Intel的性能偏差设置需要root权限\n" + +#: utils/cpupower-info.c:128 +#, c-format +msgid "System does not support Intel's performance bias setting\n" +msgstr "系统不支持Intel的性能偏差设置\n" + +#: utils/cpupower-info.c:147 +#, c-format +msgid "Could not read perf-bias value\n" +msgstr "无法读取性能偏差值\n" + +#: utils/cpupower-info.c:150 +#, c-format +msgid "perf-bias: %d\n" +msgstr "性能偏差:%d\n" + +#: utils/cpuidle-info.c:28 +#, c-format +msgid "Analyzing CPU %d:\n" +msgstr "正在分析 CPU %d:\n" + +#: utils/cpuidle-info.c:32 +#, c-format +msgid "CPU %u: No idle states\n" +msgstr "CPU %u:无空闲状态\n" + +#: utils/cpuidle-info.c:36 +#, c-format +msgid "CPU %u: Can't read idle state info\n" +msgstr "CPU %u:无法读取空闲状态信息\n" + +#: utils/cpuidle-info.c:41 +#, c-format +msgid "Could not determine max idle state %u\n" +msgstr "无法确定最大空闲状态 %u\n" + +#: utils/cpuidle-info.c:46 +#, c-format +msgid "Number of idle states: %d\n" +msgstr "空闲状态数:%d\n" + +#: utils/cpuidle-info.c:48 +#, c-format +msgid "Available idle states:" +msgstr "可用的空闲状态:" + +#: utils/cpuidle-info.c:71 +#, c-format +msgid "Flags/Description: %s\n" +msgstr "标志/描述:%s\n" + +#: utils/cpuidle-info.c:74 +#, c-format +msgid "Latency: %lu\n" +msgstr "延迟:%lu\n" + +#: utils/cpuidle-info.c:76 +#, c-format +msgid "Usage: %lu\n" +msgstr "用法:%lu\n" + +#: utils/cpuidle-info.c:78 +#, c-format +msgid "Duration: %llu\n" +msgstr "持续时间:%llu\n" + +#: utils/cpuidle-info.c:90 +#, c-format +msgid "Could not determine cpuidle driver\n" +msgstr "无法确定 cpuidle 驱动程序\n" + +#: utils/cpuidle-info.c:94 +#, c-format +msgid "CPUidle driver: %s\n" +msgstr "CPU 空闲驱动程序:%s\n" + +#: utils/cpuidle-info.c:99 +#, c-format +msgid "Could not determine cpuidle governor\n" +msgstr "无法确定 cpuidle 调控器\n" + +#: utils/cpuidle-info.c:103 +#, c-format +msgid "CPUidle governor: %s\n" +msgstr "CPU 空闲调节器:%s\n" + +#: utils/cpuidle-info.c:122 +#, c-format +msgid "CPU %u: Can't read C-state info\n" +msgstr "CPU %u:无法读取 C 状态信息\n" + +#. printf("Cstates: %d\n", cstates); +#: utils/cpuidle-info.c:127 +#, c-format +msgid "active state: C0\n" +msgstr "活动状态: C0\n" + +#: utils/cpuidle-info.c:128 +#, c-format +msgid "max_cstate: C%u\n" +msgstr "最大c状态: C%u\n" + +#: utils/cpuidle-info.c:129 +#, c-format +msgid "maximum allowed latency: %lu usec\n" +msgstr "允许的最大延迟:%lu usec\n" + +#: utils/cpuidle-info.c:130 +#, c-format +msgid "states:\t\n" +msgstr "状态:\t\n" + +#: utils/cpuidle-info.c:132 +#, c-format +msgid " C%d: type[C%d] " +msgstr " C%d: 类型[C%d]" + +#: utils/cpuidle-info.c:134 +#, c-format +msgid "promotion[--] demotion[--] " +msgstr "晋升[--] 降级[--]" + +#: utils/cpuidle-info.c:135 +#, c-format +msgid "latency[%03lu] " +msgstr "延迟[%03lu]" + +#: utils/cpuidle-info.c:137 +#, c-format +msgid "usage[%08lu] " +msgstr "使用情况[%08lu]" + +#: utils/cpuidle-info.c:139 +#, c-format +msgid "duration[%020Lu] \n" +msgstr "持续时间[%020Lu]\n" + +#: utils/cpuidle-info.c:147 +#, c-format +msgid "Usage: cpupower idleinfo [options]\n" +msgstr "用法:cpupower idleinfo [选项]\n" + +#: utils/cpuidle-info.c:149 +#, c-format +msgid " -s, --silent Only show general C-state information\n" +msgstr " -s, --silent 只显示一般C状态信息\n" + +#: utils/cpuidle-info.c:150 +#, c-format +msgid "" +" -o, --proc Prints out information like provided by the /proc/" +"acpi/processor/*/power\n" +" interface in older kernels\n" +msgstr "" +" -o, --proc 打印 /proc/acpi/processor/*/power 提供的信息\n" +" 旧内核中的接口\n" + +#: utils/cpuidle-info.c:209 +#, c-format +msgid "You can't specify more than one output-specific argument\n" +msgstr "您不能指定多个特定于输出的参数\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU CPU number which information shall be determined " +#~ "about\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU Numéro du CPU pour lequel l'information sera " +#~ "affichée\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be " +#~ "modified\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU numéro du CPU à prendre en compte pour les\n" +#~ " changements\n" diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c index c96b77365c63..fc750e127404 100644 --- a/tools/power/cpupower/utils/cpufreq-info.c +++ b/tools/power/cpupower/utils/cpufreq-info.c @@ -120,7 +120,6 @@ static void print_duration(unsigned long duration) } else printf("%lu ns", duration); } - return; } static int get_boost_mode_x86(unsigned int cpu) @@ -255,7 +254,12 @@ static int get_freq_kernel(unsigned int cpu, unsigned int human) static int get_freq_hardware(unsigned int cpu, unsigned int human) { - unsigned long freq = cpufreq_get_freq_hardware(cpu); + unsigned long freq; + + if (cpupower_cpu_info.caps & CPUPOWER_CAP_APERF) + return -EINVAL; + + freq = cpufreq_get_freq_hardware(cpu); printf(_(" current CPU frequency: ")); if (!freq) { printf("Unable to call hardware\n"); @@ -418,12 +422,32 @@ static int get_freq_stats(unsigned int cpu, unsigned int human) return 0; } +/* --epp / -z */ + +static int get_epp(unsigned int cpu, bool interactive) +{ + char *epp; + + epp = cpufreq_get_energy_performance_preference(cpu); + if (!epp) + return -EINVAL; + if (interactive) + printf(_(" energy performance preference: %s\n"), epp); + + cpufreq_put_energy_performance_preference(epp); + + return 0; +} + /* --latency / -y */ static int get_latency(unsigned int cpu, unsigned int human) { unsigned long latency = cpufreq_get_transition_latency(cpu); + if (!get_epp(cpu, false)) + return -EINVAL; + printf(_(" maximum transition latency: ")); if (!latency || latency == UINT_MAX) { printf(_(" Cannot determine or is not supported.\n")); @@ -457,6 +481,7 @@ static void debug_output_one(unsigned int cpu) get_related_cpus(cpu); get_affected_cpus(cpu); get_latency(cpu, 1); + get_epp(cpu, true); get_hardware_limits(cpu, 1); freqs = cpufreq_get_available_frequencies(cpu); @@ -497,6 +522,7 @@ static struct option info_opts[] = { {"human", no_argument, NULL, 'm'}, {"no-rounding", no_argument, NULL, 'n'}, {"performance", no_argument, NULL, 'c'}, + {"epp", no_argument, NULL, 'z'}, { }, }; @@ -510,7 +536,7 @@ int cmd_freq_info(int argc, char **argv) int output_param = 0; do { - ret = getopt_long(argc, argv, "oefwldpgrasmybnc", info_opts, + ret = getopt_long(argc, argv, "oefwldpgrasmybncz", info_opts, NULL); switch (ret) { case '?': @@ -534,6 +560,7 @@ int cmd_freq_info(int argc, char **argv) case 's': case 'y': case 'c': + case 'z': if (output_param) { output_param = -1; cont = 0; @@ -643,6 +670,9 @@ int cmd_freq_info(int argc, char **argv) case 'c': ret = get_perf_cap(cpu); break; + case 'z': + ret = get_epp(cpu, true); + break; } if (ret) return ret; diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c index 44126a87fa7a..e0d17f0de3fe 100644 --- a/tools/power/cpupower/utils/cpuidle-info.c +++ b/tools/power/cpupower/utils/cpuidle-info.c @@ -64,6 +64,8 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose) printf(_("Latency: %lu\n"), cpuidle_state_latency(cpu, idlestate)); + printf(_("Residency: %lu\n"), + cpuidle_state_residency(cpu, idlestate)); printf(_("Usage: %lu\n"), cpuidle_state_usage(cpu, idlestate)); printf(_("Duration: %llu\n"), @@ -115,6 +117,8 @@ static void proc_cpuidle_cpu_output(unsigned int cpu) printf(_("promotion[--] demotion[--] ")); printf(_("latency[%03lu] "), cpuidle_state_latency(cpu, cstate)); + printf(_("residency[%05lu] "), + cpuidle_state_residency(cpu, cstate)); printf(_("usage[%08lu] "), cpuidle_state_usage(cpu, cstate)); printf(_("duration[%020Lu] \n"), diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index c519cc89c97f..795562e879de 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -41,6 +41,16 @@ union core_pstate { unsigned res1:31; unsigned en:1; } pstatedef; + /* since fam 1Ah: */ + struct { + unsigned fid:12; + unsigned res1:2; + unsigned vid:8; + unsigned iddval:8; + unsigned idddiv:2; + unsigned res2:31; + unsigned en:1; + } pstatedef2; unsigned long long val; }; @@ -48,6 +58,10 @@ static int get_did(union core_pstate pstate) { int t; + /* Fam 1Ah onward do not use did */ + if (cpupower_cpu_info.family >= 0x1A) + return 0; + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) t = pstate.pstatedef.did; else if (cpupower_cpu_info.family == 0x12) @@ -61,12 +75,18 @@ static int get_did(union core_pstate pstate) static int get_cof(union core_pstate pstate) { int t; - int fid, did, cof; + int fid, did, cof = 0; did = get_did(pstate); if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) { - fid = pstate.pstatedef.fid; - cof = 200 * fid / did; + if (cpupower_cpu_info.family >= 0x1A) { + fid = pstate.pstatedef2.fid; + if (fid > 0x0f) + cof = (fid * 5); + } else { + fid = pstate.pstatedef.fid; + cof = 200 * fid / did; + } } else { t = 0x10; fid = pstate.pstate.fid; @@ -157,6 +177,8 @@ enum amd_pstate_value { AMD_PSTATE_HIGHEST_PERF, AMD_PSTATE_MAX_FREQ, AMD_PSTATE_LOWEST_NONLINEAR_FREQ, + AMD_PSTATE_HW_PREFCORE, + AMD_PSTATE_PREFCORE_RANKING, MAX_AMD_PSTATE_VALUE_READ_FILES, }; @@ -164,6 +186,8 @@ static const char *amd_pstate_value_files[MAX_AMD_PSTATE_VALUE_READ_FILES] = { [AMD_PSTATE_HIGHEST_PERF] = "amd_pstate_highest_perf", [AMD_PSTATE_MAX_FREQ] = "amd_pstate_max_freq", [AMD_PSTATE_LOWEST_NONLINEAR_FREQ] = "amd_pstate_lowest_nonlinear_freq", + [AMD_PSTATE_HW_PREFCORE] = "amd_pstate_hw_prefcore", + [AMD_PSTATE_PREFCORE_RANKING] = "amd_pstate_prefcore_ranking", }; static unsigned long amd_pstate_get_data(unsigned int cpu, @@ -195,7 +219,9 @@ void amd_pstate_boost_init(unsigned int cpu, int *support, int *active) void amd_pstate_show_perf_and_freq(unsigned int cpu, int no_rounding) { - printf(_(" AMD PSTATE Highest Performance: %lu. Maximum Frequency: "), + + printf(_(" amd-pstate limits:\n")); + printf(_(" Highest Performance: %lu. Maximum Frequency: "), amd_pstate_get_data(cpu, AMD_PSTATE_HIGHEST_PERF)); /* * If boost isn't active, the cpuinfo_max doesn't indicate real max @@ -204,22 +230,26 @@ void amd_pstate_show_perf_and_freq(unsigned int cpu, int no_rounding) print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_MAX_FREQ), no_rounding); printf(".\n"); - printf(_(" AMD PSTATE Nominal Performance: %lu. Nominal Frequency: "), + printf(_(" Nominal Performance: %lu. Nominal Frequency: "), acpi_cppc_get_data(cpu, NOMINAL_PERF)); print_speed(acpi_cppc_get_data(cpu, NOMINAL_FREQ) * 1000, no_rounding); printf(".\n"); - printf(_(" AMD PSTATE Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: "), + printf(_(" Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: "), acpi_cppc_get_data(cpu, LOWEST_NONLINEAR_PERF)); print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_LOWEST_NONLINEAR_FREQ), no_rounding); printf(".\n"); - printf(_(" AMD PSTATE Lowest Performance: %lu. Lowest Frequency: "), + printf(_(" Lowest Performance: %lu. Lowest Frequency: "), acpi_cppc_get_data(cpu, LOWEST_PERF)); print_speed(acpi_cppc_get_data(cpu, LOWEST_FREQ) * 1000, no_rounding); printf(".\n"); + + printf(_(" Preferred Core Support: %lu. Preferred Core Ranking: %lu.\n"), + amd_pstate_get_data(cpu, AMD_PSTATE_HW_PREFCORE), + amd_pstate_get_data(cpu, AMD_PSTATE_PREFCORE_RANKING)); } /* AMD P-State Helper Functions ************************************/ diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c index 075e766ff1f3..ad493157f826 100644 --- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c +++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c @@ -6,6 +6,7 @@ */ +#include <errno.h> #include <stdio.h> #include <unistd.h> #include <stdlib.h> @@ -35,7 +36,7 @@ static unsigned int avail_monitors; static char *progname; enum operation_mode_e { list = 1, show, show_all }; -static int mode; +static enum operation_mode_e mode; static int interval = 1; static char *show_monitors_param; static struct cpupower_topology cpu_top; @@ -91,7 +92,11 @@ int fill_string_with_spaces(char *s, int n) return 0; } -#define MAX_COL_WIDTH 6 +#define MAX_COL_WIDTH 6 +#define TOPOLOGY_DEPTH_PKG 3 +#define TOPOLOGY_DEPTH_CORE 2 +#define TOPOLOGY_DEPTH_CPU 1 + void print_header(int topology_depth) { int unsigned mon; @@ -113,12 +118,19 @@ void print_header(int topology_depth) } printf("\n"); - if (topology_depth > 2) + switch (topology_depth) { + case TOPOLOGY_DEPTH_PKG: printf(" PKG|"); - if (topology_depth > 1) + break; + case TOPOLOGY_DEPTH_CORE: printf("CORE|"); - if (topology_depth > 0) + break; + case TOPOLOGY_DEPTH_CPU: printf(" CPU|"); + break; + default: + return; + } for (mon = 0; mon < avail_monitors; mon++) { if (mon != 0) @@ -152,12 +164,19 @@ void print_results(int topology_depth, int cpu) cpu_top.core_info[cpu].pkg == -1) return; - if (topology_depth > 2) + switch (topology_depth) { + case TOPOLOGY_DEPTH_PKG: printf("%4d|", cpu_top.core_info[cpu].pkg); - if (topology_depth > 1) + break; + case TOPOLOGY_DEPTH_CORE: printf("%4d|", cpu_top.core_info[cpu].core); - if (topology_depth > 0) + break; + case TOPOLOGY_DEPTH_CPU: printf("%4d|", cpu_top.core_info[cpu].cpu); + break; + default: + return; + } for (mon = 0; mon < avail_monitors; mon++) { if (mon != 0) @@ -294,7 +313,10 @@ int fork_it(char **argv) if (!child_pid) { /* child */ - execvp(argv[0], argv); + if (execvp(argv[0], argv) == -1) { + printf("Invalid monitor command %s\n", argv[0]); + exit(errno); + } } else { /* parent */ if (child_pid == -1) { @@ -423,11 +445,13 @@ int cmd_monitor(int argc, char **argv) if (avail_monitors == 0) { printf(_("No HW Cstate monitors found\n")); + cpu_topology_release(cpu_top); return 1; } if (mode == list) { list_monitors(); + cpu_topology_release(cpu_top); exit(EXIT_SUCCESS); } @@ -448,15 +472,15 @@ int cmd_monitor(int argc, char **argv) /* ToDo: Topology parsing needs fixing first to do this more generically */ if (cpu_top.pkgs > 1) - print_header(3); + print_header(TOPOLOGY_DEPTH_PKG); else - print_header(1); + print_header(TOPOLOGY_DEPTH_CPU); for (cpu = 0; cpu < cpu_count; cpu++) { if (cpu_top.pkgs > 1) - print_results(3, cpu); + print_results(TOPOLOGY_DEPTH_PKG, cpu); else - print_results(1, cpu); + print_results(TOPOLOGY_DEPTH_CPU, cpu); } for (num = 0; num < avail_monitors; num++) { diff --git a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c index 55e55b6b42f9..f5a2a326b1b7 100644 --- a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c @@ -117,7 +117,7 @@ static int hsw_ext_start(void) for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { - hsw_ext_get_count(num, &val, cpu); + is_valid[cpu] = !hsw_ext_get_count(num, &val, cpu); previous_count[num][cpu] = val; } } @@ -134,7 +134,7 @@ static int hsw_ext_stop(void) for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { - is_valid[cpu] = !hsw_ext_get_count(num, &val, cpu); + is_valid[cpu] |= !hsw_ext_get_count(num, &val, cpu); current_count[num][cpu] = val; } } diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c index ae6af354a81d..73b6b10cbdd2 100644 --- a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c +++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c @@ -33,7 +33,7 @@ static int mperf_get_count_percent(unsigned int self_id, double *percent, unsigned int cpu); static int mperf_get_count_freq(unsigned int id, unsigned long long *count, unsigned int cpu); -static struct timespec time_start, time_end; +static struct timespec *time_start, *time_end; static cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = { { @@ -148,7 +148,7 @@ static int mperf_measure_stats(unsigned int cpu) ret = get_aperf_mperf(cpu, &aval, &mval); aperf_current_count[cpu] = aval; mperf_current_count[cpu] = mval; - is_valid[cpu] = !ret; + is_valid[cpu] |= !ret; return 0; } @@ -174,7 +174,7 @@ static int mperf_get_count_percent(unsigned int id, double *percent, dprint("%s: TSC Ref - mperf_diff: %llu, tsc_diff: %llu\n", mperf_cstates[id].name, mperf_diff, tsc_diff); } else if (max_freq_mode == MAX_FREQ_SYSFS) { - timediff = max_frequency * timespec_diff_us(time_start, time_end); + timediff = max_frequency * timespec_diff_us(time_start[cpu], time_end[cpu]); *percent = 100.0 * mperf_diff / timediff; dprint("%s: MAXFREQ - mperf_diff: %llu, time_diff: %llu\n", mperf_cstates[id].name, mperf_diff, timediff); @@ -207,7 +207,7 @@ static int mperf_get_count_freq(unsigned int id, unsigned long long *count, if (max_freq_mode == MAX_FREQ_TSC_REF) { /* Calculate max_freq from TSC count */ tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu]; - time_diff = timespec_diff_us(time_start, time_end); + time_diff = timespec_diff_us(time_start[cpu], time_end[cpu]); max_frequency = tsc_diff / time_diff; } @@ -226,9 +226,8 @@ static int mperf_start(void) { int cpu; - clock_gettime(CLOCK_REALTIME, &time_start); - for (cpu = 0; cpu < cpu_count; cpu++) { + clock_gettime(CLOCK_REALTIME, &time_start[cpu]); mperf_get_tsc(&tsc_at_measure_start[cpu]); mperf_init_stats(cpu); } @@ -243,9 +242,9 @@ static int mperf_stop(void) for (cpu = 0; cpu < cpu_count; cpu++) { mperf_measure_stats(cpu); mperf_get_tsc(&tsc_at_measure_end[cpu]); + clock_gettime(CLOCK_REALTIME, &time_end[cpu]); } - clock_gettime(CLOCK_REALTIME, &time_end); return 0; } @@ -349,6 +348,8 @@ struct cpuidle_monitor *mperf_register(void) aperf_current_count = calloc(cpu_count, sizeof(unsigned long long)); tsc_at_measure_start = calloc(cpu_count, sizeof(unsigned long long)); tsc_at_measure_end = calloc(cpu_count, sizeof(unsigned long long)); + time_start = calloc(cpu_count, sizeof(struct timespec)); + time_end = calloc(cpu_count, sizeof(struct timespec)); mperf_monitor.name_len = strlen(mperf_monitor.name); return &mperf_monitor; } @@ -361,6 +362,8 @@ void mperf_unregister(void) free(aperf_current_count); free(tsc_at_measure_start); free(tsc_at_measure_end); + free(time_start); + free(time_end); free(is_valid); } diff --git a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c index 16eaf006f61f..6b1733782ffa 100644 --- a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c @@ -151,7 +151,7 @@ static int nhm_stop(void) for (num = 0; num < NHM_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { - is_valid[cpu] = !nhm_get_count(num, &val, cpu); + is_valid[cpu] |= !nhm_get_count(num, &val, cpu); current_count[num][cpu] = val; } } diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c index 811d63ab17a7..5969b88a85b4 100644 --- a/tools/power/cpupower/utils/idle_monitor/snb_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c @@ -115,7 +115,7 @@ static int snb_start(void) for (num = 0; num < SNB_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { - snb_get_count(num, &val, cpu); + is_valid[cpu] = !snb_get_count(num, &val, cpu); previous_count[num][cpu] = val; } } @@ -132,7 +132,7 @@ static int snb_stop(void) for (num = 0; num < SNB_CSTATE_COUNT; num++) { for (cpu = 0; cpu < cpu_count; cpu++) { - is_valid[cpu] = !snb_get_count(num, &val, cpu); + is_valid[cpu] |= !snb_get_count(num, &val, cpu); current_count[num][cpu] = val; } } |