From 4617721c502b2ddaa4e324e86da4997edf738fa5 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 2 Sep 2026 09:55:01 -0400 Subject: ftrace: Synchronize the initialization of ftrace_ops There's some internal state that ftrace_ops needs to have set, but since it can be declared outside of the ftrace.c code, it calls ftrace_ops_init() on the ops in every global function. The issue is that if two tasks call it on the same ops at the same time it is possible to have the initialization of one corrupt the initialization of the other call. Create a ops_mutex to use to synchronize every initialization of the ftrace_ops. The mutex is taken within checking the ftrace_ops flag that states it was initializied but the flag is checked again after the mutex has been taken. Checking first outside the mutex allows it to shortcut having to take the mutex. But then the check needs to be done again after the mute is taken in case of races. Cc: stable@vger.kernel.org Link: https://patch.msgid.link/20260902095501.6b59af20@gandalf.local.home Fixes: f04f24fb7e48d ("ftrace, kprobes: Fix a deadlock on ftrace_regex_lock") Reported-by: sashiko-bot@kernel.org Close: https://lore.kernel.org/all/20260829025528.49A831F000E9@smtp.kernel.org/ Signed-off-by: Steven Rostedt --- tools/power/cpupower/.gitignore | 29 + tools/power/cpupower/Makefile | 416 +++++++++ tools/power/cpupower/README | 215 +++++ tools/power/cpupower/TODO | 24 + tools/power/cpupower/bench/Makefile | 48 + tools/power/cpupower/bench/README-BENCH | 124 +++ tools/power/cpupower/bench/benchmark.c | 181 ++++ tools/power/cpupower/bench/benchmark.h | 16 + tools/power/cpupower/bench/config.h | 23 + tools/power/cpupower/bench/cpufreq-bench_plot.sh | 91 ++ tools/power/cpupower/bench/cpufreq-bench_script.sh | 88 ++ tools/power/cpupower/bench/example.cfg | 11 + tools/power/cpupower/bench/main.c | 189 ++++ tools/power/cpupower/bench/parse.c | 230 +++++ tools/power/cpupower/bench/parse.h | 40 + tools/power/cpupower/bench/system.c | 179 ++++ tools/power/cpupower/bench/system.h | 16 + tools/power/cpupower/bindings/python/.gitignore | 7 + tools/power/cpupower/bindings/python/Makefile | 43 + tools/power/cpupower/bindings/python/README | 87 ++ .../cpupower/bindings/python/raw_pylibcpupower.swg | 252 ++++++ .../bindings/python/test_raw_pylibcpupower.py | 58 ++ tools/power/cpupower/cpupower-completion.sh | 128 +++ tools/power/cpupower/cpupower-service.conf | 37 + tools/power/cpupower/cpupower.service.in | 16 + tools/power/cpupower/cpupower.sh | 32 + tools/power/cpupower/debug/i386/Makefile | 42 + tools/power/cpupower/debug/i386/centrino-decode.c | 112 +++ tools/power/cpupower/debug/i386/dump_psb.c | 194 ++++ tools/power/cpupower/debug/i386/intel_gsic.c | 77 ++ .../power/cpupower/debug/i386/powernow-k8-decode.c | 95 ++ tools/power/cpupower/debug/kernel/Makefile | 23 + .../power/cpupower/debug/kernel/cpufreq-test_tsc.c | 111 +++ tools/power/cpupower/debug/x86_64/Makefile | 31 + tools/power/cpupower/lib/acpi_cppc.c | 59 ++ tools/power/cpupower/lib/acpi_cppc.h | 21 + tools/power/cpupower/lib/cpufreq.c | 803 +++++++++++++++++ tools/power/cpupower/lib/cpufreq.h | 230 +++++ tools/power/cpupower/lib/cpuidle.c | 387 ++++++++ tools/power/cpupower/lib/cpuidle.h | 26 + tools/power/cpupower/lib/cpupower.c | 251 ++++++ tools/power/cpupower/lib/cpupower.h | 39 + tools/power/cpupower/lib/cpupower_intern.h | 12 + tools/power/cpupower/lib/powercap.c | 307 +++++++ tools/power/cpupower/lib/powercap.h | 54 ++ tools/power/cpupower/man/cpupower-frequency-info.1 | 86 ++ tools/power/cpupower/man/cpupower-frequency-set.1 | 52 ++ tools/power/cpupower/man/cpupower-idle-info.1 | 91 ++ tools/power/cpupower/man/cpupower-idle-set.1 | 79 ++ tools/power/cpupower/man/cpupower-info.1 | 26 + tools/power/cpupower/man/cpupower-monitor.1 | 195 ++++ tools/power/cpupower/man/cpupower-powercap-info.1 | 25 + tools/power/cpupower/man/cpupower-set.1 | 100 +++ tools/power/cpupower/man/cpupower.1 | 72 ++ tools/power/cpupower/po/cs.po | 944 ++++++++++++++++++++ tools/power/cpupower/po/de.po | 977 ++++++++++++++++++++ tools/power/cpupower/po/fr.po | 947 ++++++++++++++++++++ tools/power/cpupower/po/it.po | 961 ++++++++++++++++++++ tools/power/cpupower/po/ka.po | 983 +++++++++++++++++++++ tools/power/cpupower/po/pt.po | 957 ++++++++++++++++++++ tools/power/cpupower/po/zh_CN.po | 942 ++++++++++++++++++++ tools/power/cpupower/utils/builtin.h | 15 + tools/power/cpupower/utils/cpufreq-info.c | 694 +++++++++++++++ tools/power/cpupower/utils/cpufreq-set.c | 337 +++++++ tools/power/cpupower/utils/cpuidle-info.c | 215 +++++ tools/power/cpupower/utils/cpuidle-set.c | 185 ++++ tools/power/cpupower/utils/cpupower-info.c | 112 +++ tools/power/cpupower/utils/cpupower-set.c | 171 ++++ tools/power/cpupower/utils/cpupower.c | 246 ++++++ tools/power/cpupower/utils/helpers/amd.c | 256 ++++++ tools/power/cpupower/utils/helpers/bitmask.c | 293 ++++++ tools/power/cpupower/utils/helpers/bitmask.h | 34 + tools/power/cpupower/utils/helpers/cppc.c | 56 ++ tools/power/cpupower/utils/helpers/cpuid.c | 213 +++++ tools/power/cpupower/utils/helpers/helpers.h | 226 +++++ tools/power/cpupower/utils/helpers/misc.c | 330 +++++++ tools/power/cpupower/utils/helpers/msr.c | 88 ++ tools/power/cpupower/utils/helpers/pci.c | 63 ++ tools/power/cpupower/utils/helpers/sysfs.c | 471 ++++++++++ tools/power/cpupower/utils/helpers/sysfs.h | 39 + tools/power/cpupower/utils/helpers/topology.c | 21 + .../cpupower/utils/idle_monitor/amd_fam14h_idle.c | 334 +++++++ .../cpupower/utils/idle_monitor/cpuidle_sysfs.c | 212 +++++ .../cpupower/utils/idle_monitor/cpupower-monitor.c | 488 ++++++++++ .../cpupower/utils/idle_monitor/cpupower-monitor.h | 95 ++ .../cpupower/utils/idle_monitor/hsw_ext_idle.c | 194 ++++ .../cpupower/utils/idle_monitor/idle_monitors.def | 9 + .../cpupower/utils/idle_monitor/idle_monitors.h | 16 + .../cpupower/utils/idle_monitor/mperf_monitor.c | 382 ++++++++ tools/power/cpupower/utils/idle_monitor/nhm_idle.c | 215 +++++ .../cpupower/utils/idle_monitor/rapl_monitor.c | 148 ++++ tools/power/cpupower/utils/idle_monitor/snb_idle.c | 199 +++++ tools/power/cpupower/utils/powercap-info.c | 115 +++ tools/power/cpupower/utils/version-gen.sh | 36 + 94 files changed, 19399 insertions(+) create mode 100644 tools/power/cpupower/.gitignore create mode 100644 tools/power/cpupower/Makefile create mode 100644 tools/power/cpupower/README create mode 100644 tools/power/cpupower/TODO create mode 100644 tools/power/cpupower/bench/Makefile create mode 100644 tools/power/cpupower/bench/README-BENCH create mode 100644 tools/power/cpupower/bench/benchmark.c create mode 100644 tools/power/cpupower/bench/benchmark.h create mode 100644 tools/power/cpupower/bench/config.h create mode 100644 tools/power/cpupower/bench/cpufreq-bench_plot.sh create mode 100644 tools/power/cpupower/bench/cpufreq-bench_script.sh create mode 100644 tools/power/cpupower/bench/example.cfg create mode 100644 tools/power/cpupower/bench/main.c create mode 100644 tools/power/cpupower/bench/parse.c create mode 100644 tools/power/cpupower/bench/parse.h create mode 100644 tools/power/cpupower/bench/system.c create mode 100644 tools/power/cpupower/bench/system.h create mode 100644 tools/power/cpupower/bindings/python/.gitignore create mode 100644 tools/power/cpupower/bindings/python/Makefile create mode 100644 tools/power/cpupower/bindings/python/README create mode 100644 tools/power/cpupower/bindings/python/raw_pylibcpupower.swg create mode 100755 tools/power/cpupower/bindings/python/test_raw_pylibcpupower.py create mode 100644 tools/power/cpupower/cpupower-completion.sh create mode 100644 tools/power/cpupower/cpupower-service.conf create mode 100644 tools/power/cpupower/cpupower.service.in create mode 100644 tools/power/cpupower/cpupower.sh create mode 100644 tools/power/cpupower/debug/i386/Makefile create mode 100644 tools/power/cpupower/debug/i386/centrino-decode.c create mode 100644 tools/power/cpupower/debug/i386/dump_psb.c create mode 100644 tools/power/cpupower/debug/i386/intel_gsic.c create mode 100644 tools/power/cpupower/debug/i386/powernow-k8-decode.c create mode 100644 tools/power/cpupower/debug/kernel/Makefile create mode 100644 tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c create mode 100644 tools/power/cpupower/debug/x86_64/Makefile create mode 100644 tools/power/cpupower/lib/acpi_cppc.c create mode 100644 tools/power/cpupower/lib/acpi_cppc.h create mode 100644 tools/power/cpupower/lib/cpufreq.c create mode 100644 tools/power/cpupower/lib/cpufreq.h create mode 100644 tools/power/cpupower/lib/cpuidle.c create mode 100644 tools/power/cpupower/lib/cpuidle.h create mode 100644 tools/power/cpupower/lib/cpupower.c create mode 100644 tools/power/cpupower/lib/cpupower.h create mode 100644 tools/power/cpupower/lib/cpupower_intern.h create mode 100644 tools/power/cpupower/lib/powercap.c create mode 100644 tools/power/cpupower/lib/powercap.h create mode 100644 tools/power/cpupower/man/cpupower-frequency-info.1 create mode 100644 tools/power/cpupower/man/cpupower-frequency-set.1 create mode 100644 tools/power/cpupower/man/cpupower-idle-info.1 create mode 100644 tools/power/cpupower/man/cpupower-idle-set.1 create mode 100644 tools/power/cpupower/man/cpupower-info.1 create mode 100644 tools/power/cpupower/man/cpupower-monitor.1 create mode 100644 tools/power/cpupower/man/cpupower-powercap-info.1 create mode 100644 tools/power/cpupower/man/cpupower-set.1 create mode 100644 tools/power/cpupower/man/cpupower.1 create mode 100644 tools/power/cpupower/po/cs.po create mode 100644 tools/power/cpupower/po/de.po create mode 100644 tools/power/cpupower/po/fr.po create mode 100644 tools/power/cpupower/po/it.po create mode 100644 tools/power/cpupower/po/ka.po create mode 100644 tools/power/cpupower/po/pt.po create mode 100644 tools/power/cpupower/po/zh_CN.po create mode 100644 tools/power/cpupower/utils/builtin.h create mode 100644 tools/power/cpupower/utils/cpufreq-info.c create mode 100644 tools/power/cpupower/utils/cpufreq-set.c create mode 100644 tools/power/cpupower/utils/cpuidle-info.c create mode 100644 tools/power/cpupower/utils/cpuidle-set.c create mode 100644 tools/power/cpupower/utils/cpupower-info.c create mode 100644 tools/power/cpupower/utils/cpupower-set.c create mode 100644 tools/power/cpupower/utils/cpupower.c create mode 100644 tools/power/cpupower/utils/helpers/amd.c create mode 100644 tools/power/cpupower/utils/helpers/bitmask.c create mode 100644 tools/power/cpupower/utils/helpers/bitmask.h create mode 100644 tools/power/cpupower/utils/helpers/cppc.c create mode 100644 tools/power/cpupower/utils/helpers/cpuid.c create mode 100644 tools/power/cpupower/utils/helpers/helpers.h create mode 100644 tools/power/cpupower/utils/helpers/misc.c create mode 100644 tools/power/cpupower/utils/helpers/msr.c create mode 100644 tools/power/cpupower/utils/helpers/pci.c create mode 100644 tools/power/cpupower/utils/helpers/sysfs.c create mode 100644 tools/power/cpupower/utils/helpers/sysfs.h create mode 100644 tools/power/cpupower/utils/helpers/topology.c create mode 100644 tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c create mode 100644 tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c create mode 100644 tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c create mode 100644 tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h create mode 100644 tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c create mode 100644 tools/power/cpupower/utils/idle_monitor/idle_monitors.def create mode 100644 tools/power/cpupower/utils/idle_monitor/idle_monitors.h create mode 100644 tools/power/cpupower/utils/idle_monitor/mperf_monitor.c create mode 100644 tools/power/cpupower/utils/idle_monitor/nhm_idle.c create mode 100644 tools/power/cpupower/utils/idle_monitor/rapl_monitor.c create mode 100644 tools/power/cpupower/utils/idle_monitor/snb_idle.c create mode 100644 tools/power/cpupower/utils/powercap-info.c create mode 100755 tools/power/cpupower/utils/version-gen.sh (limited to 'tools/power/cpupower') diff --git a/tools/power/cpupower/.gitignore b/tools/power/cpupower/.gitignore new file mode 100644 index 000000000..7677329c4 --- /dev/null +++ b/tools/power/cpupower/.gitignore @@ -0,0 +1,29 @@ +# SPDX-License-Identifier: GPL-2.0-only +.libs +libcpupower.so +libcpupower.so.* +build/ccdv +cpufreq-info +cpufreq-set +cpufreq-aperf +lib/.libs +lib/cpufreq.lo +lib/cpufreq.o +lib/proc.lo +lib/proc.o +lib/sysfs.lo +lib/sysfs.o +po/cpupowerutils.pot +po/*.gmo +utils/cpufreq-info.o +utils/cpufreq-set.o +utils/cpufreq-aperf.o +cpupower +bench/cpufreq-bench +debug/kernel/Module.symvers +debug/i386/centrino-decode +debug/i386/dump_psb +debug/i386/intel_gsic +debug/i386/powernow-k8-decode +debug/x86_64/centrino-decode +debug/x86_64/powernow-k8-decode diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile new file mode 100644 index 000000000..ab428e336 --- /dev/null +++ b/tools/power/cpupower/Makefile @@ -0,0 +1,416 @@ +# SPDX-License-Identifier: GPL-2.0-only +# Makefile for cpupower +# +# Copyright (C) 2005,2006 Dominik Brodowski +# Copyright (C) 2025 Francesco Poli +# +# Based largely on the Makefile for udev by: +# +# Copyright (C) 2003,2004 Greg Kroah-Hartman +# +OUTPUT=./ +ifeq ("$(origin O)", "command line") + OUTPUT := $(O)/ +endif + +ifneq ($(OUTPUT),) +# check that the output directory actually exists +OUTDIR := $(shell cd $(OUTPUT) && pwd) +$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) +endif + + +# --- CONFIGURATION BEGIN --- + +# Set the following to `true' to make a unstripped, unoptimized +# binary. Leave this set to `false' for production use. +DEBUG ?= true + +# make the build silent. Set this to something else to make it noisy again. +V ?= false + +# Internationalization support (output in different languages). +# Requires gettext. +NLS ?= true + +# Set the following to 'true' to build/install the +# cpufreq-bench benchmarking tool +CPUFREQ_BENCH ?= true + +# Build the code, including libraries, statically. +export STATIC ?= false + +# Prefix to the directories we're installing to +DESTDIR ?= + +# --- CONFIGURATION END --- + + + +# Package-related definitions. Distributions can modify the version +# and _should_ modify the PACKAGE_BUGREPORT definition + +VERSION:= $(shell ./utils/version-gen.sh) +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 zh_CN + + +# Directory definitions. These are default and most probably +# do not need to be changed. Please note that DESTDIR is +# added in front of any of them + +bindir ?= /usr/bin +sbindir ?= /usr/sbin +mandir ?= /usr/man +libdir ?= /usr/lib +libexecdir ?= /usr/libexec +unitdir ?= /usr/lib/systemd/system +includedir ?= /usr/include +localedir ?= /usr/share/locale +docdir ?= /usr/share/doc/packages/cpupower +confdir ?= /etc/ +bash_completion_dir ?= /usr/share/bash-completion/completions + +# Toolchain: what tools do we use, and what options do they need: + +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- +ifneq ($(CROSS), ) +CC = $(CROSS)gcc +LD = $(CROSS)gcc +AR = $(CROSS)ar +STRIP = $(CROSS)strip +RANLIB = $(CROSS)ranlib +else +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 +# + +GMO_FILES = ${shell for HLANG in ${LANGUAGES}; do echo $(OUTPUT)po/$$HLANG.gmo; done;} + +export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS + +# check if compiler option is supported +cc-supports = ${shell if $(CC) ${1} -S -o /dev/null -x c /dev/null > /dev/null 2>&1; then echo "$(1)"; fi;} + +# use '-Os' optimization if available, else use -O2 +OPTIMIZATION := $(call cc-supports,-Os,-O2) + +WARNINGS := -Wall -Wchar-subscripts -Wpointer-arith -Wsign-compare +WARNINGS += $(call cc-supports,-Wno-pointer-sign) +WARNINGS += $(call cc-supports,-Wdeclaration-after-statement) +WARNINGS += -Wshadow + +override CFLAGS += -DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PACKAGE)\" \ + -DPACKAGE_BUGREPORT=\"$(PACKAGE_BUGREPORT)\" -D_GNU_SOURCE + +UTIL_OBJS = utils/helpers/amd.o utils/helpers/msr.o \ + utils/helpers/sysfs.o utils/helpers/misc.o utils/helpers/cpuid.o \ + utils/helpers/pci.o utils/helpers/bitmask.o utils/helpers/cppc.o \ + utils/idle_monitor/nhm_idle.o utils/idle_monitor/snb_idle.o \ + utils/idle_monitor/hsw_ext_idle.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/idle_monitor/rapl_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/cpuidle-set.o utils/powercap-info.o + +UTIL_SRC := $(UTIL_OBJS:.o=.c) + +UTIL_OBJS := $(addprefix $(OUTPUT),$(UTIL_OBJS)) + +UTIL_HEADERS = utils/helpers/helpers.h utils/idle_monitor/cpupower-monitor.h \ + utils/helpers/bitmask.h \ + utils/idle_monitor/idle_monitors.h utils/idle_monitor/idle_monitors.def + +LIB_HEADERS = lib/cpufreq.h lib/cpupower.h lib/cpuidle.h lib/acpi_cppc.h \ + lib/powercap.h +LIB_SRC = lib/cpufreq.c lib/cpupower.c lib/cpuidle.c lib/acpi_cppc.c \ + lib/powercap.c +LIB_OBJS = lib/cpufreq.o lib/cpupower.o lib/cpuidle.o lib/acpi_cppc.o \ + lib/powercap.o +LIB_OBJS := $(addprefix $(OUTPUT),$(LIB_OBJS)) + +override CFLAGS += -pipe + +ifeq ($(strip $(NLS)),true) + INSTALL_NLS += install-gmo + COMPILE_NLS += create-gmo + override CFLAGS += -DNLS +endif + +ifeq ($(strip $(CPUFREQ_BENCH)),true) + INSTALL_BENCH += install-bench + COMPILE_BENCH += compile-bench +endif + +ifeq ($(strip $(STATIC)),true) + UTIL_OBJS += $(LIB_OBJS) + UTIL_HEADERS += $(LIB_HEADERS) + UTIL_SRC += $(LIB_SRC) +endif + +override CFLAGS += $(WARNINGS) + +ifeq ($(strip $(V)),false) + QUIET=@ + ECHO=@echo +else + QUIET= + ECHO=@\# +endif +export QUIET ECHO + +# if DEBUG is enabled, then we do not strip or optimize +ifeq ($(strip $(DEBUG)),true) + override CFLAGS += -O1 -g -DDEBUG + STRIPCMD = /bin/true -Since_we_are_debugging +else + override CFLAGS += $(OPTIMIZATION) -fomit-frame-pointer + STRIPCMD = $(STRIP) -s --remove-section=.note --remove-section=.comment +endif + + +# the actual make rules + +all: libcpupower $(OUTPUT)cpupower $(COMPILE_NLS) $(COMPILE_BENCH) + +$(OUTPUT)lib/%.o: $(LIB_SRC) $(LIB_HEADERS) + $(ECHO) " CC " $@ + $(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c + +ifeq ($(strip $(STATIC)),true) +LIBCPUPOWER := libcpupower.a +else +LIBCPUPOWER := libcpupower.so.$(LIB_VER) +endif + +$(OUTPUT)$(LIBCPUPOWER): $(LIB_OBJS) +ifeq ($(strip $(STATIC)),true) + $(ECHO) " AR " $@ + $(QUIET) $(AR) rcs $@ $(LIB_OBJS) +else + $(ECHO) " LD " $@ + $(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \ + -Wl,-soname,libcpupower.so.$(LIB_MAJ) $(LIB_OBJS) + @ln -sf $(@F) $(OUTPUT)libcpupower.so + @ln -sf $(@F) $(OUTPUT)libcpupower.so.$(LIB_MAJ) +endif + +libcpupower: $(OUTPUT)$(LIBCPUPOWER) + +# 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 +$(UTIL_OBJS): $(UTIL_HEADERS) + +$(OUTPUT)%.o: %.c + $(ECHO) " CC " $@ + $(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c + +$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)$(LIBCPUPOWER) + $(ECHO) " CC " $@ +ifeq ($(strip $(STATIC)),true) + $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lm -lrt -lpci -L$(OUTPUT) -o $@ +else + $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lm -lcpupower -lrt -lpci -L$(OUTPUT) -o $@ +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 \ + echo -n "Updating $$HLANG "; \ + if msgmerge po/$$HLANG.po $< -o \ + $(OUTPUT)po/$$HLANG.new.po; then \ + mv -f $(OUTPUT)po/$$HLANG.new.po $(OUTPUT)po/$$HLANG.po; \ + else \ + echo "msgmerge for $$HLANG failed!"; \ + rm -f $(OUTPUT)po/$$HLANG.new.po; \ + fi; \ + done; +endif + +compile-bench: $(OUTPUT)$(LIBCPUPOWER) + @V=$(V) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) + +# we compile into subdirectories. if the target directory is not the +# source directory, they might not exists. So we depend the various +# files onto their directories. +DIRECTORY_DEPS = $(LIB_OBJS) $(UTIL_OBJS) $(GMO_FILES) +$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS))) + +# In the second step, we make a rule to actually create these directories +$(sort $(dir $(DIRECTORY_DEPS))): + $(ECHO) " MKDIR " $@ + $(QUIET) $(MKDIR) -p $@ 2>/dev/null + +clean: + -find $(OUTPUT) \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ + | xargs rm -f + -rm -f $(OUTPUT)cpupower + -rm -f $(OUTPUT)libcpupower.a + -rm -f $(OUTPUT)libcpupower.so* + -rm -rf $(OUTPUT)po/*.gmo + -rm -rf $(OUTPUT)po/*.pot + $(MAKE) -C bench O=$(OUTPUT) clean + + +install-lib: libcpupower + $(INSTALL) -d $(DESTDIR)${libdir} +ifeq ($(strip $(STATIC)),true) + $(CP) $(OUTPUT)libcpupower.a $(DESTDIR)${libdir}/ +else + $(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/ +endif + $(INSTALL) -d $(DESTDIR)${includedir} + $(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h + $(INSTALL_DATA) lib/cpuidle.h $(DESTDIR)${includedir}/cpuidle.h + $(INSTALL_DATA) lib/powercap.h $(DESTDIR)${includedir}/powercap.h + +# SYSTEMD=false disables installation of the systemd unit file +SYSTEMD ?= true + +install-systemd: + $(INSTALL) -d $(DESTDIR)${unitdir} + sed 's|___CDIR___|${confdir}|; s|___LDIR___|${libexecdir}|' cpupower.service.in > '$(DESTDIR)${unitdir}/cpupower.service' + $(SETPERM_DATA) '$(DESTDIR)${unitdir}/cpupower.service' + +INSTALL_SYSTEMD := $(if $(filter true,$(strip $(SYSTEMD))),install-systemd) + +install-tools: $(OUTPUT)cpupower $(INSTALL_SYSTEMD) + $(INSTALL) -d $(DESTDIR)${bindir} + $(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-man: + $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1 + $(INSTALL_DATA) -D man/cpupower-frequency-set.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-set.1 + $(INSTALL_DATA) -D man/cpupower-frequency-info.1 $(DESTDIR)${mandir}/man1/cpupower-frequency-info.1 + $(INSTALL_DATA) -D man/cpupower-idle-set.1 $(DESTDIR)${mandir}/man1/cpupower-idle-set.1 + $(INSTALL_DATA) -D man/cpupower-idle-info.1 $(DESTDIR)${mandir}/man1/cpupower-idle-info.1 + $(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1 + $(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1 + $(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1 + $(INSTALL_DATA) -D man/cpupower-powercap-info.1 $(DESTDIR)${mandir}/man1/cpupower-powercap-info.1 + +install-gmo: create-gmo + $(INSTALL) -d $(DESTDIR)${localedir} + for HLANG in $(LANGUAGES); do \ + echo '$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \ + $(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \ + done; + +install-bench: compile-bench + @#DESTDIR must be set from outside to survive + @sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) install + +install: all install-lib install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH) + +uninstall: + - rm -f $(DESTDIR)${libdir}/libcpupower.* + - 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)${unitdir}/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 + - rm -f $(DESTDIR)${mandir}/man1/cpupower-set.1 + - rm -f $(DESTDIR)${mandir}/man1/cpupower-info.1 + - rm -f $(DESTDIR)${mandir}/man1/cpupower-monitor.1 + - rm -f $(DESTDIR)${mandir}/man1/cpupower-powercap-info.1 + - for HLANG in $(LANGUAGES); do \ + rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \ + done; + +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-systemd install-tools install-man install-gmo install uninstall clean help diff --git a/tools/power/cpupower/README b/tools/power/cpupower/README new file mode 100644 index 000000000..9de449469 --- /dev/null +++ b/tools/power/cpupower/README @@ -0,0 +1,215 @@ +The cpupower package consists of the following elements: + +requirements +------------ + +On x86 pciutils is needed at runtime (-lpci). +For compilation pciutils-devel (pci/pci.h) and a gcc version +providing cpuid.h is needed. +For both it's not explicitly checked for (yet). + + +libcpupower +---------- + +"libcpupower" is a library which offers a unified access method for userspace +tools and programs to the cpufreq core and drivers in the Linux kernel. This +allows for code reduction in userspace tools, a clean implementation of +the interaction to the cpufreq core, and support for both the sysfs and proc +interfaces [depending on configuration, see below]. + + +compilation and installation +---------------------------- + +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= + +Example: +$ make O=/home/hedin/prj/cpupower/build + +install +------- + +$ make O= DESTDIR= + +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= 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= + +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 '/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 +------ +Many thanks to Mattia Dongili who wrote the autotoolization and +libtoolization, the manpages and the italian language file for cpupower; +to Dave Jones for his feedback and his dump_psb tool; to Bruno Ducrot for his +powernow-k8-decode and intel_gsic tools as well as the french language file; +and to various others commenting on the previous (pre-)releases of +cpupower. + + + Dominik Brodowski diff --git a/tools/power/cpupower/TODO b/tools/power/cpupower/TODO new file mode 100644 index 000000000..b196a139a --- /dev/null +++ b/tools/power/cpupower/TODO @@ -0,0 +1,24 @@ +ToDos sorted by priority: + +- Use bitmask functions to parse CPU topology more robust + (current implementation has issues on AMD) +- Try to read out boost states and frequencies on Intel +- Somewhere saw the ability to read power consumption of + RAM from HW on Intel SandyBridge -> another monitor? +- Add another c1e debug idle monitor + -> Is by design racy with BIOS, but could be added + with a --force option and some "be careful" messages +- Add cpu_start()/cpu_stop() callbacks for monitor + -> This is to move the per_cpu logic from inside the + monitor to outside it. This can be given higher + priority in fork_it. +- Fork as many processes as there are CPUs in case the + per_cpu_schedule flag is set. + -> Bind forked process to each cpu. + -> Execute start measures via the forked processes on + each cpu. + -> Run test executable in a forked process. + -> Execute stop measures via the forked processes on + each cpu. + This would be ideal as it will not introduce noise in the + tested executable. diff --git a/tools/power/cpupower/bench/Makefile b/tools/power/cpupower/bench/Makefile new file mode 100644 index 000000000..34e589447 --- /dev/null +++ b/tools/power/cpupower/bench/Makefile @@ -0,0 +1,48 @@ +# 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),) + OUTPUT := $(O)/ +endif +endif + +ifeq ($(strip $(STATIC)),true) +LIBS = -L../ -L$(OUTPUT) -lm +OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o \ + $(OUTPUT)../lib/cpufreq.o $(OUTPUT)../lib/cpupower.o +else +LIBS = -L../ -L$(OUTPUT) -lm -lcpupower +OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o +endif + +override CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\" + +$(OUTPUT)%.o : %.c + $(ECHO) " CC " $@ + $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ + +$(OUTPUT)cpufreq-bench: $(OBJS) + $(ECHO) " CC " $@ + $(QUIET) $(CC) -o $@ $(CFLAGS) $(LDFLAGS) $(OBJS) $(LIBS) + +all: $(OUTPUT)cpufreq-bench + +install: $(OUTPUT)cpufreq-bench + mkdir -p $(DESTDIR)/$(sbindir) + mkdir -p $(DESTDIR)/$(bindir) + mkdir -p $(DESTDIR)/$(docdir) + mkdir -p $(DESTDIR)/$(confdir) + install -m 755 $(OUTPUT)cpufreq-bench $(DESTDIR)/$(sbindir)/cpufreq-bench + install -m 755 cpufreq-bench_plot.sh $(DESTDIR)/$(bindir)/cpufreq-bench_plot.sh + install -m 644 README-BENCH $(DESTDIR)/$(docdir)/README-BENCH + install -m 755 cpufreq-bench_script.sh $(DESTDIR)/$(docdir)/cpufreq-bench_script.sh + install -m 644 example.cfg $(DESTDIR)/$(confdir)/cpufreq-bench.conf + +clean: + rm -f $(OUTPUT)*.o + rm -f $(OUTPUT)cpufreq-bench diff --git a/tools/power/cpupower/bench/README-BENCH b/tools/power/cpupower/bench/README-BENCH new file mode 100644 index 000000000..97727aed6 --- /dev/null +++ b/tools/power/cpupower/bench/README-BENCH @@ -0,0 +1,124 @@ +This is cpufreq-bench, a microbenchmark for the cpufreq framework. + +Purpose +======= + +What is this benchmark for: + - Identify worst case performance loss when doing dynamic frequency + scaling using Linux kernel governors + - Identify average reaction time of a governor to CPU load changes + - (Stress) Testing whether a cpufreq low level driver or governor works + as expected + - Identify cpufreq related performance regressions between kernels + - Possibly Real time priority testing? -> what happens if there are + processes with a higher prio than the governor's kernel thread + - ... + +What this benchmark does *not* cover: + - Power saving related regressions (In fact as better the performance + throughput is, the worse the power savings will be, but the first should + mostly count more...) + - Real world (workloads) + + +Description +=========== + +cpufreq-bench helps to test the condition of a given cpufreq governor. +For that purpose, it compares the performance governor to a configured +powersave module. + + +How it works +============ +You can specify load (100% CPU load) and sleep (0% CPU load) times in us which +will be run X time in a row (cycles): + + sleep=25000 + load=25000 + cycles=20 + +This part of the configuration file will create 25ms load/sleep turns, +repeated 20 times. + +Adding this: + sleep_step=25000 + load_step=25000 + rounds=5 +Will increase load and sleep time by 25ms 5 times. +Together you get following test: +25ms load/sleep time repeated 20 times (cycles). +50ms load/sleep time repeated 20 times (cycles). +.. +100ms load/sleep time repeated 20 times (cycles). + +First it is calibrated how long a specific CPU intensive calculation +takes on this machine and needs to be run in a loop using the performance +governor. +Then the above test runs are processed using the performance governor +and the governor to test. The time the calculation really needed +with the dynamic freq scaling governor is compared with the time needed +on full performance and you get the overall performance loss. + + +Example of expected results with ondemand governor: + +This shows expected results of the first two test run rounds from +above config, you there have: + +100% CPU load (load) | 0 % CPU load (sleep) | round + 25 ms | 25 ms | 1 + 50 ms | 50 ms | 2 + +For example if ondemand governor is configured to have a 50ms +sampling rate you get: + +In round 1, ondemand should have rather static 50% load and probably +won't ever switch up (as long as up_threshold is above). + +In round 2, if the ondemand sampling times exactly match the load/sleep +trigger of the cpufreq-bench, you will see no performance loss (compare with +below possible ondemand sample kick ins (1)): + +But if ondemand always kicks in in the middle of the load sleep cycles, it +will always see 50% loads and you get worst performance impact never +switching up (compare with below possible ondemand sample kick ins (2)):: + + 50 50 50 50ms ->time +load -----| |-----| |-----| |-----| + | | | | | | | +sleep |-----| |-----| |-----| |---- + |-----|-----|-----|-----|-----|-----|-----|---- ondemand sampling (1) + 100 0 100 0 100 0 100 load seen by ondemand(%) + |-----|-----|-----|-----|-----|-----|-----|-- ondemand sampling (2) + 50 50 50 50 50 50 50 load seen by ondemand(%) + +You can easily test all kind of load/sleep times and check whether your +governor in average behaves as expected. + + +ToDo +==== + +Provide a gnuplot utility script for easy generation of plots to present +the outcome nicely. + + +cpufreq-bench Command Usage +=========================== +-l, --load= initial load time in us +-s, --sleep= initial sleep time in us +-x, --load-step= time to be added to load time, in us +-y, --sleep-step= time to be added to sleep time, in us +-c, --cpu= CPU Number to use, starting at 0 +-p, --prio= scheduler priority, HIGH, LOW or DEFAULT +-g, --governor= cpufreq governor to test +-n, --cycles= load/sleep cycles to get an average value to compare +-r, --rounds load/sleep rounds +-f, --file= config file to use +-o, --output= output dir, must exist +-v, --verbose verbose output on/off + +Due to the high priority, the application may not be responsible for some time. +After the benchmark, the logfile is saved in OUTPUTDIR/benchmark_TIMESTAMP.log + diff --git a/tools/power/cpupower/bench/benchmark.c b/tools/power/cpupower/bench/benchmark.c new file mode 100644 index 000000000..c7234cf3f --- /dev/null +++ b/tools/power/cpupower/bench/benchmark.c @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* cpufreq-bench CPUFreq microbenchmark + * + * Copyright (C) 2008 Christian Kornacker + */ + +#include +#include +#include + +#include "config.h" +#include "system.h" +#include "benchmark.h" + +/* Print out progress if we log into a file */ +#define show_progress(total_time, progress_time) \ +if (config->output != stdout) { \ + fprintf(stdout, "Progress: %02lu %%\r", \ + (progress_time * 100) / total_time); \ + fflush(stdout); \ +} + +/** + * compute how many rounds of calculation we should do + * to get the given load time + * + * @param load aimed load time in µs + * + * @retval rounds of calculation + **/ + +unsigned int calculate_timespace(long load, struct config *config) +{ + int i; + long long now, then; + unsigned int estimated = GAUGECOUNT; + unsigned int rounds = 0; + unsigned int timed = 0; + + if (config->verbose) + printf("calibrating load of %lius, please wait...\n", load); + + /* get the initial calculation time for a specific number of rounds */ + now = get_time(); + ROUNDS(estimated); + then = get_time(); + + timed = (unsigned int)(then - now); + + /* approximation of the wanted load time by comparing with the + * initial calculation time */ + for (i = 0; i < 4; i++) { + rounds = (unsigned int)(load * estimated / timed); + dprintf("calibrating with %u rounds\n", rounds); + now = get_time(); + ROUNDS(rounds); + then = get_time(); + + timed = (unsigned int)(then - now); + estimated = rounds; + } + if (config->verbose) + printf("calibration done\n"); + + return estimated; +} + +/** + * benchmark + * generates a specific sleep an load time with the performance + * governor and compares the used time for same calculations done + * with the configured powersave governor + * + * @param config config values for the benchmark + * + **/ + +void start_benchmark(struct config *config) +{ + unsigned int _round, cycle; + long long now, then; + long sleep_time = 0, load_time = 0; + long performance_time = 0, powersave_time = 0; + unsigned int calculations; + unsigned long total_time = 0, progress_time = 0; + + sleep_time = config->sleep; + load_time = config->load; + + /* For the progress bar */ + for (_round = 1; _round <= config->rounds; _round++) + total_time += _round * (config->sleep + config->load); + total_time *= 2; /* powersave and performance cycles */ + + for (_round = 0; _round < config->rounds; _round++) { + performance_time = 0LL; + powersave_time = 0LL; + + show_progress(total_time, progress_time); + + /* set the cpufreq governor to "performance" which disables + * P-State switching. */ + if (set_cpufreq_governor("performance", config->cpu) != 0) + return; + + /* calibrate the calculation time. the resulting calculation + * _rounds should produce a load which matches the configured + * load time */ + calculations = calculate_timespace(load_time, config); + + if (config->verbose) + printf("_round %i: doing %u cycles with %u calculations" + " for %lius\n", _round + 1, config->cycles, + calculations, load_time); + + fprintf(config->output, "%u %li %li ", + _round, load_time, sleep_time); + + if (config->verbose) + printf("average: %lius, rps:%li\n", + load_time / calculations, + 1000000 * calculations / load_time); + + /* do some sleep/load cycles with the performance governor */ + for (cycle = 0; cycle < config->cycles; cycle++) { + now = get_time(); + usleep(sleep_time); + ROUNDS(calculations); + then = get_time(); + performance_time += then - now - sleep_time; + if (config->verbose) + printf("performance cycle took %lius, " + "sleep: %lius, " + "load: %lius, rounds: %u\n", + (long)(then - now), sleep_time, + load_time, calculations); + } + fprintf(config->output, "%li ", + performance_time / config->cycles); + + progress_time += sleep_time + load_time; + show_progress(total_time, progress_time); + + /* set the powersave governor which activates P-State switching + * again */ + if (set_cpufreq_governor(config->governor, config->cpu) != 0) + return; + + /* again, do some sleep/load cycles with the + * powersave governor */ + for (cycle = 0; cycle < config->cycles; cycle++) { + now = get_time(); + usleep(sleep_time); + ROUNDS(calculations); + then = get_time(); + powersave_time += then - now - sleep_time; + if (config->verbose) + printf("powersave cycle took %lius, " + "sleep: %lius, " + "load: %lius, rounds: %u\n", + (long)(then - now), sleep_time, + load_time, calculations); + } + + progress_time += sleep_time + load_time; + + /* compare the average sleep/load cycles */ + fprintf(config->output, "%li ", + powersave_time / config->cycles); + fprintf(config->output, "%.3f\n", + performance_time * 100.0 / powersave_time); + fflush(config->output); + + if (config->verbose) + printf("performance is at %.2f%%\n", + performance_time * 100.0 / powersave_time); + + sleep_time += config->sleep_step; + load_time += config->load_step; + } +} diff --git a/tools/power/cpupower/bench/benchmark.h b/tools/power/cpupower/bench/benchmark.h new file mode 100644 index 000000000..bf612de89 --- /dev/null +++ b/tools/power/cpupower/bench/benchmark.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* cpufreq-bench CPUFreq microbenchmark + * + * Copyright (C) 2008 Christian Kornacker + */ + +/* load loop, this schould take about 1 to 2ms to complete */ +#define ROUNDS(x) {unsigned int rcnt; \ + for (rcnt = 0; rcnt < x*1000; rcnt++) { \ + (void)(((int)(pow(rcnt, rcnt) * \ + sqrt(rcnt*7230970)) ^ 7230716) ^ \ + (int)atan2(rcnt, rcnt)); \ + } } \ + + +void start_benchmark(struct config *config); diff --git a/tools/power/cpupower/bench/config.h b/tools/power/cpupower/bench/config.h new file mode 100644 index 000000000..fec5b0b05 --- /dev/null +++ b/tools/power/cpupower/bench/config.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* cpufreq-bench CPUFreq microbenchmark + * + * Copyright (C) 2008 Christian Kornacker + */ + +/* initial loop count for the load calibration */ +#define GAUGECOUNT 1500 + +/* default scheduling policy SCHED_OTHER */ +#define SCHEDULER SCHED_OTHER + +#define PRIORITY_DEFAULT 0 +#define PRIORITY_HIGH sched_get_priority_max(SCHEDULER) +#define PRIORITY_LOW sched_get_priority_min(SCHEDULER) + +/* enable further debug messages */ +#ifdef DEBUG +#define dprintf printf +#else +#define dprintf(...) do { } while (0) +#endif + diff --git a/tools/power/cpupower/bench/cpufreq-bench_plot.sh b/tools/power/cpupower/bench/cpufreq-bench_plot.sh new file mode 100644 index 000000000..f5f8b3c8f --- /dev/null +++ b/tools/power/cpupower/bench/cpufreq-bench_plot.sh @@ -0,0 +1,91 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later + + +# Author/Copyright(c): 2009, Thomas Renninger , Novell Inc. + +# Helper script to easily create nice plots of your cpufreq-bench results + +dir=`mktemp -d` +output_file="cpufreq-bench.png" +global_title="cpufreq-bench plot" +picture_type="jpeg" +file[0]="" + +function usage() +{ + echo "cpufreq-bench_plot.sh [OPTIONS] logfile [measure_title] [logfile [measure_title]] ...]" + echo + echo "Options" + echo " -o output_file" + echo " -t global_title" + echo " -p picture_type [jpeg|gif|png|postscript|...]" + exit 1 +} + +if [ $# -eq 0 ];then + echo "No benchmark results file provided" + echo + usage +fi + +while getopts o:t:p: name ; do + case $name in + o) + output_file="$OPTARG".$picture_type + ;; + t) + global_title="$OPTARG" + ;; + p) + picture_type="$OPTARG" + ;; + ?) + usage + ;; + esac +done +shift $(($OPTIND -1)) + +plots=0 +while [ "$1" ];do + if [ ! -f "$1" ];then + echo "File $1 does not exist" + usage + fi + file[$plots]="$1" + title[$plots]="$2" + # echo "File: ${file[$plots]} - ${title[plots]}" + shift;shift + plots=$((plots + 1)) +done + +echo "set terminal $picture_type" >> $dir/plot_script.gpl +echo "set output \"$output_file\"" >> $dir/plot_script.gpl +echo "set title \"$global_title\"" >> $dir/plot_script.gpl +echo "set xlabel \"sleep/load time\"" >> $dir/plot_script.gpl +echo "set ylabel \"Performance (%)\"" >> $dir/plot_script.gpl + +for((plot=0;plot<$plots;plot++));do + + # Sanity check + ###### I am to dump to get this redirected to stderr/stdout in one awk call... ##### + cat ${file[$plot]} |grep -v "^#" |awk '{if ($2 != $3) printf("Error in measure %d:Load time %s does not equal sleep time %s, plot will not be correct\n", $1, $2, $3); ERR=1}' + ###### I am to dump to get this redirected in one awk call... ##### + + # Parse out load time (which must be equal to sleep time for a plot), divide it by 1000 + # to get ms and parse out the performance in percentage and write it to a temp file for plotting + cat ${file[$plot]} |grep -v "^#" |awk '{printf "%lu %.1f\n",$2/1000, $6}' >$dir/data_$plot + + if [ $plot -eq 0 ];then + echo -n "plot " >> $dir/plot_script.gpl + fi + echo -n "\"$dir/data_$plot\" title \"${title[$plot]}\" with lines" >> $dir/plot_script.gpl + if [ $(($plot + 1)) -ne $plots ];then + echo -n ", " >> $dir/plot_script.gpl + fi +done +echo >> $dir/plot_script.gpl + +gnuplot $dir/plot_script.gpl +rm -r $dir diff --git a/tools/power/cpupower/bench/cpufreq-bench_script.sh b/tools/power/cpupower/bench/cpufreq-bench_script.sh new file mode 100644 index 000000000..785a3679c --- /dev/null +++ b/tools/power/cpupower/bench/cpufreq-bench_script.sh @@ -0,0 +1,88 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0-or-later + + +# Author/Copyright(c): 2009, Thomas Renninger , Novell Inc. + +# Ondemand up_threshold and sampling rate test script for cpufreq-bench +# mircobenchmark. +# Modify the general variables at the top or extend or copy out parts +# if you want to test other things +# + +# Default with latest kernels is 95, before micro account patches +# it was 80, cmp. with git commit 808009131046b62ac434dbc796 +UP_THRESHOLD="60 80 95" +# Depending on the kernel and the HW sampling rate could be restricted +# and cannot be set that low... +# E.g. before git commit cef9615a853ebc4972084f7 one could only set +# min sampling rate of 80000 if CONFIG_HZ=250 +SAMPLING_RATE="20000 80000" + +function measure() +{ + local -i up_threshold_set + local -i sampling_rate_set + + for up_threshold in $UP_THRESHOLD;do + for sampling_rate in $SAMPLING_RATE;do + # Set values in sysfs + echo $up_threshold >/sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold + echo $sampling_rate >/sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate + up_threshold_set=$(cat /sys/devices/system/cpu/cpu0/cpufreq/ondemand/up_threshold) + sampling_rate_set=$(cat /sys/devices/system/cpu/cpu0/cpufreq/ondemand/sampling_rate) + + # Verify set values in sysfs + if [ ${up_threshold_set} -eq ${up_threshold} ];then + echo "up_threshold: $up_threshold, set in sysfs: ${up_threshold_set}" + else + echo "WARNING: Tried to set up_threshold: $up_threshold, set in sysfs: ${up_threshold_set}" + fi + if [ ${sampling_rate_set} -eq ${sampling_rate} ];then + echo "sampling_rate: $sampling_rate, set in sysfs: ${sampling_rate_set}" + else + echo "WARNING: Tried to set sampling_rate: $sampling_rate, set in sysfs: ${sampling_rate_set}" + fi + + # Benchmark + cpufreq-bench -o /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate} + done + done +} + +function create_plots() +{ + local command + + for up_threshold in $UP_THRESHOLD;do + command="cpufreq-bench_plot.sh -o \"sampling_rate_${SAMPLING_RATE}_up_threshold_${up_threshold}\" -t \"Ondemand sampling_rate: ${SAMPLING_RATE} comparison - Up_threshold: $up_threshold %\"" + for sampling_rate in $SAMPLING_RATE;do + command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"sampling_rate = $sampling_rate\"" + done + echo $command + eval "$command" + echo + done + + for sampling_rate in $SAMPLING_RATE;do + command="cpufreq-bench_plot.sh -o \"up_threshold_${UP_THRESHOLD}_sampling_rate_${sampling_rate}\" -t \"Ondemand up_threshold: ${UP_THRESHOLD} % comparison - sampling_rate: $sampling_rate\"" + for up_threshold in $UP_THRESHOLD;do + command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"up_threshold = $up_threshold\"" + done + echo $command + eval "$command" + echo + done + + command="cpufreq-bench_plot.sh -o \"up_threshold_${UP_THRESHOLD}_sampling_rate_${SAMPLING_RATE}\" -t \"Ondemand up_threshold: ${UP_THRESHOLD} and sampling_rate ${SAMPLING_RATE} comparison\"" + for sampling_rate in $SAMPLING_RATE;do + for up_threshold in $UP_THRESHOLD;do + command="${command} /var/log/cpufreq-bench/up_threshold_${up_threshold}_sampling_rate_${sampling_rate}/* \"up_threshold = $up_threshold - sampling_rate = $sampling_rate\"" + done + done + echo "$command" + eval "$command" +} + +measure +create_plots diff --git a/tools/power/cpupower/bench/example.cfg b/tools/power/cpupower/bench/example.cfg new file mode 100644 index 000000000..f91f64360 --- /dev/null +++ b/tools/power/cpupower/bench/example.cfg @@ -0,0 +1,11 @@ +sleep = 50000 +load = 50000 +cpu = 0 +priority = LOW +output = /var/log/cpufreq-bench +sleep_step = 50000 +load_step = 50000 +cycles = 20 +rounds = 40 +verbose = 0 +governor = ondemand diff --git a/tools/power/cpupower/bench/main.c b/tools/power/cpupower/bench/main.c new file mode 100644 index 000000000..429d1b6b8 --- /dev/null +++ b/tools/power/cpupower/bench/main.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* cpufreq-bench CPUFreq microbenchmark + * + * Copyright (C) 2008 Christian Kornacker + */ + +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "system.h" +#include "benchmark.h" + +static struct option long_options[] = { + {"output", 1, 0, 'o'}, + {"sleep", 1, 0, 's'}, + {"load", 1, 0, 'l'}, + {"verbose", 0, 0, 'v'}, + {"cpu", 1, 0, 'c'}, + {"governor", 1, 0, 'g'}, + {"prio", 1, 0, 'p'}, + {"file", 1, 0, 'f'}, + {"cycles", 1, 0, 'n'}, + {"rounds", 1, 0, 'r'}, + {"load-step", 1, 0, 'x'}, + {"sleep-step", 1, 0, 'y'}, + {"help", 0, 0, 'h'}, + {0, 0, 0, 0} +}; + +/******************************************************************* + usage +*******************************************************************/ + +void usage() +{ + printf("usage: ./bench\n"); + printf("Options:\n"); + printf(" -l, --load=\t\tinitial load time in us\n"); + printf(" -s, --sleep=\t\tinitial sleep time in us\n"); + printf(" -x, --load-step=\ttime to be added to load time, in us\n"); + printf(" -y, --sleep-step=\ttime to be added to sleep time, in us\n"); + printf(" -c, --cpu=\t\t\tCPU Nr. to use, starting at 0\n"); + printf(" -p, --prio=\t\t\tscheduler priority, HIGH, LOW or DEFAULT\n"); + printf(" -g, --governor=\t\tcpufreq governor to test\n"); + printf(" -n, --cycles=\t\t\tload/sleep cycles\n"); + printf(" -r, --rounds\t\t\tload/sleep rounds\n"); + printf(" -f, --file=\t\tconfig file to use\n"); + printf(" -o, --output=\t\t\toutput path. Filename will be OUTPUTPATH/benchmark_TIMESTAMP.log\n"); + printf(" -v, --verbose\t\t\t\tverbose output on/off\n"); + printf(" -h, --help\t\t\t\tPrint this help screen\n"); + exit(1); +} + +/******************************************************************* + main +*******************************************************************/ + +int main(int argc, char **argv) +{ + int c; + int option_index = 0; + struct config *config = NULL; + + config = prepare_default_config(); + + if (config == NULL) + return EXIT_FAILURE; + + while (1) { + c = getopt_long (argc, argv, "hg:o:s:l:vc:p:f:n:r:x:y:", + long_options, &option_index); + if (c == -1) + break; + + switch (c) { + case 'o': + if (config->output != NULL) + fclose(config->output); + + config->output = prepare_output(optarg); + + if (config->output == NULL) + return EXIT_FAILURE; + + dprintf("user output path -> %s\n", optarg); + break; + case 's': + sscanf(optarg, "%li", &config->sleep); + dprintf("user sleep time -> %s\n", optarg); + break; + case 'l': + sscanf(optarg, "%li", &config->load); + dprintf("user load time -> %s\n", optarg); + break; + case 'c': + sscanf(optarg, "%u", &config->cpu); + dprintf("user cpu -> %s\n", optarg); + break; + case 'g': + strncpy(config->governor, optarg, 14); + dprintf("user governor -> %s\n", optarg); + break; + case 'p': + if (string_to_prio(optarg) != SCHED_ERR) { + config->prio = string_to_prio(optarg); + dprintf("user prio -> %s\n", optarg); + } else { + if (config != NULL) { + if (config->output != NULL) + fclose(config->output); + free(config); + } + usage(); + } + break; + case 'n': + sscanf(optarg, "%u", &config->cycles); + dprintf("user cycles -> %s\n", optarg); + break; + case 'r': + sscanf(optarg, "%u", &config->rounds); + dprintf("user rounds -> %s\n", optarg); + break; + case 'x': + sscanf(optarg, "%li", &config->load_step); + dprintf("user load_step -> %s\n", optarg); + break; + case 'y': + sscanf(optarg, "%li", &config->sleep_step); + dprintf("user sleep_step -> %s\n", optarg); + break; + case 'f': + if (prepare_config(optarg, config)) + return EXIT_FAILURE; + break; + case 'v': + config->verbose = 1; + dprintf("verbose output enabled\n"); + break; + case 'h': + case '?': + default: + if (config != NULL) { + if (config->output != NULL) + fclose(config->output); + free(config); + } + usage(); + } + } + + if (config->verbose) { + printf("starting benchmark with parameters:\n"); + printf("config:\n\t" + "sleep=%li\n\t" + "load=%li\n\t" + "sleep_step=%li\n\t" + "load_step=%li\n\t" + "cpu=%u\n\t" + "cycles=%u\n\t" + "rounds=%u\n\t" + "governor=%s\n\n", + config->sleep, + config->load, + config->sleep_step, + config->load_step, + config->cpu, + config->cycles, + config->rounds, + config->governor); + } + + prepare_user(config); + prepare_system(config); + start_benchmark(config); + + if (config->output != stdout) + fclose(config->output); + + free(config); + + return EXIT_SUCCESS; +} + diff --git a/tools/power/cpupower/bench/parse.c b/tools/power/cpupower/bench/parse.c new file mode 100644 index 000000000..bd67c758b --- /dev/null +++ b/tools/power/cpupower/bench/parse.c @@ -0,0 +1,230 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* cpufreq-bench CPUFreq microbenchmark + * + * Copyright (C) 2008 Christian Kornacker + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "parse.h" +#include "config.h" + +/** + * converts priority string to priority + * + * @param str string that represents a scheduler priority + * + * @retval priority + * @retval SCHED_ERR when the priority doesn't exit + **/ + +enum sched_prio string_to_prio(const char *str) +{ + if (strncasecmp("high", str, strlen(str)) == 0) + return SCHED_HIGH; + else if (strncasecmp("default", str, strlen(str)) == 0) + return SCHED_DEFAULT; + else if (strncasecmp("low", str, strlen(str)) == 0) + return SCHED_LOW; + else + return SCHED_ERR; +} + +/** + * create and open logfile + * + * @param dir directory in which the logfile should be created + * + * @retval logfile on success + * @retval NULL when the file can't be created + **/ + +FILE *prepare_output(const char *dirname) +{ + FILE *output = NULL; + int len; + char *filename, *filename_tmp; + struct utsname sysdata; + DIR *dir; + + dir = opendir(dirname); + if (dir == NULL) { + if (mkdir(dirname, 0755)) { + perror("mkdir"); + fprintf(stderr, "error: Cannot create dir %s\n", + dirname); + return NULL; + } + } + + len = strlen(dirname) + 30; + filename = malloc(sizeof(char) * len); + if (!filename) { + perror("malloc"); + goto out_dir; + } + + if (uname(&sysdata) == 0) { + len += strlen(sysdata.nodename) + strlen(sysdata.release); + filename_tmp = realloc(filename, sizeof(*filename) * len); + + if (filename_tmp == NULL) { + free(filename); + perror("realloc"); + goto out_dir; + } + + filename = filename_tmp; + snprintf(filename, len - 1, "%s/benchmark_%s_%s_%li.log", + dirname, sysdata.nodename, sysdata.release, time(NULL)); + } else { + snprintf(filename, len - 1, "%s/benchmark_%li.log", + dirname, time(NULL)); + } + + dprintf("logfilename: %s\n", filename); + + output = fopen(filename, "w+"); + if (output == NULL) { + perror("fopen"); + fprintf(stderr, "error: unable to open logfile\n"); + goto out; + } + + fprintf(stdout, "Logfile: %s\n", filename); + + fprintf(output, "#round load sleep performance powersave percentage\n"); +out: + free(filename); +out_dir: + closedir(dir); + return output; +} + +/** + * returns the default config + * + * @retval default config on success + * @retval NULL when the output file can't be created + **/ + +struct config *prepare_default_config() +{ + struct config *config = malloc(sizeof(struct config)); + if (!config) { + perror("malloc"); + return NULL; + } + + dprintf("loading defaults\n"); + + config->sleep = 500000; + config->load = 500000; + config->sleep_step = 500000; + config->load_step = 500000; + config->cycles = 5; + config->rounds = 50; + config->cpu = 0; + config->prio = SCHED_HIGH; + config->verbose = 0; + strncpy(config->governor, "ondemand", sizeof(config->governor)); + + config->output = stdout; + +#ifdef DEFAULT_CONFIG_FILE + if (prepare_config(DEFAULT_CONFIG_FILE, config)) + return NULL; +#endif + return config; +} + +/** + * parses config file and returns the config to the caller + * + * @param path config file name + * + * @retval 1 on error + * @retval 0 on success + **/ + +int prepare_config(const char *path, struct config *config) +{ + size_t len = 0; + char opt[16], val[32], *line = NULL; + FILE *configfile; + + if (config == NULL) { + fprintf(stderr, "error: config is NULL\n"); + return 1; + } + + configfile = fopen(path, "r"); + if (configfile == NULL) { + fprintf(stderr, "error: unable to read configfile: %s, %s\n", + path, strerror(errno)); + free(config); + return 1; + } + + while (getline(&line, &len, configfile) != -1) { + if (line[0] == '#' || line[0] == ' ' || line[0] == '\n') + continue; + + if (sscanf(line, "%14s = %30s", opt, val) < 2) + continue; + + dprintf("parsing: %s -> %s\n", opt, val); + + if (strcmp("sleep", opt) == 0) + sscanf(val, "%li", &config->sleep); + + else if (strcmp("load", opt) == 0) + sscanf(val, "%li", &config->load); + + else if (strcmp("load_step", opt) == 0) + sscanf(val, "%li", &config->load_step); + + else if (strcmp("sleep_step", opt) == 0) + sscanf(val, "%li", &config->sleep_step); + + else if (strcmp("cycles", opt) == 0) + sscanf(val, "%u", &config->cycles); + + else if (strcmp("rounds", opt) == 0) + sscanf(val, "%u", &config->rounds); + + else if (strcmp("verbose", opt) == 0) + sscanf(val, "%u", &config->verbose); + + else if (strcmp("output", opt) == 0) + config->output = prepare_output(val); + + else if (strcmp("cpu", opt) == 0) + sscanf(val, "%u", &config->cpu); + + else if (strcmp("governor", opt) == 0) { + strncpy(config->governor, val, + sizeof(config->governor)); + config->governor[sizeof(config->governor) - 1] = '\0'; + } + + else if (strcmp("priority", opt) == 0) { + if (string_to_prio(val) != SCHED_ERR) + config->prio = string_to_prio(val); + } + } + + free(line); + + return 0; +} diff --git a/tools/power/cpupower/bench/parse.h b/tools/power/cpupower/bench/parse.h new file mode 100644 index 000000000..d5b3e34d7 --- /dev/null +++ b/tools/power/cpupower/bench/parse.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* cpufreq-bench CPUFreq microbenchmark + * + * Copyright (C) 2008 Christian Kornacker + */ + +/* struct that holds the required config parameters */ +struct config +{ + long sleep; /* sleep time in µs */ + long load; /* load time in µs */ + long sleep_step; /* time value which changes the + * sleep time after every round in µs */ + long load_step; /* time value which changes the + * load time after every round in µs */ + unsigned int cycles; /* calculation cycles with the same sleep/load time */ + unsigned int rounds; /* calculation rounds with iterated sleep/load time */ + unsigned int cpu; /* cpu for which the affinity is set */ + char governor[15]; /* cpufreq governor */ + enum sched_prio /* possible scheduler priorities */ + { + SCHED_ERR = -1, + SCHED_HIGH, + SCHED_DEFAULT, + SCHED_LOW + } prio; + + unsigned int verbose; /* verbose output */ + FILE *output; /* logfile */ + char *output_filename; /* logfile name, must be freed at the end + if output != NULL and output != stdout*/ +}; + +enum sched_prio string_to_prio(const char *str); + +FILE *prepare_output(const char *dir); + +int prepare_config(const char *path, struct config *config); +struct config *prepare_default_config(); + diff --git a/tools/power/cpupower/bench/system.c b/tools/power/cpupower/bench/system.c new file mode 100644 index 000000000..40f3679e7 --- /dev/null +++ b/tools/power/cpupower/bench/system.c @@ -0,0 +1,179 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* cpufreq-bench CPUFreq microbenchmark + * + * Copyright (C) 2008 Christian Kornacker + */ + +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include "config.h" +#include "system.h" + +/** + * returns time since epoch in µs + * + * @retval time + **/ + +long long int get_time() +{ + struct timeval now; + + gettimeofday(&now, NULL); + + return (long long int)(now.tv_sec * 1000000LL + now.tv_usec); +} + +/** + * sets the cpufreq governor + * + * @param governor cpufreq governor name + * @param cpu cpu for which the governor should be set + * + * @retval 0 on success + * @retval -1 when failed + **/ + +int set_cpufreq_governor(char *governor, unsigned int cpu) +{ + + dprintf("set %s as cpufreq governor\n", governor); + + if (cpupower_is_cpu_online(cpu) != 1) { + perror("cpufreq_cpu_exists"); + fprintf(stderr, "error: cpu %u does not exist\n", cpu); + return -1; + } + + if (cpufreq_modify_policy_governor(cpu, governor) != 0) { + perror("cpufreq_modify_policy_governor"); + fprintf(stderr, "error: unable to set %s governor\n", governor); + return -1; + } + + return 0; +} + +/** + * sets cpu affinity for the process + * + * @param cpu cpu# to which the affinity should be set + * + * @retval 0 on success + * @retval -1 when setting the affinity failed + **/ + +int set_cpu_affinity(unsigned int cpu) +{ + cpu_set_t cpuset; + + CPU_ZERO(&cpuset); + CPU_SET(cpu, &cpuset); + + dprintf("set affinity to cpu #%u\n", cpu); + + if (sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpuset) < 0) { + perror("sched_setaffinity"); + fprintf(stderr, "warning: unable to set cpu affinity\n"); + return -1; + } + + return 0; +} + +/** + * sets the process priority parameter + * + * @param priority priority value + * + * @retval 0 on success + * @retval -1 when setting the priority failed + **/ + +int set_process_priority(int priority) +{ + struct sched_param param; + + dprintf("set scheduler priority to %i\n", priority); + + param.sched_priority = priority; + + if (sched_setscheduler(0, SCHEDULER, ¶m) < 0) { + perror("sched_setscheduler"); + fprintf(stderr, "warning: unable to set scheduler priority\n"); + return -1; + } + + return 0; +} + +/** + * notifies the user that the benchmark may run some time + * + * @param config benchmark config values + * + **/ + +void prepare_user(const struct config *config) +{ + unsigned long sleep_time = 0; + unsigned long load_time = 0; + unsigned int round; + + for (round = 0; round < config->rounds; round++) { + sleep_time += 2 * config->cycles * + (config->sleep + config->sleep_step * round); + load_time += 2 * config->cycles * + (config->load + config->load_step * round) + + (config->load + config->load_step * round * 4); + } + + if (config->verbose || config->output != stdout) + printf("approx. test duration: %im\n", + (int)((sleep_time + load_time) / 60000000)); +} + +/** + * sets up the cpu affinity and scheduler priority + * + * @param config benchmark config values + * + **/ + +void prepare_system(const struct config *config) +{ + if (config->verbose) + printf("set cpu affinity to cpu #%u\n", config->cpu); + + set_cpu_affinity(config->cpu); + + switch (config->prio) { + case SCHED_HIGH: + if (config->verbose) + printf("high priority condition requested\n"); + + set_process_priority(PRIORITY_HIGH); + break; + case SCHED_LOW: + if (config->verbose) + printf("low priority condition requested\n"); + + set_process_priority(PRIORITY_LOW); + break; + default: + if (config->verbose) + printf("default priority condition requested\n"); + + set_process_priority(PRIORITY_DEFAULT); + } +} + diff --git a/tools/power/cpupower/bench/system.h b/tools/power/cpupower/bench/system.h new file mode 100644 index 000000000..530fa2823 --- /dev/null +++ b/tools/power/cpupower/bench/system.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* cpufreq-bench CPUFreq microbenchmark + * + * Copyright (C) 2008 Christian Kornacker + */ + +#include "parse.h" + +long long get_time(); + +int set_cpufreq_governor(char *governor, unsigned int cpu); +int set_cpu_affinity(unsigned int cpu); +int set_process_priority(int priority); + +void prepare_user(const struct config *config); +void prepare_system(const struct config *config); diff --git a/tools/power/cpupower/bindings/python/.gitignore b/tools/power/cpupower/bindings/python/.gitignore new file mode 100644 index 000000000..51cbb8799 --- /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 000000000..4527cd732 --- /dev/null +++ b/tools/power/cpupower/bindings/python/Makefile @@ -0,0 +1,43 @@ +# 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 +# CFLAGS ?= +LDFLAGS ?= -lcpupower +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 $(LDFLAGS) raw_pylibcpupower_wrap.o -o _raw_pylibcpupower.so + +raw_pylibcpupower_wrap.o: raw_pylibcpupower_wrap.c + $(CC) $(CFLAGS) $(PY_INCLUDE) -fPIC -c raw_pylibcpupower_wrap.c + +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 000000000..2a4896b64 --- /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 000000000..d82af6fa9 --- /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 000000000..ca5aa46c9 --- /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-completion.sh b/tools/power/cpupower/cpupower-completion.sh new file mode 100644 index 000000000..e10839cfc --- /dev/null +++ b/tools/power/cpupower/cpupower-completion.sh @@ -0,0 +1,128 @@ +# -*- shell-script -*- +# bash completion script for cpupower +# Taken from git.git's completion script. + +_cpupower_commands="frequency-info frequency-set idle-info idle-set set info monitor" + +_frequency_info () +{ + local flags="-f -w -l -d -p -g -a -s -y -o -m -n --freq --hwfreq --hwlimits --driver --policy --governors --related-cpus --affected-cpus --stats --latency --proc --human --no-rounding" + local prev="${COMP_WORDS[COMP_CWORD-1]}" + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$prev" in + frequency-info) COMPREPLY=($(compgen -W "$flags" -- "$cur")) ;; + esac +} + +_frequency_set () +{ + local flags="-f -g --freq --governor -d --min -u --max -r --related" + local prev="${COMP_WORDS[COMP_CWORD-1]}" + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$prev" in + -f| --freq | -d | --min | -u | --max) + if [ -d /sys/devices/system/cpu/cpufreq/ ] ; then + COMPREPLY=($(compgen -W '$(cat $(ls -d /sys/devices/system/cpu/cpufreq/policy* | head -1)/scaling_available_frequencies)' -- "$cur")) + fi ;; + -g| --governor) + if [ -d /sys/devices/system/cpu/cpufreq/ ] ; then + COMPREPLY=($(compgen -W '$(cat $(ls -d /sys/devices/system/cpu/cpufreq/policy* | head -1)/scaling_available_governors)' -- "$cur")) + fi;; + frequency-set) COMPREPLY=($(compgen -W "$flags" -- "$cur")) ;; + esac +} + +_idle_info() +{ + local flags="-f --silent" + local prev="${COMP_WORDS[COMP_CWORD-1]}" + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$prev" in + idle-info) COMPREPLY=($(compgen -W "$flags" -- "$cur")) ;; + esac +} + +_idle_set() +{ + local flags="-d --disable -e --enable -D --disable-by-latency -E --enable-all" + local prev="${COMP_WORDS[COMP_CWORD-1]}" + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$prev" in + idle-set) COMPREPLY=($(compgen -W "$flags" -- "$cur")) ;; + esac +} + +_set() +{ + local flags="--perf-bias, -b" + local prev="${COMP_WORDS[COMP_CWORD-1]}" + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$prev" in + set) COMPREPLY=($(compgen -W "$flags" -- "$cur")) ;; + esac +} + +_monitor() +{ + local flags="-l -m -i -c -v" + local prev="${COMP_WORDS[COMP_CWORD-1]}" + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$prev" in + monitor) COMPREPLY=($(compgen -W "$flags" -- "$cur")) ;; + esac +} + +_taskset() +{ + local prev_to_prev="${COMP_WORDS[COMP_CWORD-2]}" + local prev="${COMP_WORDS[COMP_CWORD-1]}" + local cur="${COMP_WORDS[COMP_CWORD]}" + case "$prev_to_prev" in + -c|--cpu) COMPREPLY=($(compgen -W "$_cpupower_commands" -- "$cur")) ;; + esac + case "$prev" in + frequency-info) _frequency_info ;; + frequency-set) _frequency_set ;; + idle-info) _idle_info ;; + idle-set) _idle_set ;; + set) _set ;; + monitor) _monitor ;; + esac + +} + +_cpupower () +{ + local i + local c=1 + local command + + while test $c -lt $COMP_CWORD; do + if test $c == 1; then + command="${COMP_WORDS[c]}" + fi + c=$((++c)) + done + + # Complete name of subcommand if the user has not finished typing it yet. + if test $c -eq $COMP_CWORD -a -z "$command"; then + COMPREPLY=($(compgen -W "help -v --version -c --cpu $_cpupower_commands" -- "${COMP_WORDS[COMP_CWORD]}")) + return + fi + + # Complete arguments to subcommands. + case "$command" in + -v|--version) return ;; + -c|--cpu) _taskset ;; + help) COMPREPLY=($(compgen -W "$_cpupower_commands" -- "${COMP_WORDS[COMP_CWORD]}")) ;; + frequency-info) _frequency_info ;; + frequency-set) _frequency_set ;; + idle-info) _idle_info ;; + idle-set) _idle_set ;; + set) _set ;; + monitor) _monitor ;; + esac +} + +complete -o bashdefault -o default -F _cpupower cpupower 2>/dev/null \ + || complete -o default -F _cpupower cpupower diff --git a/tools/power/cpupower/cpupower-service.conf b/tools/power/cpupower/cpupower-service.conf new file mode 100644 index 000000000..abbb46967 --- /dev/null +++ b/tools/power/cpupower/cpupower-service.conf @@ -0,0 +1,37 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2012, Sébastien Luttringer +# Copyright (C) 2024-2025, Francesco Poli + +# 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= + +# Set the Energy Performance Preference +# Available options can be read from +# /sys/devices/system/cpu/cpufreq/policy0/energy_performance_available_preferences +#EPP= diff --git a/tools/power/cpupower/cpupower.service.in b/tools/power/cpupower/cpupower.service.in new file mode 100644 index 000000000..fbd5b8c14 --- /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 + +[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 000000000..6283e8bf2 --- /dev/null +++ b/tools/power/cpupower/cpupower.sh @@ -0,0 +1,32 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright (C) 2012, Sébastien Luttringer +# Copyright (C) 2024, Francesco Poli + +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 + +# apply Energy Performance Preference +if test -n "$EPP" +then + cpupower set -e "$EPP" > /dev/null || ESTATUS=1 +fi + +exit $ESTATUS diff --git a/tools/power/cpupower/debug/i386/Makefile b/tools/power/cpupower/debug/i386/Makefile new file mode 100644 index 000000000..b3f771039 --- /dev/null +++ b/tools/power/cpupower/debug/i386/Makefile @@ -0,0 +1,42 @@ +# SPDX-License-Identifier: GPL-2.0 +OUTPUT=./ +ifeq ("$(origin O)", "command line") + OUTPUT := $(O)/ +endif + +DESTDIR = +bindir = /usr/bin + +INSTALL = /usr/bin/install + + +default: all + +$(OUTPUT)centrino-decode: centrino-decode.c + $(CC) $(CFLAGS) -o $@ centrino-decode.c + +$(OUTPUT)dump_psb: dump_psb.c + $(CC) $(CFLAGS) -o $@ dump_psb.c + +$(OUTPUT)intel_gsic: intel_gsic.c + $(CC) $(CFLAGS) -o $@ -llrmi intel_gsic.c + +$(OUTPUT)powernow-k8-decode: powernow-k8-decode.c + $(CC) $(CFLAGS) -o $@ powernow-k8-decode.c + +all: $(OUTPUT)centrino-decode $(OUTPUT)dump_psb $(OUTPUT)intel_gsic $(OUTPUT)powernow-k8-decode + +clean: + rm -rf $(OUTPUT)centrino-decode + rm -rf $(OUTPUT)dump_psb + rm -rf $(OUTPUT)intel_gsic + rm -rf $(OUTPUT)powernow-k8-decode + +install: + $(INSTALL) -d $(DESTDIR)${bindir} + $(INSTALL) $(OUTPUT)centrino-decode $(DESTDIR)${bindir} + $(INSTALL) $(OUTPUT)powernow-k8-decode $(DESTDIR)${bindir} + $(INSTALL) $(OUTPUT)dump_psb $(DESTDIR)${bindir} + $(INSTALL) $(OUTPUT)intel_gsic $(DESTDIR)${bindir} + +.PHONY: all default clean install diff --git a/tools/power/cpupower/debug/i386/centrino-decode.c b/tools/power/cpupower/debug/i386/centrino-decode.c new file mode 100644 index 000000000..700cd31a7 --- /dev/null +++ b/tools/power/cpupower/debug/i386/centrino-decode.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2003 - 2004 Dominik Brodowski + * + * Based on code found in + * linux/arch/i386/kernel/cpu/cpufreq/speedstep-centrino.c + * and originally developed by Jeremy Fitzhardinge. + * + * USAGE: simply run it to decode the current settings on CPU 0, + * or pass the CPU number as argument, or pass the MSR content + * as argument. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MCPU 32 + +#define MSR_IA32_PERF_STATUS 0x198 + +static int rdmsr(unsigned int cpu, unsigned int msr, + unsigned int *lo, unsigned int *hi) +{ + int fd; + char file[20]; + unsigned long long val; + int retval = -1; + + *lo = *hi = 0; + + if (cpu > MCPU) + goto err1; + + sprintf(file, "/dev/cpu/%d/msr", cpu); + fd = open(file, O_RDONLY); + + if (fd < 0) + goto err1; + + if (lseek(fd, msr, SEEK_CUR) == -1) + goto err2; + + if (read(fd, &val, 8) != 8) + goto err2; + + *lo = (uint32_t )(val & 0xffffffffull); + *hi = (uint32_t )(val>>32 & 0xffffffffull); + + retval = 0; +err2: + close(fd); +err1: + return retval; +} + +static void decode (unsigned int msr) +{ + unsigned int multiplier; + unsigned int mv; + + multiplier = ((msr >> 8) & 0xFF); + + mv = (((msr & 0xFF) * 16) + 700); + + printf("0x%x means multiplier %d @ %d mV\n", msr, multiplier, mv); +} + +static int decode_live(unsigned int cpu) +{ + unsigned int lo, hi; + int err; + + err = rdmsr(cpu, MSR_IA32_PERF_STATUS, &lo, &hi); + + if (err) { + printf("can't get MSR_IA32_PERF_STATUS for cpu %d\n", cpu); + printf("Possible trouble: you don't run an Enhanced SpeedStep capable cpu\n"); + printf("or you are not root, or the msr driver is not present\n"); + return 1; + } + + decode(lo); + + return 0; +} + +int main (int argc, char **argv) +{ + unsigned int cpu, mode = 0; + + if (argc < 2) + cpu = 0; + else { + cpu = strtoul(argv[1], NULL, 0); + if (cpu >= MCPU) + mode = 1; + } + + if (mode) + decode(cpu); + else + decode_live(cpu); + + return 0; +} diff --git a/tools/power/cpupower/debug/i386/dump_psb.c b/tools/power/cpupower/debug/i386/dump_psb.c new file mode 100644 index 000000000..6fb81b42e --- /dev/null +++ b/tools/power/cpupower/debug/i386/dump_psb.c @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0-only +// dump_psb. (c) 2004, Dave Jones, Red Hat Inc. + +#include +#include +#include +#include +#include + +#define _GNU_SOURCE +#include + +#include + +#define LEN (0x100000 - 0xc0000) +#define OFFSET (0xc0000) + +#ifndef __packed +#define __packed __attribute((packed)) +#endif + +static long relevant; + +static const int fid_to_mult[32] = { + 110, 115, 120, 125, 50, 55, 60, 65, + 70, 75, 80, 85, 90, 95, 100, 105, + 30, 190, 40, 200, 130, 135, 140, 210, + 150, 225, 160, 165, 170, 180, -1, -1, +}; + +static const int vid_to_voltage[32] = { + 2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650, + 1600, 1550, 1500, 1450, 1400, 1350, 1300, 0, + 1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100, + 1075, 1050, 1024, 1000, 975, 950, 925, 0, +}; + +struct psb_header { + char signature[10]; + u_char version; + u_char flags; + u_short settlingtime; + u_char res1; + u_char numpst; +} __packed; + +struct pst_header { + u_int32_t cpuid; + u_char fsb; + u_char maxfid; + u_char startvid; + u_char numpstates; +} __packed; + +static u_int fsb; +static u_int sgtc; + +static int +decode_pst(char *p, int npstates) +{ + int i; + int freq, fid, vid; + + for (i = 0; i < npstates; ++i) { + fid = *p++; + vid = *p++; + freq = 100 * fid_to_mult[fid] * fsb; + + printf(" %2d %8dkHz FID %02x (%2d.%01d) VID %02x (%4dmV)\n", + i, + freq, + fid, fid_to_mult[fid]/10, fid_to_mult[fid]%10, + vid, vid_to_voltage[vid]); + } + + return 0; +} + +static +void decode_psb(char *p, int numpst) +{ + int i; + struct psb_header *psb; + struct pst_header *pst; + + psb = (struct psb_header*) p; + + if (psb->version != 0x12) + return; + + printf("PSB version: %hhx flags: %hhx settling time %hhuus res1 %hhx num pst %hhu\n", + psb->version, + psb->flags, + psb->settlingtime, + psb->res1, + psb->numpst); + sgtc = psb->settlingtime * 100; + + if (sgtc < 10000) + sgtc = 10000; + + p = ((char *) psb) + sizeof(struct psb_header); + + if (numpst < 0) + numpst = psb->numpst; + else + printf("Overriding number of pst :%d\n", numpst); + + for (i = 0; i < numpst; i++) { + pst = (struct pst_header*) p; + + if (relevant != 0) { + if (relevant!= pst->cpuid) + goto next_one; + } + + printf(" PST %d cpuid %.3x fsb %hhu mfid %hhx svid %hhx numberstates %hhu\n", + i+1, + pst->cpuid, + pst->fsb, + pst->maxfid, + pst->startvid, + pst->numpstates); + + fsb = pst->fsb; + decode_pst(p + sizeof(struct pst_header), pst->numpstates); + +next_one: + p += sizeof(struct pst_header) + 2*pst->numpstates; + } + +} + +static struct option info_opts[] = { + {"numpst", no_argument, NULL, 'n'}, +}; + +void print_help(void) +{ + printf ("Usage: dump_psb [options]\n"); + printf ("Options:\n"); + printf (" -n, --numpst Set number of PST tables to scan\n"); + printf (" -r, --relevant Only display PSTs relevant to cpuid N\n"); +} + +int +main(int argc, char *argv[]) +{ + int fd; + int numpst=-1; + int ret=0, cont=1; + char *mem = NULL; + char *p; + + do { + ret = getopt_long(argc, argv, "hr:n:", info_opts, NULL); + switch (ret){ + case '?': + case 'h': + print_help(); + cont = 0; + break; + case 'r': + relevant = strtol(optarg, NULL, 16); + break; + case 'n': + numpst = strtol(optarg, NULL, 10); + break; + case -1: + cont = 0; + break; + } + + } while(cont); + + fd = open("/dev/mem", O_RDONLY); + if (fd < 0) { + printf ("Couldn't open /dev/mem. Are you root?\n"); + exit(1); + } + + mem = mmap(mem, 0x100000 - 0xc0000, PROT_READ, MAP_SHARED, fd, 0xc0000); + close(fd); + + for (p = mem; p - mem < LEN; p+=16) { + if (memcmp(p, "AMDK7PNOW!", 10) == 0) { + decode_psb(p, numpst); + break; + } + } + + munmap(mem, LEN); + return 0; +} diff --git a/tools/power/cpupower/debug/i386/intel_gsic.c b/tools/power/cpupower/debug/i386/intel_gsic.c new file mode 100644 index 000000000..befd837f0 --- /dev/null +++ b/tools/power/cpupower/debug/i386/intel_gsic.c @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2003 Bruno Ducrot + * (C) 2004 Dominik Brodowski + * + * Based on code found in + * linux/include/asm-i386/ist.h and linux/arch/i386/kernel/setup.c + * and originally developed by Andy Grover + */ + +#include +#include +#include + +int main (void) +{ + struct LRMI_regs r; + int retval; + + if (!LRMI_init()) + return 0; + + memset(&r, 0, sizeof(r)); + + r.eax = 0x0000E980; + r.edx = 0x47534943; + + retval = LRMI_int(0x15, &r); + + if (!retval) { + printf("Failed!\n"); + return 0; + } + if (r.eax == 0x47534943) { + printf("BIOS supports GSIC call:\n"); + printf("\tsignature: %c%c%c%c\n", + (r.eax >> 24) & 0xff, + (r.eax >> 16) & 0xff, + (r.eax >> 8) & 0xff, + (r.eax) & 0xff); + printf("\tcommand port = 0x%.4x\n", + r.ebx & 0xffff); + printf("\tcommand = 0x%.4x\n", + (r.ebx >> 16) & 0xffff); + printf("\tevent port = 0x%.8x\n", r.ecx); + printf("\tflags = 0x%.8x\n", r.edx); + if (((r.ebx >> 16) & 0xffff) != 0x82) { + printf("non-default command value. If speedstep-smi " + "doesn't work out of the box,\nyou may want to " + "try out the default value by passing " + "smi_cmd=0x82 to the module\n ON YOUR OWN " + "RISK.\n"); + } + if ((r.ebx & 0xffff) != 0xb2) { + printf("non-default command port. If speedstep-smi " + "doesn't work out of the box,\nyou may want to " + "try out the default value by passing " + "smi_port=0x82 to the module\n ON YOUR OWN " + "RISK.\n"); + } + } else { + printf("BIOS DOES NOT support GSIC call. Dumping registers anyway:\n"); + printf("eax = 0x%.8x\n", r.eax); + printf("ebx = 0x%.8x\n", r.ebx); + printf("ecx = 0x%.8x\n", r.ecx); + printf("edx = 0x%.8x\n", r.edx); + printf("Note also that some BIOS do not support the initial " + "GSIC call, but the newer\nspeedstep-smi driver may " + "work.\nFor this, you need to pass some arguments to " + "the speedstep-smi driver:\n"); + printf("\tsmi_cmd=0x?? smi_port=0x?? smi_sig=1\n"); + printf("\nUnfortunately, you have to know what exactly are " + "smi_cmd and smi_port, and this\nis system " + "dependent.\n"); + } + return 1; +} diff --git a/tools/power/cpupower/debug/i386/powernow-k8-decode.c b/tools/power/cpupower/debug/i386/powernow-k8-decode.c new file mode 100644 index 000000000..735dca1e2 --- /dev/null +++ b/tools/power/cpupower/debug/i386/powernow-k8-decode.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2004 Bruno Ducrot + * + * Based on code found in + * linux/arch/i386/kernel/cpu/cpufreq/powernow-k8.c + * and originally developed by Paul Devriendt + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define MCPU 32 + +#define MSR_FIDVID_STATUS 0xc0010042 + +#define MSR_S_HI_CURRENT_VID 0x0000001f +#define MSR_S_LO_CURRENT_FID 0x0000003f + +static int get_fidvid(uint32_t cpu, uint32_t *fid, uint32_t *vid) +{ + int err = 1; + uint64_t msr = 0; + int fd; + char file[20]; + + if (cpu > MCPU) + goto out; + + sprintf(file, "/dev/cpu/%d/msr", cpu); + + fd = open(file, O_RDONLY); + if (fd < 0) + goto out; + lseek(fd, MSR_FIDVID_STATUS, SEEK_CUR); + if (read(fd, &msr, 8) != 8) + goto err1; + + *fid = ((uint32_t )(msr & 0xffffffffull)) & MSR_S_LO_CURRENT_FID; + *vid = ((uint32_t )(msr>>32 & 0xffffffffull)) & MSR_S_HI_CURRENT_VID; + err = 0; +err1: + close(fd); +out: + return err; +} + + +/* Return a frequency in MHz, given an input fid */ +static uint32_t find_freq_from_fid(uint32_t fid) +{ + return 800 + (fid * 100); +} + +/* Return a voltage in miliVolts, given an input vid */ +static uint32_t find_millivolts_from_vid(uint32_t vid) +{ + return 1550-vid*25; +} + +int main (int argc, char *argv[]) +{ + int err; + int cpu; + uint32_t fid, vid; + + if (argc < 2) + cpu = 0; + else + cpu = strtoul(argv[1], NULL, 0); + + err = get_fidvid(cpu, &fid, &vid); + + if (err) { + printf("can't get fid, vid from MSR\n"); + printf("Possible trouble: you don't run a powernow-k8 capable cpu\n"); + printf("or you are not root, or the msr driver is not present\n"); + exit(1); + } + + + printf("cpu %d currently at %d MHz and %d mV\n", + cpu, + find_freq_from_fid(fid), + find_millivolts_from_vid(vid)); + + return 0; +} diff --git a/tools/power/cpupower/debug/kernel/Makefile b/tools/power/cpupower/debug/kernel/Makefile new file mode 100644 index 000000000..7b5c43684 --- /dev/null +++ b/tools/power/cpupower/debug/kernel/Makefile @@ -0,0 +1,23 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-m := + +KDIR := /lib/modules/$(shell uname -r)/build +KMISC := /lib/modules/$(shell uname -r)/cpufrequtils/ + +ifeq ("$(CONFIG_X86_TSC)", "y") + obj-m += cpufreq-test_tsc.o +endif + +default: + $(MAKE) -C $(KDIR) M=$(CURDIR) + +clean: + - rm -rf *.o *.ko .*.cmd .*.mod.* *.mod.c + - rm -rf Module.symvers modules.order + +install: default + install -d $(KMISC) + install -m 644 -c *.ko $(KMISC) + /sbin/depmod -a + +all: default diff --git a/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c b/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c new file mode 100644 index 000000000..e364b170b --- /dev/null +++ b/tools/power/cpupower/debug/kernel/cpufreq-test_tsc.c @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * test module to check whether the TSC-based delay routine continues + * to work properly after cpufreq transitions. Needs ACPI to work + * properly. + * + * Based partly on the Power Management Timer (PMTMR) code to be found + * in arch/i386/kernel/timers/timer_pm.c on recent 2.6. kernels, especially + * code written by John Stultz. The read_pmtmr function was copied verbatim + * from that file. + * + * (C) 2004 Dominik Brodowski + * + * To use: + * 1.) pass clock=tsc to the kernel on your bootloader + * 2.) modprobe this module (it'll fail) + * 3.) change CPU frequency + * 4.) modprobe this module again + * 5.) if the third value, "diff_pmtmr", changes between 2. and 4., the + * TSC-based delay routine on the Linux kernel does not correctly + * handle the cpufreq transition. Please report this to + * linux-pm@vger.kernel.org + */ + +#include +#include +#include +#include +#include +#include + +static int pm_tmr_ioport = 0; + +/*helper function to safely read acpi pm timesource*/ +static u32 read_pmtmr(void) +{ + u32 v1=0,v2=0,v3=0; + /* It has been reported that because of various broken + * chipsets (ICH4, PIIX4 and PIIX4E) where the ACPI PM time + * source is not latched, so you must read it multiple + * times to insure a safe value is read. + */ + do { + v1 = inl(pm_tmr_ioport); + v2 = inl(pm_tmr_ioport); + v3 = inl(pm_tmr_ioport); + } while ((v1 > v2 && v1 < v3) || (v2 > v3 && v2 < v1) + || (v3 > v1 && v3 < v2)); + + /* mask the output to 24 bits */ + return (v2 & 0xFFFFFF); +} + +static int __init cpufreq_test_tsc(void) +{ + u32 now, then, diff; + u64 now_tsc, then_tsc, diff_tsc; + int i; + + /* the following code snipped is copied from arch/x86/kernel/acpi/boot.c + of Linux v2.6.25. */ + + /* detect the location of the ACPI PM Timer */ + if (acpi_gbl_FADT.header.revision >= FADT2_REVISION_ID) { + /* FADT rev. 2 */ + if (acpi_gbl_FADT.xpm_timer_block.space_id != + ACPI_ADR_SPACE_SYSTEM_IO) + return 0; + + pm_tmr_ioport = acpi_gbl_FADT.xpm_timer_block.address; + /* + * "X" fields are optional extensions to the original V1.0 + * fields, so we must selectively expand V1.0 fields if the + * corresponding X field is zero. + */ + if (!pm_tmr_ioport) + pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block; + } else { + /* FADT rev. 1 */ + pm_tmr_ioport = acpi_gbl_FADT.pm_timer_block; + } + + printk(KERN_DEBUG "start--> \n"); + then = read_pmtmr(); + then_tsc = rdtsc(); + for (i=0;i<20;i++) { + mdelay(100); + now = read_pmtmr(); + now_tsc = rdtsc(); + diff = (now - then) & 0xFFFFFF; + diff_tsc = now_tsc - then_tsc; + printk(KERN_DEBUG "t1: %08u t2: %08u diff_pmtmr: %08u diff_tsc: %016llu\n", then, now, diff, diff_tsc); + then = now; + then_tsc = now_tsc; + } + printk(KERN_DEBUG "<-- end \n"); + return -ENODEV; +} + +static void __exit cpufreq_none(void) +{ + return; +} + +module_init(cpufreq_test_tsc) +module_exit(cpufreq_none) + + +MODULE_AUTHOR("Dominik Brodowski"); +MODULE_DESCRIPTION("Verify the TSC cpufreq notifier working correctly -- needs ACPI-enabled system"); +MODULE_LICENSE ("GPL"); diff --git a/tools/power/cpupower/debug/x86_64/Makefile b/tools/power/cpupower/debug/x86_64/Makefile new file mode 100644 index 000000000..b1b6c4364 --- /dev/null +++ b/tools/power/cpupower/debug/x86_64/Makefile @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0 +OUTPUT=./ +ifeq ("$(origin O)", "command line") + OUTPUT := $(O)/ +endif + +DESTDIR = +bindir = /usr/bin + +INSTALL = /usr/bin/install + + +default: all + +$(OUTPUT)centrino-decode: ../i386/centrino-decode.c + $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< + +$(OUTPUT)powernow-k8-decode: ../i386/powernow-k8-decode.c + $(CC) $(CFLAGS) -o $@ $(LDFLAGS) $< + +all: $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode + +clean: + rm -rf $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode + +install: + $(INSTALL) -d $(DESTDIR)${bindir} + $(INSTALL) $(OUTPUT)centrino-decode $(DESTDIR)${bindir} + $(INSTALL) $(OUTPUT)powernow-k8-decode $(DESTDIR)${bindir} + +.PHONY: all default clean install diff --git a/tools/power/cpupower/lib/acpi_cppc.c b/tools/power/cpupower/lib/acpi_cppc.c new file mode 100644 index 000000000..c401ac331 --- /dev/null +++ b/tools/power/cpupower/lib/acpi_cppc.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cpupower_intern.h" +#include "acpi_cppc.h" + +/* ACPI CPPC sysfs access ***********************************************/ + +static int acpi_cppc_read_file(unsigned int cpu, const char *fname, + char *buf, size_t buflen) +{ + char path[SYSFS_PATH_MAX]; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/acpi_cppc/%s", + cpu, fname); + return cpupower_read_sysfs(path, buf, buflen); +} + +static const char * const acpi_cppc_value_files[] = { + [HIGHEST_PERF] = "highest_perf", + [LOWEST_PERF] = "lowest_perf", + [NOMINAL_PERF] = "nominal_perf", + [LOWEST_NONLINEAR_PERF] = "lowest_nonlinear_perf", + [LOWEST_FREQ] = "lowest_freq", + [NOMINAL_FREQ] = "nominal_freq", + [REFERENCE_PERF] = "reference_perf", + [WRAPAROUND_TIME] = "wraparound_time" +}; + +unsigned long acpi_cppc_get_data(unsigned int cpu, enum acpi_cppc_value which) +{ + unsigned long long value; + unsigned int len; + char linebuf[MAX_LINE_LEN]; + char *endp; + + if (which >= MAX_CPPC_VALUE_FILES) + return 0; + + len = acpi_cppc_read_file(cpu, acpi_cppc_value_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) + return 0; + + value = strtoull(linebuf, &endp, 0); + + if (endp == linebuf || errno == ERANGE) + return 0; + + return value; +} diff --git a/tools/power/cpupower/lib/acpi_cppc.h b/tools/power/cpupower/lib/acpi_cppc.h new file mode 100644 index 000000000..85ca83080 --- /dev/null +++ b/tools/power/cpupower/lib/acpi_cppc.h @@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __ACPI_CPPC_H__ +#define __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); + +#endif /* _ACPI_CPPC_H */ diff --git a/tools/power/cpupower/lib/cpufreq.c b/tools/power/cpupower/lib/cpufreq.c new file mode 100644 index 000000000..8dda3db2d --- /dev/null +++ b/tools/power/cpupower/lib/cpufreq.c @@ -0,0 +1,803 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2004-2009 Dominik Brodowski + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cpufreq.h" +#include "cpupower_intern.h" + +/* CPUFREQ sysfs access **************************************************/ + +/* helper function to read file from /sys into given buffer */ +/* fname is a relative path under "cpuX/cpufreq" dir */ +static unsigned int sysfs_cpufreq_read_file(unsigned int cpu, const char *fname, + char *buf, size_t buflen) +{ + char path[SYSFS_PATH_MAX]; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", + cpu, fname); + return cpupower_read_sysfs(path, buf, buflen); +} + +/* helper function to write a new value to a /sys file */ +/* fname is a relative path under "cpuX/cpufreq" dir */ +static unsigned int sysfs_cpufreq_write_file(unsigned int cpu, + const char *fname, + const char *value, size_t len) +{ + char path[SYSFS_PATH_MAX]; + int fd; + ssize_t numwrite; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpufreq/%s", + cpu, fname); + + fd = open(path, O_WRONLY); + if (fd == -1) + return 0; + + numwrite = write(fd, value, len); + if (numwrite < 1) { + close(fd); + return 0; + } + + close(fd); + + return (unsigned int) numwrite; +} + +/* read access to files which contain one numeric value */ + +enum cpufreq_value { + CPUINFO_CUR_FREQ, + CPUINFO_MIN_FREQ, + CPUINFO_MAX_FREQ, + CPUINFO_LATENCY, + SCALING_CUR_FREQ, + SCALING_MIN_FREQ, + SCALING_MAX_FREQ, + STATS_NUM_TRANSITIONS, + MAX_CPUFREQ_VALUE_READ_FILES +}; + +static const char *cpufreq_value_files[MAX_CPUFREQ_VALUE_READ_FILES] = { + [CPUINFO_CUR_FREQ] = "cpuinfo_cur_freq", + [CPUINFO_MIN_FREQ] = "cpuinfo_min_freq", + [CPUINFO_MAX_FREQ] = "cpuinfo_max_freq", + [CPUINFO_LATENCY] = "cpuinfo_transition_latency", + [SCALING_CUR_FREQ] = "scaling_cur_freq", + [SCALING_MIN_FREQ] = "scaling_min_freq", + [SCALING_MAX_FREQ] = "scaling_max_freq", + [STATS_NUM_TRANSITIONS] = "stats/total_trans" +}; + +unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu, + const char **table, + unsigned int index, + unsigned int size) +{ + unsigned long value; + unsigned int len; + char linebuf[MAX_LINE_LEN]; + char *endp; + + if (!table || index >= size || !table[index]) + return 0; + + len = sysfs_cpufreq_read_file(cpu, table[index], linebuf, + sizeof(linebuf)); + + 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) + return 0; + + return value; +} + +static unsigned long sysfs_cpufreq_get_one_value(unsigned int cpu, + enum cpufreq_value which) +{ + return cpufreq_get_sysfs_value_from_table(cpu, cpufreq_value_files, + which, + MAX_CPUFREQ_VALUE_READ_FILES); +} + +/* read access to files which contain one string */ + +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", +}; + + +static char *sysfs_cpufreq_get_one_string(unsigned int cpu, + enum cpufreq_string which) +{ + char linebuf[MAX_LINE_LEN]; + char *result; + unsigned int len; + + if (which >= MAX_CPUFREQ_STRING_FILES) + return NULL; + + len = sysfs_cpufreq_read_file(cpu, cpufreq_string_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + result = strdup(linebuf); + if (result == NULL) + return NULL; + + if (result[strlen(result) - 1] == '\n') + result[strlen(result) - 1] = '\0'; + + return result; +} + +/* write access */ + +enum cpufreq_write { + WRITE_SCALING_MIN_FREQ, + WRITE_SCALING_MAX_FREQ, + WRITE_SCALING_GOVERNOR, + WRITE_SCALING_SET_SPEED, + MAX_CPUFREQ_WRITE_FILES +}; + +static const char *cpufreq_write_files[MAX_CPUFREQ_WRITE_FILES] = { + [WRITE_SCALING_MIN_FREQ] = "scaling_min_freq", + [WRITE_SCALING_MAX_FREQ] = "scaling_max_freq", + [WRITE_SCALING_GOVERNOR] = "scaling_governor", + [WRITE_SCALING_SET_SPEED] = "scaling_setspeed", +}; + +static int sysfs_cpufreq_write_one_value(unsigned int cpu, + enum cpufreq_write which, + const char *new_value, size_t len) +{ + if (which >= MAX_CPUFREQ_WRITE_FILES) + return 0; + + if (sysfs_cpufreq_write_file(cpu, cpufreq_write_files[which], + new_value, len) != len) + return -ENODEV; + + return 0; +}; + +unsigned long cpufreq_get_freq_kernel(unsigned int cpu) +{ + return sysfs_cpufreq_get_one_value(cpu, SCALING_CUR_FREQ); +} + +unsigned long cpufreq_get_freq_hardware(unsigned int cpu) +{ + return sysfs_cpufreq_get_one_value(cpu, CPUINFO_CUR_FREQ); +} + +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) +{ + if ((!min) || (!max)) + return -EINVAL; + + *min = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MIN_FREQ); + if (!*min) + return -ENODEV; + + *max = sysfs_cpufreq_get_one_value(cpu, CPUINFO_MAX_FREQ); + if (!*max) + return -ENODEV; + + return 0; +} + +char *cpufreq_get_driver(unsigned int cpu) +{ + return sysfs_cpufreq_get_one_string(cpu, SCALING_DRIVER); +} + +void cpufreq_put_driver(char *ptr) +{ + if (!ptr) + return; + free(ptr); +} + +struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu) +{ + struct cpufreq_policy *policy; + + policy = malloc(sizeof(struct cpufreq_policy)); + if (!policy) + return NULL; + + policy->governor = sysfs_cpufreq_get_one_string(cpu, SCALING_GOVERNOR); + if (!policy->governor) { + free(policy); + return NULL; + } + policy->min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ); + policy->max = sysfs_cpufreq_get_one_value(cpu, SCALING_MAX_FREQ); + if ((!policy->min) || (!policy->max)) { + free(policy->governor); + free(policy); + return NULL; + } + + return policy; +} + +void cpufreq_put_policy(struct cpufreq_policy *policy) +{ + if ((!policy) || (!policy->governor)) + return; + + free(policy->governor); + policy->governor = NULL; + free(policy); +} + +struct cpufreq_available_governors *cpufreq_get_available_governors(unsigned + int cpu) +{ + struct cpufreq_available_governors *first = NULL; + struct cpufreq_available_governors *current = NULL; + char linebuf[MAX_LINE_LEN]; + unsigned int pos, i; + unsigned int len; + + len = sysfs_cpufreq_read_file(cpu, "scaling_available_governors", + linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + pos = 0; + for (i = 0; i < len; i++) { + if (linebuf[i] == ' ' || linebuf[i] == '\n') { + if (i - pos < 2) + continue; + if (current) { + current->next = malloc(sizeof(*current)); + if (!current->next) + goto error_out; + current = current->next; + } else { + first = malloc(sizeof(*first)); + if (!first) + return NULL; + current = first; + } + current->first = first; + current->next = NULL; + + current->governor = malloc(i - pos + 1); + if (!current->governor) + goto error_out; + + memcpy(current->governor, linebuf + pos, i - pos); + current->governor[i - pos] = '\0'; + pos = i + 1; + } + } + + return first; + + error_out: + while (first) { + current = first->next; + if (first->governor) + free(first->governor); + free(first); + first = current; + } + return NULL; +} + +void cpufreq_put_available_governors(struct cpufreq_available_governors *any) +{ + struct cpufreq_available_governors *tmp, *next; + + if (!any) + return; + + tmp = any->first; + while (tmp) { + next = tmp->next; + if (tmp->governor) + free(tmp->governor); + free(tmp); + tmp = next; + } +} + + +struct cpufreq_available_frequencies +*cpufreq_get_available_frequencies(unsigned int cpu) +{ + struct cpufreq_available_frequencies *first = NULL; + struct cpufreq_available_frequencies *current = NULL; + char one_value[SYSFS_PATH_MAX]; + char linebuf[MAX_LINE_LEN]; + unsigned int pos, i; + unsigned int len; + + len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies", + linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + pos = 0; + for (i = 0; i < len; i++) { + if (linebuf[i] == ' ' || linebuf[i] == '\n') { + if (i - pos < 2) + continue; + if (i - pos >= SYSFS_PATH_MAX) + goto error_out; + if (current) { + current->next = malloc(sizeof(*current)); + if (!current->next) + goto error_out; + current = current->next; + } else { + first = malloc(sizeof(*first)); + if (!first) + return NULL; + current = first; + } + current->first = first; + current->next = NULL; + + memcpy(one_value, linebuf + pos, i - pos); + one_value[i - pos] = '\0'; + if (sscanf(one_value, "%lu", ¤t->frequency) != 1) + goto error_out; + + pos = i + 1; + } + } + + return first; + + error_out: + while (first) { + current = first->next; + free(first); + first = current; + } + return NULL; +} + +struct cpufreq_available_frequencies +*cpufreq_get_boost_frequencies(unsigned int cpu) +{ + struct cpufreq_available_frequencies *first = NULL; + struct cpufreq_available_frequencies *current = NULL; + char one_value[SYSFS_PATH_MAX]; + char linebuf[MAX_LINE_LEN]; + unsigned int pos, i; + unsigned int len; + + len = sysfs_cpufreq_read_file(cpu, "scaling_boost_frequencies", + linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + pos = 0; + for (i = 0; i < len; i++) { + if (linebuf[i] == ' ' || linebuf[i] == '\n') { + if (i - pos < 2) + continue; + if (i - pos >= SYSFS_PATH_MAX) + goto error_out; + if (current) { + current->next = malloc(sizeof(*current)); + if (!current->next) + goto error_out; + current = current->next; + } else { + first = malloc(sizeof(*first)); + if (!first) + return NULL; + current = first; + } + current->first = first; + current->next = NULL; + + memcpy(one_value, linebuf + pos, i - pos); + one_value[i - pos] = '\0'; + if (sscanf(one_value, "%lu", ¤t->frequency) != 1) + goto error_out; + + pos = i + 1; + } + } + + return first; + + error_out: + while (first) { + current = first->next; + free(first); + first = current; + } + return NULL; +} + +void cpufreq_put_available_frequencies(struct cpufreq_available_frequencies *any) +{ + struct cpufreq_available_frequencies *tmp, *next; + + if (!any) + return; + + tmp = any->first; + while (tmp) { + next = tmp->next; + free(tmp); + tmp = next; + } +} + +void cpufreq_put_boost_frequencies(struct cpufreq_available_frequencies *any) +{ + cpufreq_put_available_frequencies(any); +} + +static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu, + const char *file) +{ + struct cpufreq_affected_cpus *first = NULL; + struct cpufreq_affected_cpus *current = NULL; + char one_value[SYSFS_PATH_MAX]; + char linebuf[MAX_LINE_LEN]; + unsigned int pos, i; + unsigned int len; + + len = sysfs_cpufreq_read_file(cpu, file, linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + pos = 0; + for (i = 0; i < len; i++) { + if (i == len || linebuf[i] == ' ' || linebuf[i] == '\n') { + if (i - pos < 1) + continue; + if (i - pos >= SYSFS_PATH_MAX) + goto error_out; + if (current) { + current->next = malloc(sizeof(*current)); + if (!current->next) + goto error_out; + current = current->next; + } else { + first = malloc(sizeof(*first)); + if (!first) + return NULL; + current = first; + } + current->first = first; + current->next = NULL; + + memcpy(one_value, linebuf + pos, i - pos); + one_value[i - pos] = '\0'; + + if (sscanf(one_value, "%u", ¤t->cpu) != 1) + goto error_out; + + pos = i + 1; + } + } + + return first; + + error_out: + while (first) { + current = first->next; + free(first); + first = current; + } + return NULL; +} + +struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned int cpu) +{ + return sysfs_get_cpu_list(cpu, "affected_cpus"); +} + +void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *any) +{ + struct cpufreq_affected_cpus *tmp, *next; + + if (!any) + return; + + tmp = any->first; + while (tmp) { + next = tmp->next; + free(tmp); + tmp = next; + } +} + + +struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned int cpu) +{ + return sysfs_get_cpu_list(cpu, "related_cpus"); +} + +void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *any) +{ + cpufreq_put_affected_cpus(any); +} + +static int verify_gov(char *new_gov, char *passed_gov) +{ + unsigned int i, j = 0; + + if (!passed_gov || (strlen(passed_gov) > 19)) + return -EINVAL; + + strncpy(new_gov, passed_gov, 20); + for (i = 0; i < 20; i++) { + if (j) { + new_gov[i] = '\0'; + continue; + } + if ((new_gov[i] >= 'a') && (new_gov[i] <= 'z')) + continue; + + if ((new_gov[i] >= 'A') && (new_gov[i] <= 'Z')) + continue; + + if (new_gov[i] == '-') + continue; + + if (new_gov[i] == '_') + continue; + + if (new_gov[i] == '\0') { + j = 1; + continue; + } + return -EINVAL; + } + new_gov[19] = '\0'; + return 0; +} + +int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy) +{ + char min[SYSFS_PATH_MAX]; + char max[SYSFS_PATH_MAX]; + char gov[SYSFS_PATH_MAX]; + int ret; + unsigned long old_min; + int write_max_first; + + if (!policy || !(policy->governor)) + return -EINVAL; + + if (policy->max < policy->min) + return -EINVAL; + + if (verify_gov(gov, policy->governor)) + return -EINVAL; + + snprintf(min, SYSFS_PATH_MAX, "%lu", policy->min); + snprintf(max, SYSFS_PATH_MAX, "%lu", policy->max); + + old_min = sysfs_cpufreq_get_one_value(cpu, SCALING_MIN_FREQ); + write_max_first = (old_min && (policy->max < old_min) ? 0 : 1); + + if (write_max_first) { + ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, + max, strlen(max)); + if (ret) + return ret; + } + + ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, min, + strlen(min)); + if (ret) + return ret; + + if (!write_max_first) { + ret = sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, + max, strlen(max)); + if (ret) + return ret; + } + + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR, + gov, strlen(gov)); +} + + +int cpufreq_modify_policy_min(unsigned int cpu, unsigned long min_freq) +{ + char value[SYSFS_PATH_MAX]; + + snprintf(value, SYSFS_PATH_MAX, "%lu", min_freq); + + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MIN_FREQ, + value, strlen(value)); +} + + +int cpufreq_modify_policy_max(unsigned int cpu, unsigned long max_freq) +{ + char value[SYSFS_PATH_MAX]; + + snprintf(value, SYSFS_PATH_MAX, "%lu", max_freq); + + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_MAX_FREQ, + value, strlen(value)); +} + +int cpufreq_modify_policy_governor(unsigned int cpu, char *governor) +{ + char new_gov[SYSFS_PATH_MAX]; + + if ((!governor) || (strlen(governor) > 19)) + return -EINVAL; + + if (verify_gov(new_gov, governor)) + return -EINVAL; + + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_GOVERNOR, + new_gov, strlen(new_gov)); +} + +int cpufreq_set_frequency(unsigned int cpu, unsigned long target_frequency) +{ + struct cpufreq_policy *pol = cpufreq_get_policy(cpu); + char userspace_gov[] = "userspace"; + char freq[SYSFS_PATH_MAX]; + int ret; + + if (!pol) + return -ENODEV; + + if (strncmp(pol->governor, userspace_gov, 9) != 0) { + ret = cpufreq_modify_policy_governor(cpu, userspace_gov); + if (ret) { + cpufreq_put_policy(pol); + return ret; + } + } + + cpufreq_put_policy(pol); + + snprintf(freq, SYSFS_PATH_MAX, "%lu", target_frequency); + + return sysfs_cpufreq_write_one_value(cpu, WRITE_SCALING_SET_SPEED, + freq, strlen(freq)); +} + +struct cpufreq_stats *cpufreq_get_stats(unsigned int cpu, + unsigned long long *total_time) +{ + struct cpufreq_stats *first = NULL; + struct cpufreq_stats *current = NULL; + char one_value[SYSFS_PATH_MAX]; + char linebuf[MAX_LINE_LEN]; + unsigned int pos, i; + unsigned int len; + + len = sysfs_cpufreq_read_file(cpu, "stats/time_in_state", + linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + *total_time = 0; + pos = 0; + for (i = 0; i < len; i++) { + if (i == strlen(linebuf) || linebuf[i] == '\n') { + if (i - pos < 2) + continue; + if ((i - pos) >= SYSFS_PATH_MAX) + goto error_out; + if (current) { + current->next = malloc(sizeof(*current)); + if (!current->next) + goto error_out; + current = current->next; + } else { + first = malloc(sizeof(*first)); + if (!first) + return NULL; + current = first; + } + current->first = first; + current->next = NULL; + + memcpy(one_value, linebuf + pos, i - pos); + one_value[i - pos] = '\0'; + if (sscanf(one_value, "%lu %llu", + ¤t->frequency, + ¤t->time_in_state) != 2) + goto error_out; + + *total_time = *total_time + current->time_in_state; + pos = i + 1; + } + } + + return first; + + error_out: + while (first) { + current = first->next; + free(first); + first = current; + } + return NULL; +} + +void cpufreq_put_stats(struct cpufreq_stats *any) +{ + struct cpufreq_stats *tmp, *next; + + if (!any) + return; + + tmp = any->first; + while (tmp) { + next = tmp->next; + free(tmp); + tmp = next; + } +} + +unsigned long cpufreq_get_transitions(unsigned int cpu) +{ + return sysfs_cpufreq_get_one_value(cpu, STATS_NUM_TRANSITIONS); +} diff --git a/tools/power/cpupower/lib/cpufreq.h b/tools/power/cpupower/lib/cpufreq.h new file mode 100644 index 000000000..bfc617311 --- /dev/null +++ b/tools/power/cpupower/lib/cpufreq.h @@ -0,0 +1,230 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * cpufreq.h - definitions for libcpufreq + * + * Copyright (C) 2004-2009 Dominik Brodowski + */ + +#ifndef __CPUPOWER_CPUFREQ_H__ +#define __CPUPOWER_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; +}; + + + +#ifdef __cplusplus +extern "C" { +#endif + +/* determine current CPU frequency + * - _kernel variant means kernel's opinion of CPU frequency + * - _hardware variant means actual hardware CPU frequency, + * which is only available to root. + * + * returns 0 on failure, else frequency in kHz. + */ + +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); + + +/* determine CPU transition latency + * + * returns 0 on failure, else transition latency in 10^(-9) s = nanoseconds + */ +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 + * considerations by cpufreq policy notifiers in the kernel. + */ + +int cpufreq_get_hardware_limits(unsigned int cpu, + unsigned long *min, + unsigned long *max); + + +/* determine CPUfreq driver used + * + * Remember to call cpufreq_put_driver when no longer needed + * to avoid memory leakage, please. + */ + +char *cpufreq_get_driver(unsigned int cpu); + +void cpufreq_put_driver(char *ptr); + + +/* determine CPUfreq policy currently used + * + * Remember to call cpufreq_put_policy when no longer needed + * to avoid memory leakage, please. + */ + + +struct cpufreq_policy *cpufreq_get_policy(unsigned int cpu); + +void cpufreq_put_policy(struct cpufreq_policy *policy); + + +/* determine CPUfreq governors currently available + * + * may be modified by modprobe'ing or rmmod'ing other governors. Please + * free allocated memory by calling cpufreq_put_available_governors + * after use. + */ + + +struct cpufreq_available_governors +*cpufreq_get_available_governors(unsigned int cpu); + +void cpufreq_put_available_governors( + struct cpufreq_available_governors *first); + + +/* determine CPU frequency states available + * + * Only present on _some_ ->target() cpufreq drivers. For information purposes + * only. Please free allocated memory by calling + * cpufreq_put_frequencies after use. + */ + +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); + + +/* determine affected CPUs + * + * Remember to call cpufreq_put_affected_cpus when no longer needed + * to avoid memory leakage, please. + */ + +struct cpufreq_affected_cpus *cpufreq_get_affected_cpus(unsigned + int cpu); + +void cpufreq_put_affected_cpus(struct cpufreq_affected_cpus *first); + + +/* determine related CPUs + * + * Remember to call cpufreq_put_related_cpus when no longer needed + * to avoid memory leakage, please. + */ + +struct cpufreq_affected_cpus *cpufreq_get_related_cpus(unsigned + int cpu); + +void cpufreq_put_related_cpus(struct cpufreq_affected_cpus *first); + + +/* determine stats for cpufreq subsystem + * + * This is not available in all kernel versions or configurations. + */ + +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); + + +/* set new cpufreq policy + * + * Tries to set the passed policy as new policy as close as possible, + * but results may differ depending e.g. on governors being available. + */ + +int cpufreq_set_policy(unsigned int cpu, struct cpufreq_policy *policy); + + +/* modify a policy by only changing min/max freq or governor + * + * Does not check whether result is what was intended. + */ + +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); + + +/* set a specific frequency + * + * Does only work if userspace governor can be used and no external + * interference (other calls to this function or to set/modify_policy) + * occurs. Also does not work on ->range() cpufreq drivers. + */ + +int cpufreq_set_frequency(unsigned int cpu, + unsigned long target_frequency); + +/* + * get the sysfs value from specific table + * + * Read the value with the sysfs file name from specific table. Does + * only work if the cpufreq driver has the specific sysfs interfaces. + */ + +unsigned long cpufreq_get_sysfs_value_from_table(unsigned int cpu, + const char **table, + unsigned int index, + unsigned int size); + +#ifdef __cplusplus +} +#endif + +#endif /* _CPUFREQ_H */ diff --git a/tools/power/cpupower/lib/cpuidle.c b/tools/power/cpupower/lib/cpuidle.c new file mode 100644 index 000000000..2fcb343d8 --- /dev/null +++ b/tools/power/cpupower/lib/cpuidle.c @@ -0,0 +1,387 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2004-2009 Dominik Brodowski + * (C) 2011 Thomas Renninger Novell Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cpuidle.h" +#include "cpupower_intern.h" + +/* + * helper function to check whether a file under "../cpuX/cpuidle/stateX/" dir + * exists. + * For example the functionality to disable c-states was introduced in later + * kernel versions, this function can be used to explicitly check for this + * feature. + * + * returns 1 if the file exists, 0 otherwise. + */ +static +unsigned int cpuidle_state_file_exists(unsigned int cpu, + unsigned int idlestate, + const char *fname) +{ + char path[SYSFS_PATH_MAX]; + struct stat statbuf; + + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", + cpu, idlestate, fname); + if (stat(path, &statbuf) != 0) + return 0; + return 1; +} + +/* + * helper function to read file from /sys into given buffer + * fname is a relative path under "cpuX/cpuidle/stateX/" dir + * cstates starting with 0, C0 is not counted as cstate. + * This means if you want C1 info, pass 0 as idlestate param + */ +static +unsigned int cpuidle_state_read_file(unsigned int cpu, + unsigned int idlestate, + const char *fname, char *buf, + size_t buflen) +{ + char path[SYSFS_PATH_MAX]; + int fd; + ssize_t numread; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", + cpu, idlestate, fname); + + fd = open(path, O_RDONLY); + if (fd == -1) + return 0; + + numread = read(fd, buf, buflen - 1); + if (numread < 1) { + close(fd); + return 0; + } + + buf[numread] = '\0'; + close(fd); + + return (unsigned int) numread; +} + +/* + * helper function to write a new value to a /sys file + * fname is a relative path under "../cpuX/cpuidle/cstateY/" dir + * + * Returns the number of bytes written or 0 on error + */ +static +unsigned int cpuidle_state_write_file(unsigned int cpu, + unsigned int idlestate, + const char *fname, + const char *value, size_t len) +{ + char path[SYSFS_PATH_MAX]; + int fd; + ssize_t numwrite; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", + cpu, idlestate, fname); + + fd = open(path, O_WRONLY); + if (fd == -1) + return 0; + + numwrite = write(fd, value, len); + if (numwrite < 1) { + close(fd); + return 0; + } + + close(fd); + + return (unsigned int) numwrite; +} + +/* read access to files which contain one numeric value */ + +enum idlestate_value { + IDLESTATE_USAGE, + IDLESTATE_POWER, + IDLESTATE_LATENCY, + IDLESTATE_RESIDENCY, + IDLESTATE_TIME, + IDLESTATE_DISABLE, + MAX_IDLESTATE_VALUE_FILES +}; + +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", +}; + +static +unsigned long long cpuidle_state_get_one_value(unsigned int cpu, + unsigned int idlestate, + enum idlestate_value which) +{ + unsigned long long value; + unsigned int len; + char linebuf[MAX_LINE_LEN]; + char *endp; + + if (which >= MAX_IDLESTATE_VALUE_FILES) + return 0; + + len = cpuidle_state_read_file(cpu, idlestate, + idlestate_value_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) + return 0; + + errno = 0; + value = strtoull(linebuf, &endp, 0); + + if (endp == linebuf || errno == ERANGE) + return 0; + + return value; +} + +/* read access to files which contain one string */ + +enum idlestate_string { + IDLESTATE_DESC, + IDLESTATE_NAME, + MAX_IDLESTATE_STRING_FILES +}; + +static const char *idlestate_string_files[MAX_IDLESTATE_STRING_FILES] = { + [IDLESTATE_DESC] = "desc", + [IDLESTATE_NAME] = "name", +}; + + +static char *cpuidle_state_get_one_string(unsigned int cpu, + unsigned int idlestate, + enum idlestate_string which) +{ + char linebuf[MAX_LINE_LEN]; + char *result; + unsigned int len; + + if (which >= MAX_IDLESTATE_STRING_FILES) + return NULL; + + len = cpuidle_state_read_file(cpu, idlestate, + idlestate_string_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + result = strdup(linebuf); + if (result == NULL) + return NULL; + + result[strcspn(result, "\n")] = '\0'; + + return result; +} + +/* + * Returns: + * 1 if disabled + * 0 if enabled + * -1 if idlestate is not available + * -2 if disabling is not supported by the kernel + */ +int cpuidle_is_state_disabled(unsigned int cpu, + unsigned int idlestate) +{ + if (cpuidle_state_count(cpu) <= idlestate) + return -1; + + if (!cpuidle_state_file_exists(cpu, idlestate, + idlestate_value_files[IDLESTATE_DISABLE])) + return -2; + return cpuidle_state_get_one_value(cpu, idlestate, IDLESTATE_DISABLE); +} + +/* + * Pass 1 as last argument to disable or 0 to enable the state + * Returns: + * 0 on success + * negative values on error, for example: + * -1 if idlestate is not available + * -2 if disabling is not supported by the kernel + * -3 No write access to disable/enable C-states + */ +int cpuidle_state_disable(unsigned int cpu, + unsigned int idlestate, + unsigned int disable) +{ + char value[SYSFS_PATH_MAX]; + int bytes_written; + int len; + + if (cpuidle_state_count(cpu) <= idlestate) + return -1; + + if (!cpuidle_state_file_exists(cpu, idlestate, + idlestate_value_files[IDLESTATE_DISABLE])) + return -2; + + len = snprintf(value, SYSFS_PATH_MAX, "%u", disable); + + bytes_written = cpuidle_state_write_file(cpu, idlestate, "disable", + value, len); + if (bytes_written) + return 0; + return -3; +} + +unsigned long cpuidle_state_latency(unsigned int cpu, + unsigned int idlestate) +{ + 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) +{ + return cpuidle_state_get_one_value(cpu, idlestate, IDLESTATE_USAGE); +} + +unsigned long long cpuidle_state_time(unsigned int cpu, + unsigned int idlestate) +{ + return cpuidle_state_get_one_value(cpu, idlestate, IDLESTATE_TIME); +} + +char *cpuidle_state_name(unsigned int cpu, unsigned int idlestate) +{ + return cpuidle_state_get_one_string(cpu, idlestate, IDLESTATE_NAME); +} + +char *cpuidle_state_desc(unsigned int cpu, unsigned int idlestate) +{ + return cpuidle_state_get_one_string(cpu, idlestate, IDLESTATE_DESC); +} + +/* + * Returns number of supported C-states of CPU core cpu + * Negativ in error case + * Zero if cpuidle does not export any C-states + */ +unsigned int cpuidle_state_count(unsigned int cpu) +{ + char file[SYSFS_PATH_MAX]; + struct stat statbuf; + int idlestates = 1; + + + snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpuidle"); + if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) + return 0; + + snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpuidle/state0", cpu); + if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) + return 0; + + while (stat(file, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { + snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU + "cpu%u/cpuidle/state%d", cpu, idlestates); + idlestates++; + } + idlestates--; + return idlestates; +} + +/* CPUidle general /sys/devices/system/cpu/cpuidle/ sysfs access ********/ + +/* + * helper function to read file from /sys into given buffer + * fname is a relative path under "cpu/cpuidle/" dir + */ +static unsigned int sysfs_cpuidle_read_file(const char *fname, char *buf, + size_t buflen) +{ + char path[SYSFS_PATH_MAX]; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpuidle/%s", fname); + + return cpupower_read_sysfs(path, buf, buflen); +} + + + +/* read access to files which contain one string */ + +enum cpuidle_string { + CPUIDLE_GOVERNOR, + CPUIDLE_GOVERNOR_RO, + CPUIDLE_DRIVER, + MAX_CPUIDLE_STRING_FILES +}; + +static const char *cpuidle_string_files[MAX_CPUIDLE_STRING_FILES] = { + [CPUIDLE_GOVERNOR] = "current_governor", + [CPUIDLE_GOVERNOR_RO] = "current_governor_ro", + [CPUIDLE_DRIVER] = "current_driver", +}; + + +static char *sysfs_cpuidle_get_one_string(enum cpuidle_string which) +{ + char linebuf[MAX_LINE_LEN]; + char *result; + unsigned int len; + + if (which >= MAX_CPUIDLE_STRING_FILES) + return NULL; + + len = sysfs_cpuidle_read_file(cpuidle_string_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + result = strdup(linebuf); + if (result == NULL) + return NULL; + + result[strcspn(result, "\n")] = '\0'; + + return result; +} + +char *cpuidle_get_governor(void) +{ + char *tmp = sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR_RO); + if (!tmp) + return sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR); + else + return tmp; +} + +char *cpuidle_get_driver(void) +{ + return sysfs_cpuidle_get_one_string(CPUIDLE_DRIVER); +} +/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */ diff --git a/tools/power/cpupower/lib/cpuidle.h b/tools/power/cpupower/lib/cpuidle.h new file mode 100644 index 000000000..2ab404d40 --- /dev/null +++ b/tools/power/cpupower/lib/cpuidle.h @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __CPUPOWER_CPUIDLE_H__ +#define __CPUPOWER_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); + +#endif /* __CPUPOWER_HELPERS_SYSFS_H__ */ diff --git a/tools/power/cpupower/lib/cpupower.c b/tools/power/cpupower/lib/cpupower.c new file mode 100644 index 000000000..d7f7ec6f1 --- /dev/null +++ b/tools/power/cpupower/lib/cpupower.c @@ -0,0 +1,251 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2004-2009 Dominik Brodowski + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cpupower.h" +#include "cpupower_intern.h" + +int is_valid_path(const char *path) +{ + if (access(path, F_OK) == -1) + return 0; + return 1; +} + +unsigned int cpupower_read_sysfs(const char *path, char *buf, size_t buflen) +{ + ssize_t numread; + int fd; + + fd = open(path, O_RDONLY); + if (fd == -1) + return 0; + + numread = read(fd, buf, buflen - 1); + if (numread < 1) { + close(fd); + return 0; + } + + buf[numread] = '\0'; + close(fd); + + return (unsigned int) numread; +} + +unsigned int cpupower_write_sysfs(const char *path, char *buf, size_t buflen) +{ + ssize_t numwritten; + int fd; + + fd = open(path, O_WRONLY); + if (fd == -1) + return 0; + + numwritten = write(fd, buf, buflen - 1); + if (numwritten < 1) { + perror(path); + close(fd); + return 0; + } + + close(fd); + + return (unsigned int) numwritten; +} + +/* + * Detect whether a CPU is online + * + * Returns: + * 1 -> if CPU is online + * 0 -> if CPU is offline + * negative errno values in error case + */ +int cpupower_is_cpu_online(unsigned int cpu) +{ + char path[SYSFS_PATH_MAX]; + int fd; + ssize_t numread; + unsigned long long value; + char linebuf[MAX_LINE_LEN]; + char *endp; + struct stat statbuf; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u", cpu); + + if (stat(path, &statbuf) != 0) + return 0; + + /* + * kernel without CONFIG_HOTPLUG_CPU + * -> cpuX directory exists, but not cpuX/online file + */ + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/online", cpu); + if (stat(path, &statbuf) != 0) + return 1; + + fd = open(path, O_RDONLY); + if (fd == -1) + return -errno; + + numread = read(fd, linebuf, MAX_LINE_LEN - 1); + if (numread < 1) { + close(fd); + return -EIO; + } + linebuf[numread] = '\0'; + close(fd); + + value = strtoull(linebuf, &endp, 0); + if (value > 1) + return -EINVAL; + + return value; +} + +/* returns -1 on failure, 0 on success */ +static int sysfs_topology_read_file(unsigned int cpu, const char *fname, int *result) +{ + char linebuf[MAX_LINE_LEN]; + char *endp; + char path[SYSFS_PATH_MAX]; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/topology/%s", + cpu, fname); + if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0) + return -1; + *result = strtol(linebuf, &endp, 0); + if (endp == linebuf || errno == ERANGE) + return -1; + return 0; +} + +static int __compare(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; + if (top1->pkg < top2->pkg) + return -1; + else if (top1->pkg > top2->pkg) + return 1; + else if (top1->core < top2->core) + return -1; + else if (top1->core > top2->core) + return 1; + else if (top1->cpu < top2->cpu) + return -1; + else if (top1->cpu > top2->cpu) + return 1; + else + 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 ->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) + return -ENOMEM; + cpu_top->pkgs = cpu_top->cores = 0; + for (cpu = 0; cpu < cpus; cpu++) { + cpu_top->core_info[cpu].cpu = cpu; + cpu_top->core_info[cpu].is_online = cpupower_is_cpu_online(cpu); + if(sysfs_topology_read_file( + cpu, + "physical_package_id", + &(cpu_top->core_info[cpu].pkg)) < 0) { + cpu_top->core_info[cpu].pkg = -1; + cpu_top->core_info[cpu].core = -1; + continue; + } + if(sysfs_topology_read_file( + cpu, + "core_id", + &(cpu_top->core_info[cpu].core)) < 0) { + cpu_top->core_info[cpu].pkg = -1; + 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), + __compare); + + /* Count the number of distinct pkgs values. This works + because the primary sort of the core_info struct was just + done by pkg value. */ + last_pkg = cpu_top->core_info[0].pkg; + for(cpu = 1; cpu < cpus; cpu++) { + if (cpu_top->core_info[cpu].pkg != last_pkg && + cpu_top->core_info[cpu].pkg != -1) { + + last_pkg = cpu_top->core_info[cpu].pkg; + cpu_top->pkgs++; + } + } + if (!(cpu_top->core_info[0].pkg == -1)) + cpu_top->pkgs++; + + return cpus; +} + +void cpu_topology_release(struct cpupower_topology cpu_top) +{ + free(cpu_top.core_info); +} diff --git a/tools/power/cpupower/lib/cpupower.h b/tools/power/cpupower/lib/cpupower.h new file mode 100644 index 000000000..2e67a080f --- /dev/null +++ b/tools/power/cpupower/lib/cpupower.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#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; + 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; + char core_cpu_list[CPULIST_BUFFER]; + + /* flags */ + unsigned int is_online:1; +}; + +#ifdef __cplusplus +extern "C" { +#endif + +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); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/tools/power/cpupower/lib/cpupower_intern.h b/tools/power/cpupower/lib/cpupower_intern.h new file mode 100644 index 000000000..5fdb8620d --- /dev/null +++ b/tools/power/cpupower/lib/cpupower_intern.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#define PATH_TO_CPU "/sys/devices/system/cpu/" + +#ifndef MAX_LINE_LEN +#define MAX_LINE_LEN 4096 +#endif + +#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); diff --git a/tools/power/cpupower/lib/powercap.c b/tools/power/cpupower/lib/powercap.c new file mode 100644 index 000000000..94a0c69e5 --- /dev/null +++ b/tools/power/cpupower/lib/powercap.c @@ -0,0 +1,307 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2016 SUSE Software Solutions GmbH + * Thomas Renninger + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "powercap.h" + +static unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) +{ + int fd; + ssize_t numread; + + fd = open(path, O_RDONLY); + if (fd == -1) + return 0; + + numread = read(fd, buf, buflen - 1); + if (numread < 1) { + close(fd); + return 0; + } + + buf[numread] = '\0'; + close(fd); + + return (unsigned int) numread; +} + +static int sysfs_get_enabled(char *path, int *mode) +{ + int fd; + char yes_no; + int ret = 0; + + *mode = 0; + + fd = open(path, O_RDONLY); + if (fd == -1) { + ret = -1; + goto out; + } + + if (read(fd, &yes_no, 1) != 1) { + ret = -1; + goto out_close; + } + + if (yes_no == '1') { + *mode = 1; + goto out_close; + } else if (yes_no == '0') { + goto out_close; + } else { + ret = -1; + goto out_close; + } +out_close: + close(fd); +out: + return ret; +} + +int powercap_get_enabled(int *mode) +{ + char path[SYSFS_PATH_MAX] = PATH_TO_POWERCAP "/intel-rapl/enabled"; + + return sysfs_get_enabled(path, 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 + */ +int powercap_get_driver(char *driver, int buflen) +{ + char file[SYSFS_PATH_MAX] = PATH_TO_RAPL; + + struct stat statbuf; + + if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) { + driver = ""; + return -1; + } else if (buflen > 10) { + strcpy(driver, "intel-rapl"); + return 0; + } else + return -1; +} + +enum powercap_get64 { + GET_ENERGY_UJ, + GET_MAX_ENERGY_RANGE_UJ, + GET_POWER_UW, + GET_MAX_POWER_RANGE_UW, + MAX_GET_64_FILES +}; + +static const char *powercap_get64_files[MAX_GET_64_FILES] = { + [GET_POWER_UW] = "power_uw", + [GET_MAX_POWER_RANGE_UW] = "max_power_range_uw", + [GET_ENERGY_UJ] = "energy_uj", + [GET_MAX_ENERGY_RANGE_UJ] = "max_energy_range_uj", +}; + +static int sysfs_powercap_get64_val(struct powercap_zone *zone, + enum powercap_get64 which, + uint64_t *val) +{ + char file[SYSFS_PATH_MAX] = PATH_TO_POWERCAP "/"; + int ret; + char buf[MAX_LINE_LEN]; + + strcat(file, zone->sys_name); + strcat(file, "/"); + strcat(file, powercap_get64_files[which]); + + ret = sysfs_read_file(file, buf, MAX_LINE_LEN); + if (ret < 0) + return ret; + if (ret == 0) + return -1; + + *val = strtoll(buf, NULL, 10); + return 0; +} + +int powercap_get_max_energy_range_uj(struct powercap_zone *zone, uint64_t *val) +{ + return sysfs_powercap_get64_val(zone, GET_MAX_ENERGY_RANGE_UJ, val); +} + +int powercap_get_energy_uj(struct powercap_zone *zone, uint64_t *val) +{ + return sysfs_powercap_get64_val(zone, GET_ENERGY_UJ, val); +} + +int powercap_get_max_power_range_uw(struct powercap_zone *zone, uint64_t *val) +{ + return sysfs_powercap_get64_val(zone, GET_MAX_POWER_RANGE_UW, val); +} + +int powercap_get_power_uw(struct powercap_zone *zone, uint64_t *val) +{ + return sysfs_powercap_get64_val(zone, GET_POWER_UW, val); +} + +int powercap_zone_get_enabled(struct powercap_zone *zone, int *mode) +{ + char path[SYSFS_PATH_MAX] = PATH_TO_POWERCAP; + + if ((strlen(PATH_TO_POWERCAP) + strlen(zone->sys_name)) + + strlen("/enabled") + 1 >= SYSFS_PATH_MAX) + return -1; + + strcat(path, "/"); + strcat(path, zone->sys_name); + strcat(path, "/enabled"); + + return sysfs_get_enabled(path, mode); +} + +int powercap_zone_set_enabled(struct powercap_zone *zone, int mode) +{ + /* To be done if needed */ + return 0; +} + + +int powercap_read_zone(struct powercap_zone *zone) +{ + struct dirent *dent; + DIR *zone_dir; + char sysfs_dir[SYSFS_PATH_MAX] = PATH_TO_POWERCAP; + struct powercap_zone *child_zone; + char file[SYSFS_PATH_MAX] = PATH_TO_POWERCAP; + int i, ret = 0; + uint64_t val = 0; + + strcat(sysfs_dir, "/"); + strcat(sysfs_dir, zone->sys_name); + + zone_dir = opendir(sysfs_dir); + if (zone_dir == NULL) + return -1; + + strcat(file, "/"); + strcat(file, zone->sys_name); + strcat(file, "/name"); + sysfs_read_file(file, zone->name, MAX_LINE_LEN); + if (zone->parent) + zone->tree_depth = zone->parent->tree_depth + 1; + ret = powercap_get_energy_uj(zone, &val); + if (ret == 0) + zone->has_energy_uj = 1; + ret = powercap_get_power_uw(zone, &val); + if (ret == 0) + zone->has_power_uw = 1; + + while ((dent = readdir(zone_dir)) != NULL) { + struct stat st; + + if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) + continue; + + if (stat(dent->d_name, &st) != 0 || !S_ISDIR(st.st_mode)) + if (fstatat(dirfd(zone_dir), dent->d_name, &st, 0) < 0) + continue; + + if (strncmp(dent->d_name, "intel-rapl:", 11) != 0) + continue; + + child_zone = calloc(1, sizeof(struct powercap_zone)); + if (child_zone == NULL) + return -1; + for (i = 0; i < POWERCAP_MAX_CHILD_ZONES; i++) { + if (zone->children[i] == NULL) { + zone->children[i] = child_zone; + break; + } + if (i == POWERCAP_MAX_CHILD_ZONES - 1) { + free(child_zone); + fprintf(stderr, "Reached POWERCAP_MAX_CHILD_ZONES %d\n", + POWERCAP_MAX_CHILD_ZONES); + return -1; + } + } + strcpy(child_zone->sys_name, zone->sys_name); + strcat(child_zone->sys_name, "/"); + strcat(child_zone->sys_name, dent->d_name); + child_zone->parent = zone; + if (zone->tree_depth >= POWERCAP_MAX_TREE_DEPTH) { + fprintf(stderr, "Maximum zone hierarchy depth[%d] reached\n", + POWERCAP_MAX_TREE_DEPTH); + ret = -1; + break; + } + powercap_read_zone(child_zone); + } + closedir(zone_dir); + return ret; +} + +struct powercap_zone *powercap_init_zones(void) +{ + int enabled; + struct powercap_zone *root_zone; + int ret; + char file[SYSFS_PATH_MAX] = PATH_TO_RAPL "/enabled"; + + ret = sysfs_get_enabled(file, &enabled); + + if (ret) + return NULL; + + if (!enabled) + return NULL; + + root_zone = calloc(1, sizeof(struct powercap_zone)); + if (!root_zone) + return NULL; + + strcpy(root_zone->sys_name, "intel-rapl/intel-rapl:0"); + + powercap_read_zone(root_zone); + + return root_zone; +} + +/* Call function *f on the passed zone and all its children */ + +int powercap_walk_zones(struct powercap_zone *zone, + int (*f)(struct powercap_zone *zone)) +{ + int i, ret; + + if (!zone) + return -1; + + ret = f(zone); + if (ret) + return ret; + + for (i = 0; i < POWERCAP_MAX_CHILD_ZONES; i++) { + if (zone->children[i] != NULL) + powercap_walk_zones(zone->children[i], f); + } + return 0; +} diff --git a/tools/power/cpupower/lib/powercap.h b/tools/power/cpupower/lib/powercap.h new file mode 100644 index 000000000..c049c109f --- /dev/null +++ b/tools/power/cpupower/lib/powercap.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * (C) 2016 SUSE Software Solutions GmbH + * Thomas Renninger + */ + +#ifndef __CPUPOWER_RAPL_H__ +#define __CPUPOWER_RAPL_H__ + +#define PATH_TO_POWERCAP "/sys/devices/virtual/powercap" +#define PATH_TO_RAPL "/sys/devices/virtual/powercap/intel-rapl" +#define PATH_TO_RAPL_CLASS "/sys/devices/virtual/powercap/intel-rapl" + +#define POWERCAP_MAX_CHILD_ZONES 10 +#define POWERCAP_MAX_TREE_DEPTH 10 + +#define MAX_LINE_LEN 4096 +#define SYSFS_PATH_MAX 255 + +#include + +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); + + +#endif /* __CPUPOWER_RAPL_H__ */ diff --git a/tools/power/cpupower/man/cpupower-frequency-info.1 b/tools/power/cpupower/man/cpupower-frequency-info.1 new file mode 100644 index 000000000..b0d69c9ad --- /dev/null +++ b/tools/power/cpupower/man/cpupower-frequency-info.1 @@ -0,0 +1,86 @@ +.TH "CPUPOWER\-FREQUENCY\-INFO" "1" "0.1" "" "cpupower Manual" +.SH "NAME" +.LP +cpupower\-frequency\-info \- Utility to retrieve cpufreq kernel information +.SH "SYNTAX" +.LP +cpupower [ \-c cpulist ] frequency\-info [\fIoptions\fP] +.SH "DESCRIPTION" +.LP +A small tool which prints out cpufreq information helpful to developers and interested users. +.SH "OPTIONS" +.LP +.TP +\fB\-e\fR \fB\-\-debug\fR +Prints out debug information. +.TP +\fB\-f\fR \fB\-\-freq\fR +Get frequency the CPU currently runs at, according to the cpufreq core. +.TP +\fB\-w\fR \fB\-\-hwfreq\fR +Get frequency the CPU currently runs at, by reading it from hardware (only available to root). +.TP +\fB\-l\fR \fB\-\-hwlimits\fR +Determine the minimum and maximum CPU frequency allowed. +.TP +\fB\-d\fR \fB\-\-driver\fR +Determines the used cpufreq kernel driver. +.TP +\fB\-p\fR \fB\-\-policy\fR +Gets the currently used cpufreq policy. +.TP +\fB\-g\fR \fB\-\-governors\fR +Determines available cpufreq governors. +.TP +\fB\-b\fR \fB\-\-boost\fR +Gets the current boost state support. +.TP +\fB\-z\fR \fB\-\-epp\fR +Gets the current EPP (energy performance preference). +.TP +\fB\-r\fR \fB\-\-related\-cpus\fR +Determines which CPUs run at the same hardware frequency. +.TP +\fB\-a\fR \fB\-\-affected\-cpus\fR +Determines which CPUs need to have their frequency coordinated by software. +.TP +\fB\-s\fR \fB\-\-stats\fR +Shows cpufreq statistics if available. +.TP +\fB\-y\fR \fB\-\-latency\fR +Determines the maximum latency on CPU frequency changes. +.TP +\fB\-o\fR \fB\-\-proc\fR +Prints out information like provided by the /proc/cpufreq interface in 2.4. and early 2.6. kernels. +.TP +\fB\-m\fR \fB\-\-human\fR +human\-readable output for the \-f, \-w, \-s and \-y parameters. +.TP +\fB\-n\fR \fB\-\-no-rounding\fR +Output frequencies and latencies without rounding off values. +.TP +\fB\-c\fR \fB\-\-performance\fR +Get performances and frequencies capabilities of CPPC, by reading it from hardware (only available on the hardware with CPPC). +.TP +.SH "REMARKS" +.LP +By default only values of core zero are displayed. How to display settings of +other cores is described in the cpupower(1) manpage in the \-\-cpu option section. +.LP +You can't specify more than one of the output specific options \-o \-e \-a \-g \-p \-d \-l \-w \-f \-y. +.LP +You also can't specify the \-o option combined with the \-c option. +.SH "FILES" +.nf +\fI/sys/devices/system/cpu/cpu*/cpufreq/\fP +\fI/proc/cpufreq\fP (deprecated) +\fI/proc/sys/cpu/\fP (deprecated) +.fi +.SH "AUTHORS" +.nf +Dominik Brodowski \- author +Mattia Dongili \- first autolibtoolization +.fi +.SH "SEE ALSO" +.LP +cpupower\-frequency\-set(1), cpupower(1) diff --git a/tools/power/cpupower/man/cpupower-frequency-set.1 b/tools/power/cpupower/man/cpupower-frequency-set.1 new file mode 100644 index 000000000..b50570221 --- /dev/null +++ b/tools/power/cpupower/man/cpupower-frequency-set.1 @@ -0,0 +1,52 @@ +.TH "CPUPOWER\-FREQUENCY\-SET" "1" "0.1" "" "cpupower Manual" +.SH "NAME" +.LP +cpupower\-frequency\-set \- A small tool which allows to modify cpufreq settings. +.SH "SYNTAX" +.LP +cpupower [ \-c cpu ] frequency\-set [\fIoptions\fP] +.SH "DESCRIPTION" +.LP +cpupower frequency\-set allows you to modify cpufreq settings without having to type e.g. "/sys/devices/system/cpu/cpu0/cpufreq/scaling_set_speed" all the time. +.SH "OPTIONS" +.LP +.TP +\fB\-d\fR \fB\-\-min\fR +new minimum CPU frequency the governor may select. +.TP +\fB\-u\fR \fB\-\-max\fR +new maximum CPU frequency the governor may select. +.TP +\fB\-g\fR \fB\-\-governor\fR +new cpufreq governor. +.TP +\fB\-f\fR \fB\-\-freq\fR +specific frequency to be set. Requires userspace governor to be available and loaded. +.TP +\fB\-r\fR \fB\-\-related\fR +modify all hardware-related CPUs at the same time +.TP +.SH "REMARKS" +.LP +By default values are applied on all cores. How to modify single core +configurations is described in the cpupower(1) manpage in the \-\-cpu option section. +.LP +The \-f FREQ, \-\-freq FREQ parameter cannot be combined with any other parameter. +.LP +FREQuencies can be passed in Hz, kHz (default), MHz, GHz, or THz by postfixing the value with the wanted unit name, without any space (frequency in kHz =^ Hz * 0.001 =^ MHz * 1000 =^ GHz * 1000000). +.LP +On Linux kernels up to 2.6.29, the \-r or \-\-related parameter is ignored. +.SH "FILES" +.nf +\fI/sys/devices/system/cpu/cpu*/cpufreq/\fP +\fI/proc/cpufreq\fP (deprecated) +\fI/proc/sys/cpu/\fP (deprecated) +.fi +.SH "AUTHORS" +.nf +Dominik Brodowski \- author +Mattia Dongili \- first autolibtoolization +.fi +.SH "SEE ALSO" +.LP +cpupower\-frequency\-info(1), cpupower(1) diff --git a/tools/power/cpupower/man/cpupower-idle-info.1 b/tools/power/cpupower/man/cpupower-idle-info.1 new file mode 100644 index 000000000..b2f92aba5 --- /dev/null +++ b/tools/power/cpupower/man/cpupower-idle-info.1 @@ -0,0 +1,91 @@ +.TH "CPUPOWER-IDLE-INFO" "1" "0.1" "" "cpupower Manual" +.SH "NAME" +.LP +cpupower\-idle\-info \- Utility to retrieve cpu idle kernel information +.SH "SYNTAX" +.LP +cpupower [ \-c cpulist ] idle\-info [\fIoptions\fP] +.SH "DESCRIPTION" +.LP +A tool which prints out per cpu idle information helpful to developers and interested users. +.SH "OPTIONS" +.LP +.TP +\fB\-s\fR \fB\-\-silent\fR +Only print a summary of all available C-states in the system. +.TP +\fB\-o\fR \fB\-\-proc\fR +deprecated. +Prints out idle information in old /proc/acpi/processor/*/power format. This +interface has been removed from the kernel for quite some time, do not let +further code depend on this option, best do not use it. + +.SH IDLE\-INFO DESCRIPTIONS +CPU sleep state statistics and descriptions are retrieved from sysfs files, +exported by the cpuidle kernel subsystem. The kernel only updates these +statistics when it enters or leaves an idle state, therefore on a very idle or +a very busy system, these statistics may not be accurate. They still provide a +good overview about the usage and availability of processor sleep states on +the platform. + +Be aware that the sleep states as exported by the hardware or BIOS and used by +the Linux kernel may not exactly reflect the capabilities of the +processor. This often is the case on the X86 architecture when the acpi_idle +driver is used. It is also possible that the hardware overrules the kernel +requests, due to internal activity monitors or other reasons. +On recent X86 platforms it is often possible to read out hardware registers +which monitor the duration of sleep states the processor resided in. The +cpupower monitor tool (cpupower\-monitor(1)) can be used to show real sleep +state residencies. Please refer to the architecture specific description +section below. + +.SH IDLE\-INFO ARCHITECTURE SPECIFIC DESCRIPTIONS +.SS "X86" +POLL idle state + +If cpuidle is active, X86 platforms have one special idle state. +The POLL idle state is not a real idle state, it does not save any +power. Instead, a busy\-loop is executed doing nothing for a short period of +time. This state is used if the kernel knows that work has to be processed +very soon and entering any real hardware idle state may result in a slight +performance penalty. + +There exist two different cpuidle drivers on the X86 architecture platform: + +"acpi_idle" cpuidle driver + +The acpi_idle cpuidle driver retrieves available sleep states (C\-states) from +the ACPI BIOS tables (from the _CST ACPI function on recent platforms or from +the FADT BIOS table on older ones). +The C1 state is not retrieved from ACPI tables. If the C1 state is entered, +the kernel will call the hlt instruction (or mwait on Intel). + +"intel_idle" cpuidle driver + +In kernel 2.6.36 the intel_idle driver was introduced. +It only serves recent Intel CPUs (Nehalem, Westmere, Sandybridge, Atoms or +newer). On older Intel CPUs the acpi_idle driver is still used (if the BIOS +provides C\-state ACPI tables). +The intel_idle driver knows the sleep state capabilities of the processor and +ignores ACPI BIOS exported processor sleep states tables. + +.SH "REMARKS" +.LP +By default only values of core zero are displayed. How to display settings of +other cores is described in the cpupower(1) manpage in the \-\-cpu option +section. +.SH REFERENCES +https://uefi.org/specifications +.SH "FILES" +.nf +\fI/sys/devices/system/cpu/cpu*/cpuidle/state*\fP +\fI/sys/devices/system/cpu/cpuidle/*\fP +.fi +.SH "AUTHORS" +.nf +Thomas Renninger +.fi +.SH "SEE ALSO" +.LP +cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1), +cpupower\-idle\-set(1) diff --git a/tools/power/cpupower/man/cpupower-idle-set.1 b/tools/power/cpupower/man/cpupower-idle-set.1 new file mode 100644 index 000000000..8cef3c71e --- /dev/null +++ b/tools/power/cpupower/man/cpupower-idle-set.1 @@ -0,0 +1,79 @@ +.TH "CPUPOWER-IDLE-SET" "1" "0.1" "" "cpupower Manual" +.SH "NAME" +.LP +cpupower\-idle\-set \- Utility to set cpu idle state specific kernel options +.SH "SYNTAX" +.LP +cpupower [ \-c cpulist ] idle\-set [\fIoptions\fP] +.SH "DESCRIPTION" +.LP +The cpupower idle\-set subcommand allows to set cpu idle, also called cpu +sleep state, specific options offered by the kernel. One example is disabling +sleep states. This can be handy for power vs performance tuning. +.SH "OPTIONS" +.LP +.TP +\fB\-d\fR \fB\-\-disable\fR +Disable a specific processor sleep state. +.TP +\fB\-e\fR \fB\-\-enable\fR +Enable a specific processor sleep state. +.TP +\fB\-D\fR \fB\-\-disable-by-latency\fR +Disable all idle states with a equal or higher latency than . + +Enable all idle states with a latency lower than . +.TP +\fB\-E\fR \fB\-\-enable-all\fR +Enable all idle states if not enabled already. + +.SH "REMARKS" +.LP +Cpuidle Governors Policy on Disabling Sleep States + +.RS 4 +Depending on the used cpuidle governor, implementing the kernel policy +how to choose sleep states, subsequent sleep states on this core, might get +disabled as well. + +There are two cpuidle governors ladder and menu. While the ladder +governor is always available, if CONFIG_CPU_IDLE is selected, the +menu governor additionally requires CONFIG_NO_HZ. + +The behavior and the effect of the disable variable depends on the +implementation of a particular governor. In the ladder governor, for +example, it is not coherent, i.e. if one is disabling a light state, +then all deeper states are disabled as well. Likewise, if one enables a +deep state but a lighter state still is disabled, then this has no effect. +.RE +.LP +Disabling the Lightest Sleep State may not have any Affect + +.RS 4 +If criteria are not met to enter deeper sleep states and the lightest sleep +state is chosen when idle, the kernel may still enter this sleep state, +irrespective of whether it is disabled or not. This is also reflected in +the usage count of the disabled sleep state when using the cpupower idle-info +command. +.RE +.LP +Selecting specific CPU Cores + +.RS 4 +By default processor sleep states of all CPU cores are set. Please refer +to the cpupower(1) manpage in the \-\-cpu option section how to disable +C-states of specific cores. +.RE +.SH "FILES" +.nf +\fI/sys/devices/system/cpu/cpu*/cpuidle/state*\fP +\fI/sys/devices/system/cpu/cpuidle/*\fP +.fi +.SH "AUTHORS" +.nf +Thomas Renninger +.fi +.SH "SEE ALSO" +.LP +cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1), +cpupower\-idle\-info(1) diff --git a/tools/power/cpupower/man/cpupower-info.1 b/tools/power/cpupower/man/cpupower-info.1 new file mode 100644 index 000000000..1f42d8c38 --- /dev/null +++ b/tools/power/cpupower/man/cpupower-info.1 @@ -0,0 +1,26 @@ +.TH CPUPOWER\-INFO "1" "22/02/2011" "" "cpupower Manual" +.SH NAME +cpupower\-info \- Shows processor power related kernel or hardware configurations +.SH SYNOPSIS +.ft B +.B cpupower info [\fIoptions\fP] + +.SH DESCRIPTION +\fBcpupower info \fP shows kernel configurations or processor hardware +registers affecting processor power saving policies. + +Some options are platform wide, some affect single cores. By default values +of core zero are displayed only. cpupower --cpu all cpuinfo will show the +settings of all cores, see cpupower(1) how to choose specific cores. + +.SH "OPTIONS" +.LP +.TP +\fB\-b\fR \fB\-\-perf-bias\fR +Gets the current performance bias value. +.TP + +.SH "SEE ALSO" +Options are described in detail in: + +cpupower(1), cpupower-set(1) diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1 new file mode 100644 index 000000000..89af019f8 --- /dev/null +++ b/tools/power/cpupower/man/cpupower-monitor.1 @@ -0,0 +1,195 @@ +.TH CPUPOWER\-MONITOR "1" "22/02/2011" "" "cpupower Manual" +.SH NAME +cpupower\-monitor \- Report processor frequency and idle statistics +.SH SYNOPSIS +.ft B +.B cpupower monitor +.RB "\-l" + +.B cpupower monitor +.RB [ -c ] [ "\-m ," [ ",..." ] ] +.RB [ "\-i seconds" ] +.br +.B cpupower monitor +.RB [ -c ][ "\-m ," [ ",..." ] ] +.RB command +.br +.SH DESCRIPTION +\fBcpupower-monitor \fP reports processor topology, frequency and idle power +state statistics. Either \fBcommand\fP is forked and +statistics are printed upon its completion, or statistics are printed periodically. + +\fBcpupower-monitor \fP implements independent processor sleep state and +frequency counters. Some are retrieved from kernel statistics, some are +directly reading out hardware registers. Use \-l to get an overview which are +supported on your system. + +.SH Options +.PP +\-l +.RS 4 +List available monitors on your system. Additional details about each monitor +are shown: +.RS 2 +.IP \(bu +The name in quotation marks which can be passed to the \-m parameter. +.IP \(bu +The number of different counters the monitor supports in brackets. +.IP \(bu +The amount of time in seconds the counters might overflow, due to +implementation constraints. +.IP \(bu +The name and a description of each counter and its processor hierarchy level +coverage in square brackets: +.RS 4 +.IP \(bu +[T] \-> Thread +.IP \(bu +[C] \-> Core +.IP \(bu +[P] \-> Processor Package (Socket) +.IP \(bu +[M] \-> Machine/Platform wide counter +.RE +.RE +.RE +.PP +\-m ,,... +.RS 4 +Only display specific monitors. Use the monitor string(s) provided by \-l option. +.RE +.PP +\-i seconds +.RS 4 +Measure interval. +.RE +.PP +\-c +.RS 4 +Schedule the process on every core before starting and ending measuring. +This could be needed for the Idle_Stats monitor when no other MSR based +monitor (has to be run on the core that is measured) is run in parallel. +This is to wake up the processors from deeper sleep states and let the +kernel re +-account its cpuidle (C-state) information before reading the +cpuidle timings from sysfs. +.RE +.PP +command +.RS 4 +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 + +.SH MONITOR DESCRIPTIONS +.SS "Idle_Stats" +Shows statistics of the cpuidle kernel subsystem. Values are retrieved from +/sys/devices/system/cpu/cpu*/cpuidle/state*/. +The kernel updates these values every time an idle state is entered or +left. Therefore there can be some inaccuracy when cores are in an idle +state for some time when the measure starts or ends. In worst case it can happen +that one core stayed in an idle state for the whole measure time and the idle +state usage time as exported by the kernel did not get updated. In this case +a state residency of 0 percent is shown while it was 100. + +.SS "Mperf" +The name comes from the aperf/mperf (average and maximum) MSR registers used +which are available on recent X86 processors. It shows the average frequency +(including boost frequencies). +The fact that on all recent hardware the mperf timer stops ticking in any idle +state it is also used to show C0 (processor is active) and Cx (processor is in +any sleep state) times. These counters do not have the inaccuracy restrictions +the "Idle_Stats" counters may show. +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" "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. +The registers are accessed via PCI and therefore can still be read out while +cores have been offlined. + +There is one special counter: NBP1 (North Bridge P1). +This one always returns 0 or 1, depending on whether the North Bridge P1 +power state got entered at least once during measure time. +Being able to enter NBP1 state also depends on graphics power management. +Therefore this counter can be used to verify whether the graphics' driver +power management is working as expected. + +.SH EXAMPLES + +cpupower monitor -l" may show: +.RS 4 +Monitor "Mperf" (3 states) \- Might overflow after 922000000 s + + ... + +Monitor "Idle_Stats" (3 states) \- Might overflow after 4294967295 s + + ... + +.RE +cpupower monitor \-m "Idle_Stats,Mperf" scp /tmp/test /nfs/tmp + +Monitor the scp command, show both Mperf and Idle_Stats states counter +statistics, but in exchanged order. + + + +.RE +Be careful that the typical command to fully utilize one CPU by doing: + +cpupower monitor cat /dev/zero >/dev/null + +Does not work as expected, because the measured output is redirected to +/dev/null. This could get workarounded by putting the line into an own, tiny +shell script. Hit CTRL\-c to terminate the command and get the measure output +displayed. + +.SH REFERENCES +"BIOS and Kernel Developer’s Guide (BKDG) for AMD Family 14h Processors" +https://support.amd.com/us/Processor_TechDocs/43170.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" +https://www.intel.com/products/processor/manuals + +.SH FILES +.ta +.nf +/dev/cpu/*/msr +/sys/devices/system/cpu/cpu*/cpuidle/state*/. +.fi + +.SH "SEE ALSO" +powertop(8), msr(4), vmstat(8) +.PP +.SH AUTHORS +.nf +Written by Thomas Renninger + +Nehalem, SandyBridge monitors and command passing +based on turbostat.8 from Len Brown diff --git a/tools/power/cpupower/man/cpupower-powercap-info.1 b/tools/power/cpupower/man/cpupower-powercap-info.1 new file mode 100644 index 000000000..145d6f06f --- /dev/null +++ b/tools/power/cpupower/man/cpupower-powercap-info.1 @@ -0,0 +1,25 @@ +.TH CPUPOWER\-POWERCAP\-INFO "1" "05/08/2016" "" "cpupower Manual" +.SH NAME +cpupower\-powercap\-info \- Shows powercapping related kernel and hardware configurations +.SH SYNOPSIS +.ft B +.B cpupower powercap-info + +.SH DESCRIPTION +\fBcpupower powercap-info \fP shows kernel powercapping subsystem information. +This needs hardware support and a loaded powercapping driver (at this time only +intel_rapl driver exits) exporting hardware values userspace via sysfs. + +Some options are platform wide, some affect single cores. By default values +of core zero are displayed only. cpupower --cpu all cpuinfo will show the +settings of all cores, see cpupower(1) how to choose specific cores. + +.SH "DOCUMENTATION" + +kernel sources: +Documentation/power/powercap/powercap.rst + + +.SH "SEE ALSO" + +cpupower(1) diff --git a/tools/power/cpupower/man/cpupower-set.1 b/tools/power/cpupower/man/cpupower-set.1 new file mode 100644 index 000000000..8ac82b6f9 --- /dev/null +++ b/tools/power/cpupower/man/cpupower-set.1 @@ -0,0 +1,100 @@ +.TH CPUPOWER\-SET "1" "22/02/2011" "" "cpupower Manual" +.SH NAME +cpupower\-set \- Set processor power related kernel or hardware configurations +.SH SYNOPSIS +.ft B +.B cpupower set [ \-b VAL | \-e POLICY | \-m MODE | \-t BOOL ] + + +.SH DESCRIPTION +\fBcpupower set \fP sets kernel configurations or directly accesses hardware +registers affecting processor power saving policies. + +Some options are platform wide, some affect single cores. By default values +are applied on all cores. How to modify single core configurations is +described in the cpupower(1) manpage in the \-\-cpu option section. Whether an +option affects the whole system or can be applied to individual cores is +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 +.PP +\-\-perf-bias, \-b +.RS 4 +Sets 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. + +The range of valid numbers is 0-15, where 0 is maximum +performance and 15 is maximum energy efficiency. + +The processor uses this information in model-specific ways +when it must select trade-offs between performance and +energy efficiency. + +This policy hint does not supersede Processor Performance states +(P-states) or CPU Idle power states (C-states), but allows +software to have influence where it would otherwise be unable +to express a preference. + +For example, this setting may tell the hardware how +aggressively or conservatively to control frequency +in the "turbo range" above the explicitly OS-controlled +P-state frequency range. It may also tell the hardware +how aggressively it should enter the OS requested C-states. + +This option can be applied to individual cores only via the \-\-cpu option, +cpupower(1). + +Setting the performance bias value on one CPU can modify the setting on +related CPUs as well (for example all CPUs on one socket), because of +hardware restrictions. +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, \-\-boost, \-t +.RS 4 +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. + +.RE + +.SH "SEE ALSO" +cpupower-info(1), cpupower-monitor(1), powertop(1) +.PP +.SH AUTHORS +.nf +\-\-perf\-bias parts written by Len Brown +Thomas Renninger diff --git a/tools/power/cpupower/man/cpupower.1 b/tools/power/cpupower/man/cpupower.1 new file mode 100644 index 000000000..a5e4523a2 --- /dev/null +++ b/tools/power/cpupower/man/cpupower.1 @@ -0,0 +1,72 @@ +.TH CPUPOWER "1" "07/03/2011" "" "cpupower Manual" +.SH NAME +cpupower \- Shows and sets processor power related values +.SH SYNOPSIS +.ft B +.B cpupower [ \-c cpulist ] [ARGS] + +.B cpupower \-v|\-\-version + +.B cpupower \-h|\-\-help + +.SH DESCRIPTION +\fBcpupower \fP is a collection of tools to examine and tune power saving +related features of your processor. + +The manpages of the commands (cpupower\-(1)) provide detailed +descriptions of supported features. Run \fBcpupower help\fP to get an overview +of supported commands. + +.SH Options +.PP +\-\-help, \-h +.RS 4 +Shows supported commands and general usage. +.RE +.PP +\-\-cpu cpulist, \-c cpulist +.RS 4 +Only show or set values for specific cores. +This option is not supported by all commands, details can be found in the +manpages of the commands. + +Some commands access all cores (typically the *\-set commands), some only +the first core (typically the *\-info commands) by default. + +The syntax for is based on how the kernel exports CPU bitmasks via +sysfs files. Some examples: +.RS 4 +.TP 16 +Input +Equivalent to +.TP +all +all cores +.TP +0\-3 +0,1,2,3 +.TP +0\-7:2 +0,2,4,6 +.TP +1,3,5-7 +1,3,5,6,7 +.TP +0\-3:2,8\-15:4 +0,2,8,12 +.RE +.RE +.PP +\-\-version, \-v +.RS 4 +Print the package name and version number. + +.SH "SEE ALSO" +cpupower-set(1), cpupower-info(1), cpupower-idle-info(1), +cpupower-idle-set(1), cpupower-frequency-set(1), cpupower-frequency-info(1), +cpupower-monitor(1), powertop(1) +.PP +.SH AUTHORS +.nf +\-\-perf\-bias parts written by Len Brown +Thomas Renninger diff --git a/tools/power/cpupower/po/cs.po b/tools/power/cpupower/po/cs.po new file mode 100644 index 000000000..bfc7e1702 --- /dev/null +++ b/tools/power/cpupower/po/cs.po @@ -0,0 +1,944 @@ +# translation of cs.po to Czech +# Czech translation for cpufrequtils package +# Czech messages for cpufrequtils. +# Copyright (C) 2007 kavol +# This file is distributed under the same license as the cpufrequtils package. +# +# Karel Volný , 2007, 2008. +msgid "" +msgstr "" +"Project-Id-Version: cs\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-03-08 17:03+0100\n" +"PO-Revision-Date: 2008-06-11 16:26+0200\n" +"Last-Translator: Karel Volný \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" +"X-Generator: KBabel 1.11.4\n" + +#: utils/idle_monitor/nhm_idle.c:36 +msgid "Processor Core C3" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:43 +msgid "Processor Core C6" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:51 +msgid "Processor Package C3" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70 +msgid "Processor Package C6" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:33 +msgid "Processor Core C7" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:40 +msgid "Processor Package C2" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:47 +msgid "Processor Package C7" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:56 +msgid "Package in sleep state (PC1 or deeper)" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:63 +msgid "Processor Package C1" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:77 +msgid "North Bridge P1 boolean counter (returns 0 or 1)" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:35 +msgid "Processor Core not idle" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:42 +msgid "Processor Core in an idle state" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:50 +msgid "Average Frequency (including boost) in MHz" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:66 +#, c-format +msgid "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:69 +#, c-format +msgid "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:71 +#, c-format +msgid "\t -v: be more verbose\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:73 +#, c-format +msgid "\t -h: print this help\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:74 +#, c-format +msgid "\t -i: time interval to measure for in seconds (default 1)\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:75 +#, c-format +msgid "\t -t: show CPU topology/hierarchy\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:76 +#, c-format +msgid "\t -l: list available CPU sleep monitors (for use with -m)\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:77 +#, c-format +msgid "\t -m: show specific CPU sleep monitors only (in same order)\n" +msgstr "" + +#: 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 "" + +#: utils/idle_monitor/cpupower-monitor.c:80 +#, c-format +msgid " all supported monitors are shown\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:197 +#, c-format +msgid "Monitor %s, Counter %s has no count function. Implementation error\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:207 +#, c-format +msgid " *is offline\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:236 +#, c-format +msgid "%s: max monitor name length (%d) exceeded\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:250 +#, c-format +msgid "No matching monitor found in %s, try -l option\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:266 +#, c-format +msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:319 +#, c-format +msgid "%s took %.5f seconds and exited with status %d\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:406 +#, c-format +msgid "Cannot read number of available processors\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:417 +#, c-format +msgid "Available monitor %s needs root access\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:428 +#, c-format +msgid "No HW Cstate monitors found\n" +msgstr "" + +#: utils/cpupower.c:78 +#, c-format +msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n" +msgstr "" + +#: utils/cpupower.c:79 +#, c-format +msgid "cpupower --version\n" +msgstr "" + +#: utils/cpupower.c:80 +#, c-format +msgid "Supported subcommands are:\n" +msgstr "" + +#: utils/cpupower.c:83 +#, c-format +msgid "" +"\n" +"Some subcommands can make use of the -c cpulist option.\n" +msgstr "" + +#: utils/cpupower.c:84 +#, c-format +msgid "Look at the general cpupower manpage how to use it\n" +msgstr "" + +#: utils/cpupower.c:85 +#, c-format +msgid "and read up the subcommand's manpage whether it is supported.\n" +msgstr "" + +#: utils/cpupower.c:86 +#, c-format +msgid "" +"\n" +"Use cpupower help subcommand for getting help for above subcommands.\n" +msgstr "" + +#: utils/cpupower.c:91 +#, c-format +msgid "Report errors and bugs to %s, please.\n" +msgstr "" +"Chyby v programu prosím hlaste na %s (anglicky).\n" +"Chyby v překladu prosím hlaste na kavol@seznam.cz (česky ;-)\n" + +#: utils/cpupower.c:114 +#, c-format +msgid "Error parsing cpu list\n" +msgstr "" + +#: utils/cpupower.c:172 +#, c-format +msgid "Subcommand %s needs root privileges\n" +msgstr "" + +#: utils/cpufreq-info.c:31 +#, c-format +msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n" +msgstr "Nelze zjistit počet CPU (%s: %s), předpokládá se 1.\n" + +#: utils/cpufreq-info.c:63 +#, c-format +msgid "" +" minimum CPU frequency - maximum CPU frequency - governor\n" +msgstr "" +" minimální frekvence CPU - maximální frekvence CPU - regulátor\n" + +#: utils/cpufreq-info.c:151 +#, c-format +msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n" +msgstr "" + +#. 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 "" + +#: utils/cpufreq-info.c:163 +#, c-format +msgid " Supported: %s\n" +msgstr "" + +#: 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 +#, fuzzy, c-format +msgid " Active: %s\n" +msgstr " ovladač: %s\n" + +#: utils/cpufreq-info.c:177 +#, c-format +msgid " Boost States: %d\n" +msgstr "" + +#: utils/cpufreq-info.c:178 +#, c-format +msgid " Total States: %d\n" +msgstr "" + +#: utils/cpufreq-info.c:181 +#, c-format +msgid " Pstate-Pb%d: %luMHz (boost state)\n" +msgstr "" + +#: utils/cpufreq-info.c:184 +#, c-format +msgid " Pstate-P%d: %luMHz\n" +msgstr "" + +#: utils/cpufreq-info.c:211 +#, c-format +msgid " no or unknown cpufreq driver is active on this CPU\n" +msgstr " pro tento CPU není aktivní žádný známý ovladač cpufreq\n" + +#: utils/cpufreq-info.c:213 +#, c-format +msgid " driver: %s\n" +msgstr " ovladač: %s\n" + +#: utils/cpufreq-info.c:219 +#, fuzzy, c-format +msgid " CPUs which run at the same hardware frequency: " +msgstr " CPU, které musí měnit frekvenci zároveň: " + +#: utils/cpufreq-info.c:230 +#, fuzzy, c-format +msgid " CPUs which need to have their frequency coordinated by software: " +msgstr " CPU, které musí měnit frekvenci zároveň: " + +#: utils/cpufreq-info.c:241 +#, c-format +msgid " maximum transition latency: " +msgstr "" + +#: utils/cpufreq-info.c:247 +#, c-format +msgid " hardware limits: " +msgstr " hardwarové meze: " + +#: utils/cpufreq-info.c:256 +#, c-format +msgid " available frequency steps: " +msgstr " dostupné frekvence: " + +#: utils/cpufreq-info.c:269 +#, c-format +msgid " available cpufreq governors: " +msgstr " dostupné regulátory: " + +#: utils/cpufreq-info.c:280 +#, c-format +msgid " current policy: frequency should be within " +msgstr " současná taktika: frekvence by měla být mezi " + +#: utils/cpufreq-info.c:282 +#, c-format +msgid " and " +msgstr " a " + +#: utils/cpufreq-info.c:286 +#, c-format +msgid "" +"The governor \"%s\" may decide which speed to use\n" +" within this range.\n" +msgstr "" +" Regulátor \"%s\" může rozhodnout jakou frekvenci použít\n" +" v těchto mezích.\n" + +#: utils/cpufreq-info.c:293 +#, c-format +msgid " current CPU frequency is " +msgstr " současná frekvence CPU je " + +#: utils/cpufreq-info.c:296 +#, c-format +msgid " (asserted by call to hardware)" +msgstr " (zjištěno hardwarovým voláním)" + +#: utils/cpufreq-info.c:304 +#, c-format +msgid " cpufreq stats: " +msgstr " statistika cpufreq: " + +#: utils/cpufreq-info.c:472 +#, fuzzy, c-format +msgid "Usage: cpupower freqinfo [options]\n" +msgstr "Užití: cpufreq-info [přepínače]\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 "Přepínače:\n" + +#: utils/cpufreq-info.c:474 +#, fuzzy, c-format +msgid " -e, --debug Prints out debug information [default]\n" +msgstr " -e, --debug Vypíše ladicí informace\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 Zjistí aktuální frekvenci, na které CPU běží\n" +" podle 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 Zjistí aktuální frekvenci, na které CPU běží\n" +" z hardware (dostupné jen uživateli root) *\n" + +#: utils/cpufreq-info.c:479 +#, c-format +msgid "" +" -l, --hwlimits Determine the minimum and maximum CPU frequency " +"allowed *\n" +msgstr "" +" -l, --hwlimits Zjistí minimální a maximální dostupnou frekvenci CPU " +"*\n" + +#: utils/cpufreq-info.c:480 +#, c-format +msgid " -d, --driver Determines the used cpufreq kernel driver *\n" +msgstr " -d, --driver Zjistí aktivní ovladač cpufreq *\n" + +#: utils/cpufreq-info.c:481 +#, c-format +msgid " -p, --policy Gets the currently used cpufreq policy *\n" +msgstr " -p, --policy Zjistí aktuální taktiku cpufreq *\n" + +#: utils/cpufreq-info.c:482 +#, c-format +msgid " -g, --governors Determines available cpufreq governors *\n" +msgstr " -g, --governors Zjistí dostupné regulátory cpufreq *\n" + +#: utils/cpufreq-info.c:483 +#, fuzzy, c-format +msgid "" +" -r, --related-cpus Determines which CPUs run at the same hardware " +"frequency *\n" +msgstr "" +" -a, --affected-cpus Zjistí, které CPU musí měnit frekvenci zároveň *\n" + +#: utils/cpufreq-info.c:484 +#, fuzzy, c-format +msgid "" +" -a, --affected-cpus Determines which CPUs need to have their frequency\n" +" coordinated by software *\n" +msgstr "" +" -a, --affected-cpus Zjistí, které CPU musí měnit frekvenci zároveň *\n" + +#: utils/cpufreq-info.c:486 +#, c-format +msgid " -s, --stats Shows cpufreq statistics if available\n" +msgstr " -s, --stats Zobrazí statistiku cpufreq, je-li dostupná\n" + +#: utils/cpufreq-info.c:487 +#, fuzzy, c-format +msgid "" +" -y, --latency Determines the maximum latency on CPU frequency " +"changes *\n" +msgstr "" +" -l, --hwlimits Zjistí minimální a maximální dostupnou frekvenci CPU " +"*\n" + +#: utils/cpufreq-info.c:488 +#, c-format +msgid " -b, --boost Checks for turbo or boost modes *\n" +msgstr "" + +#: 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 Vypíše informace ve formátu, jaký používalo rozhraní\n" +" /proc/cpufreq v kernelech řady 2.4 a časné 2.6\n" + +#: utils/cpufreq-info.c:491 +#, fuzzy, c-format +msgid "" +" -m, --human human-readable output for the -f, -w, -s and -y " +"parameters\n" +msgstr "" +" -m, --human Výstup parametrů -f, -w a -s v „lidmi čitelném“ " +"formátu\n" + +#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152 +#, c-format +msgid " -h, --help Prints out this screen\n" +msgstr " -h, --help Vypíše tuto nápovědu\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 "" +"Není-li zadán žádný parametr nebo je-li zadán pouze přepínač -c, --cpu, " +"jsou\n" +"vypsány ladicí informace, což může být užitečné například při hlášení chyb.\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 "" +"Není-li při použití přepínačů označených * zadán parametr -c nebo --cpu,\n" +"předpokládá se jeho hodnota 0.\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 "Zadaný parametr nemůže být použit zároveň s přepínačem -c nebo --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 "" +"Nelze zadat více než jeden parametr -c nebo --cpu\n" +"anebo více než jeden parametr určující výstup\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 "neplatný nebo neznámý parametr\n" + +#: utils/cpufreq-info.c:617 +#, c-format +msgid "couldn't analyze CPU %d as it doesn't seem to be present\n" +msgstr "nelze analyzovat CPU %d, vypadá to, že není přítomen\n" + +#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142 +#, c-format +msgid "analyzing CPU %d:\n" +msgstr "analyzuji CPU %d:\n" + +#: utils/cpufreq-set.c:25 +#, fuzzy, c-format +msgid "Usage: cpupower frequency-set [options]\n" +msgstr "Užití: cpufreq-set [přepínače]\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 Nová nejnižší frekvence, kterou může regulátor " +"vybrat\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 Nová nejvyšší frekvence, kterou může regulátor " +"zvolit\n" + +#: utils/cpufreq-set.c:29 +#, c-format +msgid " -g GOV, --governor GOV new cpufreq governor\n" +msgstr " -g GOV, --governors GOV Nový regulátor 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 Frekvence, která má být nastavena. Vyžaduje, aby " +"byl\n" +" v jádře nahrán regulátor ‚userspace‘.\n" + +#: utils/cpufreq-set.c:32 +#, c-format +msgid " -r, --related Switches all hardware-related CPUs\n" +msgstr "" + +#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27 +#, fuzzy, c-format +msgid " -h, --help Prints out this screen\n" +msgstr " -h, --help Vypíše tuto nápovědu\n" + +#: utils/cpufreq-set.c:35 +#, fuzzy, c-format +msgid "" +"Notes:\n" +"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n" +msgstr "" +"Není-li při použití přepínačů označených * zadán parametr -c nebo --cpu,\n" +"předpokládá se jeho hodnota 0.\n" + +#: utils/cpufreq-set.c:37 +#, fuzzy, 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 "" +"Poznámky:\n" +"1. Vynechání parametru -c nebo --cpu je ekvivalentní jeho nastavení na 0\n" +"2. Přepínač -f nebo --freq nemůže být použit zároveň s žádným jiným vyjma -" +"c\n" +" nebo --cpu\n" +"3. Frekvence (FREQ) mohou být zadány v Hz, kHz (výchozí), MHz, GHz nebo THz\n" +" připojením názvu jednotky bez mezery mezi číslem a jednotkou\n" +" (FREQ v 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 "" +"Chyba při nastavování nových hodnot. Obvyklé problémy:\n" +"- Máte patřičná administrátorská práva? (root?)\n" +"- Je požadovaný regulátor dostupný v jádře? (modprobe?)\n" +"- Snažíte se nastavit neplatnou taktiku?\n" +"- Snažíte se nastavit určitou frekvenci, ale není dostupný\n" +" regulátor ‚userspace‘, například protože není nahrán v jádře,\n" +" nebo nelze na tomto hardware nastavit určitou frekvenci?\n" + +#: utils/cpufreq-set.c:170 +#, c-format +msgid "wrong, unknown or unhandled CPU?\n" +msgstr "neznámý nebo nepodporovaný 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 "" +"přepínač -f/--freq nemůže být použit zároveň\n" +"s přepínačem -d/--min, -u/--max nebo -g/--governor\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 "" +"Musí být zadán alespoň jeden přepínač\n" +"-f/--freq, -d/--min, -u/--max nebo -g/--governor\n" + +#: utils/cpufreq-set.c:347 +#, c-format +msgid "Setting cpu: %d\n" +msgstr "" + +#: utils/cpupower-set.c:22 +#, c-format +msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" +msgstr "" + +#: 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 "" + +#: utils/cpupower-set.c:26 +#, c-format +msgid "" +" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n" +msgstr "" + +#: utils/cpupower-set.c:27 +#, c-format +msgid "" +" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler " +"policy.\n" +msgstr "" + +#: utils/cpupower-set.c:80 +#, c-format +msgid "--perf-bias param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:91 +#, c-format +msgid "--sched-mc param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:102 +#, c-format +msgid "--sched-smt param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:121 +#, c-format +msgid "Error setting sched-mc %s\n" +msgstr "" + +#: utils/cpupower-set.c:127 +#, c-format +msgid "Error setting sched-smt %s\n" +msgstr "" + +#: utils/cpupower-set.c:146 +#, c-format +msgid "Error setting perf-bias value on CPU %d\n" +msgstr "" + +#: utils/cpupower-info.c:21 +#, c-format +msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n" +msgstr "" + +#: 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 "" + +#: utils/cpupower-info.c:25 +#, fuzzy, c-format +msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n" +msgstr " -p, --policy Zjistí aktuální taktiku cpufreq *\n" + +#: utils/cpupower-info.c:26 +#, c-format +msgid "" +" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n" +msgstr "" + +#: utils/cpupower-info.c:28 +#, c-format +msgid "" +"\n" +"Passing no option will show all info, by default only on core 0\n" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: utils/cpupower-info.c:128 +#, c-format +msgid "System does not support Intel's performance bias setting\n" +msgstr "" + +#: utils/cpupower-info.c:147 +#, c-format +msgid "Could not read perf-bias value\n" +msgstr "" + +#: utils/cpupower-info.c:150 +#, c-format +msgid "perf-bias: %d\n" +msgstr "" + +#: utils/cpuidle-info.c:28 +#, fuzzy, c-format +msgid "Analyzing CPU %d:\n" +msgstr "analyzuji CPU %d:\n" + +#: utils/cpuidle-info.c:32 +#, c-format +msgid "CPU %u: No idle states\n" +msgstr "" + +#: utils/cpuidle-info.c:36 +#, c-format +msgid "CPU %u: Can't read idle state info\n" +msgstr "" + +#: utils/cpuidle-info.c:41 +#, c-format +msgid "Could not determine max idle state %u\n" +msgstr "" + +#: utils/cpuidle-info.c:46 +#, c-format +msgid "Number of idle states: %d\n" +msgstr "" + +#: utils/cpuidle-info.c:48 +#, fuzzy, c-format +msgid "Available idle states:" +msgstr " dostupné frekvence: " + +#: utils/cpuidle-info.c:71 +#, c-format +msgid "Flags/Description: %s\n" +msgstr "" + +#: utils/cpuidle-info.c:74 +#, c-format +msgid "Latency: %lu\n" +msgstr "" + +#: utils/cpuidle-info.c:76 +#, c-format +msgid "Usage: %lu\n" +msgstr "" + +#: utils/cpuidle-info.c:78 +#, c-format +msgid "Duration: %llu\n" +msgstr "" + +#: utils/cpuidle-info.c:90 +#, c-format +msgid "Could not determine cpuidle driver\n" +msgstr "" + +#: utils/cpuidle-info.c:94 +#, fuzzy, c-format +msgid "CPUidle driver: %s\n" +msgstr " ovladač: %s\n" + +#: utils/cpuidle-info.c:99 +#, c-format +msgid "Could not determine cpuidle governor\n" +msgstr "" + +#: utils/cpuidle-info.c:103 +#, c-format +msgid "CPUidle governor: %s\n" +msgstr "" + +#: utils/cpuidle-info.c:122 +#, c-format +msgid "CPU %u: Can't read C-state info\n" +msgstr "" + +#. printf("Cstates: %d\n", cstates); +#: utils/cpuidle-info.c:127 +#, c-format +msgid "active state: C0\n" +msgstr "" + +#: utils/cpuidle-info.c:128 +#, c-format +msgid "max_cstate: C%u\n" +msgstr "" + +#: utils/cpuidle-info.c:129 +#, c-format +msgid "maximum allowed latency: %lu usec\n" +msgstr "" + +#: utils/cpuidle-info.c:130 +#, c-format +msgid "states:\t\n" +msgstr "" + +#: utils/cpuidle-info.c:132 +#, c-format +msgid " C%d: type[C%d] " +msgstr "" + +#: utils/cpuidle-info.c:134 +#, c-format +msgid "promotion[--] demotion[--] " +msgstr "" + +#: utils/cpuidle-info.c:135 +#, c-format +msgid "latency[%03lu] " +msgstr "" + +#: utils/cpuidle-info.c:137 +#, c-format +msgid "usage[%08lu] " +msgstr "" + +#: utils/cpuidle-info.c:139 +#, c-format +msgid "duration[%020Lu] \n" +msgstr "" + +#: utils/cpuidle-info.c:147 +#, fuzzy, c-format +msgid "Usage: cpupower idleinfo [options]\n" +msgstr "Užití: cpufreq-info [přepínače]\n" + +#: utils/cpuidle-info.c:149 +#, fuzzy, c-format +msgid " -s, --silent Only show general C-state information\n" +msgstr " -e, --debug Vypíše ladicí informace\n" + +#: utils/cpuidle-info.c:150 +#, fuzzy, 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 Vypíše informace ve formátu, jaký používalo rozhraní\n" +" /proc/cpufreq v kernelech řady 2.4 a časné 2.6\n" + +#: utils/cpuidle-info.c:209 +#, fuzzy, c-format +msgid "You can't specify more than one output-specific argument\n" +msgstr "" +"Nelze zadat více než jeden parametr -c nebo --cpu\n" +"anebo více než jeden parametr určující výstup\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU CPU number which information shall be determined " +#~ "about\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU Číslo CPU, o kterém se mají zjistit informace\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be " +#~ "modified\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU Číslo CPU pro který se má provést nastavení " +#~ "cpufreq\n" diff --git a/tools/power/cpupower/po/de.po b/tools/power/cpupower/po/de.po new file mode 100644 index 000000000..9780a447b --- /dev/null +++ b/tools/power/cpupower/po/de.po @@ -0,0 +1,977 @@ +# German translations for cpufrequtils package +# German messages for cpufrequtils. +# Copyright (C) 2004-2009 Dominik Brodowski +# This file is distributed under the same license as the cpufrequtils package. +# +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: 2019-06-02 15:23+0200\n" +"Last-Translator: Benjamin Weis \n" +"Language-Team: NONE\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: utils/idle_monitor/nhm_idle.c:36 +msgid "Processor Core C3" +msgstr "Prozessorkern C3" + +#: utils/idle_monitor/nhm_idle.c:43 +msgid "Processor Core C6" +msgstr "Prozessorkern C6" + +#: utils/idle_monitor/nhm_idle.c:51 +msgid "Processor Package C3" +msgstr "Prozessorpaket C3" + +#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70 +msgid "Processor Package C6" +msgstr "Prozessorpaket C6" + +#: utils/idle_monitor/snb_idle.c:33 +msgid "Processor Core C7" +msgstr "Prozessorkern C7" + +#: utils/idle_monitor/snb_idle.c:40 +msgid "Processor Package C2" +msgstr "Prozessorpaket C2" + +#: utils/idle_monitor/snb_idle.c:47 +msgid "Processor Package C7" +msgstr "Prozessorpaket C7" + +#: utils/idle_monitor/amd_fam14h_idle.c:56 +msgid "Package in sleep state (PC1 or deeper)" +msgstr "Paket in Schlafzustand (PC1 oder tiefer)" + +#: utils/idle_monitor/amd_fam14h_idle.c:63 +msgid "Processor Package C1" +msgstr "Prozessorpaket C1" + +#: utils/idle_monitor/amd_fam14h_idle.c:77 +msgid "North Bridge P1 boolean counter (returns 0 or 1)" +msgstr "North Bridge P1 boolescher Zähler (gibt 0 oder 1 zurück)" + +#: utils/idle_monitor/mperf_monitor.c:35 +msgid "Processor Core not idle" +msgstr "Prozessorkern ist nicht im Leerlauf" + +#: utils/idle_monitor/mperf_monitor.c:42 +msgid "Processor Core in an idle state" +msgstr "Prozessorkern ist in einem Ruhezustand" + +#: utils/idle_monitor/mperf_monitor.c:50 +msgid "Average Frequency (including boost) in MHz" +msgstr "Durchschnittliche Frequenz (einschließlich Boost) in MHz" + +#: utils/idle_monitor/cpupower-monitor.c:66 +#, c-format +msgid "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c Befehl ...]\n" + +#: utils/idle_monitor/cpupower-monitor.c:69 +#, c-format +msgid "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c Befehl ...]\n" + +#: utils/idle_monitor/cpupower-monitor.c:71 +#, c-format +msgid "\t -v: be more verbose\n" +msgstr "\t -v: ausführlicher\n" + +#: utils/idle_monitor/cpupower-monitor.c:73 +#, c-format +msgid "\t -h: print this help\n" +msgstr "\t -h: diese Hilfe ausgeben\n" + +#: utils/idle_monitor/cpupower-monitor.c:74 +#, c-format +msgid "\t -i: time interval to measure for in seconds (default 1)\n" +msgstr "\t -i: Zeitintervall für die Messung in Sekunden (Standard 1)\n" + +#: utils/idle_monitor/cpupower-monitor.c:75 +#, c-format +msgid "\t -t: show CPU topology/hierarchy\n" +msgstr "\t -t: CPU-Topologie/Hierarchie anzeigen\n" + +#: utils/idle_monitor/cpupower-monitor.c:76 +#, c-format +msgid "\t -l: list available CPU sleep monitors (for use with -m)\n" +msgstr "" +"\t -l: verfügbare CPU-Schlafwächter auflisten (für Verwendung mit -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 "" +"\t -m: spezifische CPU-Schlafwächter anzeigen (in gleicher Reihenfolge)\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 "" +"nur einer von: -t, -l, -m ist erlaubt\n" +"Wenn keiner von ihnen übergeben wird," + +#: utils/idle_monitor/cpupower-monitor.c:80 +#, c-format +msgid " all supported monitors are shown\n" +msgstr " werden alle unterstützten Wächter angezeigt\n" + +#: utils/idle_monitor/cpupower-monitor.c:197 +#, c-format +msgid "Monitor %s, Counter %s has no count function. Implementation error\n" +msgstr "Wächter %s, Zähler %s hat keine Zählfunktion. Implementierungsfehler\n" + +#: utils/idle_monitor/cpupower-monitor.c:207 +#, c-format +msgid " *is offline\n" +msgstr " *ist offline\n" + +#: utils/idle_monitor/cpupower-monitor.c:236 +#, c-format +msgid "%s: max monitor name length (%d) exceeded\n" +msgstr "%s: max. Wächternamenslänge (%d) überschritten\n" + +#: utils/idle_monitor/cpupower-monitor.c:250 +#, c-format +msgid "No matching monitor found in %s, try -l option\n" +msgstr "Kein passender Wächter in %s gefunden, versuchen Sie die Option -l\n" + +#: utils/idle_monitor/cpupower-monitor.c:266 +#, c-format +msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n" +msgstr "Wächter \"%s\" (%d Zustände) - Könnte nach %u s überlaufen\n" + +#: utils/idle_monitor/cpupower-monitor.c:319 +#, c-format +msgid "%s took %.5f seconds and exited with status %d\n" +msgstr "%s hat %.5f Sekunden gedauert und hat sich mit Status %d beendet\n" + +#: utils/idle_monitor/cpupower-monitor.c:406 +#, c-format +msgid "Cannot read number of available processors\n" +msgstr "Anzahl der verfügbaren Prozessoren kann nicht gelesen werden\n" + +#: utils/idle_monitor/cpupower-monitor.c:417 +#, c-format +msgid "Available monitor %s needs root access\n" +msgstr "Verfügbarer Wächter %s benötigt root-Zugriff\n" + +#: utils/idle_monitor/cpupower-monitor.c:428 +#, c-format +msgid "No HW Cstate monitors found\n" +msgstr "Keine HW C-Zustandswächter gefunden\n" + +#: utils/cpupower.c:78 +#, c-format +msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n" +msgstr "cpupower [ -c cpulist ] Unterbefehl [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 "Unterstützte Unterbefehle sind:\n" + +#: utils/cpupower.c:83 +#, c-format +msgid "" +"\n" +"Some subcommands can make use of the -c cpulist option.\n" +msgstr "" +"\n" +"Einige Unterbefehle können die Option -c cpulist verwenden.\n" + +#: utils/cpupower.c:84 +#, c-format +msgid "Look at the general cpupower manpage how to use it\n" +msgstr "" +"Schauen Sie sich die allgemeine cpupower manpage an, um zu erfahren, wie man " +"es benutzt\n" + +#: utils/cpupower.c:85 +#, c-format +msgid "and read up the subcommand's manpage whether it is supported.\n" +msgstr "" + +#: utils/cpupower.c:86 +#, c-format +msgid "" +"\n" +"Use cpupower help subcommand for getting help for above subcommands.\n" +msgstr "" + +#: utils/cpupower.c:91 +#, c-format +msgid "Report errors and bugs to %s, please.\n" +msgstr "Bitte melden Sie Fehler an %s.\n" + +#: utils/cpupower.c:114 +#, c-format +msgid "Error parsing cpu list\n" +msgstr "Fehler beim Parsen der CPU-Liste\n" + +#: utils/cpupower.c:172 +#, c-format +msgid "Subcommand %s needs root privileges\n" +msgstr "Unterbefehl %s benötigt root-Rechte\n" + +#: utils/cpufreq-info.c:31 +#, c-format +msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n" +msgstr "" +"Anzahl der CPUs konnte nicht herausgefinden werden (%s: %s), es wird daher 1 " +"angenommen\n" + +#: utils/cpufreq-info.c:63 +#, c-format +msgid "" +" minimum CPU frequency - maximum CPU frequency - governor\n" +msgstr " minimale CPU-Frequenz - maximale CPU-Frequenz - Regler\n" + +#: utils/cpufreq-info.c:151 +#, c-format +msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n" +msgstr "" +"Fehler beim Evaluieren der Boost-Fähigkeiten bei CPU %d -- sind Sie 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 " Boost-Zustand-Unterstützung: \n" + +#: utils/cpufreq-info.c:163 +#, c-format +msgid " Supported: %s\n" +msgstr " Unterstützt: %s\n" + +#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164 +msgid "yes" +msgstr "ja" + +#: utils/cpufreq-info.c:163 utils/cpufreq-info.c:164 +msgid "no" +msgstr "nein" + +#: utils/cpufreq-info.c:164 +#, c-format +msgid " Active: %s\n" +msgstr " Aktiv: %s\n" + +#: utils/cpufreq-info.c:177 +#, c-format +msgid " Boost States: %d\n" +msgstr " Boost-Zustände: %d\n" + +#: utils/cpufreq-info.c:178 +#, c-format +msgid " Total States: %d\n" +msgstr " Gesamtzustände: %d\n" + +#: utils/cpufreq-info.c:181 +#, c-format +msgid " Pstate-Pb%d: %luMHz (boost state)\n" +msgstr " Pstate-Pb%d: %luMHz (Boost-Zustand)\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 " kein oder ein unbekannter cpufreq-Treiber ist auf dieser CPU aktiv\n" + +#: utils/cpufreq-info.c:213 +#, c-format +msgid " driver: %s\n" +msgstr " Treiber: %s\n" + +#: utils/cpufreq-info.c:219 +#, c-format +msgid " CPUs which run at the same hardware frequency: " +msgstr " CPUs, die mit der gleichen Hardwarefrequenz laufen: " + +#: utils/cpufreq-info.c:230 +#, c-format +msgid " CPUs which need to have their frequency coordinated by software: " +msgstr " CPUs, die ihre Frequenz mit Software koordinieren müssen: " + +#: utils/cpufreq-info.c:241 +#, c-format +msgid " maximum transition latency: " +msgstr " Maximale Dauer eines Taktfrequenzwechsels: " + +#: utils/cpufreq-info.c:247 +#, c-format +msgid " hardware limits: " +msgstr " Hardwarebegrenzungen: " + +#: utils/cpufreq-info.c:256 +#, c-format +msgid " available frequency steps: " +msgstr " verfügbare Frequenzschritte: " + +#: utils/cpufreq-info.c:269 +#, c-format +msgid " available cpufreq governors: " +msgstr " verfügbare cpufreq-Regler: " + +#: utils/cpufreq-info.c:280 +#, c-format +msgid " current policy: frequency should be within " +msgstr " momentane Richtlinie: Frequenz sollte innerhalb " + +#: utils/cpufreq-info.c:282 +#, c-format +msgid " and " +msgstr " und " + +#: utils/cpufreq-info.c:286 +#, c-format +msgid "" +"The governor \"%s\" may decide which speed to use\n" +" within this range.\n" +msgstr "" +" sein. Der Regler \"%s\" kann frei entscheiden,\n" +" welche Geschwindigkeit er in diesem Bereich verwendet.\n" + +#: utils/cpufreq-info.c:293 +#, c-format +msgid " current CPU frequency is " +msgstr " momentane CPU-Frequenz ist " + +#: utils/cpufreq-info.c:296 +#, c-format +msgid " (asserted by call to hardware)" +msgstr " (durch Aufruf der Hardware sichergestellt)" + +#: utils/cpufreq-info.c:304 +#, c-format +msgid " cpufreq stats: " +msgstr " cpufreq-Statistiken: " + +#: utils/cpufreq-info.c:472 +#, c-format +msgid "Usage: cpupower freqinfo [options]\n" +msgstr "Aufruf: cpupower freqinfo [Optionen]\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 "Optionen:\n" + +#: utils/cpufreq-info.c:474 +#, c-format +msgid " -e, --debug Prints out debug information [default]\n" +msgstr " -e, --debug Gibt Debug-Informationen aus [Standard]\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 Findet die momentane CPU-Taktfrquenz heraus (nach\n" +" Meinung des Betriebssystems) *\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 Findet die momentane CPU-Taktfrequenz heraus\n" +" (verifiziert durch Nachfrage bei der Hardware)\n" +" [nur der Administrator kann dies tun] *\n" + +#: utils/cpufreq-info.c:479 +#, c-format +msgid "" +" -l, --hwlimits Determine the minimum and maximum CPU frequency " +"allowed *\n" +msgstr "" +" -l, --hwlimits Findet die minimale und maximale Taktfrequenz heraus " +"*\n" + +#: utils/cpufreq-info.c:480 +#, c-format +msgid " -d, --driver Determines the used cpufreq kernel driver *\n" +msgstr " -d, --driver Findet den momentanen Treiber heraus *\n" + +#: utils/cpufreq-info.c:481 +#, c-format +msgid " -p, --policy Gets the currently used cpufreq policy *\n" +msgstr " -p, --policy Findet die momentane Taktik heraus *\n" + +#: utils/cpufreq-info.c:482 +#, c-format +msgid " -g, --governors Determines available cpufreq governors *\n" +msgstr " -g, --governors Ermittelt verfügbare cpufreq-Regler *\n" + +#: utils/cpufreq-info.c:483 +#, c-format +msgid "" +" -r, --related-cpus Determines which CPUs run at the same hardware " +"frequency *\n" +msgstr "" +" -r, --related-cpus Findet heraus, welche CPUs mit derselben " +"physikalischen\n" +" Taktfrequenz laufen *\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 Findet heraus, von welchen CPUs die Taktfrequenz " +"durch\n" +" Software koordiniert werden muss *\n" + +#: utils/cpufreq-info.c:486 +#, c-format +msgid " -s, --stats Shows cpufreq statistics if available\n" +msgstr " -s, --stats Zeigt cpufreq-Statistiken an, falls vorhanden\n" + +#: utils/cpufreq-info.c:487 +#, c-format +msgid "" +" -y, --latency Determines the maximum latency on CPU frequency " +"changes *\n" +msgstr "" +" -y, --latency Findet die maximale Dauer eines Taktfrequenzwechsels " +"heraus *\n" + +#: utils/cpufreq-info.c:488 +#, c-format +msgid " -b, --boost Checks for turbo or boost modes *\n" +msgstr " -b, --boost Prüft auf Turbo- oder Boost-Modi *\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 Erzeugt Informationen in einem ähnlichem Format zu " +"dem\n" +" der /proc/cpufreq-Datei in 2.4. und frühen 2.6.\n" +" Kernel-Versionen\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 Formatiert Taktfrequenz- und Zeitdauerangaben in " +"besser\n" +" lesbarer Form (MHz, GHz; us, ms)\n" + +#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152 +#, c-format +msgid " -h, --help Prints out this screen\n" +msgstr " -h, --help Gibt diese Kurzübersicht aus\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 "" +"Sofern kein anderer Parameter als '-c, --cpu' angegeben wird, liefert " +"dieses\n" +"Programm Informationen, die z.B. zum Berichten von Fehlern nützlich sind.\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 "" +"Für die mit * markierten Argumente ist das Weglassen des Arguments\n" +"-c oder --cpu gleichbedeutend mit der Einstellung auf Null\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 "Diese Option kann nicht mit der --cpu-Option kombiniert werden\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 "" +"Sie können nicht mehr als einen Parameter --cpu und/oder\n" +"mehr als ein ausgabespezifisches Argument angeben\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 "unbekannter oder falscher Parameter\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 konnte nicht analysiert werden, da sie scheinbar nicht existiert\n" + +#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142 +#, c-format +msgid "analyzing CPU %d:\n" +msgstr "CPU %d wird analysiert:\n" + +#: utils/cpufreq-set.c:25 +#, c-format +msgid "Usage: cpupower frequency-set [options]\n" +msgstr "Aufruf: cpupower frequency-set [Optionen]\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 neue minimale CPU-Frequenz, die der Regler\n" +" auswählen darf\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 neue maximale Taktfrequenz, die der Regler\n" +" auswählen darf\n" + +#: utils/cpufreq-set.c:29 +#, c-format +msgid " -g GOV, --governor GOV new cpufreq governor\n" +msgstr " -g GOV, --governors GOV neuer cpufreq-Regler\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 bestimmte Frequenz, die eingestellt werden soll.\n" +" Erfordert einen verfügbaren und geladenen " +"userspace-Regler\n" + +#: utils/cpufreq-set.c:32 +#, c-format +msgid " -r, --related Switches all hardware-related CPUs\n" +msgstr " -r, --related Schaltet alle hardwarebezogenen CPUs um\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 Gibt diesen Bildschirm aus\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 "" +"Hinweis:\n" +"1. Das Weglassen des Arguments -c oder --cpu ist gleichbedeutend mit der " +"Einstellung auf \"all\"\n" + +#: utils/cpufreq-set.c:37 +#, fuzzy, 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 "" +"Hinweise:\n" +"1. Sofern kein -c oder --cpu-Parameter angegeben ist, wird '--cpu 0'\n" +" angenommen\n" +"2. Der Parameter -f bzw. --freq kann mit keinem anderen als dem Parameter\n" +" -c bzw. --cpu kombiniert werden\n" +"3. FREQuenzen können in Hz, kHz (Standard), MHz, GHz oder THz eingegeben\n" +" werden, indem der Wert und unmittelbar anschließend (ohne Leerzeichen!)\n" +" die Einheit angegeben werden. (Bsp: 1GHz )\n" +" (FREQuenz in kHz =^ 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 "" +"Fehler beim Festlegen neuer Werte. Häufige Fehler:\n" +"- Verfügen Sie über die erforderlichen Administrationsrechte? (Superuser?)\n" +"- Ist der von Ihnen gewünschte Regler verfügbar und mittels modprobe " +"geladen?\n" +"- Versuchen Sie eine ungültige Richtlinie festzulegen?\n" +"- Versuchen Sie eine bestimmte Frequenz festzulegen, aber der " +"userspace-Regler ist nicht verfügbar,\n" +" z.B. wegen Hardware, die nicht auf eine bestimmte Frequenz eingestellt " +"werden kann\n" +" oder weil der userspace-Regler nicht geladen ist?\n" + +#: utils/cpufreq-set.c:170 +#, c-format +msgid "wrong, unknown or unhandled CPU?\n" +msgstr "falsche, unbekannte oder nicht regelbare 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 "" +"Der -f bzw. --freq-Parameter kann nicht mit den Parametern -d/--min, " +"-u/--max\n" +"oder -g/--governor kombiniert werden\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 "" +"Mindestens ein Parameter aus -f/--freq, -d/--min, -u/--max und\n" +"-g/--governor muss übergeben werden\n" + +#: utils/cpufreq-set.c:347 +#, c-format +msgid "Setting cpu: %d\n" +msgstr "CPU einstellen: %d\n" + +#: utils/cpupower-set.c:22 +#, c-format +msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" +msgstr "Aufruf: 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 "" + +#: 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] Legt die Mehrkern-Scheduler-Richtlinie des " +"Kernels fest.\n" + +#: utils/cpupower-set.c:27 +#, c-format +msgid "" +" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler " +"policy.\n" +msgstr "" + +#: utils/cpupower-set.c:80 +#, c-format +msgid "--perf-bias param out of range [0-%d]\n" +msgstr "--perf-bias-Parameter außerhalb des Bereichs [0-%d]\n" + +#: utils/cpupower-set.c:91 +#, c-format +msgid "--sched-mc param out of range [0-%d]\n" +msgstr "Parameter --sched-mc außerhalb des Bereichs [0-%d]\n" + +#: utils/cpupower-set.c:102 +#, c-format +msgid "--sched-smt param out of range [0-%d]\n" +msgstr "Parameter --sched-smt außerhalb des Bereichs [0-%d]\n" + +#: utils/cpupower-set.c:121 +#, c-format +msgid "Error setting sched-mc %s\n" +msgstr "Fehler beim Einstellen von sched-mc %s\n" + +#: utils/cpupower-set.c:127 +#, c-format +msgid "Error setting sched-smt %s\n" +msgstr "Fehler beim Einstellen von sched-smt %s\n" + +#: utils/cpupower-set.c:146 +#, c-format +msgid "Error setting perf-bias value on CPU %d\n" +msgstr "Fehler beim Einstellen des perf-bias-Wertes auf der CPU %d\n" + +#: utils/cpupower-info.c:21 +#, c-format +msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n" +msgstr "Aufruf: 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 "" + +#: utils/cpupower-info.c:25 +#, c-format +msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n" +msgstr "" +" -m, --sched-mc Ruft die Mehrkern-Scheduler-Richtlinie des Kernels ab.\n" + +#: utils/cpupower-info.c:26 +#, c-format +msgid "" +" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n" +msgstr "" + +#: 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" +"Wenn Sie keine Option übergeben, werden alle Informationen angezeigt, " +"standardmäßig nur auf Kern 0\n" + +#: utils/cpupower-info.c:102 +#, c-format +msgid "System's multi core scheduler setting: " +msgstr "Mehrkern-Scheduler-Einstellung des Systems: " + +#. 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 "nicht unterstützt\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 "" + +#: utils/cpupower-info.c:128 +#, c-format +msgid "System does not support Intel's performance bias setting\n" +msgstr "" + +#: utils/cpupower-info.c:147 +#, c-format +msgid "Could not read perf-bias value\n" +msgstr "perf-bias-Wert konnte nicht gelesen werden\n" + +#: utils/cpupower-info.c:150 +#, c-format +msgid "perf-bias: %d\n" +msgstr "perf-bias: %d\n" + +#: utils/cpuidle-info.c:28 +#, c-format +msgid "Analyzing CPU %d:\n" +msgstr "CPU %d wird analysiert:\n" + +#: utils/cpuidle-info.c:32 +#, c-format +msgid "CPU %u: No idle states\n" +msgstr "CPU %u: Keine Ruhezustände\n" + +#: utils/cpuidle-info.c:36 +#, c-format +msgid "CPU %u: Can't read idle state info\n" +msgstr "CPU %u: Ruhezustands-Informationen können nicht gelesen werden\n" + +#: utils/cpuidle-info.c:41 +#, c-format +msgid "Could not determine max idle state %u\n" +msgstr "Max. Ruhezustand %u konnte nicht bestimmt werden\n" + +#: utils/cpuidle-info.c:46 +#, c-format +msgid "Number of idle states: %d\n" +msgstr "Anzahl der Ruhezustände: %d\n" + +#: utils/cpuidle-info.c:48 +#, c-format +msgid "Available idle states:" +msgstr "Verfügbare Ruhezustände:" + +#: utils/cpuidle-info.c:71 +#, c-format +msgid "Flags/Description: %s\n" +msgstr "Merker/Beschreibung: %s\n" + +#: utils/cpuidle-info.c:74 +#, c-format +msgid "Latency: %lu\n" +msgstr "Latenz: %lu\n" + +#: utils/cpuidle-info.c:76 +#, c-format +msgid "Usage: %lu\n" +msgstr "Aufruf: %lu\n" + +#: utils/cpuidle-info.c:78 +#, c-format +msgid "Duration: %llu\n" +msgstr "Dauer: %llu\n" + +#: utils/cpuidle-info.c:90 +#, c-format +msgid "Could not determine cpuidle driver\n" +msgstr "cpuidle-Treiber konnte nicht bestimmt werden\n" + +#: utils/cpuidle-info.c:94 +#, c-format +msgid "CPUidle driver: %s\n" +msgstr "CPUidle-Treiber: %s\n" + +#: utils/cpuidle-info.c:99 +#, c-format +msgid "Could not determine cpuidle governor\n" +msgstr "cpuidle-Regler konnte nicht bestimmt werden\n" + +#: utils/cpuidle-info.c:103 +#, c-format +msgid "CPUidle governor: %s\n" +msgstr "CPUidle-Regler: %s\n" + +#: utils/cpuidle-info.c:122 +#, c-format +msgid "CPU %u: Can't read C-state info\n" +msgstr "CPU %u: C-Zustands-Informationen können nicht gelesen werden\n" + +#. printf("Cstates: %d\n", cstates); +#: utils/cpuidle-info.c:127 +#, c-format +msgid "active state: C0\n" +msgstr "aktiver Zustand: C0\n" + +#: utils/cpuidle-info.c:128 +#, c-format +msgid "max_cstate: C%u\n" +msgstr "max_cstate: C%u\n" + +#: utils/cpuidle-info.c:129 +#, c-format +msgid "maximum allowed latency: %lu usec\n" +msgstr "maximal erlaubte Latenz: %lu usec\n" + +#: utils/cpuidle-info.c:130 +#, c-format +msgid "states:\t\n" +msgstr "Zustände:\t\n" + +#: utils/cpuidle-info.c:132 +#, c-format +msgid " C%d: type[C%d] " +msgstr " C%d: Typ[C%d] " + +#: utils/cpuidle-info.c:134 +#, c-format +msgid "promotion[--] demotion[--] " +msgstr "promotion[--] demotion[--] " + +#: utils/cpuidle-info.c:135 +#, c-format +msgid "latency[%03lu] " +msgstr "Latenz[%03lu] " + +#: utils/cpuidle-info.c:137 +#, c-format +msgid "usage[%08lu] " +msgstr "Aufruf[%08lu] " + +#: utils/cpuidle-info.c:139 +#, c-format +msgid "duration[%020Lu] \n" +msgstr "Dauer[%020Lu] \n" + +#: utils/cpuidle-info.c:147 +#, c-format +msgid "Usage: cpupower idleinfo [options]\n" +msgstr "Aufruf: cpupower idleinfo [Optionen]\n" + +#: utils/cpuidle-info.c:149 +#, c-format +msgid " -s, --silent Only show general C-state information\n" +msgstr "" +" -s, --silent Nur allgemeine C-Zustands-Informationen anzeigen\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 Gibt Informationen so aus, wie sie von der " +"Schnittstelle\n" +" /proc/acpi/processor/*/power in älteren Kerneln " +"bereitgestellt werden\n" + +#: utils/cpuidle-info.c:209 +#, c-format +msgid "You can't specify more than one output-specific argument\n" +msgstr "Sie können nicht mehr als ein ausgabenspezifisches Argument angeben\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU CPU number which information shall be determined " +#~ "about\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU Nummer der CPU, über die Informationen " +#~ "herausgefunden werden sollen\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be " +#~ "modified\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU Nummer der CPU, deren " +#~ "Taktfrequenz-Einstellung\n" +#~ " werden soll\n" diff --git a/tools/power/cpupower/po/fr.po b/tools/power/cpupower/po/fr.po new file mode 100644 index 000000000..b6e505b34 --- /dev/null +++ b/tools/power/cpupower/po/fr.po @@ -0,0 +1,947 @@ +# French translations for cpufrequtils package +# Copyright (C) 2004 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the cpufrequtils package. +# Ducrot Bruno , 2004. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: cpufrequtils 0.1-pre2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-03-08 17:03+0100\n" +"PO-Revision-Date: 2004-11-17 15:53+1000\n" +"Last-Translator: Bruno Ducrot \n" +"Language-Team: NONE\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8bit\n" + +#: utils/idle_monitor/nhm_idle.c:36 +msgid "Processor Core C3" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:43 +msgid "Processor Core C6" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:51 +msgid "Processor Package C3" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70 +msgid "Processor Package C6" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:33 +msgid "Processor Core C7" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:40 +msgid "Processor Package C2" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:47 +msgid "Processor Package C7" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:56 +msgid "Package in sleep state (PC1 or deeper)" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:63 +msgid "Processor Package C1" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:77 +msgid "North Bridge P1 boolean counter (returns 0 or 1)" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:35 +msgid "Processor Core not idle" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:42 +msgid "Processor Core in an idle state" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:50 +msgid "Average Frequency (including boost) in MHz" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:66 +#, c-format +msgid "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:69 +#, c-format +msgid "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:71 +#, c-format +msgid "\t -v: be more verbose\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:73 +#, c-format +msgid "\t -h: print this help\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:74 +#, c-format +msgid "\t -i: time interval to measure for in seconds (default 1)\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:75 +#, c-format +msgid "\t -t: show CPU topology/hierarchy\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:76 +#, c-format +msgid "\t -l: list available CPU sleep monitors (for use with -m)\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:77 +#, c-format +msgid "\t -m: show specific CPU sleep monitors only (in same order)\n" +msgstr "" + +#: 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 "" + +#: utils/idle_monitor/cpupower-monitor.c:80 +#, c-format +msgid " all supported monitors are shown\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:197 +#, c-format +msgid "Monitor %s, Counter %s has no count function. Implementation error\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:207 +#, c-format +msgid " *is offline\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:236 +#, c-format +msgid "%s: max monitor name length (%d) exceeded\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:250 +#, c-format +msgid "No matching monitor found in %s, try -l option\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:266 +#, c-format +msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:319 +#, c-format +msgid "%s took %.5f seconds and exited with status %d\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:406 +#, c-format +msgid "Cannot read number of available processors\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:417 +#, c-format +msgid "Available monitor %s needs root access\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:428 +#, c-format +msgid "No HW Cstate monitors found\n" +msgstr "" + +#: utils/cpupower.c:78 +#, c-format +msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n" +msgstr "" + +#: utils/cpupower.c:79 +#, c-format +msgid "cpupower --version\n" +msgstr "" + +#: utils/cpupower.c:80 +#, c-format +msgid "Supported subcommands are:\n" +msgstr "" + +#: utils/cpupower.c:83 +#, c-format +msgid "" +"\n" +"Some subcommands can make use of the -c cpulist option.\n" +msgstr "" + +#: utils/cpupower.c:84 +#, c-format +msgid "Look at the general cpupower manpage how to use it\n" +msgstr "" + +#: utils/cpupower.c:85 +#, c-format +msgid "and read up the subcommand's manpage whether it is supported.\n" +msgstr "" + +#: utils/cpupower.c:86 +#, c-format +msgid "" +"\n" +"Use cpupower help subcommand for getting help for above subcommands.\n" +msgstr "" + +#: utils/cpupower.c:91 +#, c-format +msgid "Report errors and bugs to %s, please.\n" +msgstr "Veuillez rapportez les erreurs et les bogues à %s, s'il vous plait.\n" + +#: utils/cpupower.c:114 +#, c-format +msgid "Error parsing cpu list\n" +msgstr "" + +#: utils/cpupower.c:172 +#, c-format +msgid "Subcommand %s needs root privileges\n" +msgstr "" + +#: utils/cpufreq-info.c:31 +#, c-format +msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n" +msgstr "Détermination du nombre de CPUs (%s : %s) impossible. Assume 1\n" + +#: utils/cpufreq-info.c:63 +#, c-format +msgid "" +" minimum CPU frequency - maximum CPU frequency - governor\n" +msgstr "" +" Fréquence CPU minimale - Fréquence CPU maximale - régulateur\n" + +#: utils/cpufreq-info.c:151 +#, c-format +msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n" +msgstr "" + +#. 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 "" + +#: utils/cpufreq-info.c:163 +#, c-format +msgid " Supported: %s\n" +msgstr "" + +#: 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 +#, fuzzy, c-format +msgid " Active: %s\n" +msgstr " pilote : %s\n" + +#: utils/cpufreq-info.c:177 +#, c-format +msgid " Boost States: %d\n" +msgstr "" + +#: utils/cpufreq-info.c:178 +#, c-format +msgid " Total States: %d\n" +msgstr "" + +#: utils/cpufreq-info.c:181 +#, c-format +msgid " Pstate-Pb%d: %luMHz (boost state)\n" +msgstr "" + +#: utils/cpufreq-info.c:184 +#, c-format +msgid " Pstate-P%d: %luMHz\n" +msgstr "" + +#: utils/cpufreq-info.c:211 +#, c-format +msgid " no or unknown cpufreq driver is active on this CPU\n" +msgstr " pas de pilotes cpufreq reconnu pour ce CPU\n" + +#: utils/cpufreq-info.c:213 +#, c-format +msgid " driver: %s\n" +msgstr " pilote : %s\n" + +#: utils/cpufreq-info.c:219 +#, fuzzy, c-format +msgid " CPUs which run at the same hardware frequency: " +msgstr " CPUs qui doivent changer de fréquences en même temps : " + +#: utils/cpufreq-info.c:230 +#, fuzzy, c-format +msgid " CPUs which need to have their frequency coordinated by software: " +msgstr " CPUs qui doivent changer de fréquences en même temps : " + +#: utils/cpufreq-info.c:241 +#, c-format +msgid " maximum transition latency: " +msgstr "" + +#: utils/cpufreq-info.c:247 +#, c-format +msgid " hardware limits: " +msgstr " limitation matérielle : " + +#: utils/cpufreq-info.c:256 +#, c-format +msgid " available frequency steps: " +msgstr " plage de fréquence : " + +#: utils/cpufreq-info.c:269 +#, c-format +msgid " available cpufreq governors: " +msgstr " régulateurs disponibles : " + +#: utils/cpufreq-info.c:280 +#, c-format +msgid " current policy: frequency should be within " +msgstr " tactique actuelle : la fréquence doit être comprise entre " + +#: utils/cpufreq-info.c:282 +#, c-format +msgid " and " +msgstr " et " + +#: utils/cpufreq-info.c:286 +#, c-format +msgid "" +"The governor \"%s\" may decide which speed to use\n" +" within this range.\n" +msgstr "" +"Le régulateur \"%s\" est libre de choisir la vitesse\n" +" dans cette plage de fréquences.\n" + +#: utils/cpufreq-info.c:293 +#, c-format +msgid " current CPU frequency is " +msgstr " la fréquence actuelle de ce CPU est " + +#: utils/cpufreq-info.c:296 +#, c-format +msgid " (asserted by call to hardware)" +msgstr " (vérifié par un appel direct du matériel)" + +#: utils/cpufreq-info.c:304 +#, c-format +msgid " cpufreq stats: " +msgstr " des statistique concernant cpufreq:" + +#: utils/cpufreq-info.c:472 +#, fuzzy, c-format +msgid "Usage: cpupower freqinfo [options]\n" +msgstr "Usage : cpufreq-info [options]\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 "Options :\n" + +#: utils/cpufreq-info.c:474 +#, fuzzy, c-format +msgid " -e, --debug Prints out debug information [default]\n" +msgstr " -e, --debug Afficher les informations de déboguage\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 Obtenir la fréquence actuelle du CPU selon le point\n" +" de vue du coeur du système de 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 Obtenir la fréquence actuelle du CPU directement par\n" +" le matériel (doit être root) *\n" + +#: utils/cpufreq-info.c:479 +#, c-format +msgid "" +" -l, --hwlimits Determine the minimum and maximum CPU frequency " +"allowed *\n" +msgstr "" +" -l, --hwlimits Affiche les fréquences minimales et maximales du CPU " +"*\n" + +#: utils/cpufreq-info.c:480 +#, c-format +msgid " -d, --driver Determines the used cpufreq kernel driver *\n" +msgstr " -d, --driver Affiche le pilote cpufreq utilisé *\n" + +#: utils/cpufreq-info.c:481 +#, c-format +msgid " -p, --policy Gets the currently used cpufreq policy *\n" +msgstr " -p, --policy Affiche la tactique actuelle de cpufreq *\n" + +#: utils/cpufreq-info.c:482 +#, c-format +msgid " -g, --governors Determines available cpufreq governors *\n" +msgstr "" +" -g, --governors Affiche les régulateurs disponibles de cpufreq *\n" + +#: utils/cpufreq-info.c:483 +#, fuzzy, c-format +msgid "" +" -r, --related-cpus Determines which CPUs run at the same hardware " +"frequency *\n" +msgstr "" +" -a, --affected-cpus Affiche quels sont les CPUs qui doivent changer de\n" +" fréquences en même temps *\n" + +#: utils/cpufreq-info.c:484 +#, fuzzy, c-format +msgid "" +" -a, --affected-cpus Determines which CPUs need to have their frequency\n" +" coordinated by software *\n" +msgstr "" +" -a, --affected-cpus Affiche quels sont les CPUs qui doivent changer de\n" +" fréquences en même temps *\n" + +#: utils/cpufreq-info.c:486 +#, c-format +msgid " -s, --stats Shows cpufreq statistics if available\n" +msgstr "" +" -s, --stats Indique des statistiques concernant cpufreq, si\n" +" disponibles\n" + +#: utils/cpufreq-info.c:487 +#, fuzzy, c-format +msgid "" +" -y, --latency Determines the maximum latency on CPU frequency " +"changes *\n" +msgstr "" +" -l, --hwlimits Affiche les fréquences minimales et maximales du CPU " +"*\n" + +#: utils/cpufreq-info.c:488 +#, c-format +msgid " -b, --boost Checks for turbo or boost modes *\n" +msgstr "" + +#: 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 Affiche les informations en utilisant l'interface\n" +" fournie par /proc/cpufreq, présente dans les " +"versions\n" +" 2.4 et les anciennes versions 2.6 du noyau\n" + +#: utils/cpufreq-info.c:491 +#, fuzzy, c-format +msgid "" +" -m, --human human-readable output for the -f, -w, -s and -y " +"parameters\n" +msgstr "" +" -m, --human affiche dans un format lisible pour un humain\n" +" pour les options -f, -w et -s (MHz, GHz)\n" + +#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152 +#, c-format +msgid " -h, --help Prints out this screen\n" +msgstr " -h, --help affiche l'aide-mémoire\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 "" +"Par défaut, les informations de déboguage seront affichées si aucun\n" +"argument, ou bien si seulement l'argument -c (--cpu) est donné, afin de\n" +"faciliter les rapports de bogues par exemple\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 "Les arguments avec un * utiliseront le CPU 0 si -c (--cpu) est omis\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 "Cette option est incompatible avec --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 "" +"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n" +"spécifier plus d'un argument de formatage\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 "option invalide\n" + +#: utils/cpufreq-info.c:617 +#, c-format +msgid "couldn't analyze CPU %d as it doesn't seem to be present\n" +msgstr "analyse du CPU %d impossible puisqu'il ne semble pas être présent\n" + +#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142 +#, c-format +msgid "analyzing CPU %d:\n" +msgstr "analyse du CPU %d :\n" + +#: utils/cpufreq-set.c:25 +#, fuzzy, c-format +msgid "Usage: cpupower frequency-set [options]\n" +msgstr "Usage : cpufreq-set [options]\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 nouvelle fréquence minimale du CPU à utiliser\n" +" par le régulateur\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 nouvelle fréquence maximale du CPU à utiliser\n" +" par le régulateur\n" + +#: utils/cpufreq-set.c:29 +#, c-format +msgid " -g GOV, --governor GOV new cpufreq governor\n" +msgstr " -g GOV, --governor GOV active le régulateur GOV\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 fixe la fréquence du processeur à FREQ. Il faut\n" +" que le régulateur « userspace » soit disponible \n" +" et activé.\n" + +#: utils/cpufreq-set.c:32 +#, c-format +msgid " -r, --related Switches all hardware-related CPUs\n" +msgstr "" + +#: utils/cpufreq-set.c:33 utils/cpupower-set.c:28 utils/cpupower-info.c:27 +#, fuzzy, c-format +msgid " -h, --help Prints out this screen\n" +msgstr " -h, --help affiche l'aide-mémoire\n" + +#: utils/cpufreq-set.c:35 +#, fuzzy, c-format +msgid "" +"Notes:\n" +"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n" +msgstr "Les arguments avec un * utiliseront le CPU 0 si -c (--cpu) est omis\n" + +#: utils/cpufreq-set.c:37 +#, fuzzy, 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 "" +"Remarque :\n" +"1. Le CPU numéro 0 sera utilisé par défaut si -c (ou --cpu) est omis ;\n" +"2. l'argument -f FREQ (ou --freq FREQ) ne peut être utilisé qu'avec --cpu ;\n" +"3. on pourra préciser l'unité des fréquences en postfixant sans aucune " +"espace\n" +" les valeurs par hz, kHz (par défaut), MHz, GHz ou THz\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 "" +"En ajustant les nouveaux paramètres, une erreur est apparue. Les sources\n" +"d'erreur typique sont :\n" +"- droit d'administration insuffisant (êtes-vous root ?) ;\n" +"- le régulateur choisi n'est pas disponible, ou bien n'est pas disponible " +"en\n" +" tant que module noyau ;\n" +"- la tactique n'est pas disponible ;\n" +"- vous voulez utiliser l'option -f/--freq, mais le régulateur « userspace »\n" +" n'est pas disponible, par exemple parce que le matériel ne le supporte\n" +" pas, ou bien n'est tout simplement pas chargé.\n" + +#: utils/cpufreq-set.c:170 +#, c-format +msgid "wrong, unknown or unhandled CPU?\n" +msgstr "CPU inconnu ou non supporté ?\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 "" +"l'option -f/--freq est incompatible avec les options -d/--min, -u/--max et\n" +"-g/--governor\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 "" +"L'un de ces paramètres est obligatoire : -f/--freq, -d/--min, -u/--max et\n" +"-g/--governor\n" + +#: utils/cpufreq-set.c:347 +#, c-format +msgid "Setting cpu: %d\n" +msgstr "" + +#: utils/cpupower-set.c:22 +#, c-format +msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" +msgstr "" + +#: 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 "" + +#: utils/cpupower-set.c:26 +#, c-format +msgid "" +" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n" +msgstr "" + +#: utils/cpupower-set.c:27 +#, c-format +msgid "" +" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler " +"policy.\n" +msgstr "" + +#: utils/cpupower-set.c:80 +#, c-format +msgid "--perf-bias param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:91 +#, c-format +msgid "--sched-mc param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:102 +#, c-format +msgid "--sched-smt param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:121 +#, c-format +msgid "Error setting sched-mc %s\n" +msgstr "" + +#: utils/cpupower-set.c:127 +#, c-format +msgid "Error setting sched-smt %s\n" +msgstr "" + +#: utils/cpupower-set.c:146 +#, c-format +msgid "Error setting perf-bias value on CPU %d\n" +msgstr "" + +#: utils/cpupower-info.c:21 +#, c-format +msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n" +msgstr "" + +#: 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 "" + +#: utils/cpupower-info.c:25 +#, fuzzy, c-format +msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n" +msgstr " -p, --policy Affiche la tactique actuelle de cpufreq *\n" + +#: utils/cpupower-info.c:26 +#, c-format +msgid "" +" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n" +msgstr "" + +#: utils/cpupower-info.c:28 +#, c-format +msgid "" +"\n" +"Passing no option will show all info, by default only on core 0\n" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: utils/cpupower-info.c:128 +#, c-format +msgid "System does not support Intel's performance bias setting\n" +msgstr "" + +#: utils/cpupower-info.c:147 +#, c-format +msgid "Could not read perf-bias value\n" +msgstr "" + +#: utils/cpupower-info.c:150 +#, c-format +msgid "perf-bias: %d\n" +msgstr "" + +#: utils/cpuidle-info.c:28 +#, fuzzy, c-format +msgid "Analyzing CPU %d:\n" +msgstr "analyse du CPU %d :\n" + +#: utils/cpuidle-info.c:32 +#, c-format +msgid "CPU %u: No idle states\n" +msgstr "" + +#: utils/cpuidle-info.c:36 +#, c-format +msgid "CPU %u: Can't read idle state info\n" +msgstr "" + +#: utils/cpuidle-info.c:41 +#, c-format +msgid "Could not determine max idle state %u\n" +msgstr "" + +#: utils/cpuidle-info.c:46 +#, c-format +msgid "Number of idle states: %d\n" +msgstr "" + +#: utils/cpuidle-info.c:48 +#, fuzzy, c-format +msgid "Available idle states:" +msgstr " plage de fréquence : " + +#: utils/cpuidle-info.c:71 +#, c-format +msgid "Flags/Description: %s\n" +msgstr "" + +#: utils/cpuidle-info.c:74 +#, c-format +msgid "Latency: %lu\n" +msgstr "" + +#: utils/cpuidle-info.c:76 +#, c-format +msgid "Usage: %lu\n" +msgstr "" + +#: utils/cpuidle-info.c:78 +#, c-format +msgid "Duration: %llu\n" +msgstr "" + +#: utils/cpuidle-info.c:90 +#, c-format +msgid "Could not determine cpuidle driver\n" +msgstr "" + +#: utils/cpuidle-info.c:94 +#, fuzzy, c-format +msgid "CPUidle driver: %s\n" +msgstr " pilote : %s\n" + +#: utils/cpuidle-info.c:99 +#, c-format +msgid "Could not determine cpuidle governor\n" +msgstr "" + +#: utils/cpuidle-info.c:103 +#, c-format +msgid "CPUidle governor: %s\n" +msgstr "" + +#: utils/cpuidle-info.c:122 +#, c-format +msgid "CPU %u: Can't read C-state info\n" +msgstr "" + +#. printf("Cstates: %d\n", cstates); +#: utils/cpuidle-info.c:127 +#, c-format +msgid "active state: C0\n" +msgstr "" + +#: utils/cpuidle-info.c:128 +#, c-format +msgid "max_cstate: C%u\n" +msgstr "" + +#: utils/cpuidle-info.c:129 +#, c-format +msgid "maximum allowed latency: %lu usec\n" +msgstr "" + +#: utils/cpuidle-info.c:130 +#, c-format +msgid "states:\t\n" +msgstr "" + +#: utils/cpuidle-info.c:132 +#, c-format +msgid " C%d: type[C%d] " +msgstr "" + +#: utils/cpuidle-info.c:134 +#, c-format +msgid "promotion[--] demotion[--] " +msgstr "" + +#: utils/cpuidle-info.c:135 +#, c-format +msgid "latency[%03lu] " +msgstr "" + +#: utils/cpuidle-info.c:137 +#, c-format +msgid "usage[%08lu] " +msgstr "" + +#: utils/cpuidle-info.c:139 +#, c-format +msgid "duration[%020Lu] \n" +msgstr "" + +#: utils/cpuidle-info.c:147 +#, fuzzy, c-format +msgid "Usage: cpupower idleinfo [options]\n" +msgstr "Usage : cpufreq-info [options]\n" + +#: utils/cpuidle-info.c:149 +#, fuzzy, c-format +msgid " -s, --silent Only show general C-state information\n" +msgstr " -e, --debug Afficher les informations de déboguage\n" + +#: utils/cpuidle-info.c:150 +#, fuzzy, 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 Affiche les informations en utilisant l'interface\n" +" fournie par /proc/cpufreq, présente dans les " +"versions\n" +" 2.4 et les anciennes versions 2.6 du noyau\n" + +#: utils/cpuidle-info.c:209 +#, fuzzy, c-format +msgid "You can't specify more than one output-specific argument\n" +msgstr "" +"On ne peut indiquer plus d'un paramètre --cpu, tout comme l'on ne peut\n" +"spécifier plus d'un argument de formatage\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/po/it.po b/tools/power/cpupower/po/it.po new file mode 100644 index 000000000..a1deeb52c --- /dev/null +++ b/tools/power/cpupower/po/it.po @@ -0,0 +1,961 @@ +# Italian translations for cpufrequtils package +# Copyright (C) 2004-2009 +# This file is distributed under the same license as the cpufrequtils package. +# Mattia Dongili . +# +# +msgid "" +msgstr "" +"Project-Id-Version: cpufrequtils 0.3\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-03-08 17:03+0100\n" +"PO-Revision-Date: 2009-08-15 12:00+0900\n" +"Last-Translator: Mattia Dongili \n" +"Language-Team: NONE\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: utils/idle_monitor/nhm_idle.c:36 +msgid "Processor Core C3" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:43 +msgid "Processor Core C6" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:51 +msgid "Processor Package C3" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70 +msgid "Processor Package C6" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:33 +msgid "Processor Core C7" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:40 +msgid "Processor Package C2" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:47 +msgid "Processor Package C7" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:56 +msgid "Package in sleep state (PC1 or deeper)" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:63 +msgid "Processor Package C1" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:77 +msgid "North Bridge P1 boolean counter (returns 0 or 1)" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:35 +msgid "Processor Core not idle" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:42 +msgid "Processor Core in an idle state" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:50 +msgid "Average Frequency (including boost) in MHz" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:66 +#, c-format +msgid "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:69 +#, c-format +msgid "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:71 +#, c-format +msgid "\t -v: be more verbose\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:73 +#, c-format +msgid "\t -h: print this help\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:74 +#, c-format +msgid "\t -i: time interval to measure for in seconds (default 1)\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:75 +#, c-format +msgid "\t -t: show CPU topology/hierarchy\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:76 +#, c-format +msgid "\t -l: list available CPU sleep monitors (for use with -m)\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:77 +#, c-format +msgid "\t -m: show specific CPU sleep monitors only (in same order)\n" +msgstr "" + +#: 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 "" + +#: utils/idle_monitor/cpupower-monitor.c:80 +#, c-format +msgid " all supported monitors are shown\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:197 +#, c-format +msgid "Monitor %s, Counter %s has no count function. Implementation error\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:207 +#, c-format +msgid " *is offline\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:236 +#, c-format +msgid "%s: max monitor name length (%d) exceeded\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:250 +#, c-format +msgid "No matching monitor found in %s, try -l option\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:266 +#, c-format +msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:319 +#, c-format +msgid "%s took %.5f seconds and exited with status %d\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:406 +#, c-format +msgid "Cannot read number of available processors\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:417 +#, c-format +msgid "Available monitor %s needs root access\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:428 +#, c-format +msgid "No HW Cstate monitors found\n" +msgstr "" + +#: utils/cpupower.c:78 +#, c-format +msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n" +msgstr "" + +#: utils/cpupower.c:79 +#, c-format +msgid "cpupower --version\n" +msgstr "" + +#: utils/cpupower.c:80 +#, c-format +msgid "Supported subcommands are:\n" +msgstr "" + +#: utils/cpupower.c:83 +#, c-format +msgid "" +"\n" +"Some subcommands can make use of the -c cpulist option.\n" +msgstr "" + +#: utils/cpupower.c:84 +#, c-format +msgid "Look at the general cpupower manpage how to use it\n" +msgstr "" + +#: utils/cpupower.c:85 +#, c-format +msgid "and read up the subcommand's manpage whether it is supported.\n" +msgstr "" + +#: utils/cpupower.c:86 +#, c-format +msgid "" +"\n" +"Use cpupower help subcommand for getting help for above subcommands.\n" +msgstr "" + +#: utils/cpupower.c:91 +#, c-format +msgid "Report errors and bugs to %s, please.\n" +msgstr "Per favore, comunicare errori e malfunzionamenti a %s.\n" + +#: utils/cpupower.c:114 +#, c-format +msgid "Error parsing cpu list\n" +msgstr "" + +#: utils/cpupower.c:172 +#, c-format +msgid "Subcommand %s needs root privileges\n" +msgstr "" + +#: utils/cpufreq-info.c:31 +#, c-format +msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n" +msgstr "Impossibile determinare il numero di CPU (%s: %s), assumo sia 1\n" + +#: utils/cpufreq-info.c:63 +#, c-format +msgid "" +" minimum CPU frequency - maximum CPU frequency - governor\n" +msgstr "" +" frequenza minima CPU - frequenza massima CPU - gestore\n" + +#: utils/cpufreq-info.c:151 +#, c-format +msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n" +msgstr "" + +#. 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 "" + +#: utils/cpufreq-info.c:163 +#, c-format +msgid " Supported: %s\n" +msgstr "" + +#: 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 +#, fuzzy, c-format +msgid " Active: %s\n" +msgstr " modulo %s\n" + +#: utils/cpufreq-info.c:177 +#, c-format +msgid " Boost States: %d\n" +msgstr "" + +#: utils/cpufreq-info.c:178 +#, c-format +msgid " Total States: %d\n" +msgstr "" + +#: utils/cpufreq-info.c:181 +#, c-format +msgid " Pstate-Pb%d: %luMHz (boost state)\n" +msgstr "" + +#: utils/cpufreq-info.c:184 +#, c-format +msgid " Pstate-P%d: %luMHz\n" +msgstr "" + +#: utils/cpufreq-info.c:211 +#, c-format +msgid " no or unknown cpufreq driver is active on this CPU\n" +msgstr " nessun modulo o modulo cpufreq sconosciuto per questa CPU\n" + +#: utils/cpufreq-info.c:213 +#, c-format +msgid " driver: %s\n" +msgstr " modulo %s\n" + +#: utils/cpufreq-info.c:219 +#, c-format +msgid " CPUs which run at the same hardware frequency: " +msgstr " CPU che operano alla stessa frequenza hardware: " + +#: utils/cpufreq-info.c:230 +#, c-format +msgid " CPUs which need to have their frequency coordinated by software: " +msgstr " CPU che è necessario siano coordinate dal software: " + +#: utils/cpufreq-info.c:241 +#, c-format +msgid " maximum transition latency: " +msgstr " latenza massima durante la transizione: " + +#: utils/cpufreq-info.c:247 +#, c-format +msgid " hardware limits: " +msgstr " limiti hardware: " + +#: utils/cpufreq-info.c:256 +#, c-format +msgid " available frequency steps: " +msgstr " frequenze disponibili: " + +#: utils/cpufreq-info.c:269 +#, c-format +msgid " available cpufreq governors: " +msgstr " gestori disponibili: " + +#: utils/cpufreq-info.c:280 +#, c-format +msgid " current policy: frequency should be within " +msgstr " gestore attuale: la frequenza deve mantenersi tra " + +#: utils/cpufreq-info.c:282 +#, c-format +msgid " and " +msgstr " e " + +#: utils/cpufreq-info.c:286 +#, c-format +msgid "" +"The governor \"%s\" may decide which speed to use\n" +" within this range.\n" +msgstr "" +" Il gestore \"%s\" può decidere quale velocità usare\n" +" in questo intervallo.\n" + +#: utils/cpufreq-info.c:293 +#, c-format +msgid " current CPU frequency is " +msgstr " la frequenza attuale della CPU è " + +#: utils/cpufreq-info.c:296 +#, c-format +msgid " (asserted by call to hardware)" +msgstr " (ottenuta da una chiamata diretta all'hardware)" + +#: utils/cpufreq-info.c:304 +#, c-format +msgid " cpufreq stats: " +msgstr " statistiche cpufreq:" + +#: utils/cpufreq-info.c:472 +#, fuzzy, c-format +msgid "Usage: cpupower freqinfo [options]\n" +msgstr "Uso: cpufreq-info [opzioni]\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 "Opzioni:\n" + +#: utils/cpufreq-info.c:474 +#, fuzzy, c-format +msgid " -e, --debug Prints out debug information [default]\n" +msgstr " -e, --debug Mostra informazioni di 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 Mostra la frequenza attuale della CPU secondo\n" +" il modulo 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 Mostra la frequenza attuale della CPU leggendola\n" +" dall'hardware (disponibile solo per l'utente root) *\n" + +#: utils/cpufreq-info.c:479 +#, c-format +msgid "" +" -l, --hwlimits Determine the minimum and maximum CPU frequency " +"allowed *\n" +msgstr "" +" -l, --hwlimits Determina le frequenze minima e massima possibili per " +"la CPU *\n" + +#: utils/cpufreq-info.c:480 +#, c-format +msgid " -d, --driver Determines the used cpufreq kernel driver *\n" +msgstr "" +" -d, --driver Determina il modulo cpufreq del kernel in uso *\n" + +#: utils/cpufreq-info.c:481 +#, c-format +msgid " -p, --policy Gets the currently used cpufreq policy *\n" +msgstr "" +" -p, --policy Mostra il gestore cpufreq attualmente in uso *\n" + +#: utils/cpufreq-info.c:482 +#, c-format +msgid " -g, --governors Determines available cpufreq governors *\n" +msgstr " -g, --governors Determina i gestori cpufreq disponibili *\n" + +#: utils/cpufreq-info.c:483 +#, c-format +msgid "" +" -r, --related-cpus Determines which CPUs run at the same hardware " +"frequency *\n" +msgstr "" +" -r, --related-cpus Determina quali CPU operano alla stessa frequenza *\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 Determina quali CPU devono avere la frequenza\n" +" coordinata dal software *\n" + +#: utils/cpufreq-info.c:486 +#, c-format +msgid " -s, --stats Shows cpufreq statistics if available\n" +msgstr " -s, --stats Mostra le statistiche se disponibili\n" + +#: utils/cpufreq-info.c:487 +#, c-format +msgid "" +" -y, --latency Determines the maximum latency on CPU frequency " +"changes *\n" +msgstr "" +" -y, --latency Determina la latenza massima durante i cambi di " +"frequenza *\n" + +#: utils/cpufreq-info.c:488 +#, c-format +msgid " -b, --boost Checks for turbo or boost modes *\n" +msgstr "" + +#: 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 Stampa le informazioni come se provenissero dalla\n" +" interfaccia cpufreq /proc/ presente nei kernel\n" +" 2.4 ed i primi 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 formatta l'output delle opzioni -f, -w, -s e -y in " +"maniera\n" +" leggibile da un essere umano\n" + +#: utils/cpufreq-info.c:492 utils/cpuidle-info.c:152 +#, c-format +msgid " -h, --help Prints out this screen\n" +msgstr " -h, --help Stampa questa schermata\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 "" +"Se non viene specificata nessuna opzione o viene specificata solo l'opzione -" +"c, --cpu,\n" +"le informazioni di debug per cpufreq saranno utili ad esempio a riportare i " +"bug.\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 "" +"Per le opzioni segnalate con *, omettere l'opzione -c o --cpu è come " +"specificarla\n" +"con il valore 0\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 "" +"L'opzione specificata a questo programma non può essere combinata con --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 "" +"Non è possibile specificare più di una volta l'opzione --cpu e/o\n" +"specificare più di un parametro di output specifico\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 "opzione sconosciuta o non valida\n" + +#: utils/cpufreq-info.c:617 +#, c-format +msgid "couldn't analyze CPU %d as it doesn't seem to be present\n" +msgstr "impossibile analizzare la CPU %d poiché non sembra essere presente\n" + +#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142 +#, c-format +msgid "analyzing CPU %d:\n" +msgstr "analisi della CPU %d:\n" + +#: utils/cpufreq-set.c:25 +#, fuzzy, c-format +msgid "Usage: cpupower frequency-set [options]\n" +msgstr "Uso: cpufreq-set [opzioni]\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 la nuova frequenza minima che il gestore cpufreq " +"può scegliere\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 la nuova frequenza massima che il gestore cpufreq " +"può scegliere\n" + +#: utils/cpufreq-set.c:29 +#, c-format +msgid " -g GOV, --governor GOV new cpufreq governor\n" +msgstr " -g GOV, --governor GOV nuovo gestore 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 specifica la frequenza a cui impostare la CPU.\n" +" È necessario che il gestore userspace sia " +"disponibile e caricato\n" + +#: utils/cpufreq-set.c:32 +#, c-format +msgid " -r, --related Switches all hardware-related CPUs\n" +msgstr "" +" -r, --related Modifica tutte le CPU coordinate dall'hardware\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 Stampa questa schermata\n" + +#: utils/cpufreq-set.c:35 +#, fuzzy, c-format +msgid "" +"Notes:\n" +"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n" +msgstr "" +"Per le opzioni segnalate con *, omettere l'opzione -c o --cpu è come " +"specificarla\n" +"con il valore 0\n" + +#: utils/cpufreq-set.c:37 +#, fuzzy, 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 "" +"Note:\n" +"1. Omettere l'opzione -c o --cpu è equivalente a impostarlo a 0\n" +"2. l'opzione -f FREQ, --freq FREQ non può essere specificata con altre " +"opzioni\n" +" ad eccezione dell'opzione -c CPU o --cpu CPU\n" +"3. le FREQuenze possono essere specuficate in Hz, kHz (default), MHz, GHz, " +"or THz\n" +" postponendo l'unità di misura al valore senza nessuno spazio fra loro\n" +" (FREQuenza in 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 "" +"Si sono verificati degli errori impostando i nuovi valori.\n" +"Alcuni errori comuni possono essere:\n" +"- Hai i necessari diritti di amministrazione? (super-user?)\n" +"- Il gestore che hai richiesto è disponibile e caricato?\n" +"- Stai provando ad impostare una politica di gestione non valida?\n" +"- Stai provando a impostare una specifica frequenza ma il gestore\n" +" userspace non è disponibile, per esempio a causa dell'hardware\n" +" che non supporta frequenze fisse o a causa del fatto che\n" +" il gestore userspace non è caricato?\n" + +#: utils/cpufreq-set.c:170 +#, c-format +msgid "wrong, unknown or unhandled CPU?\n" +msgstr "CPU errata, sconosciuta o non gestita?\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 "" +"l'opzione -f/--freq non può venire combinata con i parametri\n" +" -d/--min, -u/--max o -g/--governor\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 "" +"Almeno una delle opzioni -f/--freq, -d/--min, -u/--max, e -g/--governor\n" +"deve essere specificata\n" + +#: utils/cpufreq-set.c:347 +#, c-format +msgid "Setting cpu: %d\n" +msgstr "" + +#: utils/cpupower-set.c:22 +#, c-format +msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" +msgstr "" + +#: 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 "" + +#: utils/cpupower-set.c:26 +#, c-format +msgid "" +" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n" +msgstr "" + +#: utils/cpupower-set.c:27 +#, c-format +msgid "" +" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler " +"policy.\n" +msgstr "" + +#: utils/cpupower-set.c:80 +#, c-format +msgid "--perf-bias param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:91 +#, c-format +msgid "--sched-mc param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:102 +#, c-format +msgid "--sched-smt param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:121 +#, c-format +msgid "Error setting sched-mc %s\n" +msgstr "" + +#: utils/cpupower-set.c:127 +#, c-format +msgid "Error setting sched-smt %s\n" +msgstr "" + +#: utils/cpupower-set.c:146 +#, c-format +msgid "Error setting perf-bias value on CPU %d\n" +msgstr "" + +#: utils/cpupower-info.c:21 +#, c-format +msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n" +msgstr "" + +#: 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 "" + +#: utils/cpupower-info.c:25 +#, fuzzy, c-format +msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n" +msgstr "" +" -p, --policy Mostra il gestore cpufreq attualmente in uso *\n" + +#: utils/cpupower-info.c:26 +#, c-format +msgid "" +" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n" +msgstr "" + +#: utils/cpupower-info.c:28 +#, c-format +msgid "" +"\n" +"Passing no option will show all info, by default only on core 0\n" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: utils/cpupower-info.c:128 +#, c-format +msgid "System does not support Intel's performance bias setting\n" +msgstr "" + +#: utils/cpupower-info.c:147 +#, c-format +msgid "Could not read perf-bias value\n" +msgstr "" + +#: utils/cpupower-info.c:150 +#, c-format +msgid "perf-bias: %d\n" +msgstr "" + +#: utils/cpuidle-info.c:28 +#, fuzzy, c-format +msgid "Analyzing CPU %d:\n" +msgstr "analisi della CPU %d:\n" + +#: utils/cpuidle-info.c:32 +#, c-format +msgid "CPU %u: No idle states\n" +msgstr "" + +#: utils/cpuidle-info.c:36 +#, c-format +msgid "CPU %u: Can't read idle state info\n" +msgstr "" + +#: utils/cpuidle-info.c:41 +#, c-format +msgid "Could not determine max idle state %u\n" +msgstr "" + +#: utils/cpuidle-info.c:46 +#, c-format +msgid "Number of idle states: %d\n" +msgstr "" + +#: utils/cpuidle-info.c:48 +#, fuzzy, c-format +msgid "Available idle states:" +msgstr " frequenze disponibili: " + +#: utils/cpuidle-info.c:71 +#, c-format +msgid "Flags/Description: %s\n" +msgstr "" + +#: utils/cpuidle-info.c:74 +#, c-format +msgid "Latency: %lu\n" +msgstr "" + +#: utils/cpuidle-info.c:76 +#, c-format +msgid "Usage: %lu\n" +msgstr "" + +#: utils/cpuidle-info.c:78 +#, c-format +msgid "Duration: %llu\n" +msgstr "" + +#: utils/cpuidle-info.c:90 +#, c-format +msgid "Could not determine cpuidle driver\n" +msgstr "" + +#: utils/cpuidle-info.c:94 +#, fuzzy, c-format +msgid "CPUidle driver: %s\n" +msgstr " modulo %s\n" + +#: utils/cpuidle-info.c:99 +#, c-format +msgid "Could not determine cpuidle governor\n" +msgstr "" + +#: utils/cpuidle-info.c:103 +#, c-format +msgid "CPUidle governor: %s\n" +msgstr "" + +#: utils/cpuidle-info.c:122 +#, c-format +msgid "CPU %u: Can't read C-state info\n" +msgstr "" + +#. printf("Cstates: %d\n", cstates); +#: utils/cpuidle-info.c:127 +#, c-format +msgid "active state: C0\n" +msgstr "" + +#: utils/cpuidle-info.c:128 +#, c-format +msgid "max_cstate: C%u\n" +msgstr "" + +#: utils/cpuidle-info.c:129 +#, fuzzy, c-format +msgid "maximum allowed latency: %lu usec\n" +msgstr " latenza massima durante la transizione: " + +#: utils/cpuidle-info.c:130 +#, c-format +msgid "states:\t\n" +msgstr "" + +#: utils/cpuidle-info.c:132 +#, c-format +msgid " C%d: type[C%d] " +msgstr "" + +#: utils/cpuidle-info.c:134 +#, c-format +msgid "promotion[--] demotion[--] " +msgstr "" + +#: utils/cpuidle-info.c:135 +#, c-format +msgid "latency[%03lu] " +msgstr "" + +#: utils/cpuidle-info.c:137 +#, c-format +msgid "usage[%08lu] " +msgstr "" + +#: utils/cpuidle-info.c:139 +#, c-format +msgid "duration[%020Lu] \n" +msgstr "" + +#: utils/cpuidle-info.c:147 +#, fuzzy, c-format +msgid "Usage: cpupower idleinfo [options]\n" +msgstr "Uso: cpufreq-info [opzioni]\n" + +#: utils/cpuidle-info.c:149 +#, fuzzy, c-format +msgid " -s, --silent Only show general C-state information\n" +msgstr " -e, --debug Mostra informazioni di debug\n" + +#: utils/cpuidle-info.c:150 +#, fuzzy, 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 Stampa le informazioni come se provenissero dalla\n" +" interfaccia cpufreq /proc/ presente nei kernel\n" +" 2.4 ed i primi 2.6\n" + +#: utils/cpuidle-info.c:209 +#, fuzzy, c-format +msgid "You can't specify more than one output-specific argument\n" +msgstr "" +"Non è possibile specificare più di una volta l'opzione --cpu e/o\n" +"specificare più di un parametro di output specifico\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU CPU number which information shall be determined " +#~ "about\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU Numero di CPU per la quale ottenere le " +#~ "informazioni\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be " +#~ "modified\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU numero di CPU per la quale modificare le " +#~ "impostazioni\n" + +#, fuzzy +#~ msgid " CPUs which coordinate software frequency requirements: " +#~ msgstr "" +#~ " CPU per le quali e` necessario cambiare la frequenza " +#~ "contemporaneamente: " diff --git a/tools/power/cpupower/po/ka.po b/tools/power/cpupower/po/ka.po new file mode 100644 index 000000000..ef71dbac5 --- /dev/null +++ b/tools/power/cpupower/po/ka.po @@ -0,0 +1,983 @@ +# Georgian translation for cpufrequtils package +# Georgian messages for cpufrequtils. +# Copyright (C) 2004-2022 Dominik Brodowski +# This file is distributed under the same license as the cpufrequtils package. +# Ekaterine Papava , 2022. + +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: 2022-09-18 22:12+0200\n" +"Last-Translator: Ekaterine Papava \n" +"Language-Team: NONE\n" +"Language: ka\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Poedit 3.1.1\n" + +#: utils/idle_monitor/nhm_idle.c:36 +msgid "Processor Core C3" +msgstr "პროცესორის ბირთვი C3" + +#: utils/idle_monitor/nhm_idle.c:43 +msgid "Processor Core C6" +msgstr "პროცესორის ბირთვი 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 "პაკეტი ძილის მდგომარეობაში (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 "პროცესორის ბირთვი უქმი არაა" + +#: utils/idle_monitor/mperf_monitor.c:42 +msgid "Processor Core in an idle state" +msgstr "პროცესორის ბირთვი უქმ მდგომარეობაში არაა" + +#: utils/idle_monitor/mperf_monitor.c:50 +msgid "Average Frequency (including boost) in MHz" +msgstr "საშუალო სიხშირე (პიკურის ჩათვლით) მეგაჰერცებში" + +#: utils/idle_monitor/cpupower-monitor.c:66 +#, c-format +msgid "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"ინტერვალი_წმ | -c ბრძანება ...]\n" + +#: utils/idle_monitor/cpupower-monitor.c:69 +#, c-format +msgid "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"ინტერვალი_წმ | -c ბრძანება ...]\n" + +#: utils/idle_monitor/cpupower-monitor.c:71 +#, c-format +msgid "\t -v: be more verbose\n" +msgstr "\t -v: დამატებითი ინფორმაციის გამოტანა\n" + +#: utils/idle_monitor/cpupower-monitor.c:73 +#, c-format +msgid "\t -h: print this help\n" +msgstr "\t -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 "" +"\t -i: გასაზომი დროის ინტერვალი, წამებში (ნაგულისხმები მნიშვნელობაა 1)\n" + +#: utils/idle_monitor/cpupower-monitor.c:75 +#, c-format +msgid "\t -t: show CPU topology/hierarchy\n" +msgstr "\t -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 "" +"\t -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 "" +"\t -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 "აპარატურული C-მდგომარეობის მონიტორები ვერ ვიპოვე\n" + +#: utils/cpupower.c:78 +#, c-format +msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n" +msgstr "cpupower [ -c cpu-ებისსია ] ქვებრძანება [არგუმენტები]\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 cpu-ებისსია პარამეტრი გამოიყენოს.\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 ქვებრძანების_სახელი.\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 "" +"შეცდომა %d-ე CPU-ის პიკური დატვირთვის მართვის შესაძლებლობების შეფასებისას -- " +"გაქვთ თუ არა 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: %luმჰც (პიკში)\n" + +#: utils/cpufreq-info.c:184 +#, c-format +msgid " Pstate-P%d: %luMHz\n" +msgstr " Pstate-P%d: %luმჰც\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 " cpufreq -ის სტატისტიკა: " + +#: 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, --related-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 ტურბო და პიკური რეჟიმების შემოწმება *\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 "" +"თუ არგუმენტები საერთოდ არ გადაცემულა ან გადაცემულია -c ან --cpu, მოხდება " +"cpufreq-ის\n" +"დრაივერის დამატებითი შეტყობინებების გამოტანა, რომელიც გამართვისთვისაა " +"საჭირო.\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 "%d-ე CPU-ის ანალიზი შეუძლებელია. ის არ არსებობს\n" + +#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142 +#, c-format +msgid "analyzing CPU %d:\n" +msgstr "%d-ე CPU -ის ანალიზი:\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. The -f FREQ, --freq FREQ პარამეტრის შეთავსება შეუძლებელია სხვა " +"პარამეტრებთან,\n" +" -c CPU, --cpu CPU -ის გარდა\n" +"3. სიხშირეების გადაცემა შეიძლება ჰერცებში (hz), კილოჰერცებში, (KHz) " +"(ნაგულისხმები), მეგაჰერცებში (MHz), GHz და THz.\n" +" რიცხვის შემდეგ შესაბამისი ერთეულის, გამოტოვების გარეშე, მიწერით\n" +" (სიხშირე in 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" +"- გაქვთ თუ არა ადმინისტრატორის უფლებები? (მომხმარებელი root)\n" +"- არის თუ არა მოთხოვნილი მმართველი ხელმისაწვდომი და შესაბამისი მოდული " +"modprobe-ით ჩატვირთული?\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/--governor პარამეტრებთან ერთად იყოს მითითებული\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, and\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 მნიშვნ ] [ -m მნიშვნ ] [ -s მნიშვნ ]\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] Intel-ის ზოგიერთ მოდელზე [0-15] CPU-ის კვებასა და " +"წარმადობას შორის დამოკიდებულების დაყენება\n" +" მეტი დეტალისთვის იხილეთ სახელმძღვანელო (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 "%d-ე CPU-ზე perf-bias -ის მნიშვნელობის დაყენების შეცდომა\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 [VAL] Intel-ის ზოგიერთ მოდელზე [0-15] CPU-ის კვებასა და " +"წარმადობას შორის დამოკიდებულების მიღება\n" +" მეტი დეტალისთვის იხილეთ სახელმძღვანელო (manpage)\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" +"მნიშვნელობის არ-გადაცემის შემთხვევაში ნაჩვენები იქნება სრული ინფორმაცია. " +"ნაგულისხმევად მხოლოდ ნულოვან ბირთვზე\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-ის წარმადობის bias-ის დაყენებას root-ის პრივილეგიები სჭირდება\n" + +#: utils/cpupower-info.c:128 +#, c-format +msgid "System does not support Intel's performance bias setting\n" +msgstr "" +"სისტემას intel-ის performance bias-ის დაყენების მხარდაჭერა არ გააჩნია\n" + +#: utils/cpupower-info.c:147 +#, c-format +msgid "Could not read perf-bias value\n" +msgstr "შეცდომა perf-bias -ის მნიშვნელობის წაკითხვისას\n" + +#: utils/cpupower-info.c:150 +#, c-format +msgid "perf-bias: %d\n" +msgstr "perf-bias: %d\n" + +#: utils/cpuidle-info.c:28 +#, c-format +msgid "Analyzing CPU %d:\n" +msgstr "%d-ე CPU -ის ანალიზი:\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 "CPUidle -ის დრაივერი: %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 "CPUidle მმართველი: %s\n" + +#: utils/cpuidle-info.c:122 +#, c-format +msgid "CPU %u: Can't read C-state info\n" +msgstr "CPU %u: C-state -ის ინფორმაციის წაკითხვის შეცდომა\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 "max_cstate: 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 "promotion[--] demotion[--] " + +#: 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-state -ის ინფორმაციის ჩვენება\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" diff --git a/tools/power/cpupower/po/pt.po b/tools/power/cpupower/po/pt.po new file mode 100644 index 000000000..902186585 --- /dev/null +++ b/tools/power/cpupower/po/pt.po @@ -0,0 +1,957 @@ +# Brazilian Portuguese translations for cpufrequtils package +# Copyright (C) 2008 THE cpufrequtils'S COPYRIGHT HOLDER +# This file is distributed under the same license as the cpufrequtils package. +# Claudio Eduardo , 2009. +# +# +msgid "" +msgstr "" +"Project-Id-Version: cpufrequtils 004\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2011-03-08 17:03+0100\n" +"PO-Revision-Date: 2008-06-14 22:16-0400\n" +"Last-Translator: Claudio Eduardo \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: utils/idle_monitor/nhm_idle.c:36 +msgid "Processor Core C3" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:43 +msgid "Processor Core C6" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:51 +msgid "Processor Package C3" +msgstr "" + +#: utils/idle_monitor/nhm_idle.c:58 utils/idle_monitor/amd_fam14h_idle.c:70 +msgid "Processor Package C6" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:33 +msgid "Processor Core C7" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:40 +msgid "Processor Package C2" +msgstr "" + +#: utils/idle_monitor/snb_idle.c:47 +msgid "Processor Package C7" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:56 +msgid "Package in sleep state (PC1 or deeper)" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:63 +msgid "Processor Package C1" +msgstr "" + +#: utils/idle_monitor/amd_fam14h_idle.c:77 +msgid "North Bridge P1 boolean counter (returns 0 or 1)" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:35 +msgid "Processor Core not idle" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:42 +msgid "Processor Core in an idle state" +msgstr "" + +#: utils/idle_monitor/mperf_monitor.c:50 +msgid "Average Frequency (including boost) in MHz" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:66 +#, c-format +msgid "" +"cpupower monitor: [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:69 +#, c-format +msgid "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:71 +#, c-format +msgid "\t -v: be more verbose\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:73 +#, c-format +msgid "\t -h: print this help\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:74 +#, c-format +msgid "\t -i: time interval to measure for in seconds (default 1)\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:75 +#, c-format +msgid "\t -t: show CPU topology/hierarchy\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:76 +#, c-format +msgid "\t -l: list available CPU sleep monitors (for use with -m)\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:77 +#, c-format +msgid "\t -m: show specific CPU sleep monitors only (in same order)\n" +msgstr "" + +#: 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 "" + +#: utils/idle_monitor/cpupower-monitor.c:80 +#, c-format +msgid " all supported monitors are shown\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:197 +#, c-format +msgid "Monitor %s, Counter %s has no count function. Implementation error\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:207 +#, c-format +msgid " *is offline\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:236 +#, c-format +msgid "%s: max monitor name length (%d) exceeded\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:250 +#, c-format +msgid "No matching monitor found in %s, try -l option\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:266 +#, c-format +msgid "Monitor \"%s\" (%d states) - Might overflow after %u s\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:319 +#, c-format +msgid "%s took %.5f seconds and exited with status %d\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:406 +#, c-format +msgid "Cannot read number of available processors\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:417 +#, c-format +msgid "Available monitor %s needs root access\n" +msgstr "" + +#: utils/idle_monitor/cpupower-monitor.c:428 +#, c-format +msgid "No HW Cstate monitors found\n" +msgstr "" + +#: utils/cpupower.c:78 +#, c-format +msgid "cpupower [ -c cpulist ] subcommand [ARGS]\n" +msgstr "" + +#: utils/cpupower.c:79 +#, c-format +msgid "cpupower --version\n" +msgstr "" + +#: utils/cpupower.c:80 +#, c-format +msgid "Supported subcommands are:\n" +msgstr "" + +#: utils/cpupower.c:83 +#, c-format +msgid "" +"\n" +"Some subcommands can make use of the -c cpulist option.\n" +msgstr "" + +#: utils/cpupower.c:84 +#, c-format +msgid "Look at the general cpupower manpage how to use it\n" +msgstr "" + +#: utils/cpupower.c:85 +#, c-format +msgid "and read up the subcommand's manpage whether it is supported.\n" +msgstr "" + +#: utils/cpupower.c:86 +#, c-format +msgid "" +"\n" +"Use cpupower help subcommand for getting help for above subcommands.\n" +msgstr "" + +#: utils/cpupower.c:91 +#, c-format +msgid "Report errors and bugs to %s, please.\n" +msgstr "Reporte erros e bugs para %s, por favor.\n" + +#: utils/cpupower.c:114 +#, c-format +msgid "Error parsing cpu list\n" +msgstr "" + +#: utils/cpupower.c:172 +#, c-format +msgid "Subcommand %s needs root privileges\n" +msgstr "" + +#: utils/cpufreq-info.c:31 +#, c-format +msgid "Couldn't count the number of CPUs (%s: %s), assuming 1\n" +msgstr "Não foi possível contar o número de CPUs (%s: %s), assumindo 1\n" + +#: utils/cpufreq-info.c:63 +#, c-format +msgid "" +" minimum CPU frequency - maximum CPU frequency - governor\n" +msgstr "" +" frequência mínina do CPU - frequência máxima do CPU - " +"regulador\n" + +#: utils/cpufreq-info.c:151 +#, c-format +msgid "Error while evaluating Boost Capabilities on CPU %d -- are you root?\n" +msgstr "" + +#. 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 "" + +#: utils/cpufreq-info.c:163 +#, c-format +msgid " Supported: %s\n" +msgstr "" + +#: 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 +#, fuzzy, c-format +msgid " Active: %s\n" +msgstr " driver: %s\n" + +#: utils/cpufreq-info.c:177 +#, c-format +msgid " Boost States: %d\n" +msgstr "" + +#: utils/cpufreq-info.c:178 +#, c-format +msgid " Total States: %d\n" +msgstr "" + +#: utils/cpufreq-info.c:181 +#, c-format +msgid " Pstate-Pb%d: %luMHz (boost state)\n" +msgstr "" + +#: utils/cpufreq-info.c:184 +#, c-format +msgid " Pstate-P%d: %luMHz\n" +msgstr "" + +#: utils/cpufreq-info.c:211 +#, c-format +msgid " no or unknown cpufreq driver is active on this CPU\n" +msgstr " nenhum ou driver do cpufreq deconhecido está ativo nesse CPU\n" + +#: utils/cpufreq-info.c:213 +#, c-format +msgid " driver: %s\n" +msgstr " driver: %s\n" + +#: utils/cpufreq-info.c:219 +#, c-format +msgid " CPUs which run at the same hardware frequency: " +msgstr " CPUs que rodam na mesma frequência de hardware: " + +#: utils/cpufreq-info.c:230 +#, c-format +msgid " CPUs which need to have their frequency coordinated by software: " +msgstr " CPUs que precisam ter suas frequências coordenadas por software: " + +#: utils/cpufreq-info.c:241 +#, c-format +msgid " maximum transition latency: " +msgstr " maior latência de transição: " + +#: utils/cpufreq-info.c:247 +#, c-format +msgid " hardware limits: " +msgstr " limites do hardware: " + +#: utils/cpufreq-info.c:256 +#, c-format +msgid " available frequency steps: " +msgstr " níveis de frequência disponíveis: " + +#: utils/cpufreq-info.c:269 +#, c-format +msgid " available cpufreq governors: " +msgstr " reguladores do cpufreq disponíveis: " + +#: utils/cpufreq-info.c:280 +#, c-format +msgid " current policy: frequency should be within " +msgstr " política de frequência atual deve estar entre " + +#: utils/cpufreq-info.c:282 +#, c-format +msgid " and " +msgstr " e " + +#: utils/cpufreq-info.c:286 +#, c-format +msgid "" +"The governor \"%s\" may decide which speed to use\n" +" within this range.\n" +msgstr "" +"O regulador \"%s\" deve decidir qual velocidade usar\n" +" dentro desse limite.\n" + +#: utils/cpufreq-info.c:293 +#, c-format +msgid " current CPU frequency is " +msgstr " frequência atual do CPU é " + +#: utils/cpufreq-info.c:296 +#, c-format +msgid " (asserted by call to hardware)" +msgstr " (declarado por chamada ao hardware)" + +#: utils/cpufreq-info.c:304 +#, c-format +msgid " cpufreq stats: " +msgstr " status do cpufreq: " + +#: utils/cpufreq-info.c:472 +#, fuzzy, c-format +msgid "Usage: cpupower freqinfo [options]\n" +msgstr "Uso: cpufreq-info [opções]\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 "Opções:\n" + +#: utils/cpufreq-info.c:474 +#, fuzzy, c-format +msgid " -e, --debug Prints out debug information [default]\n" +msgstr " -e, --debug Mostra informação de 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 Obtem a frequência na qual o CPU roda no momento, de " +"acordo\n" +" com o núcleo do 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 Obtem a frequência na qual o CPU está operando no " +"momento,\n" +" através de leitura no hardware (disponível somente " +"para root) *\n" + +#: utils/cpufreq-info.c:479 +#, c-format +msgid "" +" -l, --hwlimits Determine the minimum and maximum CPU frequency " +"allowed *\n" +msgstr "" +" -l, --hwlimits Determina a frequência mínima e máxima do CPU " +"permitida *\n" + +#: utils/cpufreq-info.c:480 +#, c-format +msgid " -d, --driver Determines the used cpufreq kernel driver *\n" +msgstr "" +" -d, --driver Determina o driver do kernel do cpufreq usado *\n" + +#: utils/cpufreq-info.c:481 +#, c-format +msgid " -p, --policy Gets the currently used cpufreq policy *\n" +msgstr "" +"--p, --policy Obtem a política do cpufreq em uso no momento *\n" + +#: utils/cpufreq-info.c:482 +#, c-format +msgid " -g, --governors Determines available cpufreq governors *\n" +msgstr "" +" -g, --governors Determina reguladores do cpufreq disponíveis *\n" + +#: utils/cpufreq-info.c:483 +#, c-format +msgid "" +" -r, --related-cpus Determines which CPUs run at the same hardware " +"frequency *\n" +msgstr "" +" -r, --related-cpus Determina quais CPUs rodam na mesma frequência de " +"hardware *\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 Determina quais CPUs precisam ter suas frequências\n" +" coordenadas por software *\n" + +#: utils/cpufreq-info.c:486 +#, c-format +msgid " -s, --stats Shows cpufreq statistics if available\n" +msgstr " -s, --stats Mostra estatísticas do cpufreq se disponíveis\n" + +#: utils/cpufreq-info.c:487 +#, c-format +msgid "" +" -y, --latency Determines the maximum latency on CPU frequency " +"changes *\n" +msgstr "" +" -y, --latency Determina a latência máxima nas trocas de frequência " +"do CPU *\n" + +#: utils/cpufreq-info.c:488 +#, c-format +msgid " -b, --boost Checks for turbo or boost modes *\n" +msgstr "" + +#: 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 Mostra informação do tipo provida pela interface /" +"proc/cpufreq\n" +" em kernels 2.4. e mais recentes 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 saída legível para humanos para os parâmetros -f, -w, " +"-s e -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 Imprime essa tela\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 "" +"Se nenhum argumento ou somente o parâmetro -c, --cpu é dado, informação de " +"debug sobre\n" +"o cpufreq é mostrada, o que é útil por exemplo para reportar bugs.\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 "" +"Para os argumentos marcados com *, omitir o argumento -c ou --cpu é\n" +"equivalente a setá-lo como zero\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 "" +"O argumento usado pra essa ferramenta não pode ser combinado com um " +"argumento --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 "" +"Você não pode especificar mais do que um parâmetro --cpu e/ou\n" +"mais do que um argumento de saída específico\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 "argumento inválido ou desconhecido\n" + +#: utils/cpufreq-info.c:617 +#, c-format +msgid "couldn't analyze CPU %d as it doesn't seem to be present\n" +msgstr "" +"não foi possível analisar o CPU % já que o mesmo parece não estar presente\n" + +#: utils/cpufreq-info.c:620 utils/cpupower-info.c:142 +#, c-format +msgid "analyzing CPU %d:\n" +msgstr "analisando o CPU %d:\n" + +#: utils/cpufreq-set.c:25 +#, fuzzy, c-format +msgid "Usage: cpupower frequency-set [options]\n" +msgstr "Uso: cpufreq-set [opções]\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 nova frequência mínima do CPU que o regulador " +"deve selecionar\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 nova frequência máxima do CPU que o regulador " +"deve escolher\n" + +#: utils/cpufreq-set.c:29 +#, c-format +msgid " -g GOV, --governor GOV new cpufreq governor\n" +msgstr " -g GOV, --governor GOV novo regulador do 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 frequência específica para ser setada. Necessita " +"que o regulador em\n" +" nível de usuário esteja disponível e carregado\n" + +#: utils/cpufreq-set.c:32 +#, c-format +msgid " -r, --related Switches all hardware-related CPUs\n" +msgstr "" +" -r, --related Modifica todos os CPUs relacionados ao hardware\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 Mostra essa tela\n" + +#: utils/cpufreq-set.c:35 +#, fuzzy, c-format +msgid "" +"Notes:\n" +"1. Omitting the -c or --cpu argument is equivalent to setting it to \"all\"\n" +msgstr "" +"Para os argumentos marcados com *, omitir o argumento -c ou --cpu é\n" +"equivalente a setá-lo como zero\n" + +#: utils/cpufreq-set.c:37 +#, fuzzy, 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 "" +"Notas:\n" +"1. Omitir o argumento -c or --cpu é equivalente a setá-lo como zero\n" +"2. O parâmetro -f FREQ, --freq FREQ não pode ser combinado com qualquer " +"outro parâmetro\n" +" exceto com o parâmetro -c CPU, --cpu CPU\n" +"3. FREQuências podem ser usadas em Hz, kHz (padrão), MHz, GHz, o THz\n" +" colocando o nome desejado da unidade após o valor, sem qualquer espaço\n" +" (FREQuência em 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 "" +"Erro ao setar novos valores. Erros comuns:\n" +"- Você tem direitos administrativos necessários? (super-usuário?)\n" +"- O regulador que você requesitou está disponível e foi \"modprobed\"?\n" +"- Tentando setar uma política inválida?\n" +"- Tentando setar uma frequência específica, mas o regulador em nível de " +"usuário não está disponível,\n" +" por exemplo devido ao hardware que não pode ser setado pra uma frequência " +"específica\n" +" ou porque o regulador em nível de usuário não foi carregado?\n" + +#: utils/cpufreq-set.c:170 +#, c-format +msgid "wrong, unknown or unhandled CPU?\n" +msgstr "CPU errado, desconhecido ou inesperado?\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 "" +"o parâmetro -f/--freq não pode ser combinado com os parâmetros -d/--min, -" +"u/--max ou\n" +"-g/--governor\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 "" +"Pelo menos um parâmetro entre -f/--freq, -d/--min, -u/--max, e\n" +"-g/--governor deve ser usado\n" + +#: utils/cpufreq-set.c:347 +#, c-format +msgid "Setting cpu: %d\n" +msgstr "" + +#: utils/cpupower-set.c:22 +#, c-format +msgid "Usage: cpupower set [ -b val ] [ -m val ] [ -s val ]\n" +msgstr "" + +#: 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 "" + +#: utils/cpupower-set.c:26 +#, c-format +msgid "" +" -m, --sched-mc [VAL] Sets the kernel's multi core scheduler policy.\n" +msgstr "" + +#: utils/cpupower-set.c:27 +#, c-format +msgid "" +" -s, --sched-smt [VAL] Sets the kernel's thread sibling scheduler " +"policy.\n" +msgstr "" + +#: utils/cpupower-set.c:80 +#, c-format +msgid "--perf-bias param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:91 +#, c-format +msgid "--sched-mc param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:102 +#, c-format +msgid "--sched-smt param out of range [0-%d]\n" +msgstr "" + +#: utils/cpupower-set.c:121 +#, c-format +msgid "Error setting sched-mc %s\n" +msgstr "" + +#: utils/cpupower-set.c:127 +#, c-format +msgid "Error setting sched-smt %s\n" +msgstr "" + +#: utils/cpupower-set.c:146 +#, c-format +msgid "Error setting perf-bias value on CPU %d\n" +msgstr "" + +#: utils/cpupower-info.c:21 +#, c-format +msgid "Usage: cpupower info [ -b ] [ -m ] [ -s ]\n" +msgstr "" + +#: 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 "" + +#: utils/cpupower-info.c:25 +#, fuzzy, c-format +msgid " -m, --sched-mc Gets the kernel's multi core scheduler policy.\n" +msgstr "" +"--p, --policy Obtem a política do cpufreq em uso no momento *\n" + +#: utils/cpupower-info.c:26 +#, c-format +msgid "" +" -s, --sched-smt Gets the kernel's thread sibling scheduler policy.\n" +msgstr "" + +#: utils/cpupower-info.c:28 +#, c-format +msgid "" +"\n" +"Passing no option will show all info, by default only on core 0\n" +msgstr "" + +#: 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 "" + +#: 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 "" + +#: utils/cpupower-info.c:128 +#, c-format +msgid "System does not support Intel's performance bias setting\n" +msgstr "" + +#: utils/cpupower-info.c:147 +#, c-format +msgid "Could not read perf-bias value\n" +msgstr "" + +#: utils/cpupower-info.c:150 +#, c-format +msgid "perf-bias: %d\n" +msgstr "" + +#: utils/cpuidle-info.c:28 +#, fuzzy, c-format +msgid "Analyzing CPU %d:\n" +msgstr "analisando o CPU %d:\n" + +#: utils/cpuidle-info.c:32 +#, c-format +msgid "CPU %u: No idle states\n" +msgstr "" + +#: utils/cpuidle-info.c:36 +#, c-format +msgid "CPU %u: Can't read idle state info\n" +msgstr "" + +#: utils/cpuidle-info.c:41 +#, c-format +msgid "Could not determine max idle state %u\n" +msgstr "" + +#: utils/cpuidle-info.c:46 +#, c-format +msgid "Number of idle states: %d\n" +msgstr "" + +#: utils/cpuidle-info.c:48 +#, fuzzy, c-format +msgid "Available idle states:" +msgstr " níveis de frequência disponíveis: " + +#: utils/cpuidle-info.c:71 +#, c-format +msgid "Flags/Description: %s\n" +msgstr "" + +#: utils/cpuidle-info.c:74 +#, c-format +msgid "Latency: %lu\n" +msgstr "" + +#: utils/cpuidle-info.c:76 +#, c-format +msgid "Usage: %lu\n" +msgstr "" + +#: utils/cpuidle-info.c:78 +#, c-format +msgid "Duration: %llu\n" +msgstr "" + +#: utils/cpuidle-info.c:90 +#, c-format +msgid "Could not determine cpuidle driver\n" +msgstr "" + +#: utils/cpuidle-info.c:94 +#, fuzzy, c-format +msgid "CPUidle driver: %s\n" +msgstr " driver: %s\n" + +#: utils/cpuidle-info.c:99 +#, c-format +msgid "Could not determine cpuidle governor\n" +msgstr "" + +#: utils/cpuidle-info.c:103 +#, c-format +msgid "CPUidle governor: %s\n" +msgstr "" + +#: utils/cpuidle-info.c:122 +#, c-format +msgid "CPU %u: Can't read C-state info\n" +msgstr "" + +#. printf("Cstates: %d\n", cstates); +#: utils/cpuidle-info.c:127 +#, c-format +msgid "active state: C0\n" +msgstr "" + +#: utils/cpuidle-info.c:128 +#, c-format +msgid "max_cstate: C%u\n" +msgstr "" + +#: utils/cpuidle-info.c:129 +#, fuzzy, c-format +msgid "maximum allowed latency: %lu usec\n" +msgstr " maior latência de transição: " + +#: utils/cpuidle-info.c:130 +#, c-format +msgid "states:\t\n" +msgstr "" + +#: utils/cpuidle-info.c:132 +#, c-format +msgid " C%d: type[C%d] " +msgstr "" + +#: utils/cpuidle-info.c:134 +#, c-format +msgid "promotion[--] demotion[--] " +msgstr "" + +#: utils/cpuidle-info.c:135 +#, c-format +msgid "latency[%03lu] " +msgstr "" + +#: utils/cpuidle-info.c:137 +#, c-format +msgid "usage[%08lu] " +msgstr "" + +#: utils/cpuidle-info.c:139 +#, c-format +msgid "duration[%020Lu] \n" +msgstr "" + +#: utils/cpuidle-info.c:147 +#, fuzzy, c-format +msgid "Usage: cpupower idleinfo [options]\n" +msgstr "Uso: cpufreq-info [opções]\n" + +#: utils/cpuidle-info.c:149 +#, fuzzy, c-format +msgid " -s, --silent Only show general C-state information\n" +msgstr " -e, --debug Mostra informação de debug\n" + +#: utils/cpuidle-info.c:150 +#, fuzzy, 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 Mostra informação do tipo provida pela interface /" +"proc/cpufreq\n" +" em kernels 2.4. e mais recentes 2.6\n" + +#: utils/cpuidle-info.c:209 +#, fuzzy, c-format +msgid "You can't specify more than one output-specific argument\n" +msgstr "" +"Você não pode especificar mais do que um parâmetro --cpu e/ou\n" +"mais do que um argumento de saída específico\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU CPU number which information shall be determined " +#~ "about\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU número do CPU sobre o qual as inforções devem ser " +#~ "determinadas\n" + +#~ msgid "" +#~ " -c CPU, --cpu CPU number of CPU where cpufreq settings shall be " +#~ "modified\n" +#~ msgstr "" +#~ " -c CPU, --cpu CPU número do CPU onde as configurações do cpufreq " +#~ "vão ser modificadas\n" diff --git a/tools/power/cpupower/po/zh_CN.po b/tools/power/cpupower/po/zh_CN.po new file mode 100644 index 000000000..0489abffb --- /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 \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 ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" +"cpupower monitor:[-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command...]\n" + +#: utils/idle_monitor/cpupower-monitor.c:69 +#, c-format +msgid "" +"cpupower monitor: [-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-i " +"interval_sec | -c command ...]\n" +msgstr "" +"cpupower monitor:[-v] [-h] [ [-t] | [-l] | [-m ,[] ] ] [-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/builtin.h b/tools/power/cpupower/utils/builtin.h new file mode 100644 index 000000000..e1caefd46 --- /dev/null +++ b/tools/power/cpupower/utils/builtin.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef BUILTIN_H +#define BUILTIN_H + +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_cap_info(int argc, const char **argv); +extern int cmd_cap_set(int argc, const char **argv); +extern int cmd_monitor(int argc, const char **argv); + +#endif diff --git a/tools/power/cpupower/utils/cpufreq-info.c b/tools/power/cpupower/utils/cpufreq-info.c new file mode 100644 index 000000000..11629ae49 --- /dev/null +++ b/tools/power/cpupower/utils/cpufreq-info.c @@ -0,0 +1,694 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2004-2009 Dominik Brodowski + */ + + +#include +#include +#include +#include +#include +#include + +#include + +#include "cpufreq.h" +#include "helpers/sysfs.h" +#include "helpers/helpers.h" +#include "helpers/bitmask.h" + +#define LINE_LEN 10 + +static unsigned int count_cpus(void) +{ + FILE *fp; + char value[LINE_LEN]; + unsigned int ret = 0; + unsigned int cpunr = 0; + + fp = fopen("/proc/stat", "r"); + if (!fp) { + printf(_("Couldn't count the number of CPUs (%s: %s), assuming 1\n"), "/proc/stat", strerror(errno)); + return 1; + } + + while (!feof(fp)) { + if (!fgets(value, LINE_LEN, fp)) + continue; + value[LINE_LEN - 1] = '\0'; + if (strlen(value) < (LINE_LEN - 2)) + continue; + if (strstr(value, "cpu ")) + continue; + if (sscanf(value, "cpu%d ", &cpunr) != 1) + continue; + if (cpunr > ret) + ret = cpunr; + } + fclose(fp); + + /* cpu count starts from 0, on error return 1 (UP) */ + return ret + 1; +} + + +static void proc_cpufreq_output(void) +{ + unsigned int cpu, nr_cpus; + struct cpufreq_policy *policy; + unsigned int min_pctg = 0; + unsigned int max_pctg = 0; + unsigned long min, max; + + printf(_(" minimum CPU frequency - maximum CPU frequency - governor\n")); + + nr_cpus = count_cpus(); + for (cpu = 0; cpu < nr_cpus; cpu++) { + policy = cpufreq_get_policy(cpu); + if (!policy) + continue; + + if (cpufreq_get_hardware_limits(cpu, &min, &max)) { + max = 0; + } else { + min_pctg = (policy->min * 100) / max; + max_pctg = (policy->max * 100) / max; + } + printf("CPU%3d %9lu kHz (%3d %%) - %9lu kHz (%3d %%) - %s\n", + cpu , policy->min, max ? min_pctg : 0, policy->max, + max ? max_pctg : 0, policy->governor); + + cpufreq_put_policy(policy); + } +} + +static int no_rounding; +static void print_duration(unsigned long duration) +{ + unsigned long tmp; + + if (no_rounding) { + if (duration > 1000000) + printf("%u.%06u ms", ((unsigned int) duration/1000000), + ((unsigned int) duration%1000000)); + else if (duration > 100000) + printf("%u us", ((unsigned int) duration/1000)); + else if (duration > 1000) + printf("%u.%03u us", ((unsigned int) duration/1000), + ((unsigned int) duration%1000)); + else + printf("%lu ns", duration); + } else { + if (duration > 1000000) { + tmp = duration%10000; + if (tmp >= 5000) + duration += 10000; + printf("%u.%02u ms", ((unsigned int) duration/1000000), + ((unsigned int) (duration%1000000)/10000)); + } else if (duration > 100000) { + tmp = duration%1000; + if (tmp >= 500) + duration += 1000; + printf("%u us", ((unsigned int) duration / 1000)); + } else if (duration > 1000) { + tmp = duration%100; + if (tmp >= 50) + duration += 100; + printf("%u.%01u us", ((unsigned int) duration/1000), + ((unsigned int) (duration%1000)/100)); + } else + printf("%lu ns", duration); + } +} + +static int get_boost_mode_x86(unsigned int cpu) +{ + int support, active, b_states = 0, ret, pstate_no, i; + /* ToDo: Make this more global */ + unsigned long pstates[MAX_HW_PSTATES] = {0,}; + + 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); + return ret; + } + /* 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))) + */ + + printf(_(" boost state support:\n")); + + printf(_(" Supported: %s\n"), support ? _("yes") : _("no")); + printf(_(" Active: %s\n"), active ? _("yes") : _("no")); + + if (cpupower_cpu_info.vendor == X86_VENDOR_AMD && + cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) { + return 0; + } else if ((cpupower_cpu_info.vendor == X86_VENDOR_AMD && + cpupower_cpu_info.family >= 0x10) || + cpupower_cpu_info.vendor == X86_VENDOR_HYGON) { + ret = decode_pstates(cpu, b_states, pstates, &pstate_no); + if (ret) + return ret; + + printf(_(" Boost States: %d\n"), b_states); + printf(_(" Total States: %d\n"), pstate_no); + for (i = 0; i < pstate_no; i++) { + if (!pstates[i]) + continue; + if (i < b_states) + printf(_(" Pstate-Pb%d: %luMHz (boost state)" + "\n"), i, pstates[i]); + else + printf(_(" Pstate-P%d: %luMHz\n"), + i - b_states, pstates[i]); + } + } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO) { + double bclk; + unsigned long long intel_turbo_ratio = 0; + unsigned int ratio; + + /* Any way to autodetect this ? */ + if (cpupower_cpu_info.caps & CPUPOWER_CAP_IS_SNB) + bclk = 100.00; + else + bclk = 133.33; + intel_turbo_ratio = msr_intel_get_turbo_ratio(cpu); + dprint (" Ratio: 0x%llx - bclk: %f\n", + intel_turbo_ratio, bclk); + + ratio = (intel_turbo_ratio >> 24) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 4 active cores\n"), + ratio * bclk); + + ratio = (intel_turbo_ratio >> 16) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 3 active cores\n"), + ratio * bclk); + + ratio = (intel_turbo_ratio >> 8) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 2 active cores\n"), + ratio * bclk); + + ratio = (intel_turbo_ratio >> 0) & 0xFF; + if (ratio) + printf(_(" %.0f MHz max turbo 1 active cores\n"), + ratio * bclk); + } + 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) +{ + struct cpufreq_available_frequencies *freqs; + + if (cpupower_cpu_info.vendor == X86_VENDOR_AMD || + 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) { + printf(_(" boost frequency steps: ")); + while (freqs->next) { + print_speed(freqs->frequency, no_rounding); + printf(", "); + freqs = freqs->next; + } + print_speed(freqs->frequency, no_rounding); + printf("\n"); + cpufreq_put_available_frequencies(freqs); + } + + return 0; +} + +/* --freq / -f */ + +static int get_freq_kernel(unsigned int cpu, unsigned int human) +{ + unsigned long freq = cpufreq_get_freq_kernel(cpu); + printf(_(" current CPU frequency: ")); + if (!freq) { + printf(_(" Unable to call to kernel\n")); + return -EINVAL; + } + if (human) { + print_speed(freq, no_rounding); + } else + printf("%lu", freq); + printf(_(" (asserted by call to kernel)\n")); + return 0; +} + + +/* --hwfreq / -w */ + +static int get_freq_hardware(unsigned int cpu, unsigned int human) +{ + unsigned long freq; + + freq = cpufreq_get_freq_hardware(cpu); + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF) && !freq) + return -EINVAL; + + printf(_(" current CPU frequency: ")); + if (!freq) { + printf("Unable to call hardware\n"); + return -EINVAL; + } + if (human) { + print_speed(freq, no_rounding); + } else + printf("%lu", freq); + printf(_(" (asserted by call to hardware)\n")); + return 0; +} + +/* --hwlimits / -l */ + +static int get_hardware_limits(unsigned int cpu, unsigned int human) +{ + unsigned long min, max; + + if (cpufreq_get_hardware_limits(cpu, &min, &max)) { + printf(_("Not Available\n")); + return -EINVAL; + } + + if (human) { + printf(_(" hardware limits: ")); + print_speed(min, no_rounding); + printf(" - "); + print_speed(max, no_rounding); + printf("\n"); + } else { + printf("%lu %lu\n", min, max); + } + return 0; +} + +/* --driver / -d */ + +static int get_driver(unsigned int cpu) +{ + char *driver = cpufreq_get_driver(cpu); + if (!driver) { + printf(_(" no or unknown cpufreq driver is active on this CPU\n")); + return -EINVAL; + } + printf(" driver: %s\n", driver); + cpufreq_put_driver(driver); + return 0; +} + +/* --policy / -p */ + +static int get_policy(unsigned int cpu) +{ + struct cpufreq_policy *policy = cpufreq_get_policy(cpu); + if (!policy) { + printf(_(" Unable to determine current policy\n")); + return -EINVAL; + } + printf(_(" current policy: frequency should be within ")); + print_speed(policy->min, no_rounding); + printf(_(" and ")); + print_speed(policy->max, no_rounding); + + printf(".\n "); + printf(_("The governor \"%s\" may decide which speed to use\n" + " within this range.\n"), + policy->governor); + cpufreq_put_policy(policy); + return 0; +} + +/* --governors / -g */ + +static int get_available_governors(unsigned int cpu) +{ + struct cpufreq_available_governors *governors = + cpufreq_get_available_governors(cpu); + + printf(_(" available cpufreq governors: ")); + if (!governors) { + printf(_("Not Available\n")); + return -EINVAL; + } + + while (governors->next) { + printf("%s ", governors->governor); + governors = governors->next; + } + printf("%s\n", governors->governor); + cpufreq_put_available_governors(governors); + return 0; +} + + +/* --affected-cpus / -a */ + +static int get_affected_cpus(unsigned int cpu) +{ + struct cpufreq_affected_cpus *cpus = cpufreq_get_affected_cpus(cpu); + + printf(_(" CPUs which need to have their frequency coordinated by software: ")); + if (!cpus) { + printf(_("Not Available\n")); + return -EINVAL; + } + + while (cpus->next) { + printf("%d ", cpus->cpu); + cpus = cpus->next; + } + printf("%d\n", cpus->cpu); + cpufreq_put_affected_cpus(cpus); + return 0; +} + +/* --related-cpus / -r */ + +static int get_related_cpus(unsigned int cpu) +{ + struct cpufreq_affected_cpus *cpus = cpufreq_get_related_cpus(cpu); + + printf(_(" CPUs which run at the same hardware frequency: ")); + if (!cpus) { + printf(_("Not Available\n")); + return -EINVAL; + } + + while (cpus->next) { + printf("%d ", cpus->cpu); + cpus = cpus->next; + } + printf("%d\n", cpus->cpu); + cpufreq_put_related_cpus(cpus); + return 0; +} + +/* --stats / -s */ + +static int get_freq_stats(unsigned int cpu, unsigned int human) +{ + unsigned long total_trans = cpufreq_get_transitions(cpu); + unsigned long long total_time; + struct cpufreq_stats *stats = cpufreq_get_stats(cpu, &total_time); + while (stats) { + if (human) { + print_speed(stats->frequency, no_rounding); + printf(":%.2f%%", + (100.0 * stats->time_in_state) / total_time); + } else + printf("%lu:%llu", + stats->frequency, stats->time_in_state); + stats = stats->next; + if (stats) + printf(", "); + } + cpufreq_put_stats(stats); + if (total_trans) + printf(" (%lu)\n", total_trans); + 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")); + return -EINVAL; + } + + if (human) { + print_duration(latency); + printf("\n"); + } else + printf("%lu\n", latency); + return 0; +} + +/* --performance / -c */ +static int get_perf_cap(unsigned int cpu) +{ + if (cpupower_cpu_info.vendor == X86_VENDOR_AMD && + cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) + amd_pstate_show_perf_and_freq(cpu, no_rounding); + else + cppc_show_perf_and_freq(cpu, no_rounding); + + return 0; +} + +static void debug_output_one(unsigned int cpu) +{ + struct cpufreq_available_frequencies *freqs; + + get_driver(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); + if (freqs) { + printf(_(" available frequency steps: ")); + while (freqs->next) { + print_speed(freqs->frequency, no_rounding); + printf(", "); + freqs = freqs->next; + } + print_speed(freqs->frequency, no_rounding); + printf("\n"); + cpufreq_put_available_frequencies(freqs); + } + + get_available_governors(cpu); + get_policy(cpu); + get_freq_hardware(cpu, 1); + get_freq_kernel(cpu, 1); + get_boost_mode(cpu); + get_perf_cap(cpu); +} + +static struct option info_opts[] = { + {"debug", no_argument, NULL, 'e'}, + {"boost", no_argument, NULL, 'b'}, + {"freq", no_argument, NULL, 'f'}, + {"hwfreq", no_argument, NULL, 'w'}, + {"hwlimits", no_argument, NULL, 'l'}, + {"driver", no_argument, NULL, 'd'}, + {"policy", no_argument, NULL, 'p'}, + {"governors", no_argument, NULL, 'g'}, + {"related-cpus", no_argument, NULL, 'r'}, + {"affected-cpus", no_argument, NULL, 'a'}, + {"stats", no_argument, NULL, 's'}, + {"latency", no_argument, NULL, 'y'}, + {"proc", no_argument, NULL, 'o'}, + {"human", no_argument, NULL, 'm'}, + {"no-rounding", no_argument, NULL, 'n'}, + {"performance", no_argument, NULL, 'c'}, + {"epp", no_argument, NULL, 'z'}, + { }, +}; + +int cmd_freq_info(int argc, char **argv) +{ + int ret = 0, cont = 1; + unsigned int cpu = 0; + unsigned int human = 0; + int output_param = 0; + + do { + ret = getopt_long(argc, argv, "oefwldpgrasmybncz", info_opts, + NULL); + switch (ret) { + case '?': + output_param = '?'; + cont = 0; + break; + case -1: + cont = 0; + break; + case 'b': + case 'o': + case 'a': + case 'r': + case 'g': + case 'p': + case 'd': + case 'l': + case 'w': + case 'f': + case 'e': + case 's': + case 'y': + case 'c': + case 'z': + if (output_param) { + output_param = -1; + cont = 0; + break; + } + output_param = ret; + break; + case 'm': + if (human) { + output_param = -1; + cont = 0; + break; + } + human = 1; + break; + case 'n': + no_rounding = 1; + break; + default: + fprintf(stderr, "invalid or unknown argument\n"); + return EXIT_FAILURE; + } + } while (cont); + + switch (output_param) { + case 'o': + if (!bitmask_isallclear(cpus_chosen)) { + printf(_("The argument passed to this tool can't be " + "combined with passing a --cpu argument\n")); + return -EINVAL; + } + break; + case 0: + output_param = 'e'; + } + + ret = 0; + + /* Default is: show output of base_cpu only */ + if (bitmask_isallclear(cpus_chosen)) + bitmask_setbit(cpus_chosen, base_cpu); + + switch (output_param) { + case -1: + printf(_("You can't specify more than one --cpu parameter and/or\n" + "more than one output-specific argument\n")); + return -EINVAL; + case '?': + printf(_("invalid or unknown argument\n")); + return -EINVAL; + case 'o': + proc_cpufreq_output(); + return EXIT_SUCCESS; + } + + for (cpu = bitmask_first(cpus_chosen); + cpu <= bitmask_last(cpus_chosen); cpu++) { + + if (!bitmask_isbitset(cpus_chosen, cpu)) + continue; + + printf(_("analyzing CPU %d:\n"), cpu); + + if (sysfs_is_cpu_online(cpu) != 1) { + printf(_(" *is offline\n")); + printf("\n"); + continue; + } + + switch (output_param) { + case 'b': + get_boost_mode(cpu); + break; + case 'e': + debug_output_one(cpu); + break; + case 'a': + ret = get_affected_cpus(cpu); + break; + case 'r': + ret = get_related_cpus(cpu); + break; + case 'g': + ret = get_available_governors(cpu); + break; + case 'p': + ret = get_policy(cpu); + break; + case 'd': + ret = get_driver(cpu); + break; + case 'l': + ret = get_hardware_limits(cpu, human); + break; + case 'w': + ret = get_freq_hardware(cpu, human); + break; + case 'f': + ret = get_freq_kernel(cpu, human); + break; + case 's': + ret = get_freq_stats(cpu, human); + break; + case 'y': + ret = get_latency(cpu, human); + break; + case 'c': + ret = get_perf_cap(cpu); + break; + case 'z': + ret = get_epp(cpu, true); + break; + } + if (ret) + return ret; + } + return ret; +} diff --git a/tools/power/cpupower/utils/cpufreq-set.c b/tools/power/cpupower/utils/cpufreq-set.c new file mode 100644 index 000000000..06cd4b280 --- /dev/null +++ b/tools/power/cpupower/utils/cpufreq-set.c @@ -0,0 +1,337 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2004-2009 Dominik Brodowski + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "cpufreq.h" +#include "cpuidle.h" +#include "helpers/helpers.h" + +#define NORM_FREQ_LEN 32 + +static struct option set_opts[] = { + {"min", required_argument, NULL, 'd'}, + {"max", required_argument, NULL, 'u'}, + {"governor", required_argument, NULL, 'g'}, + {"freq", required_argument, NULL, 'f'}, + {"related", no_argument, NULL, 'r'}, + { }, +}; + +static void print_error(void) +{ + printf(_("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")); +}; + +struct freq_units { + char *str_unit; + int power_of_ten; +}; + +const struct freq_units def_units[] = { + {"hz", -3}, + {"khz", 0}, /* default */ + {"mhz", 3}, + {"ghz", 6}, + {"thz", 9}, + {NULL, 0} +}; + +static void print_unknown_arg(void) +{ + printf(_("invalid or unknown argument\n")); +} + +static unsigned long string_to_frequency(const char *str) +{ + char normalized[NORM_FREQ_LEN]; + const struct freq_units *unit; + const char *scan; + char *end; + unsigned long freq; + int power = 0, match_count = 0, i, cp, pad; + + while (*str == '0') + str++; + + for (scan = str; isdigit(*scan) || *scan == '.'; scan++) { + if (*scan == '.' && match_count == 0) + match_count = 1; + else if (*scan == '.' && match_count == 1) + return 0; + } + + if (*scan) { + match_count = 0; + for (unit = def_units; unit->str_unit; unit++) { + for (i = 0; + scan[i] && tolower(scan[i]) == unit->str_unit[i]; + ++i) + continue; + if (scan[i]) + continue; + match_count++; + power = unit->power_of_ten; + } + if (match_count != 1) + return 0; + } + + /* count the number of digits to be copied */ + for (cp = 0; isdigit(str[cp]); cp++) + continue; + + if (str[cp] == '.') { + while (power > -1 && isdigit(str[cp+1])) { + cp++; + power--; + } + } + if (power >= -1) { /* not enough => pad */ + pad = power + 1; + } else { /* too much => strip */ + pad = 0; + cp += power + 1; + } + /* check bounds */ + if (cp <= 0 || cp + pad > NORM_FREQ_LEN - 1) + return 0; + + /* copy digits */ + for (i = 0; i < cp; i++, str++) { + if (*str == '.') + str++; + normalized[i] = *str; + } + /* and pad */ + for (; i < cp + pad; i++) + normalized[i] = '0'; + + /* round up, down ? */ + match_count = (normalized[i-1] >= '5'); + /* and drop the decimal part */ + normalized[i-1] = 0; /* cp > 0 && pad >= 0 ==> i > 0 */ + + /* final conversion (and applying rounding) */ + errno = 0; + freq = strtoul(normalized, &end, 10); + if (errno) + return 0; + else { + if (match_count && freq != ULONG_MAX) + freq++; + return freq; + } +} + +static int do_new_policy(unsigned int cpu, struct cpufreq_policy *new_pol) +{ + struct cpufreq_policy *cur_pol = cpufreq_get_policy(cpu); + int ret; + + if (!cur_pol) { + printf(_("wrong, unknown or unhandled CPU?\n")); + return -EINVAL; + } + + if (!new_pol->min) + new_pol->min = cur_pol->min; + + if (!new_pol->max) + new_pol->max = cur_pol->max; + + if (!new_pol->governor) + new_pol->governor = cur_pol->governor; + + ret = cpufreq_set_policy(cpu, new_pol); + + cpufreq_put_policy(cur_pol); + + return ret; +} + + +static int do_one_cpu(unsigned int cpu, struct cpufreq_policy *new_pol, + unsigned long freq, unsigned int pc) +{ + switch (pc) { + case 0: + return cpufreq_set_frequency(cpu, freq); + + case 1: + /* if only one value of a policy is to be changed, we can + * use a "fast path". + */ + if (new_pol->min) + return cpufreq_modify_policy_min(cpu, new_pol->min); + else if (new_pol->max) + return cpufreq_modify_policy_max(cpu, new_pol->max); + else if (new_pol->governor) + return cpufreq_modify_policy_governor(cpu, + new_pol->governor); + + default: + /* slow path */ + return do_new_policy(cpu, new_pol); + } +} + +int cmd_freq_set(int argc, char **argv) +{ + int ret = 0, cont = 1; + int double_parm = 0, related = 0, policychange = 0; + unsigned long freq = 0; + char gov[20]; + unsigned int cpu; + + struct cpufreq_policy new_pol = { + .min = 0, + .max = 0, + .governor = NULL, + }; + + /* parameter parsing */ + do { + ret = getopt_long(argc, argv, "d:u:g:f:r", set_opts, NULL); + switch (ret) { + case '?': + print_unknown_arg(); + return -EINVAL; + case -1: + cont = 0; + break; + case 'r': + if (related) + double_parm++; + related++; + break; + case 'd': + if (new_pol.min) + double_parm++; + policychange++; + new_pol.min = string_to_frequency(optarg); + if (new_pol.min == 0) { + print_unknown_arg(); + return -EINVAL; + } + break; + case 'u': + if (new_pol.max) + double_parm++; + policychange++; + new_pol.max = string_to_frequency(optarg); + if (new_pol.max == 0) { + print_unknown_arg(); + return -EINVAL; + } + break; + case 'f': + if (freq) + double_parm++; + freq = string_to_frequency(optarg); + if (freq == 0) { + print_unknown_arg(); + return -EINVAL; + } + break; + case 'g': + if (new_pol.governor) + double_parm++; + policychange++; + if ((strlen(optarg) < 3) || (strlen(optarg) > 18)) { + print_unknown_arg(); + return -EINVAL; + } + if ((sscanf(optarg, "%19s", gov)) != 1) { + print_unknown_arg(); + return -EINVAL; + } + new_pol.governor = gov; + break; + } + } while (cont); + + /* parameter checking */ + if (double_parm) { + printf("the same parameter was passed more than once\n"); + return -EINVAL; + } + + if (freq && policychange) { + printf(_("the -f/--freq parameter cannot be combined with -d/--min, -u/--max or\n" + "-g/--governor parameters\n")); + return -EINVAL; + } + + if (!freq && !policychange) { + printf(_("At least one parameter out of -f/--freq, -d/--min, -u/--max, and\n" + "-g/--governor must be passed\n")); + return -EINVAL; + } + + /* Default is: set all CPUs */ + if (bitmask_isallclear(cpus_chosen)) + bitmask_setall(cpus_chosen); + + /* Also set frequency settings for related CPUs if -r is passed */ + if (related) { + for (cpu = bitmask_first(cpus_chosen); + cpu <= bitmask_last(cpus_chosen); cpu++) { + struct cpufreq_affected_cpus *cpus; + + if (!bitmask_isbitset(cpus_chosen, cpu) || + cpupower_is_cpu_online(cpu) != 1) + continue; + + cpus = cpufreq_get_related_cpus(cpu); + if (!cpus) + break; + while (cpus->next) { + bitmask_setbit(cpus_chosen, cpus->cpu); + cpus = cpus->next; + } + /* Set the last cpu in related cpus list */ + bitmask_setbit(cpus_chosen, cpus->cpu); + cpufreq_put_related_cpus(cpus); + } + } + + get_cpustate(); + + /* loop over CPUs */ + for (cpu = bitmask_first(cpus_chosen); + cpu <= bitmask_last(cpus_chosen); cpu++) { + + if (!bitmask_isbitset(cpus_chosen, cpu) || + cpupower_is_cpu_online(cpu) != 1) + continue; + + printf(_("Setting cpu: %d\n"), cpu); + ret = do_one_cpu(cpu, &new_pol, freq, policychange); + if (ret) { + print_error(); + return ret; + } + } + + print_offline_cpus(); + + return 0; +} diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c new file mode 100644 index 000000000..ccb37125b --- /dev/null +++ b/tools/power/cpupower/utils/cpuidle-info.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2004-2009 Dominik Brodowski + * (C) 2010 Thomas Renninger + */ + + +#include +#include +#include +#include +#include +#include + +#include + +#include "helpers/sysfs.h" +#include "helpers/helpers.h" +#include "helpers/bitmask.h" + +#define LINE_LEN 10 + +static void cpuidle_cpu_output(unsigned int cpu, int verbose) +{ + unsigned int idlestates, idlestate; + char *tmp; + + idlestates = cpuidle_state_count(cpu); + if (idlestates == 0) { + printf(_("CPU %u: No idle states\n"), cpu); + return; + } + + printf(_("Number of idle states: %d\n"), idlestates); + printf(_("Available idle states:")); + for (idlestate = 0; idlestate < idlestates; idlestate++) { + tmp = cpuidle_state_name(cpu, idlestate); + if (!tmp) + continue; + printf(" %s", tmp); + free(tmp); + } + printf("\n"); + + if (!verbose) + return; + + for (idlestate = 0; idlestate < idlestates; idlestate++) { + int disabled = cpuidle_is_state_disabled(cpu, idlestate); + /* Disabled interface not supported on older kernels */ + if (disabled < 0) + disabled = 0; + tmp = cpuidle_state_name(cpu, idlestate); + if (!tmp) + continue; + printf("%s%s:\n", tmp, (disabled) ? " (DISABLED) " : ""); + free(tmp); + + tmp = cpuidle_state_desc(cpu, idlestate); + if (!tmp) + continue; + printf(_("Flags/Description: %s\n"), tmp); + free(tmp); + + 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"), + cpuidle_state_time(cpu, idlestate)); + } +} + +static void cpuidle_general_output(void) +{ + char *tmp; + + tmp = cpuidle_get_driver(); + if (!tmp) { + printf(_("Could not determine cpuidle driver\n")); + return; + } + + printf(_("CPUidle driver: %s\n"), tmp); + free(tmp); + + tmp = cpuidle_get_governor(); + if (!tmp) { + printf(_("Could not determine cpuidle governor\n")); + return; + } + + printf(_("CPUidle governor: %s\n"), tmp); + free(tmp); +} + +static void proc_cpuidle_cpu_output(unsigned int cpu) +{ + long max_allowed_cstate = 2000000000; + unsigned int cstate, cstates; + + cstates = cpuidle_state_count(cpu); + if (cstates == 0) { + printf(_("CPU %u: No C-states info\n"), cpu); + return; + } + + printf(_("active state: C0\n")); + printf(_("max_cstate: C%u\n"), cstates-1); + printf(_("maximum allowed latency: %lu usec\n"), max_allowed_cstate); + printf(_("states:\t\n")); + for (cstate = 0; cstate < cstates; cstate++) { + printf(_(" C%d: " + "type[C%d] "), cstate, cstate); + 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"), + cpuidle_state_time(cpu, cstate)); + } +} + +static struct option info_opts[] = { + {"silent", no_argument, NULL, 's'}, + {"proc", no_argument, NULL, 'o'}, + { }, +}; + +static inline void cpuidle_exit(int fail) +{ + exit(EXIT_FAILURE); +} + +int cmd_idle_info(int argc, char **argv) +{ + int ret = 0, cont = 1, output_param = 0, verbose = 1; + unsigned int cpu = 0; + + do { + ret = getopt_long(argc, argv, "os", info_opts, NULL); + if (ret == -1) + break; + switch (ret) { + case '?': + output_param = '?'; + cont = 0; + break; + case 's': + verbose = 0; + break; + case -1: + cont = 0; + break; + case 'o': + if (output_param) { + output_param = -1; + cont = 0; + break; + } + output_param = ret; + break; + } + } while (cont); + + switch (output_param) { + case -1: + printf(_("You can't specify more than one " + "output-specific argument\n")); + cpuidle_exit(EXIT_FAILURE); + case '?': + printf(_("invalid or unknown argument\n")); + cpuidle_exit(EXIT_FAILURE); + } + + /* Default is: show output of base_cpu only */ + if (bitmask_isallclear(cpus_chosen)) + bitmask_setbit(cpus_chosen, base_cpu); + + if (output_param == 0) + cpuidle_general_output(); + + for (cpu = bitmask_first(cpus_chosen); + cpu <= bitmask_last(cpus_chosen); cpu++) { + + if (!bitmask_isbitset(cpus_chosen, cpu)) + continue; + + printf(_("analyzing CPU %d:\n"), cpu); + + if (sysfs_is_cpu_online(cpu) != 1) { + printf(_(" *is offline\n")); + printf("\n"); + continue; + } + + switch (output_param) { + + case 'o': + proc_cpuidle_cpu_output(cpu); + break; + case 0: + printf("\n"); + cpuidle_cpu_output(cpu, verbose); + break; + } + printf("\n"); + } + return EXIT_SUCCESS; +} diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c new file mode 100644 index 000000000..703094f13 --- /dev/null +++ b/tools/power/cpupower/utils/cpuidle-set.c @@ -0,0 +1,185 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "helpers/helpers.h" + +static struct option info_opts[] = { + {"disable", required_argument, NULL, 'd'}, + {"enable", required_argument, NULL, 'e'}, + {"disable-by-latency", required_argument, NULL, 'D'}, + {"enable-all", no_argument, NULL, 'E'}, + { }, +}; + + +int cmd_idle_set(int argc, char **argv) +{ + int ret = 0, cont = 1, param = 0, disabled; + unsigned long long latency = 0, state_latency; + unsigned int cpu = 0, idlestate = 0, idlestates = 0; + char *endptr; + + do { + ret = getopt_long(argc, argv, "d:e:ED:", info_opts, NULL); + if (ret == -1) + break; + switch (ret) { + case '?': + param = '?'; + cont = 0; + break; + case 'd': + case 'e': + if (param) { + param = -1; + cont = 0; + break; + } + param = ret; + strtol(optarg, &endptr, 10); + if (*endptr != '\0') { + printf(_("Bad value: %s, Integer expected\n"), optarg); + exit(EXIT_FAILURE); + } else { + idlestate = atoi(optarg); + } + break; + case 'D': + if (param) { + param = -1; + cont = 0; + break; + } + param = ret; + latency = strtoull(optarg, &endptr, 10); + if (*endptr != '\0') { + printf(_("Bad latency value: %s\n"), optarg); + exit(EXIT_FAILURE); + } + break; + case 'E': + if (param) { + param = -1; + cont = 0; + break; + } + param = ret; + 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); + } + + get_cpustate(); + + /* 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; + + if (cpupower_is_cpu_online(cpu) != 1) + continue; + + idlestates = cpuidle_state_count(cpu); + if (idlestates <= 0) + continue; + + switch (param) { + case 'd': + ret = cpuidle_state_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 = cpuidle_state_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; + case 'D': + for (idlestate = 0; idlestate < idlestates; idlestate++) { + disabled = cpuidle_is_state_disabled + (cpu, idlestate); + state_latency = cpuidle_state_latency + (cpu, idlestate); + if (disabled == 1) { + if (latency > state_latency){ + ret = cpuidle_state_disable + (cpu, idlestate, 0); + if (ret == 0) + printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu); + } + continue; + } + if (latency <= state_latency){ + ret = cpuidle_state_disable + (cpu, idlestate, 1); + if (ret == 0) + printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu); + } + } + break; + case 'E': + for (idlestate = 0; idlestate < idlestates; idlestate++) { + disabled = cpuidle_is_state_disabled + (cpu, idlestate); + if (disabled == 1) { + ret = cpuidle_state_disable + (cpu, idlestate, 0); + if (ret == 0) + printf(_("Idlestate %u 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; + } + } + + print_offline_cpus(); + return EXIT_SUCCESS; +} diff --git a/tools/power/cpupower/utils/cpupower-info.c b/tools/power/cpupower/utils/cpupower-info.c new file mode 100644 index 000000000..79154d71e --- /dev/null +++ b/tools/power/cpupower/utils/cpupower-info.c @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2011 Thomas Renninger , Novell Inc. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "helpers/helpers.h" +#include "helpers/sysfs.h" + +static struct option set_opts[] = { + {"perf-bias", optional_argument, NULL, 'b'}, + { }, +}; + +static void print_wrong_arg_exit(void) +{ + printf(_("invalid or unknown argument\n")); + exit(EXIT_FAILURE); +} + +int cmd_info(int argc, char **argv) +{ + unsigned int cpu; + struct utsname uts; + + union { + struct { + int perf_bias:1; + }; + int params; + } params = {}; + int ret = 0; + + ret = uname(&uts); + if (!ret && (!strcmp(uts.machine, "ppc64le") || + !strcmp(uts.machine, "ppc64"))) { + fprintf(stderr, _("Subcommand not supported on POWER.\n")); + return ret; + } + + setlocale(LC_ALL, ""); + textdomain(PACKAGE); + + /* parameter parsing */ + while ((ret = getopt_long(argc, argv, "b", set_opts, NULL)) != -1) { + switch (ret) { + case 'b': + if (params.perf_bias) + print_wrong_arg_exit(); + params.perf_bias = 1; + break; + default: + print_wrong_arg_exit(); + } + } + + if (!params.params) + params.params = 0x7; + + /* Default is: show output of base_cpu only */ + if (bitmask_isallclear(cpus_chosen)) + bitmask_setbit(cpus_chosen, base_cpu); + + /* Add more per cpu options here */ + if (!params.perf_bias) + return ret; + + if (params.perf_bias) { + if (!run_as_root) { + params.perf_bias = 0; + printf(_("Intel's performance bias setting needs root privileges\n")); + } else if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) { + printf(_("System does not support Intel's performance" + " bias setting\n")); + params.perf_bias = 0; + } + } + + /* loop over CPUs */ + for (cpu = bitmask_first(cpus_chosen); + cpu <= bitmask_last(cpus_chosen); cpu++) { + + if (!bitmask_isbitset(cpus_chosen, cpu)) + continue; + + printf(_("analyzing CPU %d:\n"), cpu); + + if (sysfs_is_cpu_online(cpu) != 1){ + printf(_(" *is offline\n")); + continue; + } + + if (params.perf_bias) { + ret = cpupower_intel_get_perf_bias(cpu); + if (ret < 0) { + fprintf(stderr, + _("Could not read perf-bias value[%d]\n"), ret); + exit(EXIT_FAILURE); + } else + printf(_("perf-bias: %d\n"), ret); + } + } + return 0; +} diff --git a/tools/power/cpupower/utils/cpupower-set.c b/tools/power/cpupower/utils/cpupower-set.c new file mode 100644 index 000000000..c2176b9fa --- /dev/null +++ b/tools/power/cpupower/utils/cpupower-set.c @@ -0,0 +1,171 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2011 Thomas Renninger , Novell Inc. + */ + + +#include +#include +#include +#include +#include +#include +#include + +#include "helpers/helpers.h" +#include "helpers/sysfs.h" +#include "helpers/bitmask.h" + +static struct option set_opts[] = { + {"perf-bias", required_argument, NULL, 'b'}, + {"epp", required_argument, NULL, 'e'}, + {"amd-pstate-mode", required_argument, NULL, 'm'}, + {"turbo-boost", required_argument, NULL, 't'}, + {"boost", required_argument, NULL, 't'}, + { }, +}; + +static void print_wrong_arg_exit(void) +{ + printf(_("invalid or unknown argument\n")); + exit(EXIT_FAILURE); +} + +int cmd_set(int argc, char **argv) +{ + unsigned int cpu; + struct utsname uts; + + union { + struct { + int perf_bias:1; + int epp:1; + int mode:1; + int turbo_boost:1; + }; + int params; + } params; + int perf_bias = 0, turbo_boost = 1; + int ret = 0; + char epp[30], mode[20]; + + ret = uname(&uts); + if (!ret && (!strcmp(uts.machine, "ppc64le") || + !strcmp(uts.machine, "ppc64"))) { + fprintf(stderr, _("Subcommand not supported on POWER.\n")); + return ret; + } + + setlocale(LC_ALL, ""); + textdomain(PACKAGE); + + params.params = 0; + /* parameter parsing */ + while ((ret = getopt_long(argc, argv, "b:e:m:t:", + set_opts, NULL)) != -1) { + switch (ret) { + case 'b': + if (params.perf_bias) + print_wrong_arg_exit(); + perf_bias = atoi(optarg); + if (perf_bias < 0 || perf_bias > 15) { + printf(_("--perf-bias param out " + "of range [0-%d]\n"), 15); + print_wrong_arg_exit(); + } + params.perf_bias = 1; + break; + case 'e': + if (params.epp) + print_wrong_arg_exit(); + if (sscanf(optarg, "%29s", epp) != 1) { + print_wrong_arg_exit(); + return -EINVAL; + } + params.epp = 1; + break; + case 'm': + if (cpupower_cpu_info.vendor != X86_VENDOR_AMD) + print_wrong_arg_exit(); + if (params.mode) + print_wrong_arg_exit(); + if (sscanf(optarg, "%19s", mode) != 1) { + print_wrong_arg_exit(); + return -EINVAL; + } + params.mode = 1; + break; + case 't': + if (params.turbo_boost) + print_wrong_arg_exit(); + turbo_boost = atoi(optarg); + if (turbo_boost < 0 || turbo_boost > 1) { + printf("--turbo-boost param out of range [0-1]\n"); + print_wrong_arg_exit(); + } + params.turbo_boost = 1; + break; + + + default: + print_wrong_arg_exit(); + } + } + + if (!params.params) + print_wrong_arg_exit(); + + if (params.mode) { + ret = cpupower_set_amd_pstate_mode(mode); + if (ret) + fprintf(stderr, "Error setting mode\n"); + } + + if (params.turbo_boost) { + if (cpupower_cpu_info.vendor == X86_VENDOR_INTEL) + ret = cpupower_set_intel_turbo_boost(turbo_boost); + else + ret = cpupower_set_generic_turbo_boost(turbo_boost); + + if (ret) + fprintf(stderr, "Error setting turbo-boost\n"); + } + + /* Default is: set all CPUs */ + if (bitmask_isallclear(cpus_chosen)) + bitmask_setall(cpus_chosen); + + /* loop over CPUs */ + for (cpu = bitmask_first(cpus_chosen); + cpu <= bitmask_last(cpus_chosen); cpu++) { + + if (!bitmask_isbitset(cpus_chosen, cpu)) + continue; + + if (sysfs_is_cpu_online(cpu) != 1){ + fprintf(stderr, _("Cannot set values on CPU %d:"), cpu); + fprintf(stderr, _(" *is offline\n")); + continue; + } + + if (params.perf_bias) { + ret = cpupower_intel_set_perf_bias(cpu, perf_bias); + if (ret) { + fprintf(stderr, _("Error setting perf-bias " + "value on CPU %d\n"), cpu); + break; + } + } + + if (params.epp) { + ret = cpupower_set_epp(cpu, epp); + if (ret) { + fprintf(stderr, + "Error setting epp value on CPU %d\n", cpu); + break; + } + } + + } + return ret; +} diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c new file mode 100644 index 000000000..9ec973165 --- /dev/null +++ b/tools/power/cpupower/utils/cpupower.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * Ideas taken over from the perf userspace tool (included in the Linus + * kernel git repo): subcommand builtins and param parsing. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "builtin.h" +#include "helpers/helpers.h" +#include "helpers/bitmask.h" + +#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) + +static int cmd_help(int argc, const char **argv); + +/* Global cpu_info object available for all binaries + * Info only retrieved from CPU 0 + * + * Values will be zero/unknown on non X86 archs + */ +struct cpupower_cpu_info cpupower_cpu_info; +int run_as_root; +int base_cpu; +/* Affected cpus chosen by -c/--cpu param */ +struct bitmask *cpus_chosen; +struct bitmask *online_cpus; +struct bitmask *offline_cpus; + +#ifdef DEBUG +int be_verbose; +#endif + +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 }, + { "powercap-info", cmd_cap_info, 0 }, + { "set", cmd_set, 1 }, + { "info", cmd_info, 0 }, + { "monitor", cmd_monitor, 0 }, + { "help", cmd_help, 0 }, + /* { "bench", cmd_bench, 1 }, */ +}; + +static void print_help(void) +{ + unsigned int i; + +#ifdef DEBUG + printf(_("Usage:\tcpupower [-d|--debug] [-c|--cpu cpulist ] []\n")); +#else + printf(_("Usage:\tcpupower [-c|--cpu cpulist ] []\n")); +#endif + printf(_("Supported commands are:\n")); + for (i = 0; i < ARRAY_SIZE(commands); i++) + printf("\t%s\n", commands[i].cmd); + printf(_("\nNot all commands can make use of the -c cpulist option.\n")); + printf(_("\nUse 'cpupower help ' for getting help for above commands.\n")); +} + +static int print_man_page(const char *subpage) +{ + int len; + char *page; + + len = 10; /* enough for "cpupower-" */ + if (subpage != NULL) + len += strlen(subpage); + + page = malloc(len); + if (!page) + return -ENOMEM; + + sprintf(page, "cpupower"); + if ((subpage != NULL) && strcmp(subpage, "help")) { + strcat(page, "-"); + strcat(page, subpage); + } + + execlp("man", "man", page, NULL); + + /* should not be reached */ + return -EINVAL; +} + +static int cmd_help(int argc, const char **argv) +{ + if (argc > 1) { + print_man_page(argv[1]); /* exits within execlp() */ + return EXIT_FAILURE; + } + + print_help(); + return EXIT_SUCCESS; +} + +static void print_version(void) +{ + printf(PACKAGE " " VERSION "\n"); + printf(_("Report errors and bugs to %s, please.\n"), PACKAGE_BUGREPORT); +} + +static void handle_options(int *argc, const char ***argv) +{ + int ret, x, new_argc = 0; + + if (*argc < 1) + return; + + for (x = 0; x < *argc && ((*argv)[x])[0] == '-'; x++) { + const char *param = (*argv)[x]; + if (!strcmp(param, "-h") || !strcmp(param, "--help")) { + print_help(); + exit(EXIT_SUCCESS); + } else if (!strcmp(param, "-c") || !strcmp(param, "--cpu")) { + if (*argc < 2) { + print_help(); + exit(EXIT_FAILURE); + } + if (!strcmp((*argv)[x+1], "all")) + bitmask_setall(cpus_chosen); + else { + ret = bitmask_parselist( + (*argv)[x+1], cpus_chosen); + if (ret < 0) { + fprintf(stderr, _("Error parsing cpu " + "list\n")); + exit(EXIT_FAILURE); + } + } + x += 1; + /* Cut out param: cpupower -c 1 info -> cpupower info */ + new_argc += 2; + continue; + } else if (!strcmp(param, "-v") || + !strcmp(param, "--version")) { + print_version(); + exit(EXIT_SUCCESS); +#ifdef DEBUG + } else if (!strcmp(param, "-d") || !strcmp(param, "--debug")) { + be_verbose = 1; + new_argc++; + continue; +#endif + } else { + fprintf(stderr, "Unknown option: %s\n", param); + print_help(); + exit(EXIT_FAILURE); + } + } + *argc -= new_argc; + *argv += new_argc; +} + +int main(int argc, const char *argv[]) +{ + const char *cmd; + unsigned int i, ret; + struct stat statbuf; + struct utsname uts; + char pathname[32]; + + cpus_chosen = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF)); + online_cpus = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF)); + offline_cpus = bitmask_alloc(sysconf(_SC_NPROCESSORS_CONF)); + + argc--; + argv += 1; + + handle_options(&argc, &argv); + + cmd = argv[0]; + + if (argc < 1) { + print_help(); + return EXIT_FAILURE; + } + + setlocale(LC_ALL, ""); + textdomain(PACKAGE); + + /* Turn "perf cmd --help" into "perf help cmd" */ + if (argc > 1 && !strcmp(argv[1], "--help")) { + argv[1] = argv[0]; + argv[0] = cmd = "help"; + } + + base_cpu = sched_getcpu(); + if (base_cpu < 0) { + fprintf(stderr, _("No valid cpus found.\n")); + return EXIT_FAILURE; + } + + get_cpu_info(&cpupower_cpu_info); + run_as_root = !geteuid(); + if (run_as_root) { + ret = uname(&uts); + sprintf(pathname, "/dev/cpu/%d/msr", base_cpu); + if (!ret && !strcmp(uts.machine, "x86_64") && + stat(pathname, &statbuf) != 0) { + if (system("modprobe msr") == -1) + fprintf(stderr, _("MSR access not available.\n")); + } + } + + for (i = 0; i < ARRAY_SIZE(commands); i++) { + struct cmd_struct *p = commands + i; + if (strcmp(p->cmd, cmd)) + continue; + if (!run_as_root && p->needs_root) { + fprintf(stderr, _("Subcommand %s needs root " + "privileges\n"), cmd); + return EXIT_FAILURE; + } + ret = p->main(argc, argv); + if (cpus_chosen) + bitmask_free(cpus_chosen); + if (online_cpus) + bitmask_free(online_cpus); + if (offline_cpus) + bitmask_free(offline_cpus); + return ret; + } + print_help(); + return EXIT_FAILURE; +} diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c new file mode 100644 index 000000000..795562e87 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -0,0 +1,256 @@ +// SPDX-License-Identifier: GPL-2.0 +#if defined(__i386__) || defined(__x86_64__) +#include +#include +#include +#include + +#include + +#include "helpers/helpers.h" +#include "cpufreq.h" +#include "acpi_cppc.h" + +/* ACPI P-States Helper Functions for AMD Processors ***************/ +#define MSR_AMD_PSTATE_STATUS 0xc0010063 +#define MSR_AMD_PSTATE 0xc0010064 +#define MSR_AMD_PSTATE_LIMIT 0xc0010061 + +union core_pstate { + /* pre fam 17h: */ + struct { + unsigned fid:6; + unsigned did:3; + unsigned vid:7; + unsigned res1:6; + unsigned nbdid:1; + unsigned res2:2; + unsigned nbvid:7; + unsigned iddval:8; + unsigned idddiv:2; + unsigned res3:21; + unsigned en:1; + } pstate; + /* since fam 17h: */ + struct { + unsigned fid:8; + unsigned did:6; + unsigned vid:8; + unsigned iddval:8; + unsigned idddiv:2; + 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; +}; + +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) + t = pstate.val & 0xf; + else + t = pstate.pstate.did; + + return t; +} + +static int get_cof(union core_pstate pstate) +{ + int t; + int fid, did, cof = 0; + + did = get_did(pstate); + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATEDEF) { + 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; + if (cpupower_cpu_info.family == 0x11) + t = 0x8; + cof = (100 * (fid + t)) >> did; + } + return cof; +} + +/* Needs: + * cpu -> the cpu that gets evaluated + * boost_states -> how much boost states the machines support + * + * Fills up: + * pstates -> a pointer to an array of size MAX_HW_PSTATES + * must be initialized with zeros. + * All available HW pstates (including boost states) + * no -> amount of pstates above array got filled up with + * + * returns zero on success, -1 on failure + */ +int decode_pstates(unsigned int cpu, int boost_states, + unsigned long *pstates, int *no) +{ + int i, psmax; + union core_pstate pstate; + unsigned long long val; + + /* Only read out frequencies from HW if HW Pstate is supported, + * otherwise frequencies are exported via ACPI tables. + */ + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_HW_PSTATE)) + return -1; + + if (read_msr(cpu, MSR_AMD_PSTATE_LIMIT, &val)) + return -1; + + psmax = (val >> 4) & 0x7; + psmax += boost_states; + for (i = 0; i <= psmax; i++) { + if (i >= MAX_HW_PSTATES) { + fprintf(stderr, "HW pstates [%d] exceeding max [%d]\n", + psmax, MAX_HW_PSTATES); + return -1; + } + if (read_msr(cpu, MSR_AMD_PSTATE + i, &pstate.val)) + return -1; + + /* The enabled bit (bit 63) is common for all families */ + if (!pstate.pstatedef.en) + continue; + + pstates[i] = get_cof(pstate); + } + *no = i; + return 0; +} + +int amd_pci_get_num_boost_states(int *active, int *states) +{ + struct pci_access *pci_acc; + struct pci_dev *device; + uint8_t val = 0; + + *active = *states = 0; + + device = pci_slot_func_init(&pci_acc, 0x18, 4); + + if (device == NULL) + return -ENODEV; + + val = pci_read_byte(device, 0x15c); + if (val & 3) + *active = 1; + else + *active = 0; + *states = (val >> 2) & 7; + + pci_cleanup(pci_acc); + return 0; +} + +/* ACPI P-States Helper Functions for AMD Processors ***************/ + +/* AMD P-State Helper Functions ************************************/ +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, +}; + +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, + enum amd_pstate_value value) +{ + return cpufreq_get_sysfs_value_from_table(cpu, + amd_pstate_value_files, + value, + MAX_AMD_PSTATE_VALUE_READ_FILES); +} + +void amd_pstate_boost_init(unsigned int cpu, int *support, int *active) +{ + unsigned long highest_perf, nominal_perf, cpuinfo_min, + cpuinfo_max, amd_pstate_max; + + highest_perf = amd_pstate_get_data(cpu, AMD_PSTATE_HIGHEST_PERF); + nominal_perf = acpi_cppc_get_data(cpu, NOMINAL_PERF); + + *support = highest_perf > nominal_perf ? 1 : 0; + if (!(*support)) + return; + + cpufreq_get_hardware_limits(cpu, &cpuinfo_min, &cpuinfo_max); + amd_pstate_max = amd_pstate_get_data(cpu, AMD_PSTATE_MAX_FREQ); + + *active = cpuinfo_max == amd_pstate_max ? 1 : 0; +} + +void amd_pstate_show_perf_and_freq(unsigned int cpu, int no_rounding) +{ + + 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 + * frequency. So we read it back from amd-pstate sysfs entry. + */ + print_speed(amd_pstate_get_data(cpu, AMD_PSTATE_MAX_FREQ), no_rounding); + printf(".\n"); + + 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(_(" 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(_(" 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 ************************************/ +#endif /* defined(__i386__) || defined(__x86_64__) */ diff --git a/tools/power/cpupower/utils/helpers/bitmask.c b/tools/power/cpupower/utils/helpers/bitmask.c new file mode 100644 index 000000000..649d87cb8 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/bitmask.c @@ -0,0 +1,293 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include + +#include + +/* How many bits in an unsigned long */ +#define bitsperlong (8 * sizeof(unsigned long)) + +/* howmany(a,b) : how many elements of size b needed to hold all of a */ +#define howmany(x, y) (((x)+((y)-1))/(y)) + +/* How many longs in mask of n bits */ +#define longsperbits(n) howmany(n, bitsperlong) + +#define max(a, b) ((a) > (b) ? (a) : (b)) + +/* + * Allocate and free `struct bitmask *` + */ + +/* Allocate a new `struct bitmask` with a size of n bits */ +struct bitmask *bitmask_alloc(unsigned int n) +{ + struct bitmask *bmp; + + bmp = malloc(sizeof(*bmp)); + if (!bmp) + return 0; + bmp->size = n; + bmp->maskp = calloc(longsperbits(n), sizeof(unsigned long)); + if (!bmp->maskp) { + free(bmp); + return 0; + } + return bmp; +} + +/* Free `struct bitmask` */ +void bitmask_free(struct bitmask *bmp) +{ + if (!bmp) + return; + free(bmp->maskp); + bmp->maskp = (unsigned long *)0xdeadcdef; /* double free tripwire */ + free(bmp); +} + +/* + * The routines _getbit() and _setbit() are the only + * routines that actually understand the layout of bmp->maskp[]. + * + * On little endian architectures, this could simply be an array of + * bytes. But the kernel layout of bitmasks _is_ visible to userspace + * via the sched_(set/get)affinity calls in Linux 2.6, and on big + * endian architectures, it is painfully obvious that this is an + * array of unsigned longs. + */ + +/* Return the value (0 or 1) of bit n in bitmask bmp */ +static unsigned int _getbit(const struct bitmask *bmp, unsigned int n) +{ + if (n < bmp->size) + return (bmp->maskp[n/bitsperlong] >> (n % bitsperlong)) & 1; + else + return 0; +} + +/* Set bit n in bitmask bmp to value v (0 or 1) */ +static void _setbit(struct bitmask *bmp, unsigned int n, unsigned int v) +{ + if (n < bmp->size) { + if (v) + bmp->maskp[n/bitsperlong] |= 1UL << (n % bitsperlong); + else + bmp->maskp[n/bitsperlong] &= + ~(1UL << (n % bitsperlong)); + } +} + +/* + * When parsing bitmask lists, only allow numbers, separated by one + * of the allowed next characters. + * + * The parameter 'sret' is the return from a sscanf "%u%c". It is + * -1 if the sscanf input string was empty. It is 0 if the first + * character in the sscanf input string was not a decimal number. + * It is 1 if the unsigned number matching the "%u" was the end of the + * input string. It is 2 if one or more additional characters followed + * the matched unsigned number. If it is 2, then 'nextc' is the first + * character following the number. The parameter 'ok_next_chars' + * is the nul-terminated list of allowed next characters. + * + * The mask term just scanned was ok if and only if either the numbers + * matching the %u were all of the input or if the next character in + * the input past the numbers was one of the allowed next characters. + */ +static int scan_was_ok(int sret, char nextc, const char *ok_next_chars) +{ + return sret == 1 || + (sret == 2 && strchr(ok_next_chars, nextc) != NULL); +} + +static const char *nexttoken(const char *q, int sep) +{ + if (q) + q = strchr(q, sep); + if (q) + q++; + return q; +} + +/* Set a single bit i in bitmask */ +struct bitmask *bitmask_setbit(struct bitmask *bmp, unsigned int i) +{ + _setbit(bmp, i, 1); + return bmp; +} + +/* Set all bits in bitmask: bmp = ~0 */ +struct bitmask *bitmask_setall(struct bitmask *bmp) +{ + unsigned int i; + for (i = 0; i < bmp->size; i++) + _setbit(bmp, i, 1); + return bmp; +} + +/* Clear all bits in bitmask: bmp = 0 */ +struct bitmask *bitmask_clearall(struct bitmask *bmp) +{ + unsigned int i; + for (i = 0; i < bmp->size; i++) + _setbit(bmp, i, 0); + return bmp; +} + +/* True if all bits are clear */ +int bitmask_isallclear(const struct bitmask *bmp) +{ + unsigned int i; + for (i = 0; i < bmp->size; i++) + if (_getbit(bmp, i)) + return 0; + return 1; +} + +/* True if specified bit i is set */ +int bitmask_isbitset(const struct bitmask *bmp, unsigned int i) +{ + return _getbit(bmp, i); +} + +/* Number of lowest set bit (min) */ +unsigned int bitmask_first(const struct bitmask *bmp) +{ + return bitmask_next(bmp, 0); +} + +/* Number of highest set bit (max) */ +unsigned int bitmask_last(const struct bitmask *bmp) +{ + unsigned int i; + unsigned int m = bmp->size; + for (i = 0; i < bmp->size; i++) + if (_getbit(bmp, i)) + m = i; + return m; +} + +/* Number of next set bit at or above given bit i */ +unsigned int bitmask_next(const struct bitmask *bmp, unsigned int i) +{ + unsigned int n; + for (n = i; n < bmp->size; n++) + if (_getbit(bmp, n)) + break; + return n; +} + +/* + * Parses a comma-separated list of numbers and ranges of numbers, + * with optional ':%u' strides modifying ranges, into provided bitmask. + * Some examples of input lists and their equivalent simple list: + * Input Equivalent to + * 0-3 0,1,2,3 + * 0-7:2 0,2,4,6 + * 1,3,5-7 1,3,5,6,7 + * 0-3:2,8-15:4 0,2,8,12 + */ +int bitmask_parselist(const char *buf, struct bitmask *bmp) +{ + const char *p, *q; + + bitmask_clearall(bmp); + + q = buf; + while (p = q, q = nexttoken(q, ','), p) { + unsigned int a; /* begin of range */ + unsigned int b; /* end of range */ + unsigned int s; /* stride */ + const char *c1, *c2; /* next tokens after '-' or ',' */ + char nextc; /* char after sscanf %u match */ + int sret; /* sscanf return (number of matches) */ + + sret = sscanf(p, "%u%c", &a, &nextc); + if (!scan_was_ok(sret, nextc, ",-")) + goto err; + b = a; + s = 1; + c1 = nexttoken(p, '-'); + c2 = nexttoken(p, ','); + if (c1 != NULL && (c2 == NULL || c1 < c2)) { + sret = sscanf(c1, "%u%c", &b, &nextc); + if (!scan_was_ok(sret, nextc, ",:")) + goto err; + c1 = nexttoken(c1, ':'); + if (c1 != NULL && (c2 == NULL || c1 < c2)) { + sret = sscanf(c1, "%u%c", &s, &nextc); + if (!scan_was_ok(sret, nextc, ",")) + goto err; + } + } + if (!(a <= b)) + goto err; + if (b >= bmp->size) + goto err; + while (a <= b) { + _setbit(bmp, a, 1); + a += s; + } + } + return 0; +err: + bitmask_clearall(bmp); + return -1; +} + +/* + * emit(buf, buflen, rbot, rtop, len) + * + * Helper routine for bitmask_displaylist(). Write decimal number + * or range to buf+len, suppressing output past buf+buflen, with optional + * comma-prefix. Return len of what would be written to buf, if it + * all fit. + */ + +static inline int emit(char *buf, int buflen, int rbot, int rtop, int len) +{ + if (len > 0) + len += snprintf(buf + len, max(buflen - len, 0), ","); + if (rbot == rtop) + len += snprintf(buf + len, max(buflen - len, 0), "%d", rbot); + else + len += snprintf(buf + len, max(buflen - len, 0), "%d-%d", + rbot, rtop); + return len; +} + +/* + * Write decimal list representation of bmp to buf. + * + * Output format is a comma-separated list of decimal numbers and + * ranges. Consecutively set bits are shown as two hyphen-separated + * decimal numbers, the smallest and largest bit numbers set in + * the range. Output format is compatible with the format + * accepted as input by bitmap_parselist(). + * + * The return value is the number of characters which would be + * generated for the given input, excluding the trailing '\0', as + * per ISO C99. + */ + +int bitmask_displaylist(char *buf, int buflen, const struct bitmask *bmp) +{ + int len = 0; + /* current bit is 'cur', most recently seen range is [rbot, rtop] */ + unsigned int cur, rbot, rtop; + + if (buflen > 0) + *buf = 0; + rbot = cur = bitmask_first(bmp); + while (cur < bmp->size) { + rtop = cur; + cur = bitmask_next(bmp, cur+1); + if (cur >= bmp->size || cur > rtop + 1) { + len = emit(buf, buflen, rbot, rtop, len); + rbot = cur; + } + } + return len; +} diff --git a/tools/power/cpupower/utils/helpers/bitmask.h b/tools/power/cpupower/utils/helpers/bitmask.h new file mode 100644 index 000000000..b98d93a44 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/bitmask.h @@ -0,0 +1,34 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __CPUPOWER_BITMASK__ +#define __CPUPOWER_BITMASK__ + +/* Taken over from libbitmask, a project initiated from sgi: + * Url: http://oss.sgi.com/projects/cpusets/ + * Unfortunately it's not very widespread, therefore relevant parts are + * pasted here. + */ + +struct bitmask { + unsigned int size; + unsigned long *maskp; +}; + +struct bitmask *bitmask_alloc(unsigned int n); +void bitmask_free(struct bitmask *bmp); + +struct bitmask *bitmask_setbit(struct bitmask *bmp, unsigned int i); +struct bitmask *bitmask_setall(struct bitmask *bmp); +struct bitmask *bitmask_clearall(struct bitmask *bmp); + +unsigned int bitmask_first(const struct bitmask *bmp); +unsigned int bitmask_next(const struct bitmask *bmp, unsigned int i); +unsigned int bitmask_last(const struct bitmask *bmp); +int bitmask_isallclear(const struct bitmask *bmp); +int bitmask_isbitset(const struct bitmask *bmp, unsigned int i); + +int bitmask_parselist(const char *buf, struct bitmask *bmp); +int bitmask_displaylist(char *buf, int len, const struct bitmask *bmp); + + + +#endif /*__CPUPOWER_BITMASK__ */ diff --git a/tools/power/cpupower/utils/helpers/cppc.c b/tools/power/cpupower/utils/helpers/cppc.c new file mode 100644 index 000000000..3493ce855 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/cppc.c @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include +#include + +#include "helpers/helpers.h" +#include "cpufreq.h" +#include "acpi_cppc.h" + +#define cppc_to_frequency(perf) (roundf(slope * (perf) + intercept)) + +void cppc_show_perf_and_freq(unsigned int cpu, int no_rounding) +{ + int64_t nominal = acpi_cppc_get_data(cpu, NOMINAL_PERF); + int64_t nominal_freq = acpi_cppc_get_data(cpu, NOMINAL_FREQ) * 1000; + int64_t lowest = acpi_cppc_get_data(cpu, LOWEST_PERF); + int64_t lowest_freq = acpi_cppc_get_data(cpu, LOWEST_FREQ) * 1000; + unsigned long non_linear = acpi_cppc_get_data(cpu, LOWEST_NONLINEAR_PERF); + unsigned long highest = acpi_cppc_get_data(cpu, HIGHEST_PERF); + float slope, intercept; + + /* do the optional freq fields look invalid? */ + if (!nominal_freq || !lowest_freq || nominal == lowest) + return; + + slope = (float)(nominal_freq - lowest_freq) / (nominal - lowest); + intercept = lowest_freq - slope * lowest; + + printf(_(" CPPC limits:\n")); + printf(_(" Highest Performance: %lu. Maximum Frequency: "), + highest); + /* + * If boost isn't active, the cpuinfo_max doesn't indicate real max + * frequency. + */ + print_speed(cppc_to_frequency(highest), no_rounding); + printf(".\n"); + + printf(_(" Nominal Performance: %lu. Nominal Frequency: "), + acpi_cppc_get_data(cpu, NOMINAL_PERF)); + print_speed(nominal_freq, no_rounding); + printf(".\n"); + + printf(_(" Lowest Non-linear Performance: %lu. Lowest Non-linear Frequency: "), + non_linear); + print_speed(cppc_to_frequency(non_linear), no_rounding); + printf(".\n"); + + printf(_(" Lowest Performance: %lu. Lowest Frequency: "), + acpi_cppc_get_data(cpu, LOWEST_PERF)); + print_speed(lowest_freq, no_rounding); + printf(".\n"); +} diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c new file mode 100644 index 000000000..eae91f11d --- /dev/null +++ b/tools/power/cpupower/utils/helpers/cpuid.c @@ -0,0 +1,213 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include +#include +#include +#include + +#include "helpers/helpers.h" + +static const char *cpu_vendor_table[X86_VENDOR_MAX] = { + "Unknown", "GenuineIntel", "AuthenticAMD", "HygonGenuine", +}; + +#if defined(__i386__) || defined(__x86_64__) + +/* from gcc */ +#include + +/* + * CPUID functions returning a single datum + * + * Define unsigned int cpuid_e[abcd]x(unsigned int op) + */ +#define cpuid_func(reg) \ + unsigned int cpuid_##reg(unsigned int op) \ + { \ + unsigned int eax, ebx, ecx, edx; \ + __cpuid(op, eax, ebx, ecx, edx); \ + return reg; \ + } +cpuid_func(eax); +cpuid_func(ebx); +cpuid_func(ecx); +cpuid_func(edx); + +#endif /* defined(__i386__) || defined(__x86_64__) */ + +/* get_cpu_info + * + * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo + * + * Returns 0 on success or a negativ error code + * + * TBD: Should there be a cpuid alternative for this if /proc is not mounted? + */ +int get_cpu_info(struct cpupower_cpu_info *cpu_info) +{ + FILE *fp; + char value[64]; + unsigned int proc, x; + unsigned int unknown = 0xffffff; + unsigned int cpuid_level, ext_cpuid_level; + + int ret = -EINVAL; + + cpu_info->vendor = X86_VENDOR_UNKNOWN; + cpu_info->family = unknown; + cpu_info->model = unknown; + cpu_info->stepping = unknown; + cpu_info->caps = 0; + + fp = fopen("/proc/cpuinfo", "r"); + if (!fp) + return -EIO; + + while (!feof(fp)) { + if (!fgets(value, 64, fp)) + continue; + value[63 - 1] = '\0'; + + if (!strncmp(value, "processor\t: ", 12)) + sscanf(value, "processor\t: %u", &proc); + + if (proc != (unsigned int)base_cpu) + continue; + + /* Get CPU vendor */ + if (!strncmp(value, "vendor_id", 9)) { + for (x = 1; x < X86_VENDOR_MAX; x++) { + if (strstr(value, cpu_vendor_table[x])) + cpu_info->vendor = x; + } + /* Get CPU family, etc. */ + } else if (!strncmp(value, "cpu family\t: ", 13)) { + sscanf(value, "cpu family\t: %u", + &cpu_info->family); + } else if (!strncmp(value, "model\t\t: ", 9)) { + sscanf(value, "model\t\t: %u", + &cpu_info->model); + } else if (!strncmp(value, "stepping\t: ", 10)) { + sscanf(value, "stepping\t: %u", + &cpu_info->stepping); + + /* Exit -> all values must have been set */ + if (cpu_info->vendor == X86_VENDOR_UNKNOWN || + cpu_info->family == unknown || + cpu_info->model == unknown || + cpu_info->stepping == unknown) { + ret = -EINVAL; + goto out; + } + + ret = 0; + goto out; + } + } + ret = -ENODEV; +out: + fclose(fp); + /* Get some useful CPU capabilities from cpuid */ + if (cpu_info->vendor != X86_VENDOR_AMD && + cpu_info->vendor != X86_VENDOR_HYGON && + cpu_info->vendor != X86_VENDOR_INTEL) + return ret; + + cpuid_level = cpuid_eax(0); + ext_cpuid_level = cpuid_eax(0x80000000); + + /* Invariant TSC */ + if (ext_cpuid_level >= 0x80000007 && + (cpuid_edx(0x80000007) & (1 << 8))) + cpu_info->caps |= CPUPOWER_CAP_INV_TSC; + + /* Aperf/Mperf registers support */ + if (cpuid_level >= 6 && (cpuid_ecx(6) & 0x1)) + cpu_info->caps |= CPUPOWER_CAP_APERF; + + /* AMD or Hygon Boost state enable/disable register */ + if (cpu_info->vendor == X86_VENDOR_AMD || + cpu_info->vendor == X86_VENDOR_HYGON) { + if (ext_cpuid_level >= 0x80000007) { + if (cpuid_edx(0x80000007) & (1 << 9)) { + cpu_info->caps |= CPUPOWER_CAP_AMD_CPB; + + if (cpu_info->family >= 0x17) + cpu_info->caps |= CPUPOWER_CAP_AMD_CPB_MSR; + } + + if ((cpuid_edx(0x80000007) & (1 << 7)) && + cpu_info->family != 0x14) { + /* HW pstate was not implemented in family 0x14 */ + cpu_info->caps |= CPUPOWER_CAP_AMD_HW_PSTATE; + + if (cpu_info->family >= 0x17) + cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATEDEF; + } + } + + if (ext_cpuid_level >= 0x80000008 && + cpuid_ebx(0x80000008) & (1 << 4)) + cpu_info->caps |= CPUPOWER_CAP_AMD_RDPRU; + + if (cpupower_amd_pstate_enabled()) { + cpu_info->caps |= CPUPOWER_CAP_AMD_PSTATE; + + /* + * If AMD P-State is enabled, the firmware will treat + * AMD P-State function as high priority. + */ + cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB; + cpu_info->caps &= ~CPUPOWER_CAP_AMD_CPB_MSR; + cpu_info->caps &= ~CPUPOWER_CAP_AMD_HW_PSTATE; + cpu_info->caps &= ~CPUPOWER_CAP_AMD_PSTATEDEF; + } + } + + if (cpu_info->vendor == X86_VENDOR_INTEL) { + if (cpuid_level >= 6 && + (cpuid_eax(6) & (1 << 1))) + cpu_info->caps |= CPUPOWER_CAP_INTEL_IDA; + } + + if (cpu_info->vendor == X86_VENDOR_INTEL) { + /* Intel's perf-bias MSR support */ + if (cpuid_level >= 6 && (cpuid_ecx(6) & (1 << 3))) + cpu_info->caps |= CPUPOWER_CAP_PERF_BIAS; + + /* Intel's Turbo Ratio Limit support */ + if (cpu_info->family == 6) { + switch (cpu_info->model) { + case 0x1A: /* Core i7, Xeon 5500 series + * Bloomfield, Gainstown NHM-EP + */ + case 0x1E: /* Core i7 and i5 Processor + * Clarksfield, Lynnfield, Jasper Forest + */ + case 0x1F: /* Core i7 and i5 Processor - Nehalem */ + case 0x25: /* Westmere Client + * Clarkdale, Arrandale + */ + case 0x2C: /* Westmere EP - Gulftown */ + cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; + break; + case 0x2A: /* SNB */ + case 0x2D: /* SNB Xeon */ + case 0x3A: /* IVB */ + case 0x3E: /* IVB Xeon */ + cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; + cpu_info->caps |= CPUPOWER_CAP_IS_SNB; + break; + case 0x2E: /* Nehalem-EX Xeon - Beckton */ + case 0x2F: /* Westmere-EX Xeon - Eagleton */ + default: + break; + } + } + } + + /* printf("ID: %u - Extid: 0x%x - Caps: 0x%llx\n", + cpuid_level, ext_cpuid_level, cpu_info->caps); + */ + return ret; +} diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h new file mode 100644 index 000000000..9c5126b63 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -0,0 +1,226 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * Miscellaneous helpers which do not fit or are worth + * to put into separate headers + */ + +#ifndef __CPUPOWERUTILS_HELPERS__ +#define __CPUPOWERUTILS_HELPERS__ + +#include +#include +#include + +#include "helpers/bitmask.h" +#include + +/* Internationalization ****************************/ +#ifdef NLS + +#define _(String) gettext(String) +#ifndef gettext_noop +#define gettext_noop(String) String +#endif +#define N_(String) gettext_noop(String) + +#else /* !NLS */ + +#define _(String) String +#define N_(String) String + +#endif +/* Internationalization ****************************/ + +extern int run_as_root; +extern int base_cpu; +extern struct bitmask *cpus_chosen; + +/* Global verbose (-d) stuff *********************************/ +/* + * define DEBUG via global Makefile variable + * Debug output is sent to stderr, do: + * cpupower monitor 2>/tmp/debug + * to split debug output away from normal output +*/ +#ifdef DEBUG +extern int be_verbose; + +#define dprint(fmt, ...) { \ + if (be_verbose) { \ + fprintf(stderr, "%s: " fmt, \ + __func__, ##__VA_ARGS__); \ + } \ + } +#else +static inline void dprint(const char *fmt, ...) { } +#endif +extern int be_verbose; +/* Global verbose (-v) stuff *********************************/ + +/* cpuid and cpuinfo helpers **************************/ +enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, + X86_VENDOR_AMD, X86_VENDOR_HYGON, X86_VENDOR_MAX}; + +#define CPUPOWER_CAP_INV_TSC 0x00000001 +#define CPUPOWER_CAP_APERF 0x00000002 +#define CPUPOWER_CAP_AMD_CPB 0x00000004 +#define CPUPOWER_CAP_PERF_BIAS 0x00000008 +#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010 +#define CPUPOWER_CAP_IS_SNB 0x00000020 +#define CPUPOWER_CAP_INTEL_IDA 0x00000040 +#define CPUPOWER_CAP_AMD_RDPRU 0x00000080 +#define CPUPOWER_CAP_AMD_HW_PSTATE 0x00000100 +#define CPUPOWER_CAP_AMD_PSTATEDEF 0x00000200 +#define CPUPOWER_CAP_AMD_CPB_MSR 0x00000400 +#define CPUPOWER_CAP_AMD_PSTATE 0x00000800 + +#define CPUPOWER_AMD_CPBDIS 0x02000000 + +#define MAX_HW_PSTATES 10 + +struct cpupower_cpu_info { + enum cpupower_cpu_vendor vendor; + unsigned int family; + unsigned int model; + unsigned int stepping; + /* CPU capabilities read out from cpuid */ + unsigned long long caps; +}; + +/* get_cpu_info + * + * Extract CPU vendor, family, model, stepping info from /proc/cpuinfo + * + * Returns 0 on success or a negative error code + * Only used on x86, below global's struct values are zero/unknown on + * other archs + */ +extern int get_cpu_info(struct cpupower_cpu_info *cpu_info); +extern struct cpupower_cpu_info cpupower_cpu_info; + + +/* cpuid and cpuinfo helpers **************************/ + +int cpufreq_has_generic_boost_support(bool *active); +int cpupower_set_generic_turbo_boost(int turbo_boost); + +/* X86 ONLY ****************************************/ +#if defined(__i386__) || defined(__x86_64__) + +#include + +/* Read/Write msr ****************************/ +extern int read_msr(int cpu, unsigned int idx, unsigned long long *val); +extern int write_msr(int cpu, unsigned int idx, unsigned long long val); + +extern int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val); +extern int cpupower_intel_get_perf_bias(unsigned int cpu); +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); + +/* Read/Write msr ****************************/ + +/* PCI stuff ****************************/ +extern int amd_pci_get_num_boost_states(int *active, int *states); +extern struct pci_dev *pci_acc_init(struct pci_access **pacc, int domain, + int bus, int slot, int func, int vendor, + int dev); +extern struct pci_dev *pci_slot_func_init(struct pci_access **pacc, + int slot, int func); + +/* PCI stuff ****************************/ + +/* AMD HW pstate decoding **************************/ + +extern int decode_pstates(unsigned int cpu, int boost_states, + unsigned long *pstates, int *no); + +/* AMD HW pstate decoding **************************/ + +int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, + int *active, int *states); +int cpupower_set_intel_turbo_boost(int turbo_boost); + +/* AMD P-State stuff **************************/ +bool cpupower_amd_pstate_enabled(void); +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); + +/* AMD P-State stuff **************************/ + +/* + * CPUID functions returning a single datum + */ +unsigned int cpuid_eax(unsigned int op); +unsigned int cpuid_ebx(unsigned int op); +unsigned int cpuid_ecx(unsigned int op); +unsigned int cpuid_edx(unsigned int op); + +/* cpuid and cpuinfo helpers **************************/ +/* X86 ONLY ********************************************/ +#else +static inline int decode_pstates(unsigned int cpu, int boost_states, + unsigned long *pstates, int *no) +{ return -1; }; + +static inline int read_msr(int cpu, unsigned int idx, unsigned long long *val) +{ return -1; }; +static inline int write_msr(int cpu, unsigned int idx, unsigned long long val) +{ return -1; }; +static inline int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val) +{ return -1; }; +static inline int cpupower_intel_get_perf_bias(unsigned int cpu) +{ return -1; }; +static inline unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu) +{ return 0; }; + +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; }; + +/* Read/Write msr ****************************/ + +static inline int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, + int *active, int *states) +{ return -1; } +static inline int cpupower_set_intel_turbo_boost(int turbo_boost) +{ return -1; } + +static inline bool cpupower_amd_pstate_enabled(void) +{ return false; } +static inline void amd_pstate_boost_init(unsigned int cpu, int *support, + int *active) +{} +static inline void amd_pstate_show_perf_and_freq(unsigned int cpu, + int no_rounding) +{} + +/* cpuid and cpuinfo helpers **************************/ + +static inline unsigned int cpuid_eax(unsigned int op) { return 0; }; +static inline unsigned int cpuid_ebx(unsigned int op) { return 0; }; +static inline unsigned int cpuid_ecx(unsigned int op) { return 0; }; +static inline unsigned int cpuid_edx(unsigned int op) { return 0; }; +#endif /* defined(__i386__) || defined(__x86_64__) */ + +/* + * CPU State related functions + */ +extern struct bitmask *online_cpus; +extern struct bitmask *offline_cpus; + +void get_cpustate(void); +void print_online_cpus(void); +void print_offline_cpus(void); +void print_speed(unsigned long speed, int no_rounding); + +void cppc_show_perf_and_freq(unsigned int cpu, int no_rounding); + +#endif /* __CPUPOWERUTILS_HELPERS__ */ diff --git a/tools/power/cpupower/utils/helpers/misc.c b/tools/power/cpupower/utils/helpers/misc.c new file mode 100644 index 000000000..eebfc79a4 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/misc.c @@ -0,0 +1,330 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include +#include +#include +#include + +#include "helpers/helpers.h" +#include "helpers/sysfs.h" +#include "cpufreq.h" +#include "cpupower_intern.h" + +#if defined(__i386__) || defined(__x86_64__) + +#define MSR_AMD_HWCR 0xc0010015 + +int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, int *active, + int *states) +{ + int ret; + unsigned long long val; + char linebuf[MAX_LINE_LEN]; + char path[SYSFS_PATH_MAX]; + char *endp; + + *support = *active = *states = 0; + + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB) { + *support = 1; + + /* AMD Family 0x17 does not utilize PCI D18F4 like prior + * families and has no fixed discrete boost states but + * has Hardware determined variable increments instead. + */ + + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_CPB_MSR) { + if (!read_msr(cpu, MSR_AMD_HWCR, &val)) { + if (!(val & CPUPOWER_AMD_CPBDIS)) + *active = 1; + } + } else { + ret = amd_pci_get_num_boost_states(active, states); + if (ret) + return ret; + } + } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_PSTATE) { + amd_pstate_boost_init(cpu, support, active); + } else if (cpupower_cpu_info.caps & CPUPOWER_CAP_INTEL_IDA) { + *support = *active = 1; + + snprintf(path, sizeof(path), PATH_TO_CPU "intel_pstate/no_turbo"); + + if (!is_valid_path(path)) + return 0; + + if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0) + return -1; + + val = strtol(linebuf, &endp, 0); + if (endp == linebuf || errno == ERANGE) + return -1; + + *active = !val; + } + return 0; +} + +int cpupower_set_intel_turbo_boost(int turbo_boost) +{ + char path[SYSFS_PATH_MAX]; + char linebuf[2] = {}; + + snprintf(path, sizeof(path), PATH_TO_CPU "intel_pstate/no_turbo"); + + /* Fallback to generic solution when intel_pstate driver not running */ + if (!is_valid_path(path)) + return cpupower_set_generic_turbo_boost(turbo_boost); + + snprintf(linebuf, sizeof(linebuf), "%d", !turbo_boost); + + if (cpupower_write_sysfs(path, linebuf, 2) <= 0) + return -1; + + return 0; +} + +int cpupower_intel_get_perf_bias(unsigned int cpu) +{ + char linebuf[MAX_LINE_LEN]; + char path[SYSFS_PATH_MAX]; + unsigned long val; + char *endp; + + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) + return -1; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/power/energy_perf_bias", cpu); + + if (cpupower_read_sysfs(path, linebuf, MAX_LINE_LEN) == 0) + return -1; + + val = strtol(linebuf, &endp, 0); + if (endp == linebuf || errno == ERANGE) + return -1; + + return val; +} + +int cpupower_intel_set_perf_bias(unsigned int cpu, unsigned int val) +{ + char path[SYSFS_PATH_MAX]; + char linebuf[3] = {}; + + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_PERF_BIAS)) + return -1; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/power/energy_perf_bias", cpu); + snprintf(linebuf, sizeof(linebuf), "%d", val); + + if (cpupower_write_sysfs(path, linebuf, 3) <= 0) + return -1; + + return 0; +} + +int cpupower_set_epp(unsigned int cpu, char *epp) +{ + char path[SYSFS_PATH_MAX]; + char linebuf[30] = {}; + + snprintf(path, sizeof(path), + PATH_TO_CPU "cpu%u/cpufreq/energy_performance_preference", cpu); + + if (!is_valid_path(path)) + return -1; + + snprintf(linebuf, sizeof(linebuf), "%s", epp); + + if (cpupower_write_sysfs(path, linebuf, 30) <= 0) + return -1; + + return 0; +} + +int cpupower_set_amd_pstate_mode(char *mode) +{ + char path[SYSFS_PATH_MAX]; + char linebuf[20] = {}; + + snprintf(path, sizeof(path), PATH_TO_CPU "amd_pstate/status"); + + if (!is_valid_path(path)) + return -1; + + snprintf(linebuf, sizeof(linebuf), "%s\n", mode); + + if (cpupower_write_sysfs(path, linebuf, 20) <= 0) + return -1; + + return 0; +} + +bool cpupower_amd_pstate_enabled(void) +{ + char *driver = cpufreq_get_driver(0); + bool ret = false; + + if (!driver) + return ret; + + if (!strncmp(driver, "amd", 3)) + ret = true; + + cpufreq_put_driver(driver); + + return ret; +} + +#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 + */ +void get_cpustate(void) +{ + unsigned int cpu = 0; + + bitmask_clearall(online_cpus); + bitmask_clearall(offline_cpus); + + for (cpu = bitmask_first(cpus_chosen); + cpu <= bitmask_last(cpus_chosen); cpu++) { + + if (cpupower_is_cpu_online(cpu) == 1) + bitmask_setbit(online_cpus, cpu); + else + bitmask_setbit(offline_cpus, cpu); + + continue; + } +} + +/* print_online_cpus + * + * Print the CPU numbers of all CPUs that are online currently + */ +void print_online_cpus(void) +{ + int str_len = 0; + char *online_cpus_str = NULL; + + str_len = online_cpus->size * 5; + online_cpus_str = (void *)malloc(sizeof(char) * str_len); + + if (!bitmask_isallclear(online_cpus)) { + bitmask_displaylist(online_cpus_str, str_len, online_cpus); + printf(_("Following CPUs are online:\n%s\n"), online_cpus_str); + } +} + +/* print_offline_cpus + * + * Print the CPU numbers of all CPUs that are offline currently + */ +void print_offline_cpus(void) +{ + int str_len = 0; + char *offline_cpus_str = NULL; + + str_len = offline_cpus->size * 5; + offline_cpus_str = (void *)malloc(sizeof(char) * str_len); + + if (!bitmask_isallclear(offline_cpus)) { + bitmask_displaylist(offline_cpus_str, str_len, offline_cpus); + printf(_("Following CPUs are offline:\n%s\n"), offline_cpus_str); + printf(_("cpupower set operation was not performed on them\n")); + } +} + +/* + * print_speed + * + * Print the exact CPU frequency with appropriate unit + */ +void print_speed(unsigned long speed, int no_rounding) +{ + unsigned long tmp; + + if (no_rounding) { + if (speed > 1000000) + printf("%u.%06u GHz", ((unsigned int)speed / 1000000), + ((unsigned int)speed % 1000000)); + else if (speed > 1000) + printf("%u.%03u MHz", ((unsigned int)speed / 1000), + (unsigned int)(speed % 1000)); + else + printf("%lu kHz", speed); + } else { + if (speed > 1000000) { + tmp = speed % 10000; + if (tmp >= 5000) + speed += 10000; + printf("%u.%02u GHz", ((unsigned int)speed / 1000000), + ((unsigned int)(speed % 1000000) / 10000)); + } else if (speed > 100000) { + tmp = speed % 1000; + if (tmp >= 500) + speed += 1000; + printf("%u MHz", ((unsigned int)speed / 1000)); + } else if (speed > 1000) { + tmp = speed % 100; + if (tmp >= 50) + speed += 100; + printf("%u.%01u MHz", ((unsigned int)speed / 1000), + ((unsigned int)(speed % 1000) / 100)); + } + } +} + +int cpupower_set_generic_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; +} diff --git a/tools/power/cpupower/utils/helpers/msr.c b/tools/power/cpupower/utils/helpers/msr.c new file mode 100644 index 000000000..8b0b6be74 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/msr.c @@ -0,0 +1,88 @@ +// SPDX-License-Identifier: GPL-2.0 +#if defined(__i386__) || defined(__x86_64__) + +#include +#include +#include +#include + +#include "helpers/helpers.h" + +/* Intel specific MSRs */ +#define MSR_IA32_PERF_STATUS 0x198 +#define MSR_IA32_MISC_ENABLES 0x1a0 +#define MSR_NEHALEM_TURBO_RATIO_LIMIT 0x1ad + +/* + * read_msr + * + * Will return 0 on success and -1 on failure. + * Possible errno values could be: + * EFAULT -If the read/write did not fully complete + * EIO -If the CPU does not support MSRs + * ENXIO -If the CPU does not exist + */ + +int read_msr(int cpu, unsigned int idx, unsigned long long *val) +{ + int fd; + char msr_file_name[64]; + + sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu); + fd = open(msr_file_name, O_RDONLY); + if (fd < 0) + return -1; + if (lseek(fd, idx, SEEK_CUR) == -1) + goto err; + if (read(fd, val, sizeof *val) != sizeof *val) + goto err; + close(fd); + return 0; + err: + close(fd); + return -1; +} + +/* + * write_msr + * + * Will return 0 on success and -1 on failure. + * Possible errno values could be: + * EFAULT -If the read/write did not fully complete + * EIO -If the CPU does not support MSRs + * ENXIO -If the CPU does not exist + */ +int write_msr(int cpu, unsigned int idx, unsigned long long val) +{ + int fd; + char msr_file_name[64]; + + sprintf(msr_file_name, "/dev/cpu/%d/msr", cpu); + fd = open(msr_file_name, O_WRONLY); + if (fd < 0) + return -1; + if (lseek(fd, idx, SEEK_CUR) == -1) + goto err; + if (write(fd, &val, sizeof val) != sizeof val) + goto err; + close(fd); + return 0; + err: + close(fd); + return -1; +} + +unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu) +{ + unsigned long long val; + int ret; + + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_HAS_TURBO_RATIO)) + return -1; + + ret = read_msr(cpu, MSR_NEHALEM_TURBO_RATIO_LIMIT, &val); + if (ret) + return ret; + return val; +} +#endif diff --git a/tools/power/cpupower/utils/helpers/pci.c b/tools/power/cpupower/utils/helpers/pci.c new file mode 100644 index 000000000..113f3da2a --- /dev/null +++ b/tools/power/cpupower/utils/helpers/pci.c @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +#if defined(__i386__) || defined(__x86_64__) + +#include + +/* + * pci_acc_init + * + * PCI access helper function depending on libpci + * + * **pacc : if a valid pci_dev is returned + * *pacc must be passed to pci_acc_cleanup to free it + * + * domain: domain + * bus: bus + * slot: slot + * func: func + * vendor: vendor + * device: device + * Pass -1 for one of the six above to match any + * + * Returns : + * struct pci_dev which can be used with pci_{read,write}_* functions + * to access the PCI config space of matching pci devices + */ +struct pci_dev *pci_acc_init(struct pci_access **pacc, int domain, int bus, + int slot, int func, int vendor, int dev) +{ + struct pci_filter filter_nb_link; + struct pci_dev *device; + + *pacc = pci_alloc(); + if (*pacc == NULL) + return NULL; + + pci_filter_init(*pacc, &filter_nb_link); + filter_nb_link.domain = domain; + filter_nb_link.bus = bus; + filter_nb_link.slot = slot; + filter_nb_link.func = func; + filter_nb_link.vendor = vendor; + filter_nb_link.device = dev; + + pci_init(*pacc); + pci_scan_bus(*pacc); + + for (device = (*pacc)->devices; device; device = device->next) { + if (pci_filter_match(&filter_nb_link, device)) + return device; + } + pci_cleanup(*pacc); + return NULL; +} + +/* Typically one wants to get a specific slot(device)/func of the root domain + and bus */ +struct pci_dev *pci_slot_func_init(struct pci_access **pacc, int slot, + int func) +{ + return pci_acc_init(pacc, 0, 0, slot, func, -1, -1); +} + +#endif /* defined(__i386__) || defined(__x86_64__) */ diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c new file mode 100644 index 000000000..e13ff3832 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/sysfs.c @@ -0,0 +1,471 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2004-2009 Dominik Brodowski + * (C) 2011 Thomas Renninger Novell Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "helpers/sysfs.h" + +unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) +{ + int fd; + ssize_t numread; + + fd = open(path, O_RDONLY); + if (fd == -1) + return 0; + + numread = read(fd, buf, buflen - 1); + if (numread < 1) { + close(fd); + return 0; + } + + buf[numread] = '\0'; + close(fd); + + return (unsigned int) numread; +} + +/* + * Detect whether a CPU is online + * + * Returns: + * 1 -> if CPU is online + * 0 -> if CPU is offline + * negative errno values in error case + */ +int sysfs_is_cpu_online(unsigned int cpu) +{ + char path[SYSFS_PATH_MAX]; + int fd; + ssize_t numread; + unsigned long long value; + char linebuf[MAX_LINE_LEN]; + char *endp; + struct stat statbuf; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u", cpu); + + if (stat(path, &statbuf) != 0) + return 0; + + /* + * kernel without CONFIG_HOTPLUG_CPU + * -> cpuX directory exists, but not cpuX/online file + */ + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/online", cpu); + if (stat(path, &statbuf) != 0) + return 1; + + fd = open(path, O_RDONLY); + if (fd == -1) + return -errno; + + numread = read(fd, linebuf, MAX_LINE_LEN - 1); + if (numread < 1) { + close(fd); + return -EIO; + } + linebuf[numread] = '\0'; + close(fd); + + value = strtoull(linebuf, &endp, 0); + if (value > 1) + return -EINVAL; + + return value; +} + +/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */ + + +/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */ + +/* + * helper function to check whether a file under "../cpuX/cpuidle/stateX/" dir + * exists. + * For example the functionality to disable c-states was introduced in later + * kernel versions, this function can be used to explicitly check for this + * feature. + * + * returns 1 if the file exists, 0 otherwise. + */ +unsigned int sysfs_idlestate_file_exists(unsigned int cpu, + unsigned int idlestate, + const char *fname) +{ + char path[SYSFS_PATH_MAX]; + struct stat statbuf; + + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", + cpu, idlestate, fname); + if (stat(path, &statbuf) != 0) + return 0; + return 1; +} + +/* + * helper function to read file from /sys into given buffer + * fname is a relative path under "cpuX/cpuidle/stateX/" dir + * cstates starting with 0, C0 is not counted as cstate. + * This means if you want C1 info, pass 0 as idlestate param + */ +unsigned int sysfs_idlestate_read_file(unsigned int cpu, unsigned int idlestate, + const char *fname, char *buf, size_t buflen) +{ + char path[SYSFS_PATH_MAX]; + int fd; + ssize_t numread; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", + cpu, idlestate, fname); + + fd = open(path, O_RDONLY); + if (fd == -1) + return 0; + + numread = read(fd, buf, buflen - 1); + if (numread < 1) { + close(fd); + return 0; + } + + buf[numread] = '\0'; + close(fd); + + return (unsigned int) numread; +} + +/* + * helper function to write a new value to a /sys file + * fname is a relative path under "../cpuX/cpuidle/cstateY/" dir + * + * Returns the number of bytes written or 0 on error + */ +static +unsigned int sysfs_idlestate_write_file(unsigned int cpu, + unsigned int idlestate, + const char *fname, + const char *value, size_t len) +{ + char path[SYSFS_PATH_MAX]; + int fd; + ssize_t numwrite; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s", + cpu, idlestate, fname); + + fd = open(path, O_WRONLY); + if (fd == -1) + return 0; + + numwrite = write(fd, value, len); + if (numwrite < 1) { + close(fd); + return 0; + } + + close(fd); + + return (unsigned int) numwrite; +} + +/* read access to files which contain one numeric value */ + +enum idlestate_value { + IDLESTATE_USAGE, + IDLESTATE_POWER, + IDLESTATE_LATENCY, + IDLESTATE_TIME, + IDLESTATE_DISABLE, + MAX_IDLESTATE_VALUE_FILES +}; + +static const char *idlestate_value_files[MAX_IDLESTATE_VALUE_FILES] = { + [IDLESTATE_USAGE] = "usage", + [IDLESTATE_POWER] = "power", + [IDLESTATE_LATENCY] = "latency", + [IDLESTATE_TIME] = "time", + [IDLESTATE_DISABLE] = "disable", +}; + +static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu, + unsigned int idlestate, + enum idlestate_value which) +{ + unsigned long long value; + unsigned int len; + char linebuf[MAX_LINE_LEN]; + char *endp; + + if (which >= MAX_IDLESTATE_VALUE_FILES) + return 0; + + len = sysfs_idlestate_read_file(cpu, idlestate, + idlestate_value_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) + return 0; + + value = strtoull(linebuf, &endp, 0); + + if (endp == linebuf || errno == ERANGE) + return 0; + + return value; +} + +/* read access to files which contain one string */ + +enum idlestate_string { + IDLESTATE_DESC, + IDLESTATE_NAME, + MAX_IDLESTATE_STRING_FILES +}; + +static const char *idlestate_string_files[MAX_IDLESTATE_STRING_FILES] = { + [IDLESTATE_DESC] = "desc", + [IDLESTATE_NAME] = "name", +}; + + +static char *sysfs_idlestate_get_one_string(unsigned int cpu, + unsigned int idlestate, + enum idlestate_string which) +{ + char linebuf[MAX_LINE_LEN]; + char *result; + unsigned int len; + + if (which >= MAX_IDLESTATE_STRING_FILES) + return NULL; + + len = sysfs_idlestate_read_file(cpu, idlestate, + idlestate_string_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + result = strdup(linebuf); + if (result == NULL) + return NULL; + + if (result[strlen(result) - 1] == '\n') + result[strlen(result) - 1] = '\0'; + + return result; +} + +/* + * Returns: + * 1 if disabled + * 0 if enabled + * -1 if idlestate is not available + * -2 if disabling is not supported by the kernel + */ +int sysfs_is_idlestate_disabled(unsigned int cpu, + unsigned int idlestate) +{ + if (sysfs_get_idlestate_count(cpu) <= idlestate) + return -1; + + if (!sysfs_idlestate_file_exists(cpu, idlestate, + idlestate_value_files[IDLESTATE_DISABLE])) + return -2; + return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_DISABLE); +} + +/* + * Pass 1 as last argument to disable or 0 to enable the state + * Returns: + * 0 on success + * negative values on error, for example: + * -1 if idlestate is not available + * -2 if disabling is not supported by the kernel + * -3 No write access to disable/enable C-states + */ +int sysfs_idlestate_disable(unsigned int cpu, + unsigned int idlestate, + unsigned int disable) +{ + char value[SYSFS_PATH_MAX]; + int bytes_written; + + if (sysfs_get_idlestate_count(cpu) <= idlestate) + return -1; + + if (!sysfs_idlestate_file_exists(cpu, idlestate, + idlestate_value_files[IDLESTATE_DISABLE])) + return -2; + + snprintf(value, SYSFS_PATH_MAX, "%u", disable); + + bytes_written = sysfs_idlestate_write_file(cpu, idlestate, "disable", + value, sizeof(disable)); + if (bytes_written) + return 0; + return -3; +} + +unsigned long sysfs_get_idlestate_latency(unsigned int cpu, + unsigned int idlestate) +{ + return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY); +} + +unsigned long sysfs_get_idlestate_usage(unsigned int cpu, + unsigned int idlestate) +{ + return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_USAGE); +} + +unsigned long long sysfs_get_idlestate_time(unsigned int cpu, + unsigned int idlestate) +{ + return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_TIME); +} + +char *sysfs_get_idlestate_name(unsigned int cpu, unsigned int idlestate) +{ + return sysfs_idlestate_get_one_string(cpu, idlestate, IDLESTATE_NAME); +} + +char *sysfs_get_idlestate_desc(unsigned int cpu, unsigned int idlestate) +{ + return sysfs_idlestate_get_one_string(cpu, idlestate, IDLESTATE_DESC); +} + +/* + * Returns number of supported C-states of CPU core cpu + * Negativ in error case + * Zero if cpuidle does not export any C-states + */ +unsigned int sysfs_get_idlestate_count(unsigned int cpu) +{ + char file[SYSFS_PATH_MAX]; + struct stat statbuf; + int idlestates = 1; + + + snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpuidle"); + if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) + return 0; + + snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU "cpu%u/cpuidle/state0", cpu); + if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) + return 0; + + while (stat(file, &statbuf) == 0 && S_ISDIR(statbuf.st_mode)) { + snprintf(file, SYSFS_PATH_MAX, PATH_TO_CPU + "cpu%u/cpuidle/state%d", cpu, idlestates); + idlestates++; + } + idlestates--; + return idlestates; +} + +/* CPUidle general /sys/devices/system/cpu/cpuidle/ sysfs access ********/ + +/* + * helper function to read file from /sys into given buffer + * fname is a relative path under "cpu/cpuidle/" dir + */ +static unsigned int sysfs_cpuidle_read_file(const char *fname, char *buf, + size_t buflen) +{ + char path[SYSFS_PATH_MAX]; + + snprintf(path, sizeof(path), PATH_TO_CPU "cpuidle/%s", fname); + + return sysfs_read_file(path, buf, buflen); +} + + + +/* read access to files which contain one string */ + +enum cpuidle_string { + CPUIDLE_GOVERNOR, + CPUIDLE_GOVERNOR_RO, + CPUIDLE_DRIVER, + MAX_CPUIDLE_STRING_FILES +}; + +static const char *cpuidle_string_files[MAX_CPUIDLE_STRING_FILES] = { + [CPUIDLE_GOVERNOR] = "current_governor", + [CPUIDLE_GOVERNOR_RO] = "current_governor_ro", + [CPUIDLE_DRIVER] = "current_driver", +}; + + +static char *sysfs_cpuidle_get_one_string(enum cpuidle_string which) +{ + char linebuf[MAX_LINE_LEN]; + char *result; + unsigned int len; + + if (which >= MAX_CPUIDLE_STRING_FILES) + return NULL; + + len = sysfs_cpuidle_read_file(cpuidle_string_files[which], + linebuf, sizeof(linebuf)); + if (len == 0) + return NULL; + + result = strdup(linebuf); + if (result == NULL) + return NULL; + + if (result[strlen(result) - 1] == '\n') + result[strlen(result) - 1] = '\0'; + + return result; +} + +char *sysfs_get_cpuidle_governor(void) +{ + char *tmp = sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR_RO); + if (!tmp) + return sysfs_cpuidle_get_one_string(CPUIDLE_GOVERNOR); + else + return tmp; +} + +char *sysfs_get_cpuidle_driver(void) +{ + return sysfs_cpuidle_get_one_string(CPUIDLE_DRIVER); +} +/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */ + +/* + * Get sched_mc or sched_smt settings + * Pass "mc" or "smt" as argument + * + * Returns negative value on failure + */ +int sysfs_get_sched(const char *smt_mc) +{ + return -ENODEV; +} + +/* + * Get sched_mc or sched_smt settings + * Pass "mc" or "smt" as argument + * + * Returns negative value on failure + */ +int sysfs_set_sched(const char *smt_mc, int val) +{ + return -ENODEV; +} diff --git a/tools/power/cpupower/utils/helpers/sysfs.h b/tools/power/cpupower/utils/helpers/sysfs.h new file mode 100644 index 000000000..0f0b9ad97 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/sysfs.h @@ -0,0 +1,39 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __CPUPOWER_HELPERS_SYSFS_H__ +#define __CPUPOWER_HELPERS_SYSFS_H__ + +#define PATH_TO_CPU "/sys/devices/system/cpu/" +#define MAX_LINE_LEN 255 +#define SYSFS_PATH_MAX 255 + +extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen); + +extern unsigned int sysfs_idlestate_file_exists(unsigned int cpu, + unsigned int idlestate, + const char *fname); + +extern int sysfs_is_cpu_online(unsigned int cpu); + +extern int sysfs_is_idlestate_disabled(unsigned int cpu, + unsigned int idlestate); +extern int sysfs_idlestate_disable(unsigned int cpu, unsigned int idlestate, + unsigned int disable); +extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu, + unsigned int idlestate); +extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu, + unsigned int idlestate); +extern unsigned long long sysfs_get_idlestate_time(unsigned int cpu, + unsigned int idlestate); +extern char *sysfs_get_idlestate_name(unsigned int cpu, + unsigned int idlestate); +extern char *sysfs_get_idlestate_desc(unsigned int cpu, + unsigned int idlestate); +extern unsigned int sysfs_get_idlestate_count(unsigned int cpu); + +extern char *sysfs_get_cpuidle_governor(void); +extern char *sysfs_get_cpuidle_driver(void); + +extern int sysfs_get_sched(const char *smt_mc); +extern int sysfs_set_sched(const char *smt_mc, int val); + +#endif /* __CPUPOWER_HELPERS_SYSFS_H__ */ diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c new file mode 100644 index 000000000..3dd0925d7 --- /dev/null +++ b/tools/power/cpupower/utils/helpers/topology.c @@ -0,0 +1,21 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * ToDo: Needs to be done more properly for AMD/Intel specifics + */ + +/* Helper struct for qsort, must be in sync with cpupower_topology.cpu_info */ +/* Be careful: Need to pass unsigned to the sort, so that offlined cores are + in the end, but double check for -1 for offlined cpus at other places */ + +#include +#include +#include +#include +#include + +#include + +/* CPU topology/hierarchy parsing ******************/ + diff --git a/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c b/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c new file mode 100644 index 000000000..5edd35bd9 --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c @@ -0,0 +1,334 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * PCI initialization based on example code from: + * Andreas Herrmann + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include +#include +#include +#include +#include + +#include + +#include "idle_monitor/cpupower-monitor.h" +#include "helpers/helpers.h" + +#define PCI_NON_PC0_OFFSET 0xb0 +#define PCI_PC1_OFFSET 0xb4 +#define PCI_PC6_OFFSET 0xb8 + +#define PCI_MONITOR_ENABLE_REG 0xe0 + +#define PCI_NON_PC0_ENABLE_BIT 0 +#define PCI_PC1_ENABLE_BIT 1 +#define PCI_PC6_ENABLE_BIT 2 + +#define PCI_NBP1_STAT_OFFSET 0x98 +#define PCI_NBP1_ACTIVE_BIT 2 +#define PCI_NBP1_ENTERED_BIT 1 + +#define PCI_NBP1_CAP_OFFSET 0x90 +#define PCI_NBP1_CAPABLE_BIT 31 + +#define OVERFLOW_MS 343597 /* 32 bit register filled at 12500 HZ + (1 tick per 80ns) */ + +enum amd_fam14h_states {NON_PC0 = 0, PC1, PC6, NBP1, + AMD_FAM14H_STATE_NUM}; + +static int fam14h_get_count_percent(unsigned int self_id, double *percent, + unsigned int cpu); +static int fam14h_nbp1_count(unsigned int id, unsigned long long *count, + unsigned int cpu); + +static cstate_t amd_fam14h_cstates[AMD_FAM14H_STATE_NUM] = { + { + .name = "!PC0", + .desc = N_("Package in sleep state (PC1 or deeper)"), + .id = NON_PC0, + .range = RANGE_PACKAGE, + .get_count_percent = fam14h_get_count_percent, + }, + { + .name = "PC1", + .desc = N_("Processor Package C1"), + .id = PC1, + .range = RANGE_PACKAGE, + .get_count_percent = fam14h_get_count_percent, + }, + { + .name = "PC6", + .desc = N_("Processor Package C6"), + .id = PC6, + .range = RANGE_PACKAGE, + .get_count_percent = fam14h_get_count_percent, + }, + { + .name = "NBP1", + .desc = N_("North Bridge P1 boolean counter (returns 0 or 1)"), + .id = NBP1, + .range = RANGE_PACKAGE, + .get_count = fam14h_nbp1_count, + }, +}; + +static struct pci_access *pci_acc; +static struct pci_dev *amd_fam14h_pci_dev; +static int nbp1_entered; + +static struct timespec start_time; +static unsigned long long timediff; + +#ifdef DEBUG +struct timespec dbg_time; +long dbg_timediff; +#endif + +static unsigned long long *previous_count[AMD_FAM14H_STATE_NUM]; +static unsigned long long *current_count[AMD_FAM14H_STATE_NUM]; + +static int amd_fam14h_get_pci_info(struct cstate *state, + unsigned int *pci_offset, + unsigned int *enable_bit, + unsigned int cpu) +{ + switch (state->id) { + case NON_PC0: + *enable_bit = PCI_NON_PC0_ENABLE_BIT; + *pci_offset = PCI_NON_PC0_OFFSET; + break; + case PC1: + *enable_bit = PCI_PC1_ENABLE_BIT; + *pci_offset = PCI_PC1_OFFSET; + break; + case PC6: + *enable_bit = PCI_PC6_ENABLE_BIT; + *pci_offset = PCI_PC6_OFFSET; + break; + case NBP1: + *enable_bit = PCI_NBP1_ENTERED_BIT; + *pci_offset = PCI_NBP1_STAT_OFFSET; + break; + default: + return -1; + } + return 0; +} + +static int amd_fam14h_init(cstate_t *state, unsigned int cpu) +{ + int enable_bit, pci_offset, ret; + uint32_t val; + + ret = amd_fam14h_get_pci_info(state, &pci_offset, &enable_bit, cpu); + if (ret) + return ret; + + /* NBP1 needs extra treating -> write 1 to D18F6x98 bit 1 for init */ + if (state->id == NBP1) { + val = pci_read_long(amd_fam14h_pci_dev, pci_offset); + val |= 1 << enable_bit; + val = pci_write_long(amd_fam14h_pci_dev, pci_offset, val); + return ret; + } + + /* Enable monitor */ + val = pci_read_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG); + dprint("Init %s: read at offset: 0x%x val: %u\n", state->name, + PCI_MONITOR_ENABLE_REG, (unsigned int) val); + val |= 1 << enable_bit; + pci_write_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG, val); + + dprint("Init %s: offset: 0x%x enable_bit: %d - val: %u (%u)\n", + state->name, PCI_MONITOR_ENABLE_REG, enable_bit, + (unsigned int) val, cpu); + + /* Set counter to zero */ + pci_write_long(amd_fam14h_pci_dev, pci_offset, 0); + previous_count[state->id][cpu] = 0; + + return 0; +} + +static int amd_fam14h_disable(cstate_t *state, unsigned int cpu) +{ + int enable_bit, pci_offset, ret; + uint32_t val; + + ret = amd_fam14h_get_pci_info(state, &pci_offset, &enable_bit, cpu); + if (ret) + return ret; + + val = pci_read_long(amd_fam14h_pci_dev, pci_offset); + dprint("%s: offset: 0x%x %u\n", state->name, pci_offset, val); + if (state->id == NBP1) { + /* was the bit whether NBP1 got entered set? */ + nbp1_entered = (val & (1 << PCI_NBP1_ACTIVE_BIT)) | + (val & (1 << PCI_NBP1_ENTERED_BIT)); + + dprint("NBP1 was %sentered - 0x%x - enable_bit: " + "%d - pci_offset: 0x%x\n", + nbp1_entered ? "" : "not ", + val, enable_bit, pci_offset); + return ret; + } + current_count[state->id][cpu] = val; + + dprint("%s: Current - %llu (%u)\n", state->name, + current_count[state->id][cpu], cpu); + dprint("%s: Previous - %llu (%u)\n", state->name, + previous_count[state->id][cpu], cpu); + + val = pci_read_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG); + val &= ~(1 << enable_bit); + pci_write_long(amd_fam14h_pci_dev, PCI_MONITOR_ENABLE_REG, val); + + return 0; +} + +static int fam14h_nbp1_count(unsigned int id, unsigned long long *count, + unsigned int cpu) +{ + if (id == NBP1) { + if (nbp1_entered) + *count = 1; + else + *count = 0; + return 0; + } + return -1; +} +static int fam14h_get_count_percent(unsigned int id, double *percent, + unsigned int cpu) +{ + unsigned long diff; + + if (id >= AMD_FAM14H_STATE_NUM) + return -1; + /* residency count in 80ns -> divide through 12.5 to get us residency */ + diff = current_count[id][cpu] - previous_count[id][cpu]; + + if (timediff == 0) + *percent = 0.0; + else + *percent = 100.0 * diff / timediff / 12.5; + + dprint("Timediff: %llu - res~: %lu us - percent: %.2f %%\n", + timediff, diff * 10 / 125, *percent); + + return 0; +} + +static int amd_fam14h_start(void) +{ + int num, cpu; + clock_gettime(CLOCK_REALTIME, &start_time); + for (num = 0; num < AMD_FAM14H_STATE_NUM; num++) { + for (cpu = 0; cpu < cpu_count; cpu++) + amd_fam14h_init(&amd_fam14h_cstates[num], cpu); + } +#ifdef DEBUG + clock_gettime(CLOCK_REALTIME, &dbg_time); + dbg_timediff = timespec_diff_us(start_time, dbg_time); + dprint("Enabling counters took: %lu us\n", + dbg_timediff); +#endif + return 0; +} + +static int amd_fam14h_stop(void) +{ + int num, cpu; + struct timespec end_time; + + clock_gettime(CLOCK_REALTIME, &end_time); + + for (num = 0; num < AMD_FAM14H_STATE_NUM; num++) { + for (cpu = 0; cpu < cpu_count; cpu++) + amd_fam14h_disable(&amd_fam14h_cstates[num], cpu); + } +#ifdef DEBUG + clock_gettime(CLOCK_REALTIME, &dbg_time); + dbg_timediff = timespec_diff_us(end_time, dbg_time); + dprint("Disabling counters took: %lu ns\n", dbg_timediff); +#endif + timediff = timespec_diff_us(start_time, end_time); + if (timediff / 1000 > OVERFLOW_MS) + print_overflow_err((unsigned int)timediff / 1000000, + OVERFLOW_MS / 1000); + + return 0; +} + +static int is_nbp1_capable(void) +{ + uint32_t val; + val = pci_read_long(amd_fam14h_pci_dev, PCI_NBP1_CAP_OFFSET); + return val & (1 << 31); +} + +struct cpuidle_monitor *amd_fam14h_register(void) +{ + int num; + + if (cpupower_cpu_info.vendor != X86_VENDOR_AMD) + return NULL; + + if (cpupower_cpu_info.family == 0x14) + strncpy(amd_fam14h_monitor.name, "Fam_14h", + MONITOR_NAME_LEN - 1); + else if (cpupower_cpu_info.family == 0x12) + strncpy(amd_fam14h_monitor.name, "Fam_12h", + MONITOR_NAME_LEN - 1); + else + return NULL; + + /* We do not alloc for nbp1 machine wide counter */ + for (num = 0; num < AMD_FAM14H_STATE_NUM - 1; num++) { + previous_count[num] = calloc(cpu_count, + sizeof(unsigned long long)); + current_count[num] = calloc(cpu_count, + sizeof(unsigned long long)); + } + + /* We need PCI device: Slot 18, Func 6, compare with BKDG + for fam 12h/14h */ + amd_fam14h_pci_dev = pci_slot_func_init(&pci_acc, 0x18, 6); + if (amd_fam14h_pci_dev == NULL || pci_acc == NULL) + return NULL; + + if (!is_nbp1_capable()) + amd_fam14h_monitor.hw_states_num = AMD_FAM14H_STATE_NUM - 1; + + amd_fam14h_monitor.name_len = strlen(amd_fam14h_monitor.name); + return &amd_fam14h_monitor; +} + +static void amd_fam14h_unregister(void) +{ + int num; + for (num = 0; num < AMD_FAM14H_STATE_NUM - 1; num++) { + free(previous_count[num]); + free(current_count[num]); + } + pci_cleanup(pci_acc); +} + +struct cpuidle_monitor amd_fam14h_monitor = { + .name = "", + .hw_states = amd_fam14h_cstates, + .hw_states_num = AMD_FAM14H_STATE_NUM, + .start = amd_fam14h_start, + .stop = amd_fam14h_stop, + .do_register = amd_fam14h_register, + .unregister = amd_fam14h_unregister, + .flags.needs_root = 1, + .overflow_s = OVERFLOW_MS / 1000, +}; +#endif /* #if defined(__i386__) || defined(__x86_64__) */ diff --git a/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c b/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c new file mode 100644 index 000000000..4225eff98 --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/cpuidle_sysfs.c @@ -0,0 +1,212 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc + */ + +#include +#include +#include +#include +#include +#include + +#include "helpers/helpers.h" +#include "idle_monitor/cpupower-monitor.h" + +#define CPUIDLE_STATES_MAX 10 +static cstate_t cpuidle_cstates[CPUIDLE_STATES_MAX]; +struct cpuidle_monitor cpuidle_sysfs_monitor; + +static unsigned long long **previous_count; +static unsigned long long **current_count; +static struct timespec start_time; +static unsigned long long timediff; + +static int cpuidle_get_count_percent(unsigned int id, double *percent, + unsigned int cpu) +{ + unsigned long long statediff = current_count[cpu][id] + - previous_count[cpu][id]; + dprint("%s: - diff: %llu - percent: %f (%u)\n", + cpuidle_cstates[id].name, timediff, *percent, cpu); + + if (timediff == 0) + *percent = 0.0; + else + *percent = ((100.0 * statediff) / timediff); + + dprint("%s: - timediff: %llu - statediff: %llu - percent: %f (%u)\n", + cpuidle_cstates[id].name, timediff, statediff, *percent, cpu); + + return 0; +} + +static int cpuidle_start(void) +{ + int cpu, state; + clock_gettime(CLOCK_REALTIME, &start_time); + for (cpu = 0; cpu < cpu_count; cpu++) { + for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num; + state++) { + previous_count[cpu][state] = + cpuidle_state_time(cpu, state); + dprint("CPU %d - State: %d - Val: %llu\n", + cpu, state, previous_count[cpu][state]); + } + } + return 0; +} + +static int cpuidle_stop(void) +{ + int cpu, state; + struct timespec end_time; + clock_gettime(CLOCK_REALTIME, &end_time); + timediff = timespec_diff_us(start_time, end_time); + + for (cpu = 0; cpu < cpu_count; cpu++) { + for (state = 0; state < cpuidle_sysfs_monitor.hw_states_num; + state++) { + current_count[cpu][state] = + cpuidle_state_time(cpu, state); + dprint("CPU %d - State: %d - Val: %llu\n", + cpu, state, current_count[cpu][state]); + } + } + return 0; +} + +void fix_up_intel_idle_driver_name(char *tmp, int num) +{ + /* fix up cpuidle name for intel idle driver */ + if (!strncmp(tmp, "NHM-", 4)) { + switch (num) { + case 1: + strcpy(tmp, "C1"); + break; + case 2: + strcpy(tmp, "C3"); + break; + case 3: + strcpy(tmp, "C6"); + break; + } + } else if (!strncmp(tmp, "SNB-", 4)) { + switch (num) { + case 1: + strcpy(tmp, "C1"); + break; + case 2: + strcpy(tmp, "C3"); + break; + case 3: + strcpy(tmp, "C6"); + break; + case 4: + strcpy(tmp, "C7"); + break; + } + } else if (!strncmp(tmp, "ATM-", 4)) { + switch (num) { + case 1: + strcpy(tmp, "C1"); + break; + case 2: + strcpy(tmp, "C2"); + break; + case 3: + strcpy(tmp, "C4"); + break; + case 4: + strcpy(tmp, "C6"); + break; + } + } +} + +#ifdef __powerpc__ +void map_power_idle_state_name(char *tmp) +{ + if (!strncmp(tmp, "stop0_lite", CSTATE_NAME_LEN)) + strcpy(tmp, "stop0L"); + else if (!strncmp(tmp, "stop1_lite", CSTATE_NAME_LEN)) + strcpy(tmp, "stop1L"); + else if (!strncmp(tmp, "stop2_lite", CSTATE_NAME_LEN)) + strcpy(tmp, "stop2L"); +} +#else +void map_power_idle_state_name(char *tmp) { } +#endif + +static struct cpuidle_monitor *cpuidle_register(void) +{ + int num; + char *tmp; + int this_cpu; + + this_cpu = sched_getcpu(); + + /* Assume idle state count is the same for all CPUs */ + cpuidle_sysfs_monitor.hw_states_num = cpuidle_state_count(this_cpu); + + if (cpuidle_sysfs_monitor.hw_states_num <= 0) + return NULL; + + for (num = 0; num < cpuidle_sysfs_monitor.hw_states_num; num++) { + tmp = cpuidle_state_name(this_cpu, num); + if (tmp == NULL) + continue; + + map_power_idle_state_name(tmp); + fix_up_intel_idle_driver_name(tmp, num); + strncpy(cpuidle_cstates[num].name, tmp, CSTATE_NAME_LEN - 1); + free(tmp); + + tmp = cpuidle_state_desc(this_cpu, num); + if (tmp == NULL) + continue; + strncpy(cpuidle_cstates[num].desc, tmp, CSTATE_DESC_LEN - 1); + free(tmp); + + cpuidle_cstates[num].range = RANGE_THREAD; + cpuidle_cstates[num].id = num; + cpuidle_cstates[num].get_count_percent = + cpuidle_get_count_percent; + } + + /* Free this at program termination */ + previous_count = malloc(sizeof(long long *) * cpu_count); + current_count = malloc(sizeof(long long *) * cpu_count); + for (num = 0; num < cpu_count; num++) { + previous_count[num] = malloc(sizeof(long long) * + cpuidle_sysfs_monitor.hw_states_num); + current_count[num] = malloc(sizeof(long long) * + cpuidle_sysfs_monitor.hw_states_num); + } + + cpuidle_sysfs_monitor.name_len = strlen(cpuidle_sysfs_monitor.name); + return &cpuidle_sysfs_monitor; +} + +void cpuidle_unregister(void) +{ + int num; + + for (num = 0; num < cpu_count; num++) { + free(previous_count[num]); + free(current_count[num]); + } + free(previous_count); + free(current_count); +} + +struct cpuidle_monitor cpuidle_sysfs_monitor = { + .name = "Idle_Stats", + .hw_states = cpuidle_cstates, + .start = cpuidle_start, + .stop = cpuidle_stop, + .do_register = cpuidle_register, + .unregister = cpuidle_unregister, + .flags.needs_root = 0, + .overflow_s = UINT_MAX, +}; diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c new file mode 100644 index 000000000..e8b3841d5 --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c @@ -0,0 +1,488 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * Output format inspired by Len Brown's turbostat tool. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "idle_monitor/cpupower-monitor.h" +#include "idle_monitor/idle_monitors.h" +#include "helpers/helpers.h" + +/* Define pointers to all monitors. */ +#define DEF(x) & x ## _monitor , +struct cpuidle_monitor *all_monitors[] = { +#include "idle_monitors.def" +0 +}; + +int cpu_count; + +static struct cpuidle_monitor *monitors[MONITORS_MAX]; +static unsigned int avail_monitors; + +static char *progname; + +enum operation_mode_e { list = 1, show, show_all }; +static enum operation_mode_e mode; +static int interval = 1; +static char *show_monitors_param; +static struct cpupower_topology cpu_top; +static unsigned int wake_cpus; + +/* ToDo: Document this in the manpage */ +static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', }; + +static void print_wrong_arg_exit(void) +{ + printf(_("invalid or unknown argument\n")); + exit(EXIT_FAILURE); +} + +long long timespec_diff_us(struct timespec start, struct timespec end) +{ + struct timespec temp; + if ((end.tv_nsec - start.tv_nsec) < 0) { + temp.tv_sec = end.tv_sec - start.tv_sec - 1; + temp.tv_nsec = 1000000000 + end.tv_nsec - start.tv_nsec; + } else { + temp.tv_sec = end.tv_sec - start.tv_sec; + temp.tv_nsec = end.tv_nsec - start.tv_nsec; + } + return (temp.tv_sec * 1000000) + (temp.tv_nsec / 1000); +} + +void print_n_spaces(int n) +{ + int x; + for (x = 0; x < n; x++) + printf(" "); +} + +/*s is filled with left and right spaces + *to make its length atleast n+1 + */ +int fill_string_with_spaces(char *s, int n) +{ + char *temp; + int len = strlen(s); + + if (len >= n) + return -1; + + temp = malloc(sizeof(char) * (n+1)); + for (; len < n; len++) + s[len] = ' '; + s[len] = '\0'; + snprintf(temp, n+1, " %s", s); + strcpy(s, temp); + free(temp); + return 0; +} + +#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; + int state, need_len; + cstate_t s; + char buf[128] = ""; + + fill_string_with_spaces(buf, topology_depth * 5 - 1); + printf("%s|", buf); + + for (mon = 0; mon < avail_monitors; mon++) { + need_len = monitors[mon]->hw_states_num * (MAX_COL_WIDTH + 1) + - 1; + if (mon != 0) + printf("||"); + sprintf(buf, "%s", monitors[mon]->name); + fill_string_with_spaces(buf, need_len); + printf("%s", buf); + } + printf("\n"); + + switch (topology_depth) { + case TOPOLOGY_DEPTH_PKG: + printf(" PKG|"); + case TOPOLOGY_DEPTH_CORE: + printf("CORE|"); + case TOPOLOGY_DEPTH_CPU: + printf(" CPU|"); + break; + default: + return; + } + + for (mon = 0; mon < avail_monitors; mon++) { + if (mon != 0) + printf("||"); + for (state = 0; state < monitors[mon]->hw_states_num; state++) { + if (state != 0) + printf("|"); + s = monitors[mon]->hw_states[state]; + sprintf(buf, "%s", s.name); + fill_string_with_spaces(buf, MAX_COL_WIDTH); + printf("%s", buf); + } + printf(" "); + } + printf("\n"); +} + + +void print_results(int topology_depth, int cpu) +{ + unsigned int mon; + int state, ret; + double percent; + unsigned long long result; + cstate_t s; + + /* Be careful CPUs may got resorted for pkg value do not just use cpu */ + if (!bitmask_isbitset(cpus_chosen, cpu_top.core_info[cpu].cpu)) + return; + if (!cpu_top.core_info[cpu].is_online && + cpu_top.core_info[cpu].pkg == -1) + return; + + switch (topology_depth) { + case TOPOLOGY_DEPTH_PKG: + printf("%4d|", cpu_top.core_info[cpu].pkg); + case TOPOLOGY_DEPTH_CORE: + printf("%4d|", cpu_top.core_info[cpu].core); + 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) + printf("||"); + + for (state = 0; state < monitors[mon]->hw_states_num; state++) { + if (state != 0) + printf("|"); + + s = monitors[mon]->hw_states[state]; + + if (s.get_count_percent) { + ret = s.get_count_percent(s.id, &percent, + cpu_top.core_info[cpu].cpu); + if (ret) + printf("******"); + else if (percent >= 100.0) + printf("%6.1f", percent); + else + printf("%6.2f", percent); + } else if (s.get_count) { + ret = s.get_count(s.id, &result, + cpu_top.core_info[cpu].cpu); + if (ret) + printf("******"); + else + printf("%6llu", result); + } else { + printf(_("Monitor %s, Counter %s has no count " + "function. Implementation error\n"), + monitors[mon]->name, s.name); + exit(EXIT_FAILURE); + } + } + } + /* + * The monitor could still provide useful data, for example + * AMD HW counters partly sit in PCI config space. + * It's up to the monitor plug-in to check .is_online, this one + * is just for additional info. + */ + if (!cpu_top.core_info[cpu].is_online && + cpu_top.core_info[cpu].pkg != -1) { + printf(_(" *is offline\n")); + return; + } else + printf("\n"); +} + + +/* param: string passed by -m param (The list of monitors to show) + * + * Monitors must have been registered already, matching monitors + * are picked out and available monitors array is overridden + * with matching ones + * + * Monitors get sorted in the same order the user passes them +*/ + +static void parse_monitor_param(char *param) +{ + unsigned int num; + int mon, hits = 0; + char *tmp = param, *token; + struct cpuidle_monitor *tmp_mons[MONITORS_MAX]; + + + for (mon = 0; mon < MONITORS_MAX; mon++, tmp = NULL) { + token = strtok(tmp, ","); + if (token == NULL) + break; + if (strlen(token) >= MONITOR_NAME_LEN) { + printf(_("%s: max monitor name length" + " (%d) exceeded\n"), token, MONITOR_NAME_LEN); + continue; + } + + for (num = 0; num < avail_monitors; num++) { + if (!strcmp(monitors[num]->name, token)) { + dprint("Found requested monitor: %s\n", token); + tmp_mons[hits] = monitors[num]; + hits++; + } + } + } + if (hits == 0) { + printf(_("No matching monitor found in %s, " + "try -l option\n"), param); + exit(EXIT_FAILURE); + } + /* Override detected/registerd monitors array with requested one */ + memcpy(monitors, tmp_mons, + sizeof(struct cpuidle_monitor *) * MONITORS_MAX); + avail_monitors = hits; +} + +void list_monitors(void) +{ + unsigned int mon; + int state; + cstate_t s; + + for (mon = 0; mon < avail_monitors; mon++) { + printf(_("Monitor \"%s\" (%d states) - Might overflow after %u " + "s\n"), + monitors[mon]->name, monitors[mon]->hw_states_num, + monitors[mon]->overflow_s); + + for (state = 0; state < monitors[mon]->hw_states_num; state++) { + s = monitors[mon]->hw_states[state]; + /* + * ToDo show more state capabilities: + * percent, time (granlarity) + */ + printf("%s\t[%c] -> %s\n", s.name, range_abbr[s.range], + gettext(s.desc)); + } + } +} + +int fork_it(char **argv) +{ + int status; + unsigned int num; + unsigned long long timediff; + pid_t child_pid; + struct timespec start, end; + + child_pid = fork(); + clock_gettime(CLOCK_REALTIME, &start); + + for (num = 0; num < avail_monitors; num++) + monitors[num]->start(); + + if (!child_pid) { + /* child */ + if (execvp(argv[0], argv) == -1) { + printf("Invalid monitor command %s\n", argv[0]); + exit(errno); + } + } else { + /* parent */ + if (child_pid == -1) { + perror("fork"); + exit(1); + } + + signal(SIGINT, SIG_IGN); + signal(SIGQUIT, SIG_IGN); + if (waitpid(child_pid, &status, 0) == -1) { + perror("wait"); + exit(1); + } + } + clock_gettime(CLOCK_REALTIME, &end); + for (num = 0; num < avail_monitors; num++) + monitors[num]->stop(); + + timediff = timespec_diff_us(start, end); + if (WIFEXITED(status)) + printf(_("%s took %.5f seconds and exited with status %d\n"), + argv[0], timediff / (1000.0 * 1000), + WEXITSTATUS(status)); + return 0; +} + +int do_interval_measure(int i) +{ + unsigned int num; + int cpu; + + if (wake_cpus) + for (cpu = 0; cpu < cpu_count; cpu++) + bind_cpu(cpu); + + for (num = 0; num < avail_monitors; num++) { + dprint("HW C-state residency monitor: %s - States: %d\n", + monitors[num]->name, monitors[num]->hw_states_num); + monitors[num]->start(); + } + + sleep(i); + + if (wake_cpus) + for (cpu = 0; cpu < cpu_count; cpu++) + bind_cpu(cpu); + + for (num = 0; num < avail_monitors; num++) + monitors[num]->stop(); + + + return 0; +} + +static void cmdline(int argc, char *argv[]) +{ + int opt; + progname = basename(argv[0]); + + while ((opt = getopt(argc, argv, "+lci:m:")) != -1) { + switch (opt) { + case 'l': + if (mode) + print_wrong_arg_exit(); + mode = list; + break; + case 'i': + /* only allow -i with -m or no option */ + if (mode && mode != show) + print_wrong_arg_exit(); + interval = atoi(optarg); + break; + case 'm': + if (mode) + print_wrong_arg_exit(); + mode = show; + show_monitors_param = optarg; + break; + case 'c': + wake_cpus = 1; + break; + default: + print_wrong_arg_exit(); + } + } + if (!mode) + mode = show_all; +} + +int cmd_monitor(int argc, char **argv) +{ + unsigned int num; + struct cpuidle_monitor *test_mon; + int cpu; + + cmdline(argc, argv); + cpu_count = get_cpu_topology(&cpu_top); + if (cpu_count < 0) { + printf(_("Cannot read number of available processors\n")); + return EXIT_FAILURE; + } + + if (!cpu_top.core_info[0].is_online) + printf("WARNING: at least one cpu is offline\n"); + + /* Default is: monitor all CPUs */ + if (bitmask_isallclear(cpus_chosen)) + bitmask_setall(cpus_chosen); + + dprint("System has up to %d CPU cores\n", cpu_count); + + for (num = 0; all_monitors[num]; num++) { + dprint("Try to register: %s\n", all_monitors[num]->name); + test_mon = all_monitors[num]->do_register(); + if (test_mon) { + if (test_mon->flags.needs_root && !run_as_root) { + fprintf(stderr, _("Available monitor %s needs " + "root access\n"), test_mon->name); + continue; + } + monitors[avail_monitors] = test_mon; + dprint("%s registered\n", all_monitors[num]->name); + avail_monitors++; + } + } + + 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); + } + + if (mode == show) + parse_monitor_param(show_monitors_param); + + dprint("Packages: %d - Cores: %d - CPUs: %d\n", + cpu_top.pkgs, cpu_top.cores, cpu_count); + + /* + * if any params left, it must be a command to fork + */ + if (argc - optind) + fork_it(argv + optind); + else + do_interval_measure(interval); + + /* ToDo: Topology parsing needs fixing first to do + this more generically */ + if (cpu_top.pkgs > 1) + print_header(TOPOLOGY_DEPTH_PKG); + else + print_header(TOPOLOGY_DEPTH_CPU); + + for (cpu = 0; cpu < cpu_count; cpu++) { + if (cpu_top.pkgs > 1) + print_results(TOPOLOGY_DEPTH_PKG, cpu); + else + print_results(TOPOLOGY_DEPTH_CPU, cpu); + } + + for (num = 0; num < avail_monitors; num++) { + if (monitors[num]->unregister) + monitors[num]->unregister(); + } + cpu_topology_release(cpu_top); + return 0; +} diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h new file mode 100644 index 000000000..c559d3115 --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + */ + +#ifndef __CPUIDLE_INFO_HW__ +#define __CPUIDLE_INFO_HW__ + +#include +#include + +#include "idle_monitor/idle_monitors.h" + +#define MONITORS_MAX 20 +#define MONITOR_NAME_LEN 20 + +/* CSTATE_NAME_LEN is limited by header field width defined + * in cpupower-monitor.c. Header field width is defined to be + * sum of percent width and two spaces for padding. + */ +#ifdef __powerpc__ +#define CSTATE_NAME_LEN 7 +#else +#define CSTATE_NAME_LEN 5 +#endif +#define CSTATE_DESC_LEN 60 + +extern int cpu_count; + +/* Hard to define the right names ...: */ +enum power_range_e { + RANGE_THREAD, /* Lowest in topology hierarcy, AMD: core, Intel: thread + kernel sysfs: cpu */ + RANGE_CORE, /* AMD: unit, Intel: core, kernel_sysfs: core_id */ + RANGE_PACKAGE, /* Package, processor socket */ + RANGE_MACHINE, /* Machine, platform wide */ + RANGE_MAX }; + +typedef struct cstate { + int id; + enum power_range_e range; + char name[CSTATE_NAME_LEN]; + char desc[CSTATE_DESC_LEN]; + + /* either provide a percentage or a general count */ + int (*get_count_percent)(unsigned int self_id, double *percent, + unsigned int cpu); + int (*get_count)(unsigned int self_id, unsigned long long *count, + unsigned int cpu); +} cstate_t; + +struct cpuidle_monitor { + /* Name must not contain whitespaces */ + char name[MONITOR_NAME_LEN]; + int name_len; + int hw_states_num; + cstate_t *hw_states; + int (*start) (void); + int (*stop) (void); + struct cpuidle_monitor* (*do_register) (void); + void (*unregister)(void); + unsigned int overflow_s; + struct { + unsigned int needs_root:1; + unsigned int per_cpu_schedule:1; + } flags; +}; + +extern long long timespec_diff_us(struct timespec start, struct timespec end); + +#define print_overflow_err(mes, ov) \ +{ \ + fprintf(stderr, gettext("Measure took %u seconds, but registers could " \ + "overflow at %u seconds, results " \ + "could be inaccurate\n"), mes, ov); \ +} + + +/* Taken over from x86info project sources -> return 0 on success */ +#include +#include +#include +static inline int bind_cpu(int cpu) +{ + cpu_set_t set; + + if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) { + CPU_ZERO(&set); + CPU_SET(cpu, &set); + return sched_setaffinity(getpid(), sizeof(set), &set); + } + return 1; +} + +#endif /* __CPUIDLE_INFO_HW__ */ diff --git a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c new file mode 100644 index 000000000..f5a2a326b --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c @@ -0,0 +1,194 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * Based on SandyBridge monitor. Implements the new package C-states + * (PC8, PC9, PC10) coming with a specific Haswell (family 0x45) CPU. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include +#include +#include +#include + +#include "helpers/helpers.h" +#include "idle_monitor/cpupower-monitor.h" + +#define MSR_PKG_C8_RESIDENCY 0x00000630 +#define MSR_PKG_C9_RESIDENCY 0x00000631 +#define MSR_PKG_C10_RESIDENCY 0x00000632 + +#define MSR_TSC 0x10 + +enum intel_hsw_ext_id { PC8 = 0, PC9, PC10, HSW_EXT_CSTATE_COUNT, + TSC = 0xFFFF }; + +static int hsw_ext_get_count_percent(unsigned int self_id, double *percent, + unsigned int cpu); + +static cstate_t hsw_ext_cstates[HSW_EXT_CSTATE_COUNT] = { + { + .name = "PC8", + .desc = N_("Processor Package C8"), + .id = PC8, + .range = RANGE_PACKAGE, + .get_count_percent = hsw_ext_get_count_percent, + }, + { + .name = "PC9", + .desc = N_("Processor Package C9"), + .id = PC9, + .range = RANGE_PACKAGE, + .get_count_percent = hsw_ext_get_count_percent, + }, + { + .name = "PC10", + .desc = N_("Processor Package C10"), + .id = PC10, + .range = RANGE_PACKAGE, + .get_count_percent = hsw_ext_get_count_percent, + }, +}; + +static unsigned long long tsc_at_measure_start; +static unsigned long long tsc_at_measure_end; +static unsigned long long *previous_count[HSW_EXT_CSTATE_COUNT]; +static unsigned long long *current_count[HSW_EXT_CSTATE_COUNT]; +/* valid flag for all CPUs. If a MSR read failed it will be zero */ +static int *is_valid; + +static int hsw_ext_get_count(enum intel_hsw_ext_id id, unsigned long long *val, + unsigned int cpu) +{ + int msr; + + switch (id) { + case PC8: + msr = MSR_PKG_C8_RESIDENCY; + break; + case PC9: + msr = MSR_PKG_C9_RESIDENCY; + break; + case PC10: + msr = MSR_PKG_C10_RESIDENCY; + break; + case TSC: + msr = MSR_TSC; + break; + default: + return -1; + } + if (read_msr(cpu, msr, val)) + return -1; + return 0; +} + +static int hsw_ext_get_count_percent(unsigned int id, double *percent, + unsigned int cpu) +{ + *percent = 0.0; + + if (!is_valid[cpu]) + return -1; + + *percent = (100.0 * + (current_count[id][cpu] - previous_count[id][cpu])) / + (tsc_at_measure_end - tsc_at_measure_start); + + dprint("%s: previous: %llu - current: %llu - (%u)\n", + hsw_ext_cstates[id].name, previous_count[id][cpu], + current_count[id][cpu], cpu); + + dprint("%s: tsc_diff: %llu - count_diff: %llu - percent: %2.f (%u)\n", + hsw_ext_cstates[id].name, + (unsigned long long) tsc_at_measure_end - tsc_at_measure_start, + current_count[id][cpu] - previous_count[id][cpu], + *percent, cpu); + + return 0; +} + +static int hsw_ext_start(void) +{ + int num, cpu; + unsigned long long val; + + 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); + previous_count[num][cpu] = val; + } + } + hsw_ext_get_count(TSC, &tsc_at_measure_start, base_cpu); + return 0; +} + +static int hsw_ext_stop(void) +{ + unsigned long long val; + int num, cpu; + + hsw_ext_get_count(TSC, &tsc_at_measure_end, base_cpu); + + 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); + current_count[num][cpu] = val; + } + } + return 0; +} + +struct cpuidle_monitor intel_hsw_ext_monitor; + +static struct cpuidle_monitor *hsw_ext_register(void) +{ + int num; + + if (cpupower_cpu_info.vendor != X86_VENDOR_INTEL + || cpupower_cpu_info.family != 6) + return NULL; + + switch (cpupower_cpu_info.model) { + case 0x45: /* HSW */ + break; + default: + return NULL; + } + + is_valid = calloc(cpu_count, sizeof(int)); + for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) { + previous_count[num] = calloc(cpu_count, + sizeof(unsigned long long)); + current_count[num] = calloc(cpu_count, + sizeof(unsigned long long)); + } + intel_hsw_ext_monitor.name_len = strlen(intel_hsw_ext_monitor.name); + return &intel_hsw_ext_monitor; +} + +void hsw_ext_unregister(void) +{ + int num; + free(is_valid); + for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) { + free(previous_count[num]); + free(current_count[num]); + } +} + +struct cpuidle_monitor intel_hsw_ext_monitor = { + .name = "HaswellExtended", + .hw_states = hsw_ext_cstates, + .hw_states_num = HSW_EXT_CSTATE_COUNT, + .start = hsw_ext_start, + .stop = hsw_ext_stop, + .do_register = hsw_ext_register, + .unregister = hsw_ext_unregister, + .flags.needs_root = 1, + .overflow_s = 922000000 /* 922337203 seconds TSC overflow + at 20GHz */ +}; +#endif /* defined(__i386__) || defined(__x86_64__) */ diff --git a/tools/power/cpupower/utils/idle_monitor/idle_monitors.def b/tools/power/cpupower/utils/idle_monitor/idle_monitors.def new file mode 100644 index 000000000..7c926e90c --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/idle_monitors.def @@ -0,0 +1,9 @@ +#if defined(__i386__) || defined(__x86_64__) +DEF(amd_fam14h) +DEF(intel_nhm) +DEF(intel_snb) +DEF(intel_hsw_ext) +DEF(mperf) +DEF(rapl) +#endif +DEF(cpuidle_sysfs) diff --git a/tools/power/cpupower/utils/idle_monitor/idle_monitors.h b/tools/power/cpupower/utils/idle_monitor/idle_monitors.h new file mode 100644 index 000000000..e9e567ec8 --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/idle_monitors.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * Based on the idea from Michael Matz + */ + +#ifndef _CPUIDLE_IDLE_MONITORS_H_ +#define _CPUIDLE_IDLE_MONITORS_H_ + +#define DEF(x) extern struct cpuidle_monitor x ##_monitor; +#include "idle_monitors.def" +#undef DEF +extern struct cpuidle_monitor *all_monitors[]; + +#endif /* _CPUIDLE_IDLE_MONITORS_H_ */ diff --git a/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c new file mode 100644 index 000000000..5ae02c3d5 --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/mperf_monitor.c @@ -0,0 +1,382 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include +#include +#include +#include +#include + +#include + +#include "helpers/helpers.h" +#include "idle_monitor/cpupower-monitor.h" + +#define MSR_APERF 0xE8 +#define MSR_MPERF 0xE7 + +#define RDPRU ".byte 0x0f, 0x01, 0xfd" +#define RDPRU_ECX_MPERF 0 +#define RDPRU_ECX_APERF 1 + +#define MSR_TSC 0x10 + +#define MSR_AMD_HWCR 0xc0010015 + +enum mperf_id { C0 = 0, Cx, AVG_FREQ, MPERF_CSTATE_COUNT }; + +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 cstate_t mperf_cstates[MPERF_CSTATE_COUNT] = { + { + .name = "C0", + .desc = N_("Processor Core not idle"), + .id = C0, + .range = RANGE_THREAD, + .get_count_percent = mperf_get_count_percent, + }, + { + .name = "Cx", + .desc = N_("Processor Core in an idle state"), + .id = Cx, + .range = RANGE_THREAD, + .get_count_percent = mperf_get_count_percent, + }, + + { + .name = "Freq", + .desc = N_("Average Frequency (including boost) in MHz"), + .id = AVG_FREQ, + .range = RANGE_THREAD, + .get_count = mperf_get_count_freq, + }, +}; + +enum MAX_FREQ_MODE { MAX_FREQ_SYSFS, MAX_FREQ_TSC_REF }; +static int max_freq_mode; +/* + * The max frequency mperf is ticking at (in C0), either retrieved via: + * 1) calculated after measurements if we know TSC ticks at mperf/P0 frequency + * 2) cpufreq /sys/devices/.../cpu0/cpufreq/cpuinfo_max_freq at init time + * 1. Is preferred as it also works without cpufreq subsystem (e.g. on Xen) + */ +static unsigned long max_frequency; + +static unsigned long long *tsc_at_measure_start; +static unsigned long long *tsc_at_measure_end; +static unsigned long long *mperf_previous_count; +static unsigned long long *aperf_previous_count; +static unsigned long long *mperf_current_count; +static unsigned long long *aperf_current_count; + +/* valid flag for all CPUs. If a MSR read failed it will be zero */ +static int *is_valid; + +static int mperf_get_tsc(unsigned long long *tsc) +{ + int ret; + + ret = read_msr(base_cpu, MSR_TSC, tsc); + if (ret) + dprint("Reading TSC MSR failed, returning %llu\n", *tsc); + return ret; +} + +static int get_aperf_mperf(int cpu, unsigned long long *aval, + unsigned long long *mval) +{ + unsigned long low_a, high_a; + unsigned long low_m, high_m; + int ret; + + /* + * Running on the cpu from which we read the registers will + * prevent APERF/MPERF from going out of sync because of IPI + * latency introduced by read_msr()s. + */ + if (mperf_monitor.flags.per_cpu_schedule) { + if (bind_cpu(cpu)) + return 1; + } + + if (cpupower_cpu_info.caps & CPUPOWER_CAP_AMD_RDPRU) { + asm volatile(RDPRU + : "=a" (low_a), "=d" (high_a) + : "c" (RDPRU_ECX_APERF)); + asm volatile(RDPRU + : "=a" (low_m), "=d" (high_m) + : "c" (RDPRU_ECX_MPERF)); + + *aval = ((low_a) | (high_a) << 32); + *mval = ((low_m) | (high_m) << 32); + + return 0; + } + + ret = read_msr(cpu, MSR_APERF, aval); + ret |= read_msr(cpu, MSR_MPERF, mval); + + return ret; +} + +static int mperf_init_stats(unsigned int cpu) +{ + unsigned long long aval, mval; + int ret; + + ret = get_aperf_mperf(cpu, &aval, &mval); + aperf_previous_count[cpu] = aval; + mperf_previous_count[cpu] = mval; + is_valid[cpu] = !ret; + + return 0; +} + +static int mperf_measure_stats(unsigned int cpu) +{ + unsigned long long aval, mval; + int ret; + + ret = get_aperf_mperf(cpu, &aval, &mval); + aperf_current_count[cpu] = aval; + mperf_current_count[cpu] = mval; + is_valid[cpu] |= !ret; + + return 0; +} + +static int mperf_get_count_percent(unsigned int id, double *percent, + unsigned int cpu) +{ + unsigned long long aperf_diff, mperf_diff, tsc_diff; + unsigned long long timediff; + + if (!is_valid[cpu]) + return -1; + + if (id != C0 && id != Cx) + return -1; + + mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu]; + aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu]; + + if (max_freq_mode == MAX_FREQ_TSC_REF) { + tsc_diff = tsc_at_measure_end[cpu] - tsc_at_measure_start[cpu]; + *percent = 100.0 * mperf_diff / tsc_diff; + 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[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); + } else + return -1; + + if (id == Cx) + *percent = 100.0 - *percent; + + dprint("%s: previous: %llu - current: %llu - (%u)\n", + mperf_cstates[id].name, mperf_diff, aperf_diff, cpu); + dprint("%s: %f\n", mperf_cstates[id].name, *percent); + return 0; +} + +static int mperf_get_count_freq(unsigned int id, unsigned long long *count, + unsigned int cpu) +{ + unsigned long long aperf_diff, mperf_diff, time_diff, tsc_diff; + + if (id != AVG_FREQ) + return 1; + + if (!is_valid[cpu]) + return -1; + + mperf_diff = mperf_current_count[cpu] - mperf_previous_count[cpu]; + aperf_diff = aperf_current_count[cpu] - aperf_previous_count[cpu]; + + 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[cpu], time_end[cpu]); + max_frequency = tsc_diff / time_diff; + } + + *count = max_frequency * ((double)aperf_diff / mperf_diff); + dprint("%s: Average freq based on %s maximum frequency:\n", + mperf_cstates[id].name, + (max_freq_mode == MAX_FREQ_TSC_REF) ? "TSC calculated" : "sysfs read"); + dprint("max_frequency: %lu\n", max_frequency); + dprint("aperf_diff: %llu\n", aperf_diff); + dprint("mperf_diff: %llu\n", mperf_diff); + dprint("avg freq: %llu\n", *count); + return 0; +} + +static int mperf_start(void) +{ + int cpu; + + 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); + } + + return 0; +} + +static int mperf_stop(void) +{ + int cpu; + + for (cpu = 0; cpu < cpu_count; cpu++) { + clock_gettime(CLOCK_REALTIME, &time_end[cpu]); + mperf_get_tsc(&tsc_at_measure_end[cpu]); + mperf_measure_stats(cpu); + } + + return 0; +} + +/* + * Mperf register is defined to tick at P0 (maximum) frequency + * + * Instead of reading out P0 which can be tricky to read out from HW, + * we use TSC counter if it reliably ticks at P0/mperf frequency. + * + * Still try to fall back to: + * /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq + * on older Intel HW without invariant TSC feature. + * Or on AMD machines where TSC does not tick at P0 (do not exist yet, but + * it's still double checked (MSR_AMD_HWCR)). + * + * On these machines the user would still get useful mperf + * stats when acpi-cpufreq driver is loaded. + */ +static int init_maxfreq_mode(void) +{ + int ret; + unsigned long long hwcr; + unsigned long min; + + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC)) + goto use_sysfs; + + if (cpupower_cpu_info.vendor == X86_VENDOR_AMD || + cpupower_cpu_info.vendor == X86_VENDOR_HYGON) { + /* MSR_AMD_HWCR tells us whether TSC runs at P0/mperf + * freq. + * A test whether hwcr is accessable/available would be: + * (cpupower_cpu_info.family > 0x10 || + * cpupower_cpu_info.family == 0x10 && + * cpupower_cpu_info.model >= 0x2)) + * This should be the case for all aperf/mperf + * capable AMD machines and is therefore safe to test here. + * Compare with Linus kernel git commit: acf01734b1747b1ec4 + */ + ret = read_msr(0, MSR_AMD_HWCR, &hwcr); + /* + * If the MSR read failed, assume a Xen system that did + * not explicitly provide access to it and assume TSC works + */ + if (ret != 0) { + dprint("TSC read 0x%x failed - assume TSC working\n", + MSR_AMD_HWCR); + return 0; + } else if (1 & (hwcr >> 24)) { + max_freq_mode = MAX_FREQ_TSC_REF; + return 0; + } else { /* Use sysfs max frequency if available */ } + } else if (cpupower_cpu_info.vendor == X86_VENDOR_INTEL) { + /* + * On Intel we assume mperf (in C0) is ticking at same + * rate than TSC + */ + max_freq_mode = MAX_FREQ_TSC_REF; + return 0; + } +use_sysfs: + if (cpufreq_get_hardware_limits(0, &min, &max_frequency)) { + dprint("Cannot retrieve max freq from cpufreq kernel " + "subsystem\n"); + return -1; + } + max_freq_mode = MAX_FREQ_SYSFS; + max_frequency /= 1000; /* Default automatically to MHz value */ + return 0; +} + +/* + * This monitor provides: + * + * 1) Average frequency a CPU resided in + * This always works if the CPU has aperf/mperf capabilities + * + * 2) C0 and Cx (any sleep state) time a CPU resided in + * Works if mperf timer stops ticking in sleep states which + * seem to be the case on all current HW. + * Both is directly retrieved from HW registers and is independent + * from kernel statistics. + */ +struct cpuidle_monitor mperf_monitor; +struct cpuidle_monitor *mperf_register(void) +{ + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF)) + return NULL; + + if (init_maxfreq_mode()) + return NULL; + + if (cpupower_cpu_info.vendor == X86_VENDOR_AMD) + mperf_monitor.flags.per_cpu_schedule = 1; + + /* Free this at program termination */ + is_valid = calloc(cpu_count, sizeof(int)); + mperf_previous_count = calloc(cpu_count, sizeof(unsigned long long)); + aperf_previous_count = calloc(cpu_count, sizeof(unsigned long long)); + mperf_current_count = calloc(cpu_count, sizeof(unsigned long long)); + 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; +} + +void mperf_unregister(void) +{ + free(mperf_previous_count); + free(aperf_previous_count); + free(mperf_current_count); + free(aperf_current_count); + free(tsc_at_measure_start); + free(tsc_at_measure_end); + free(time_start); + free(time_end); + free(is_valid); +} + +struct cpuidle_monitor mperf_monitor = { + .name = "Mperf", + .hw_states_num = MPERF_CSTATE_COUNT, + .hw_states = mperf_cstates, + .start = mperf_start, + .stop = mperf_stop, + .do_register = mperf_register, + .unregister = mperf_unregister, + .flags.needs_root = 1, + .overflow_s = 922000000 /* 922337203 seconds TSC overflow + at 20GHz */ +}; +#endif /* #if defined(__i386__) || defined(__x86_64__) */ diff --git a/tools/power/cpupower/utils/idle_monitor/nhm_idle.c b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c new file mode 100644 index 000000000..6b1733782 --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/nhm_idle.c @@ -0,0 +1,215 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * Based on Len Brown's turbostat tool. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include +#include +#include +#include + +#include "helpers/helpers.h" +#include "idle_monitor/cpupower-monitor.h" + +#define MSR_PKG_C3_RESIDENCY 0x3F8 +#define MSR_PKG_C6_RESIDENCY 0x3F9 +#define MSR_CORE_C3_RESIDENCY 0x3FC +#define MSR_CORE_C6_RESIDENCY 0x3FD + +#define MSR_TSC 0x10 + +#define NHM_CSTATE_COUNT 4 + +enum intel_nhm_id { C3 = 0, C6, PC3, PC6, TSC = 0xFFFF }; + +static int nhm_get_count_percent(unsigned int self_id, double *percent, + unsigned int cpu); + +static cstate_t nhm_cstates[NHM_CSTATE_COUNT] = { + { + .name = "C3", + .desc = N_("Processor Core C3"), + .id = C3, + .range = RANGE_CORE, + .get_count_percent = nhm_get_count_percent, + }, + { + .name = "C6", + .desc = N_("Processor Core C6"), + .id = C6, + .range = RANGE_CORE, + .get_count_percent = nhm_get_count_percent, + }, + + { + .name = "PC3", + .desc = N_("Processor Package C3"), + .id = PC3, + .range = RANGE_PACKAGE, + .get_count_percent = nhm_get_count_percent, + }, + { + .name = "PC6", + .desc = N_("Processor Package C6"), + .id = PC6, + .range = RANGE_PACKAGE, + .get_count_percent = nhm_get_count_percent, + }, +}; + +static unsigned long long tsc_at_measure_start; +static unsigned long long tsc_at_measure_end; +static unsigned long long *previous_count[NHM_CSTATE_COUNT]; +static unsigned long long *current_count[NHM_CSTATE_COUNT]; +/* valid flag for all CPUs. If a MSR read failed it will be zero */ +static int *is_valid; + +static int nhm_get_count(enum intel_nhm_id id, unsigned long long *val, + unsigned int cpu) +{ + int msr; + + switch (id) { + case C3: + msr = MSR_CORE_C3_RESIDENCY; + break; + case C6: + msr = MSR_CORE_C6_RESIDENCY; + break; + case PC3: + msr = MSR_PKG_C3_RESIDENCY; + break; + case PC6: + msr = MSR_PKG_C6_RESIDENCY; + break; + case TSC: + msr = MSR_TSC; + break; + default: + return -1; + } + if (read_msr(cpu, msr, val)) + return -1; + + return 0; +} + +static int nhm_get_count_percent(unsigned int id, double *percent, + unsigned int cpu) +{ + *percent = 0.0; + + if (!is_valid[cpu]) + return -1; + + *percent = (100.0 * + (current_count[id][cpu] - previous_count[id][cpu])) / + (tsc_at_measure_end - tsc_at_measure_start); + + dprint("%s: previous: %llu - current: %llu - (%u)\n", + nhm_cstates[id].name, previous_count[id][cpu], + current_count[id][cpu], cpu); + + dprint("%s: tsc_diff: %llu - count_diff: %llu - percent: %2.f (%u)\n", + nhm_cstates[id].name, + (unsigned long long) tsc_at_measure_end - tsc_at_measure_start, + current_count[id][cpu] - previous_count[id][cpu], + *percent, cpu); + + return 0; +} + +static int nhm_start(void) +{ + int num, cpu; + unsigned long long dbg, val; + + nhm_get_count(TSC, &tsc_at_measure_start, base_cpu); + + for (num = 0; num < NHM_CSTATE_COUNT; num++) { + for (cpu = 0; cpu < cpu_count; cpu++) { + is_valid[cpu] = !nhm_get_count(num, &val, cpu); + previous_count[num][cpu] = val; + } + } + nhm_get_count(TSC, &dbg, base_cpu); + dprint("TSC diff: %llu\n", dbg - tsc_at_measure_start); + return 0; +} + +static int nhm_stop(void) +{ + unsigned long long val; + unsigned long long dbg; + int num, cpu; + + nhm_get_count(TSC, &tsc_at_measure_end, base_cpu); + + for (num = 0; num < NHM_CSTATE_COUNT; num++) { + for (cpu = 0; cpu < cpu_count; cpu++) { + is_valid[cpu] |= !nhm_get_count(num, &val, cpu); + current_count[num][cpu] = val; + } + } + nhm_get_count(TSC, &dbg, base_cpu); + dprint("TSC diff: %llu\n", dbg - tsc_at_measure_end); + + return 0; +} + +struct cpuidle_monitor intel_nhm_monitor; + +struct cpuidle_monitor *intel_nhm_register(void) +{ + int num; + + if (cpupower_cpu_info.vendor != X86_VENDOR_INTEL) + return NULL; + + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_INV_TSC)) + return NULL; + + if (!(cpupower_cpu_info.caps & CPUPOWER_CAP_APERF)) + return NULL; + + /* Free this at program termination */ + is_valid = calloc(cpu_count, sizeof(int)); + for (num = 0; num < NHM_CSTATE_COUNT; num++) { + previous_count[num] = calloc(cpu_count, + sizeof(unsigned long long)); + current_count[num] = calloc(cpu_count, + sizeof(unsigned long long)); + } + + intel_nhm_monitor.name_len = strlen(intel_nhm_monitor.name); + return &intel_nhm_monitor; +} + +void intel_nhm_unregister(void) +{ + int num; + + for (num = 0; num < NHM_CSTATE_COUNT; num++) { + free(previous_count[num]); + free(current_count[num]); + } + free(is_valid); +} + +struct cpuidle_monitor intel_nhm_monitor = { + .name = "Nehalem", + .hw_states_num = NHM_CSTATE_COUNT, + .hw_states = nhm_cstates, + .start = nhm_start, + .stop = nhm_stop, + .do_register = intel_nhm_register, + .unregister = intel_nhm_unregister, + .flags.needs_root = 1, + .overflow_s = 922000000 /* 922337203 seconds TSC overflow + at 20GHz */ +}; +#endif diff --git a/tools/power/cpupower/utils/idle_monitor/rapl_monitor.c b/tools/power/cpupower/utils/idle_monitor/rapl_monitor.c new file mode 100644 index 000000000..46153f129 --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/rapl_monitor.c @@ -0,0 +1,148 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2016 SUSE Software Solutions GmbH + * Thomas Renninger + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include +#include +#include +#include +#include + +#include + +#include "idle_monitor/cpupower-monitor.h" +#include "helpers/helpers.h" +#include "powercap.h" + +#define MAX_RAPL_ZONES 10 + +int rapl_zone_count; +cstate_t rapl_zones[MAX_RAPL_ZONES]; +struct powercap_zone *rapl_zones_pt[MAX_RAPL_ZONES] = { 0 }; + +unsigned long long rapl_zone_previous_count[MAX_RAPL_ZONES]; +unsigned long long rapl_zone_current_count[MAX_RAPL_ZONES]; +unsigned long long rapl_max_count; + +static int rapl_get_count_uj(unsigned int id, unsigned long long *count, + unsigned int cpu) +{ + if (rapl_zones_pt[id] == NULL) + /* error */ + return -1; + + *count = rapl_zone_current_count[id] - rapl_zone_previous_count[id]; + + return 0; +} + +static int powercap_count_zones(struct powercap_zone *zone) +{ + uint64_t val; + int uj; + + if (rapl_zone_count >= MAX_RAPL_ZONES) + return -1; + + if (!zone->has_energy_uj) + return 0; + + printf("%s\n", zone->sys_name); + uj = powercap_get_energy_uj(zone, &val); + printf("%d\n", uj); + + strncpy(rapl_zones[rapl_zone_count].name, zone->name, CSTATE_NAME_LEN - 1); + strcpy(rapl_zones[rapl_zone_count].desc, ""); + rapl_zones[rapl_zone_count].id = rapl_zone_count; + rapl_zones[rapl_zone_count].range = RANGE_MACHINE; + rapl_zones[rapl_zone_count].get_count = rapl_get_count_uj; + rapl_zones_pt[rapl_zone_count] = zone; + rapl_zone_count++; + + return 0; +} + +static int rapl_start(void) +{ + int i, ret; + uint64_t uj_val; + + for (i = 0; i < rapl_zone_count; i++) { + ret = powercap_get_energy_uj(rapl_zones_pt[i], &uj_val); + if (ret) + return ret; + rapl_zone_previous_count[i] = uj_val; + } + + return 0; +} + +static int rapl_stop(void) +{ + int i; + uint64_t uj_val; + + for (i = 0; i < rapl_zone_count; i++) { + int ret; + + ret = powercap_get_energy_uj(rapl_zones_pt[i], &uj_val); + if (ret) + return ret; + rapl_zone_current_count[i] = uj_val; + if (rapl_max_count < uj_val) + rapl_max_count = uj_val - rapl_zone_previous_count[i]; + } + return 0; +} + +struct cpuidle_monitor *rapl_register(void) +{ + struct powercap_zone *root_zone; + char line[MAX_LINE_LEN] = ""; + int ret, val; + + ret = powercap_get_driver(line, MAX_LINE_LEN); + if (ret < 0) { + dprint("No powercapping driver loaded\n"); + return NULL; + } + + dprint("Driver: %s\n", line); + ret = powercap_get_enabled(&val); + if (ret < 0) + return NULL; + if (!val) { + dprint("Powercapping is disabled\n"); + return NULL; + } + + dprint("Powercap domain hierarchy:\n\n"); + root_zone = powercap_init_zones(); + + if (root_zone == NULL) { + dprint("No powercap info found\n"); + return NULL; + } + + powercap_walk_zones(root_zone, powercap_count_zones); + rapl_monitor.hw_states_num = rapl_zone_count; + + return &rapl_monitor; +} + +struct cpuidle_monitor rapl_monitor = { + .name = "RAPL", + .hw_states = rapl_zones, + .hw_states_num = 0, + .start = rapl_start, + .stop = rapl_stop, + .do_register = rapl_register, + .flags.needs_root = 0, + .overflow_s = 60 * 60 * 24 * 100, /* To be implemented */ +}; + +#endif diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c new file mode 100644 index 000000000..5969b88a8 --- /dev/null +++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c @@ -0,0 +1,199 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2010,2011 Thomas Renninger , Novell Inc. + * + * Based on Len Brown's turbostat tool. + */ + +#if defined(__i386__) || defined(__x86_64__) + +#include +#include +#include +#include + +#include "helpers/helpers.h" +#include "idle_monitor/cpupower-monitor.h" + +#define MSR_PKG_C2_RESIDENCY 0x60D +#define MSR_PKG_C7_RESIDENCY 0x3FA +#define MSR_CORE_C7_RESIDENCY 0x3FE + +#define MSR_TSC 0x10 + +enum intel_snb_id { C7 = 0, PC2, PC7, SNB_CSTATE_COUNT, TSC = 0xFFFF }; + +static int snb_get_count_percent(unsigned int self_id, double *percent, + unsigned int cpu); + +static cstate_t snb_cstates[SNB_CSTATE_COUNT] = { + { + .name = "C7", + .desc = N_("Processor Core C7"), + .id = C7, + .range = RANGE_CORE, + .get_count_percent = snb_get_count_percent, + }, + { + .name = "PC2", + .desc = N_("Processor Package C2"), + .id = PC2, + .range = RANGE_PACKAGE, + .get_count_percent = snb_get_count_percent, + }, + { + .name = "PC7", + .desc = N_("Processor Package C7"), + .id = PC7, + .range = RANGE_PACKAGE, + .get_count_percent = snb_get_count_percent, + }, +}; + +static unsigned long long tsc_at_measure_start; +static unsigned long long tsc_at_measure_end; +static unsigned long long *previous_count[SNB_CSTATE_COUNT]; +static unsigned long long *current_count[SNB_CSTATE_COUNT]; +/* valid flag for all CPUs. If a MSR read failed it will be zero */ +static int *is_valid; + +static int snb_get_count(enum intel_snb_id id, unsigned long long *val, + unsigned int cpu) +{ + int msr; + + switch (id) { + case C7: + msr = MSR_CORE_C7_RESIDENCY; + break; + case PC2: + msr = MSR_PKG_C2_RESIDENCY; + break; + case PC7: + msr = MSR_PKG_C7_RESIDENCY; + break; + case TSC: + msr = MSR_TSC; + break; + default: + return -1; + } + if (read_msr(cpu, msr, val)) + return -1; + return 0; +} + +static int snb_get_count_percent(unsigned int id, double *percent, + unsigned int cpu) +{ + *percent = 0.0; + + if (!is_valid[cpu]) + return -1; + + *percent = (100.0 * + (current_count[id][cpu] - previous_count[id][cpu])) / + (tsc_at_measure_end - tsc_at_measure_start); + + dprint("%s: previous: %llu - current: %llu - (%u)\n", + snb_cstates[id].name, previous_count[id][cpu], + current_count[id][cpu], cpu); + + dprint("%s: tsc_diff: %llu - count_diff: %llu - percent: %2.f (%u)\n", + snb_cstates[id].name, + (unsigned long long) tsc_at_measure_end - tsc_at_measure_start, + current_count[id][cpu] - previous_count[id][cpu], + *percent, cpu); + + return 0; +} + +static int snb_start(void) +{ + int num, cpu; + unsigned long long val; + + for (num = 0; num < SNB_CSTATE_COUNT; num++) { + for (cpu = 0; cpu < cpu_count; cpu++) { + is_valid[cpu] = !snb_get_count(num, &val, cpu); + previous_count[num][cpu] = val; + } + } + snb_get_count(TSC, &tsc_at_measure_start, base_cpu); + return 0; +} + +static int snb_stop(void) +{ + unsigned long long val; + int num, cpu; + + snb_get_count(TSC, &tsc_at_measure_end, base_cpu); + + for (num = 0; num < SNB_CSTATE_COUNT; num++) { + for (cpu = 0; cpu < cpu_count; cpu++) { + is_valid[cpu] |= !snb_get_count(num, &val, cpu); + current_count[num][cpu] = val; + } + } + return 0; +} + +struct cpuidle_monitor intel_snb_monitor; + +static struct cpuidle_monitor *snb_register(void) +{ + int num; + + if (cpupower_cpu_info.vendor != X86_VENDOR_INTEL + || cpupower_cpu_info.family != 6) + return NULL; + + switch (cpupower_cpu_info.model) { + case 0x2A: /* SNB */ + case 0x2D: /* SNB Xeon */ + case 0x3A: /* IVB */ + case 0x3E: /* IVB Xeon */ + case 0x3C: /* HSW */ + case 0x3F: /* HSW */ + case 0x45: /* HSW */ + case 0x46: /* HSW */ + break; + default: + return NULL; + } + + is_valid = calloc(cpu_count, sizeof(int)); + for (num = 0; num < SNB_CSTATE_COUNT; num++) { + previous_count[num] = calloc(cpu_count, + sizeof(unsigned long long)); + current_count[num] = calloc(cpu_count, + sizeof(unsigned long long)); + } + intel_snb_monitor.name_len = strlen(intel_snb_monitor.name); + return &intel_snb_monitor; +} + +void snb_unregister(void) +{ + int num; + free(is_valid); + for (num = 0; num < SNB_CSTATE_COUNT; num++) { + free(previous_count[num]); + free(current_count[num]); + } +} + +struct cpuidle_monitor intel_snb_monitor = { + .name = "SandyBridge", + .hw_states = snb_cstates, + .hw_states_num = SNB_CSTATE_COUNT, + .start = snb_start, + .stop = snb_stop, + .do_register = snb_register, + .unregister = snb_unregister, + .flags.needs_root = 1, + .overflow_s = 922000000 /* 922337203 seconds TSC overflow + at 20GHz */ +}; +#endif /* defined(__i386__) || defined(__x86_64__) */ diff --git a/tools/power/cpupower/utils/powercap-info.c b/tools/power/cpupower/utils/powercap-info.c new file mode 100644 index 000000000..88a5edb76 --- /dev/null +++ b/tools/power/cpupower/utils/powercap-info.c @@ -0,0 +1,115 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * (C) 2016 SUSE Software Solutions GmbH + * Thomas Renninger + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "powercap.h" +#include "helpers/helpers.h" + +int powercap_show_all; + +static struct option info_opts[] = { + { "all", no_argument, NULL, 'a'}, + { }, +}; + +static int powercap_print_one_zone(struct powercap_zone *zone) +{ + int mode, i, ret = 0; + char pr_prefix[1024] = ""; + + for (i = 0; i < zone->tree_depth && i < POWERCAP_MAX_TREE_DEPTH; i++) + strcat(pr_prefix, "\t"); + + printf("%sZone: %s", pr_prefix, zone->name); + ret = powercap_zone_get_enabled(zone, &mode); + if (ret < 0) + return ret; + printf(" (%s)\n", mode ? "enabled" : "disabled"); + + if (zone->has_power_uw) + printf(_("%sPower can be monitored in micro Watts\n"), + pr_prefix); + + if (zone->has_energy_uj) + printf(_("%sPower can be monitored in micro Jules\n"), + pr_prefix); + + printf("\n"); + + return ret; +} + +static int powercap_show(void) +{ + struct powercap_zone *root_zone; + char line[MAX_LINE_LEN] = ""; + int ret, val; + + ret = powercap_get_driver(line, MAX_LINE_LEN); + if (ret < 0) { + printf(_("No powercapping driver loaded\n")); + return ret; + } + + printf("Driver: %s\n", line); + ret = powercap_get_enabled(&val); + if (ret < 0) + return ret; + if (!val) { + printf(_("Powercapping is disabled\n")); + return -1; + } + + printf(_("Powercap domain hierarchy:\n\n")); + root_zone = powercap_init_zones(); + + if (root_zone == NULL) { + printf(_("No powercap info found\n")); + return 1; + } + + powercap_walk_zones(root_zone, powercap_print_one_zone); + + return 0; +} + +int cmd_cap_set(int argc, char **argv) +{ + return 0; +}; +int cmd_cap_info(int argc, char **argv) +{ + int ret = 0, cont = 1; + + do { + ret = getopt_long(argc, argv, "a", info_opts, NULL); + switch (ret) { + case '?': + cont = 0; + break; + case -1: + cont = 0; + break; + case 'a': + powercap_show_all = 1; + break; + default: + fprintf(stderr, _("invalid or unknown argument\n")); + return EXIT_FAILURE; + } + } while (cont); + + powercap_show(); + return 0; +} diff --git a/tools/power/cpupower/utils/version-gen.sh b/tools/power/cpupower/utils/version-gen.sh new file mode 100755 index 000000000..c70de2eab --- /dev/null +++ b/tools/power/cpupower/utils/version-gen.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# SPDX-License-Identifier: GPL-2.0 +# +# Script which prints out the version to use for building cpupowerutils. +# Must be called from tools/power/cpupower/ +# +# Heavily based on tools/perf/util/PERF-VERSION-GEN . + +LF=' +' + +# First check if there is a .git to get the version from git describe +# otherwise try to get the version from the kernel makefile +if test -d ../../../.git -o -f ../../../.git && + VN=$(git describe --abbrev=4 HEAD 2>/dev/null) && + case "$VN" in + *$LF*) (exit 1) ;; + v[0-9]*) + git update-index -q --refresh + test -z "$(git diff-index --name-only HEAD --)" || + VN="$VN-dirty" ;; + esac +then + VN=$(echo "$VN" | sed -e 's/-/./g'); +else + eval $(grep '^VERSION[[:space:]]*=' ../../../Makefile|tr -d ' ') + eval $(grep '^PATCHLEVEL[[:space:]]*=' ../../../Makefile|tr -d ' ') + eval $(grep '^SUBLEVEL[[:space:]]*=' ../../../Makefile|tr -d ' ') + eval $(grep '^EXTRAVERSION[[:space:]]*=' ../../../Makefile|tr -d ' ') + + VN="${VERSION}.${PATCHLEVEL}.${SUBLEVEL}${EXTRAVERSION}" +fi + +VN=$(expr "$VN" : v*'\(.*\)') + +echo $VN -- cgit v1.3.1