Commit 1c036588 authored by Linus Torvalds's avatar Linus Torvalds

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
parents a6f707b6 f1660338
...@@ -19,6 +19,16 @@ ...@@ -19,6 +19,16 @@
# along with this program; if not, write to the Free Software # along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # 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 --- # --- CONFIGURATION BEGIN ---
...@@ -87,6 +97,7 @@ AR = $(CROSS)ar ...@@ -87,6 +97,7 @@ AR = $(CROSS)ar
STRIP = $(CROSS)strip STRIP = $(CROSS)strip
RANLIB = $(CROSS)ranlib RANLIB = $(CROSS)ranlib
HOSTCC = gcc HOSTCC = gcc
MKDIR = mkdir
# Now we set up the build system # Now we set up the build system
...@@ -95,7 +106,7 @@ HOSTCC = gcc ...@@ -95,7 +106,7 @@ HOSTCC = gcc
# set up PWD so that older versions of make will work with our build. # set up PWD so that older versions of make will work with our build.
PWD = $(shell pwd) 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 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 \ ...@@ -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.o utils/cpufreq-info.o utils/cpufreq-set.o \
utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o
UTIL_SRC := $(UTIL_OBJS:.o=.c)
UTIL_OBJS := $(addprefix $(OUTPUT),$(UTIL_OBJS))
UTIL_HEADERS = utils/helpers/helpers.h utils/idle_monitor/cpupower-monitor.h \ UTIL_HEADERS = utils/helpers/helpers.h utils/idle_monitor/cpupower-monitor.h \
utils/helpers/bitmask.h \ utils/helpers/bitmask.h \
utils/idle_monitor/idle_monitors.h utils/idle_monitor/idle_monitors.def 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_HEADERS = lib/cpufreq.h lib/sysfs.h
LIB_SRC = lib/cpufreq.c lib/sysfs.c LIB_SRC = lib/cpufreq.c lib/sysfs.c
LIB_OBJS = lib/cpufreq.o lib/sysfs.o LIB_OBJS = lib/cpufreq.o lib/sysfs.o
LIB_OBJS := $(addprefix $(OUTPUT),$(LIB_OBJS))
CFLAGS += -pipe CFLAGS += -pipe
...@@ -168,83 +182,90 @@ endif ...@@ -168,83 +182,90 @@ endif
# the actual make rules # 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 " $@ $(ECHO) " CC " $@
$(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c $(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c
libcpupower.so.$(LIB_MAJ): $(LIB_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ): $(LIB_OBJS)
$(ECHO) " LD " $@ $(ECHO) " LD " $@
$(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \ $(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \
-Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS) -Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS)
@ln -sf $@ libcpupower.so @ln -sf $(@F) $(OUTPUT)libcpupower.so
@ln -sf $@ libcpupower.so.$(LIB_MIN) @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 # 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 # Might be worth to put this into utils/Makefile at some point of time
$(UTIL_OBJS): $(UTIL_HEADERS) $(UTIL_OBJS): $(UTIL_HEADERS)
.c.o: $(OUTPUT)%.o: %.c
$(ECHO) " CC " $@ $(ECHO) " CC " $@
$(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c $(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 " $@ $(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) $@ $(QUIET) $(STRIPCMD) $@
po/$(PACKAGE).pot: $(UTIL_SRC) $(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC)
$(ECHO) " GETTEXT " $@ $(ECHO) " GETTEXT " $@
$(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \ $(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \
--keyword=_ --keyword=N_ $(UTIL_SRC) && \ --keyword=_ --keyword=N_ $(UTIL_SRC) -p $(@D) -o $(@F)
test -f $(PACKAGE).po && \
mv -f $(PACKAGE).po po/$(PACKAGE).pot
po/%.gmo: po/%.po $(OUTPUT)po/%.gmo: po/%.po
$(ECHO) " MSGFMT " $@ $(ECHO) " MSGFMT " $@
$(QUIET) msgfmt -o $@ po/$*.po $(QUIET) msgfmt -o $@ po/$*.po
create-gmo: ${GMO_FILES} create-gmo: ${GMO_FILES}
update-po: po/$(PACKAGE).pot update-po: $(OUTPUT)po/$(PACKAGE).pot
$(ECHO) " MSGMRG " $@ $(ECHO) " MSGMRG " $@
$(QUIET) @for HLANG in $(LANGUAGES); do \ $(QUIET) @for HLANG in $(LANGUAGES); do \
echo -n "Updating $$HLANG "; \ echo -n "Updating $$HLANG "; \
if msgmerge po/$$HLANG.po po/$(PACKAGE).pot -o \ if msgmerge po/$$HLANG.po $< -o \
po/$$HLANG.new.po; then \ $(OUTPUT)po/$$HLANG.new.po; then \
mv -f po/$$HLANG.new.po po/$$HLANG.po; \ mv -f $(OUTPUT)po/$$HLANG.new.po $(OUTPUT)po/$$HLANG.po; \
else \ else \
echo "msgmerge for $$HLANG failed!"; \ echo "msgmerge for $$HLANG failed!"; \
rm -f po/$$HLANG.new.po; \ rm -f $(OUTPUT)po/$$HLANG.new.po; \
fi; \ fi; \
done; done;
compile-bench: libcpupower.so.$(LIB_MAJ) compile-bench: $(OUTPUT)libcpupower.so.$(LIB_MAJ)
@V=$(V) confdir=$(confdir) $(MAKE) -C bench @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: 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 | xargs rm -f
-rm -f $(UTIL_BINS) -rm -f $(OUTPUT)cpupower
-rm -f $(IDLE_OBJS) -rm -f $(OUTPUT)libcpupower.so*
-rm -f cpupower -rm -rf $(OUTPUT)po/*.{gmo,pot}
-rm -f libcpupower.so* $(MAKE) -C bench O=$(OUTPUT) clean
-rm -rf po/*.gmo po/*.pot
$(MAKE) -C bench clean
install-lib: install-lib:
$(INSTALL) -d $(DESTDIR)${libdir} $(INSTALL) -d $(DESTDIR)${libdir}
$(CP) libcpupower.so* $(DESTDIR)${libdir}/ $(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/
$(INSTALL) -d $(DESTDIR)${includedir} $(INSTALL) -d $(DESTDIR)${includedir}
$(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h $(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h
install-tools: install-tools:
$(INSTALL) -d $(DESTDIR)${bindir} $(INSTALL) -d $(DESTDIR)${bindir}
$(INSTALL_PROGRAM) cpupower $(DESTDIR)${bindir} $(INSTALL_PROGRAM) $(OUTPUT)cpupower $(DESTDIR)${bindir}
install-man: install-man:
$(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1 $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1
...@@ -257,13 +278,13 @@ install-man: ...@@ -257,13 +278,13 @@ install-man:
install-gmo: install-gmo:
$(INSTALL) -d $(DESTDIR)${localedir} $(INSTALL) -d $(DESTDIR)${localedir}
for HLANG in $(LANGUAGES); do \ for HLANG in $(LANGUAGES); do \
echo '$(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 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; done;
install-bench: install-bench:
@#DESTDIR must be set from outside to survive @#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) install: all install-lib install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH)
......
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\" CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\"
%.o : %.c $(OUTPUT)%.o : %.c
$(ECHO) " CC " $@ $(ECHO) " CC " $@
$(QUIET) $(CC) -c $(CFLAGS) $< -o $@ $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
cpufreq-bench: $(OBJS) $(OUTPUT)cpufreq-bench: $(OBJS)
$(ECHO) " CC " $@ $(ECHO) " CC " $@
$(QUIET) $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS) $(QUIET) $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS)
all: cpufreq-bench all: $(OUTPUT)cpufreq-bench
install: install:
mkdir -p $(DESTDIR)/$(sbindir) mkdir -p $(DESTDIR)/$(sbindir)
mkdir -p $(DESTDIR)/$(bindir) mkdir -p $(DESTDIR)/$(bindir)
mkdir -p $(DESTDIR)/$(docdir) mkdir -p $(DESTDIR)/$(docdir)
mkdir -p $(DESTDIR)/$(confdir) 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 755 cpufreq-bench_plot.sh $(DESTDIR)/$(bindir)/cpufreq-bench_plot.sh
install -m 644 README-BENCH $(DESTDIR)/$(docdir)/README-BENCH install -m 644 README-BENCH $(DESTDIR)/$(docdir)/README-BENCH
install -m 755 cpufreq-bench_script.sh $(DESTDIR)/$(docdir)/cpufreq-bench_script.sh install -m 755 cpufreq-bench_script.sh $(DESTDIR)/$(docdir)/cpufreq-bench_script.sh
install -m 644 example.cfg $(DESTDIR)/$(confdir)/cpufreq-bench.conf install -m 644 example.cfg $(DESTDIR)/$(confdir)/cpufreq-bench.conf
clean: clean:
rm -f *.o rm -f $(OUTPUT)*.o
rm -f cpufreq-bench rm -f $(OUTPUT)cpufreq-bench
OUTPUT=./
ifeq ("$(origin O)", "command line")
OUTPUT := $(O)/
endif
DESTDIR =
bindir = /usr/bin
INSTALL = /usr/bin/install
default: all default: all
centrino-decode: centrino-decode.c $(OUTPUT)centrino-decode: centrino-decode.c
$(CC) $(CFLAGS) -o centrino-decode centrino-decode.c $(CC) $(CFLAGS) -o $@ centrino-decode.c
dump_psb: dump_psb.c $(OUTPUT)dump_psb: dump_psb.c
$(CC) $(CFLAGS) -o dump_psb dump_psb.c $(CC) $(CFLAGS) -o $@ dump_psb.c
intel_gsic: intel_gsic.c $(OUTPUT)intel_gsic: intel_gsic.c
$(CC) $(CFLAGS) -o intel_gsic -llrmi intel_gsic.c $(CC) $(CFLAGS) -o $@ -llrmi intel_gsic.c
powernow-k8-decode: powernow-k8-decode.c $(OUTPUT)powernow-k8-decode: powernow-k8-decode.c
$(CC) $(CFLAGS) -o 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: 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
OUTPUT=./
ifeq ("$(origin O)", "command line")
OUTPUT := $(O)/
endif
DESTDIR =
bindir = /usr/bin
INSTALL = /usr/bin/install
default: all default: all
centrino-decode: ../i386/centrino-decode.c $(OUTPUT)centrino-decode: ../i386/centrino-decode.c
$(CC) $(CFLAGS) -o $@ $< $(CC) $(CFLAGS) -o $@ $<
powernow-k8-decode: ../i386/powernow-k8-decode.c $(OUTPUT)powernow-k8-decode: ../i386/powernow-k8-decode.c
$(CC) $(CFLAGS) -o $@ $< $(CC) $(CFLAGS) -o $@ $<
all: centrino-decode powernow-k8-decode all: $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode
clean: 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
.TH "cpupower-frequency-info" "1" "0.1" "Mattia Dongili" "" .TH "CPUPOWER\-FREQUENCY\-INFO" "1" "0.1" "" "cpupower Manual"
.SH "NAME" .SH "NAME"
.LP .LP
cpupower frequency\-info \- Utility to retrieve cpufreq kernel information 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 ...@@ -50,8 +50,6 @@ Prints out information like provided by the /proc/cpufreq interface in 2.4. and
\fB\-m\fR \fB\-\-human\fR \fB\-m\fR \fB\-\-human\fR
human\-readable output for the \-f, \-w, \-s and \-y parameters. human\-readable output for the \-f, \-w, \-s and \-y parameters.
.TP .TP
\fB\-h\fR \fB\-\-help\fR
Prints out the help screen.
.SH "REMARKS" .SH "REMARKS"
.LP .LP
By default only values of core zero are displayed. How to display settings of By default only values of core zero are displayed. How to display settings of
......
.TH "cpupower-freqency-set" "1" "0.1" "Mattia Dongili" "" .TH "CPUPOWER\-FREQUENCY\-SET" "1" "0.1" "" "cpupower Manual"
.SH "NAME" .SH "NAME"
.LP .LP
cpupower frequency\-set \- A small tool which allows to modify cpufreq settings. 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 ...@@ -26,8 +26,6 @@ specific frequency to be set. Requires userspace governor to be available and lo
\fB\-r\fR \fB\-\-related\fR \fB\-r\fR \fB\-\-related\fR
modify all hardware-related CPUs at the same time modify all hardware-related CPUs at the same time
.TP .TP
\fB\-h\fR \fB\-\-help\fR
Prints out the help screen.
.SH "REMARKS" .SH "REMARKS"
.LP .LP
By default values are applied on all cores. How to modify single core By default values are applied on all cores. How to modify single core
......
.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)
...@@ -107,7 +107,7 @@ Deepest package sleep states may in reality show up as machine/platform wide ...@@ -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 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. 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. 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 The registers are accessed via PCI and therefore can still be read out while
cores have been offlined. cores have been offlined.
......
...@@ -35,17 +35,9 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose) ...@@ -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); printf(_("CPU %u: Can't read idle state info\n"), cpu);
return; 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(_("Number of idle states: %d\n"), idlestates);
printf(_("Available idle states:")); printf(_("Available idle states:"));
for (idlestate = 1; idlestate < idlestates; idlestate++) { for (idlestate = 0; idlestate < idlestates; idlestate++) {
tmp = sysfs_get_idlestate_name(cpu, idlestate); tmp = sysfs_get_idlestate_name(cpu, idlestate);
if (!tmp) if (!tmp)
continue; continue;
...@@ -57,7 +49,7 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose) ...@@ -57,7 +49,7 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose)
if (!verbose) if (!verbose)
return; return;
for (idlestate = 1; idlestate < idlestates; idlestate++) { for (idlestate = 0; idlestate < idlestates; idlestate++) {
tmp = sysfs_get_idlestate_name(cpu, idlestate); tmp = sysfs_get_idlestate_name(cpu, idlestate);
if (!tmp) if (!tmp)
continue; continue;
......
...@@ -112,14 +112,12 @@ int decode_pstates(unsigned int cpu, unsigned int cpu_family, ...@@ -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) int amd_pci_get_num_boost_states(int *active, int *states)
{ {
struct pci_access *pci_acc; struct pci_access *pci_acc;
int vendor_id = 0x1022;
int boost_dev_ids[4] = {0x1204, 0x1604, 0x1704, 0};
struct pci_dev *device; struct pci_dev *device;
uint8_t val = 0; uint8_t val = 0;
*active = *states = 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) if (device == NULL)
return -ENODEV; return -ENODEV;
......
...@@ -66,8 +66,8 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL, ...@@ -66,8 +66,8 @@ enum cpupower_cpu_vendor {X86_VENDOR_UNKNOWN = 0, X86_VENDOR_INTEL,
#define CPUPOWER_CAP_AMD_CBP 0x00000004 #define CPUPOWER_CAP_AMD_CBP 0x00000004
#define CPUPOWER_CAP_PERF_BIAS 0x00000008 #define CPUPOWER_CAP_PERF_BIAS 0x00000008
#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010 #define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010
#define CPUPOWER_CAP_IS_SNB 0x00000011 #define CPUPOWER_CAP_IS_SNB 0x00000020
#define CPUPOWER_CAP_INTEL_IDA 0x00000012 #define CPUPOWER_CAP_INTEL_IDA 0x00000040
#define MAX_HW_PSTATES 10 #define MAX_HW_PSTATES 10
...@@ -132,8 +132,11 @@ extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu); ...@@ -132,8 +132,11 @@ extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu);
/* PCI stuff ****************************/ /* PCI stuff ****************************/
extern int amd_pci_get_num_boost_states(int *active, int *states); 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, extern struct pci_dev *pci_acc_init(struct pci_access **pacc, int domain,
int *dev_ids); 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 ****************************/ /* PCI stuff ****************************/
......
...@@ -10,19 +10,24 @@ ...@@ -10,19 +10,24 @@
* **pacc : if a valid pci_dev is returned * **pacc : if a valid pci_dev is returned
* *pacc must be passed to pci_acc_cleanup to free it * *pacc must be passed to pci_acc_cleanup to free it
* *
* vendor_id : the pci vendor id matching the pci device to access * domain: domain
* dev_ids : device ids matching the pci device to access * bus: bus
* slot: slot
* func: func
* vendor: vendor
* device: device
* Pass -1 for one of the six above to match any
* *
* Returns : * Returns :
* struct pci_dev which can be used with pci_{read,write}_* functions * struct pci_dev which can be used with pci_{read,write}_* functions
* to access the PCI config space of matching pci devices * to access the PCI config space of matching pci devices
*/ */
struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id, struct pci_dev *pci_acc_init(struct pci_access **pacc, int domain, int bus,
int *dev_ids) 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; struct pci_dev *device;
unsigned int i;
*pacc = pci_alloc(); *pacc = pci_alloc();
if (*pacc == NULL) if (*pacc == NULL)
...@@ -31,14 +36,20 @@ struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id, ...@@ -31,14 +36,20 @@ struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id,
pci_init(*pacc); pci_init(*pacc);
pci_scan_bus(*pacc); pci_scan_bus(*pacc);
for (i = 0; dev_ids[i] != 0; i++) { for (device = (*pacc)->devices; device; device = device->next) {
filter_nb_link.device = dev_ids[i]; if (pci_filter_match(&filter_nb_link, device))
for (device = (*pacc)->devices; device; device = device->next) { return device;
if (pci_filter_match(&filter_nb_link, device))
return device;
}
} }
pci_cleanup(*pacc); pci_cleanup(*pacc);
return NULL; 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__) */ #endif /* defined(__i386__) || defined(__x86_64__) */
...@@ -20,8 +20,6 @@ ...@@ -20,8 +20,6 @@
#include "idle_monitor/cpupower-monitor.h" #include "idle_monitor/cpupower-monitor.h"
#include "helpers/helpers.h" #include "helpers/helpers.h"
/******** PCI parts could go into own file and get shared ***************/
#define PCI_NON_PC0_OFFSET 0xb0 #define PCI_NON_PC0_OFFSET 0xb0
#define PCI_PC1_OFFSET 0xb4 #define PCI_PC1_OFFSET 0xb4
#define PCI_PC6_OFFSET 0xb8 #define PCI_PC6_OFFSET 0xb8
...@@ -82,10 +80,7 @@ static cstate_t amd_fam14h_cstates[AMD_FAM14H_STATE_NUM] = { ...@@ -82,10 +80,7 @@ static cstate_t amd_fam14h_cstates[AMD_FAM14H_STATE_NUM] = {
}; };
static struct pci_access *pci_acc; 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 struct pci_dev *amd_fam14h_pci_dev;
static int nbp1_entered; static int nbp1_entered;
struct timespec start_time; struct timespec start_time;
...@@ -286,13 +281,13 @@ struct cpuidle_monitor *amd_fam14h_register(void) ...@@ -286,13 +281,13 @@ struct cpuidle_monitor *amd_fam14h_register(void)
if (cpupower_cpu_info.vendor != X86_VENDOR_AMD) if (cpupower_cpu_info.vendor != X86_VENDOR_AMD)
return NULL; return NULL;
if (cpupower_cpu_info.family == 0x14) { if (cpupower_cpu_info.family == 0x14)
if (cpu_count <= 0 || cpu_count > 2) { strncpy(amd_fam14h_monitor.name, "Fam_14h",
fprintf(stderr, "AMD fam14h: Invalid cpu count: %d\n", MONITOR_NAME_LEN - 1);
cpu_count); else if (cpupower_cpu_info.family == 0x12)
return NULL; strncpy(amd_fam14h_monitor.name, "Fam_12h",
} MONITOR_NAME_LEN - 1);
} else else
return NULL; return NULL;
/* We do not alloc for nbp1 machine wide counter */ /* We do not alloc for nbp1 machine wide counter */
...@@ -303,7 +298,9 @@ struct cpuidle_monitor *amd_fam14h_register(void) ...@@ -303,7 +298,9 @@ struct cpuidle_monitor *amd_fam14h_register(void)
sizeof(unsigned long long)); 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) if (amd_fam14h_pci_dev == NULL || pci_acc == NULL)
return NULL; return NULL;
...@@ -325,7 +322,7 @@ static void amd_fam14h_unregister(void) ...@@ -325,7 +322,7 @@ static void amd_fam14h_unregister(void)
} }
struct cpuidle_monitor amd_fam14h_monitor = { struct cpuidle_monitor amd_fam14h_monitor = {
.name = "Ontario", .name = "",
.hw_states = amd_fam14h_cstates, .hw_states = amd_fam14h_cstates,
.hw_states_num = AMD_FAM14H_STATE_NUM, .hw_states_num = AMD_FAM14H_STATE_NUM,
.start = amd_fam14h_start, .start = amd_fam14h_start,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment