diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-29 16:03:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-03-29 16:03:12 -0700 |
commit | 1c036588772d01655d851f75dffc27c971e072e2 (patch) | |
tree | ee35c5ecc726d4fdb77c462cccbe499d1c3292b7 | |
parent | a6f707b601c3f85d4b816ea08a757ea1af4f1cc0 (diff) | |
parent | f16603386b38c28979f4df1cafdc2fe73fa87d37 (diff) | |
download | kernel-common-1c036588772d01655d851f75dffc27c971e072e2.tar.gz kernel-common-1c036588772d01655d851f75dffc27c971e072e2.tar.bz2 kernel-common-1c036588772d01655d851f75dffc27c971e072e2.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/cpupowerutils
Pull cpupower updates from Dominik Brodowski.
* git://git.kernel.org/pub/scm/linux/kernel/git/brodo/cpupowerutils:
cpupower tools: add install target to the debug tools' makefiles
cpupower tools: allow to build debug tools in a separate directory too
cpupower: Fix broken mask values
cpupower tool: allow to build in a separate directory
cpupower tool: makefile: simplify the recipe used to generate cpupower.pot target
cpupower tool: remove use of undefined variables from the clean target of the top makefile
cpupower: Fix linking with --as-needed
cpupower: Remove unneeded code and by that fix a memleak
cpupower: Fix number of idle states
cpupower: Unify cpupower-frequency-* manpages
cpupower: Add cpupower-idle-info manpage
cpupower: AMD fam14h/Ontario monitor can also be used by fam12h cpus
cpupower: Better interface for accessing AMD pci registers
-rw-r--r-- | tools/power/cpupower/Makefile | 93 | ||||
-rw-r--r-- | tools/power/cpupower/bench/Makefile | 23 | ||||
-rw-r--r-- | tools/power/cpupower/debug/i386/Makefile | 40 | ||||
-rw-r--r-- | tools/power/cpupower/debug/x86_64/Makefile | 26 | ||||
-rw-r--r-- | tools/power/cpupower/man/cpupower-frequency-info.1 | 4 | ||||
-rw-r--r-- | tools/power/cpupower/man/cpupower-frequency-set.1 | 4 | ||||
-rw-r--r-- | tools/power/cpupower/man/cpupower-idle-info.1 | 90 | ||||
-rw-r--r-- | tools/power/cpupower/man/cpupower-monitor.1 | 2 | ||||
-rw-r--r-- | tools/power/cpupower/utils/cpuidle-info.c | 12 | ||||
-rw-r--r-- | tools/power/cpupower/utils/helpers/amd.c | 4 | ||||
-rw-r--r-- | tools/power/cpupower/utils/helpers/helpers.h | 11 | ||||
-rw-r--r-- | tools/power/cpupower/utils/helpers/pci.c | 35 | ||||
-rw-r--r-- | tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c | 25 |
13 files changed, 259 insertions, 110 deletions
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile index e8a03aceceb1..a93e06cfcc2a 100644 --- a/tools/power/cpupower/Makefile +++ b/tools/power/cpupower/Makefile @@ -19,6 +19,16 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +OUTPUT=./ +ifeq ("$(origin O)", "command line") + OUTPUT := $(O)/ +endif + +ifneq ($(OUTPUT),) +# check that the output directory actually exists +OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd) +$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) +endif # --- CONFIGURATION BEGIN --- @@ -87,6 +97,7 @@ AR = $(CROSS)ar STRIP = $(CROSS)strip RANLIB = $(CROSS)ranlib HOSTCC = gcc +MKDIR = mkdir # Now we set up the build system @@ -95,7 +106,7 @@ HOSTCC = gcc # set up PWD so that older versions of make will work with our build. PWD = $(shell pwd) -GMO_FILES = ${shell for HLANG in ${LANGUAGES}; do echo po/$$HLANG.gmo; done;} +GMO_FILES = ${shell for HLANG in ${LANGUAGES}; do echo $(OUTPUT)po/$$HLANG.gmo; done;} export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS @@ -122,15 +133,18 @@ UTIL_OBJS = utils/helpers/amd.o utils/helpers/topology.o utils/helpers/msr.o \ utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \ utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-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 -UTIL_SRC := $(UTIL_OBJS:.o=.c) - LIB_HEADERS = lib/cpufreq.h lib/sysfs.h LIB_SRC = lib/cpufreq.c lib/sysfs.c LIB_OBJS = lib/cpufreq.o lib/sysfs.o +LIB_OBJS := $(addprefix $(OUTPUT),$(LIB_OBJS)) CFLAGS += -pipe @@ -168,83 +182,90 @@ endif # the actual make rules -all: libcpupower cpupower $(COMPILE_NLS) $(COMPILE_BENCH) +all: libcpupower $(OUTPUT)cpupower $(COMPILE_NLS) $(COMPILE_BENCH) -lib/%.o: $(LIB_SRC) $(LIB_HEADERS) +$(OUTPUT)lib/%.o: $(LIB_SRC) $(LIB_HEADERS) $(ECHO) " CC " $@ $(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c -libcpupower.so.$(LIB_MAJ): $(LIB_OBJS) +$(OUTPUT)libcpupower.so.$(LIB_MAJ): $(LIB_OBJS) $(ECHO) " LD " $@ $(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \ -Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS) - @ln -sf $@ libcpupower.so - @ln -sf $@ libcpupower.so.$(LIB_MIN) + @ln -sf $(@F) $(OUTPUT)libcpupower.so + @ln -sf $(@F) $(OUTPUT)libcpupower.so.$(LIB_MIN) -libcpupower: libcpupower.so.$(LIB_MAJ) +libcpupower: $(OUTPUT)libcpupower.so.$(LIB_MAJ) # 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) -.c.o: +$(OUTPUT)%.o: %.c $(ECHO) " CC " $@ $(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c -cpupower: $(UTIL_OBJS) libcpupower.so.$(LIB_MAJ) +$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ) $(ECHO) " CC " $@ - $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) -lcpupower -lrt -lpci -L. -o $@ $(UTIL_OBJS) + $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@ $(QUIET) $(STRIPCMD) $@ -po/$(PACKAGE).pot: $(UTIL_SRC) +$(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC) $(ECHO) " GETTEXT " $@ $(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \ - --keyword=_ --keyword=N_ $(UTIL_SRC) && \ - test -f $(PACKAGE).po && \ - mv -f $(PACKAGE).po po/$(PACKAGE).pot + --keyword=_ --keyword=N_ $(UTIL_SRC) -p $(@D) -o $(@F) -po/%.gmo: po/%.po +$(OUTPUT)po/%.gmo: po/%.po $(ECHO) " MSGFMT " $@ $(QUIET) msgfmt -o $@ po/$*.po create-gmo: ${GMO_FILES} -update-po: po/$(PACKAGE).pot +update-po: $(OUTPUT)po/$(PACKAGE).pot $(ECHO) " MSGMRG " $@ $(QUIET) @for HLANG in $(LANGUAGES); do \ echo -n "Updating $$HLANG "; \ - if msgmerge po/$$HLANG.po po/$(PACKAGE).pot -o \ - po/$$HLANG.new.po; then \ - mv -f po/$$HLANG.new.po po/$$HLANG.po; \ + 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 po/$$HLANG.new.po; \ + rm -f $(OUTPUT)po/$$HLANG.new.po; \ fi; \ done; -compile-bench: libcpupower.so.$(LIB_MAJ) - @V=$(V) confdir=$(confdir) $(MAKE) -C bench +compile-bench: $(OUTPUT)libcpupower.so.$(LIB_MAJ) + @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 . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ + -find $(OUTPUT) \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ | xargs rm -f - -rm -f $(UTIL_BINS) - -rm -f $(IDLE_OBJS) - -rm -f cpupower - -rm -f libcpupower.so* - -rm -rf po/*.gmo po/*.pot - $(MAKE) -C bench clean + -rm -f $(OUTPUT)cpupower + -rm -f $(OUTPUT)libcpupower.so* + -rm -rf $(OUTPUT)po/*.{gmo,pot} + $(MAKE) -C bench O=$(OUTPUT) clean install-lib: $(INSTALL) -d $(DESTDIR)${libdir} - $(CP) libcpupower.so* $(DESTDIR)${libdir}/ + $(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/ $(INSTALL) -d $(DESTDIR)${includedir} $(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h install-tools: $(INSTALL) -d $(DESTDIR)${bindir} - $(INSTALL_PROGRAM) cpupower $(DESTDIR)${bindir} + $(INSTALL_PROGRAM) $(OUTPUT)cpupower $(DESTDIR)${bindir} install-man: $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1 @@ -257,13 +278,13 @@ install-man: install-gmo: $(INSTALL) -d $(DESTDIR)${localedir} for HLANG in $(LANGUAGES); do \ - echo '$(INSTALL_DATA) -D po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \ - $(INSTALL_DATA) -D po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \ + 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: @#DESTDIR must be set from outside to survive - @sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench install + @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) diff --git a/tools/power/cpupower/bench/Makefile b/tools/power/cpupower/bench/Makefile index 2b67606fc3e3..7ec7021a29cd 100644 --- a/tools/power/cpupower/bench/Makefile +++ b/tools/power/cpupower/bench/Makefile @@ -1,29 +1,36 @@ -LIBS = -L../ -lm -lcpupower +OUTPUT := ./ +ifeq ("$(origin O)", "command line") +ifneq ($(O),) + OUTPUT := $(O)/ +endif +endif -OBJS = main.o parse.o system.o benchmark.o +LIBS = -L../ -L$(OUTPUT) -lm -lcpupower + +OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\" -%.o : %.c +$(OUTPUT)%.o : %.c $(ECHO) " CC " $@ $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ -cpufreq-bench: $(OBJS) +$(OUTPUT)cpufreq-bench: $(OBJS) $(ECHO) " CC " $@ $(QUIET) $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS) -all: cpufreq-bench +all: $(OUTPUT)cpufreq-bench install: mkdir -p $(DESTDIR)/$(sbindir) mkdir -p $(DESTDIR)/$(bindir) mkdir -p $(DESTDIR)/$(docdir) mkdir -p $(DESTDIR)/$(confdir) - install -m 755 cpufreq-bench $(DESTDIR)/$(sbindir)/cpufreq-bench + 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 *.o - rm -f cpufreq-bench + rm -f $(OUTPUT)*.o + rm -f $(OUTPUT)cpufreq-bench diff --git a/tools/power/cpupower/debug/i386/Makefile b/tools/power/cpupower/debug/i386/Makefile index d08cc1ead9bc..3ba158f0e287 100644 --- a/tools/power/cpupower/debug/i386/Makefile +++ b/tools/power/cpupower/debug/i386/Makefile @@ -1,20 +1,38 @@ +OUTPUT=./ +ifeq ("$(origin O)", "command line") + OUTPUT := $(O)/ +endif + +DESTDIR = +bindir = /usr/bin + +INSTALL = /usr/bin/install + + default: all -centrino-decode: centrino-decode.c - $(CC) $(CFLAGS) -o centrino-decode centrino-decode.c +$(OUTPUT)centrino-decode: centrino-decode.c + $(CC) $(CFLAGS) -o $@ centrino-decode.c -dump_psb: dump_psb.c - $(CC) $(CFLAGS) -o dump_psb dump_psb.c +$(OUTPUT)dump_psb: dump_psb.c + $(CC) $(CFLAGS) -o $@ dump_psb.c -intel_gsic: intel_gsic.c - $(CC) $(CFLAGS) -o intel_gsic -llrmi intel_gsic.c +$(OUTPUT)intel_gsic: intel_gsic.c + $(CC) $(CFLAGS) -o $@ -llrmi intel_gsic.c -powernow-k8-decode: powernow-k8-decode.c - $(CC) $(CFLAGS) -o powernow-k8-decode powernow-k8-decode.c +$(OUTPUT)powernow-k8-decode: powernow-k8-decode.c + $(CC) $(CFLAGS) -o $@ powernow-k8-decode.c -all: centrino-decode dump_psb intel_gsic powernow-k8-decode +all: $(OUTPUT)centrino-decode $(OUTPUT)dump_psb $(OUTPUT)intel_gsic $(OUTPUT)powernow-k8-decode clean: - rm -rf centrino-decode dump_psb intel_gsic powernow-k8-decode + rm -rf $(OUTPUT){centrino-decode,dump_psb,intel_gsic,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 +.PHONY: all default clean install diff --git a/tools/power/cpupower/debug/x86_64/Makefile b/tools/power/cpupower/debug/x86_64/Makefile index 3326217dd311..1c5214526716 100644 --- a/tools/power/cpupower/debug/x86_64/Makefile +++ b/tools/power/cpupower/debug/x86_64/Makefile @@ -1,14 +1,30 @@ +OUTPUT=./ +ifeq ("$(origin O)", "command line") + OUTPUT := $(O)/ +endif + +DESTDIR = +bindir = /usr/bin + +INSTALL = /usr/bin/install + + default: all -centrino-decode: ../i386/centrino-decode.c +$(OUTPUT)centrino-decode: ../i386/centrino-decode.c $(CC) $(CFLAGS) -o $@ $< -powernow-k8-decode: ../i386/powernow-k8-decode.c +$(OUTPUT)powernow-k8-decode: ../i386/powernow-k8-decode.c $(CC) $(CFLAGS) -o $@ $< -all: centrino-decode powernow-k8-decode +all: $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode clean: - rm -rf centrino-decode powernow-k8-decode + 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 +.PHONY: all default clean install diff --git a/tools/power/cpupower/man/cpupower-frequency-info.1 b/tools/power/cpupower/man/cpupower-frequency-info.1 index bb60a8d1e45a..4a1918ea8f9c 100644 --- a/tools/power/cpupower/man/cpupower-frequency-info.1 +++ b/tools/power/cpupower/man/cpupower-frequency-info.1 @@ -1,4 +1,4 @@ -.TH "cpupower-frequency-info" "1" "0.1" "Mattia Dongili" "" +.TH "CPUPOWER\-FREQUENCY\-INFO" "1" "0.1" "" "cpupower Manual" .SH "NAME" .LP cpupower frequency\-info \- Utility to retrieve cpufreq kernel information @@ -50,8 +50,6 @@ Prints out information like provided by the /proc/cpufreq interface in 2.4. and \fB\-m\fR \fB\-\-human\fR human\-readable output for the \-f, \-w, \-s and \-y parameters. .TP -\fB\-h\fR \fB\-\-help\fR -Prints out the help screen. .SH "REMARKS" .LP By default only values of core zero are displayed. How to display settings of diff --git a/tools/power/cpupower/man/cpupower-frequency-set.1 b/tools/power/cpupower/man/cpupower-frequency-set.1 index 685f469093ad..3eacc8d03d1a 100644 --- a/tools/power/cpupower/man/cpupower-frequency-set.1 +++ b/tools/power/cpupower/man/cpupower-frequency-set.1 @@ -1,4 +1,4 @@ -.TH "cpupower-freqency-set" "1" "0.1" "Mattia Dongili" "" +.TH "CPUPOWER\-FREQUENCY\-SET" "1" "0.1" "" "cpupower Manual" .SH "NAME" .LP cpupower frequency\-set \- A small tool which allows to modify cpufreq settings. @@ -26,8 +26,6 @@ specific frequency to be set. Requires userspace governor to be available and lo \fB\-r\fR \fB\-\-related\fR modify all hardware-related CPUs at the same time .TP -\fB\-h\fR \fB\-\-help\fR -Prints out the help screen. .SH "REMARKS" .LP By default values are applied on all cores. How to modify single core 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 000000000000..4178effd9e99 --- /dev/null +++ b/tools/power/cpupower/man/cpupower-idle-info.1 @@ -0,0 +1,90 @@ +.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\-f\fR \fB\-\-silent\fR +Only print a summary of all available C-states in the system. +.TP +\fB\-e\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 +http://www.acpi.info/spec.htm +.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 <trenn@suse.de> +.fi +.SH "SEE ALSO" +.LP +cpupower(1), cpupower\-monitor(1), cpupower\-info(1), cpupower\-set(1) diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1 index d5cfa265c3d3..1141c2073719 100644 --- a/tools/power/cpupower/man/cpupower-monitor.1 +++ b/tools/power/cpupower/man/cpupower-monitor.1 @@ -107,7 +107,7 @@ 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. -.SS "Ontario" "Liano" +.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. diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c index b028267c1376..8145af5f93a6 100644 --- a/tools/power/cpupower/utils/cpuidle-info.c +++ b/tools/power/cpupower/utils/cpuidle-info.c @@ -35,17 +35,9 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose) printf(_("CPU %u: Can't read idle state info\n"), cpu); return; } - tmp = sysfs_get_idlestate_name(cpu, idlestates - 1); - if (!tmp) { - printf(_("Could not determine max idle state %u\n"), - idlestates - 1); - return; - } - printf(_("Number of idle states: %d\n"), idlestates); - printf(_("Available idle states:")); - for (idlestate = 1; idlestate < idlestates; idlestate++) { + for (idlestate = 0; idlestate < idlestates; idlestate++) { tmp = sysfs_get_idlestate_name(cpu, idlestate); if (!tmp) continue; @@ -57,7 +49,7 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose) if (!verbose) return; - for (idlestate = 1; idlestate < idlestates; idlestate++) { + for (idlestate = 0; idlestate < idlestates; idlestate++) { tmp = sysfs_get_idlestate_name(cpu, idlestate); if (!tmp) continue; diff --git a/tools/power/cpupower/utils/helpers/amd.c b/tools/power/cpupower/utils/helpers/amd.c index 87d5605bdda8..6437ef39aeea 100644 --- a/tools/power/cpupower/utils/helpers/amd.c +++ b/tools/power/cpupower/utils/helpers/amd.c @@ -112,14 +112,12 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, int amd_pci_get_num_boost_states(int *active, int *states) { struct pci_access *pci_acc; - int vendor_id = 0x1022; - int boost_dev_ids[4] = {0x1204, 0x1604, 0x1704, 0}; struct pci_dev *device; uint8_t val = 0; *active = *states = 0; - device = pci_acc_init(&pci_acc, vendor_id, boost_dev_ids); + device = pci_slot_func_init(&pci_acc, 0x18, 4); if (device == NULL) return -ENODEV; diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h index 2747e738efb0..2eb584cf2f55 100644 --- a/tools/power/cpupower/utils/helpers/helpers.h +++ b/tools/power/cpupower/utils/helpers/helpers.h @@ -66,8 +66,8 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, #define CPUPOWER_CAP_AMD_CBP 0x00000004 #define CPUPOWER_CAP_PERF_BIAS 0x00000008 #define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010 -#define CPUPOWER_CAP_IS_SNB 0x00000011 -#define CPUPOWER_CAP_INTEL_IDA 0x00000012 +#define CPUPOWER_CAP_IS_SNB 0x00000020 +#define CPUPOWER_CAP_INTEL_IDA 0x00000040 #define MAX_HW_PSTATES 10 @@ -132,8 +132,11 @@ extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu); /* 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 vendor_id, - int *dev_ids); +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 ****************************/ diff --git a/tools/power/cpupower/utils/helpers/pci.c b/tools/power/cpupower/utils/helpers/pci.c index cd2eb6fe41c4..9690798e6446 100644 --- a/tools/power/cpupower/utils/helpers/pci.c +++ b/tools/power/cpupower/utils/helpers/pci.c @@ -10,19 +10,24 @@ * **pacc : if a valid pci_dev is returned * *pacc must be passed to pci_acc_cleanup to free it * - * vendor_id : the pci vendor id matching the pci device to access - * dev_ids : device ids matching the pci device to access + * 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 vendor_id, - int *dev_ids) +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 = { -1, -1, -1, -1, vendor_id, 0}; + struct pci_filter filter_nb_link = { domain, bus, slot, func, + vendor, dev }; struct pci_dev *device; - unsigned int i; *pacc = pci_alloc(); if (*pacc == NULL) @@ -31,14 +36,20 @@ struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id, pci_init(*pacc); pci_scan_bus(*pacc); - for (i = 0; dev_ids[i] != 0; i++) { - filter_nb_link.device = dev_ids[i]; - for (device = (*pacc)->devices; device; device = device->next) { - if (pci_filter_match(&filter_nb_link, device)) - return device; - } + 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/idle_monitor/amd_fam14h_idle.c b/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c index 202e555988be..2116df9ad832 100644 --- a/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c +++ b/tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c @@ -20,8 +20,6 @@ #include "idle_monitor/cpupower-monitor.h" #include "helpers/helpers.h" -/******** PCI parts could go into own file and get shared ***************/ - #define PCI_NON_PC0_OFFSET 0xb0 #define PCI_PC1_OFFSET 0xb4 #define PCI_PC6_OFFSET 0xb8 @@ -82,10 +80,7 @@ static cstate_t amd_fam14h_cstates[AMD_FAM14H_STATE_NUM] = { }; static struct pci_access *pci_acc; -static int pci_vendor_id = 0x1022; -static int pci_dev_ids[2] = {0x1716, 0}; static struct pci_dev *amd_fam14h_pci_dev; - static int nbp1_entered; struct timespec start_time; @@ -286,13 +281,13 @@ struct cpuidle_monitor *amd_fam14h_register(void) if (cpupower_cpu_info.vendor != X86_VENDOR_AMD) return NULL; - if (cpupower_cpu_info.family == 0x14) { - if (cpu_count <= 0 || cpu_count > 2) { - fprintf(stderr, "AMD fam14h: Invalid cpu count: %d\n", - cpu_count); - return NULL; - } - } else + 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 */ @@ -303,7 +298,9 @@ struct cpuidle_monitor *amd_fam14h_register(void) sizeof(unsigned long long)); } - amd_fam14h_pci_dev = pci_acc_init(&pci_acc, pci_vendor_id, pci_dev_ids); + /* 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; @@ -325,7 +322,7 @@ static void amd_fam14h_unregister(void) } struct cpuidle_monitor amd_fam14h_monitor = { - .name = "Ontario", + .name = "", .hw_states = amd_fam14h_cstates, .hw_states_num = AMD_FAM14H_STATE_NUM, .start = amd_fam14h_start, |