aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorIngo Molnar <mingo@kernel.org>2012-03-30 02:47:19 -0400
committerIngo Molnar <mingo@kernel.org>2012-03-30 02:50:06 -0400
commit186e54cbe1145f4d11e32fe10e7e20a11f1b27dd (patch)
tree9b6cf3667a3ea90e0cec0ea7119688ba76c55a71 /tools
parent99dd5497e5be4fe4194cad181d45fd6569a930db (diff)
parent4bde23f8751f388867766b0a62ed1ef8b7e01561 (diff)
Merge branch 'linus' into x86/urgent
Merge reason: Needed for include file dependencies. Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools')
-rw-r--r--tools/perf/util/include/linux/bitops.h2
-rw-r--r--tools/power/cpupower/Makefile93
-rw-r--r--tools/power/cpupower/bench/Makefile23
-rw-r--r--tools/power/cpupower/debug/i386/Makefile40
-rw-r--r--tools/power/cpupower/debug/x86_64/Makefile26
-rw-r--r--tools/power/cpupower/man/cpupower-frequency-info.14
-rw-r--r--tools/power/cpupower/man/cpupower-frequency-set.14
-rw-r--r--tools/power/cpupower/man/cpupower-idle-info.190
-rw-r--r--tools/power/cpupower/man/cpupower-monitor.12
-rw-r--r--tools/power/cpupower/utils/cpuidle-info.c12
-rw-r--r--tools/power/cpupower/utils/helpers/amd.c4
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h11
-rw-r--r--tools/power/cpupower/utils/helpers/pci.c35
-rw-r--r--tools/power/cpupower/utils/idle_monitor/amd_fam14h_idle.c25
-rwxr-xr-xtools/testing/ktest/ktest.pl56
-rw-r--r--tools/testing/ktest/sample.conf14
-rw-r--r--tools/testing/selftests/Makefile7
-rw-r--r--tools/testing/selftests/breakpoints/Makefile7
-rw-r--r--tools/testing/selftests/run_tests8
-rw-r--r--tools/testing/selftests/vm/Makefile14
-rw-r--r--tools/testing/selftests/vm/hugepage-mmap.c92
-rw-r--r--tools/testing/selftests/vm/hugepage-shm.c100
-rw-r--r--tools/testing/selftests/vm/map_hugetlb.c79
-rw-r--r--tools/testing/selftests/vm/run_vmtests77
-rw-r--r--tools/virtio/linux/hrtimer.h0
-rw-r--r--tools/virtio/linux/module.h0
-rw-r--r--tools/virtio/linux/virtio.h3
-rw-r--r--tools/vm/Makefile11
-rw-r--r--tools/vm/page-types.c1102
-rw-r--r--tools/vm/slabinfo.c (renamed from tools/slub/slabinfo.c)0
30 files changed, 1805 insertions, 136 deletions
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h
index 62cdee78db7b..f1584833bd22 100644
--- a/tools/perf/util/include/linux/bitops.h
+++ b/tools/perf/util/include/linux/bitops.h
@@ -15,7 +15,7 @@
15 (bit) = find_next_bit((addr), (size), (bit) + 1)) 15 (bit) = find_next_bit((addr), (size), (bit) + 1))
16 16
17/* same as for_each_set_bit() but use bit as value to start with */ 17/* same as for_each_set_bit() but use bit as value to start with */
18#define for_each_set_bit_cont(bit, addr, size) \ 18#define for_each_set_bit_from(bit, addr, size) \
19 for ((bit) = find_next_bit((addr), (size), (bit)); \ 19 for ((bit) = find_next_bit((addr), (size), (bit)); \
20 (bit) < (size); \ 20 (bit) < (size); \
21 (bit) = find_next_bit((addr), (size), (bit) + 1)) 21 (bit) = find_next_bit((addr), (size), (bit) + 1))
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 @@
19# along with this program; if not, write to the Free Software 19# along with this program; if not, write to the Free Software
20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21# 21#
22OUTPUT=./
23ifeq ("$(origin O)", "command line")
24 OUTPUT := $(O)/
25endif
26
27ifneq ($(OUTPUT),)
28# check that the output directory actually exists
29OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
30$(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
31endif
22 32
23# --- CONFIGURATION BEGIN --- 33# --- CONFIGURATION BEGIN ---
24 34
@@ -87,6 +97,7 @@ AR = $(CROSS)ar
87STRIP = $(CROSS)strip 97STRIP = $(CROSS)strip
88RANLIB = $(CROSS)ranlib 98RANLIB = $(CROSS)ranlib
89HOSTCC = gcc 99HOSTCC = gcc
100MKDIR = mkdir
90 101
91 102
92# Now we set up the build system 103# Now we set up the build system
@@ -95,7 +106,7 @@ HOSTCC = gcc
95# set up PWD so that older versions of make will work with our build. 106# set up PWD so that older versions of make will work with our build.
96PWD = $(shell pwd) 107PWD = $(shell pwd)
97 108
98GMO_FILES = ${shell for HLANG in ${LANGUAGES}; do echo po/$$HLANG.gmo; done;} 109GMO_FILES = ${shell for HLANG in ${LANGUAGES}; do echo $(OUTPUT)po/$$HLANG.gmo; done;}
99 110
100export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS 111export CROSS CC AR STRIP RANLIB CFLAGS LDFLAGS LIB_OBJS
101 112
@@ -122,15 +133,18 @@ UTIL_OBJS = utils/helpers/amd.o utils/helpers/topology.o utils/helpers/msr.o \
122 utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \ 133 utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \
123 utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o 134 utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o
124 135
136UTIL_SRC := $(UTIL_OBJS:.o=.c)
137
138UTIL_OBJS := $(addprefix $(OUTPUT),$(UTIL_OBJS))
139
125UTIL_HEADERS = utils/helpers/helpers.h utils/idle_monitor/cpupower-monitor.h \ 140UTIL_HEADERS = utils/helpers/helpers.h utils/idle_monitor/cpupower-monitor.h \
126 utils/helpers/bitmask.h \ 141 utils/helpers/bitmask.h \
127 utils/idle_monitor/idle_monitors.h utils/idle_monitor/idle_monitors.def 142 utils/idle_monitor/idle_monitors.h utils/idle_monitor/idle_monitors.def
128 143
129UTIL_SRC := $(UTIL_OBJS:.o=.c)
130
131LIB_HEADERS = lib/cpufreq.h lib/sysfs.h 144LIB_HEADERS = lib/cpufreq.h lib/sysfs.h
132LIB_SRC = lib/cpufreq.c lib/sysfs.c 145LIB_SRC = lib/cpufreq.c lib/sysfs.c
133LIB_OBJS = lib/cpufreq.o lib/sysfs.o 146LIB_OBJS = lib/cpufreq.o lib/sysfs.o
147LIB_OBJS := $(addprefix $(OUTPUT),$(LIB_OBJS))
134 148
135CFLAGS += -pipe 149CFLAGS += -pipe
136 150
@@ -168,83 +182,90 @@ endif
168 182
169# the actual make rules 183# the actual make rules
170 184
171all: libcpupower cpupower $(COMPILE_NLS) $(COMPILE_BENCH) 185all: libcpupower $(OUTPUT)cpupower $(COMPILE_NLS) $(COMPILE_BENCH)
172 186
173lib/%.o: $(LIB_SRC) $(LIB_HEADERS) 187$(OUTPUT)lib/%.o: $(LIB_SRC) $(LIB_HEADERS)
174 $(ECHO) " CC " $@ 188 $(ECHO) " CC " $@
175 $(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c 189 $(QUIET) $(CC) $(CFLAGS) -fPIC -o $@ -c lib/$*.c
176 190
177libcpupower.so.$(LIB_MAJ): $(LIB_OBJS) 191$(OUTPUT)libcpupower.so.$(LIB_MAJ): $(LIB_OBJS)
178 $(ECHO) " LD " $@ 192 $(ECHO) " LD " $@
179 $(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \ 193 $(QUIET) $(CC) -shared $(CFLAGS) $(LDFLAGS) -o $@ \
180 -Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS) 194 -Wl,-soname,libcpupower.so.$(LIB_MIN) $(LIB_OBJS)
181 @ln -sf $@ libcpupower.so 195 @ln -sf $(@F) $(OUTPUT)libcpupower.so
182 @ln -sf $@ libcpupower.so.$(LIB_MIN) 196 @ln -sf $(@F) $(OUTPUT)libcpupower.so.$(LIB_MIN)
183 197
184libcpupower: libcpupower.so.$(LIB_MAJ) 198libcpupower: $(OUTPUT)libcpupower.so.$(LIB_MAJ)
185 199
186# Let all .o files depend on its .c file and all headers 200# Let all .o files depend on its .c file and all headers
187# Might be worth to put this into utils/Makefile at some point of time 201# Might be worth to put this into utils/Makefile at some point of time
188$(UTIL_OBJS): $(UTIL_HEADERS) 202$(UTIL_OBJS): $(UTIL_HEADERS)
189 203
190.c.o: 204$(OUTPUT)%.o: %.c
191 $(ECHO) " CC " $@ 205 $(ECHO) " CC " $@
192 $(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c 206 $(QUIET) $(CC) $(CFLAGS) -I./lib -I ./utils -o $@ -c $*.c
193 207
194cpupower: $(UTIL_OBJS) libcpupower.so.$(LIB_MAJ) 208$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ)
195 $(ECHO) " CC " $@ 209 $(ECHO) " CC " $@
196 $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) -lcpupower -lrt -lpci -L. -o $@ $(UTIL_OBJS) 210 $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@
197 $(QUIET) $(STRIPCMD) $@ 211 $(QUIET) $(STRIPCMD) $@
198 212
199po/$(PACKAGE).pot: $(UTIL_SRC) 213$(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC)
200 $(ECHO) " GETTEXT " $@ 214 $(ECHO) " GETTEXT " $@
201 $(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \ 215 $(QUIET) xgettext --default-domain=$(PACKAGE) --add-comments \
202 --keyword=_ --keyword=N_ $(UTIL_SRC) && \ 216 --keyword=_ --keyword=N_ $(UTIL_SRC) -p $(@D) -o $(@F)
203 test -f $(PACKAGE).po && \
204 mv -f $(PACKAGE).po po/$(PACKAGE).pot
205 217
206po/%.gmo: po/%.po 218$(OUTPUT)po/%.gmo: po/%.po
207 $(ECHO) " MSGFMT " $@ 219 $(ECHO) " MSGFMT " $@
208 $(QUIET) msgfmt -o $@ po/$*.po 220 $(QUIET) msgfmt -o $@ po/$*.po
209 221
210create-gmo: ${GMO_FILES} 222create-gmo: ${GMO_FILES}
211 223
212update-po: po/$(PACKAGE).pot 224update-po: $(OUTPUT)po/$(PACKAGE).pot
213 $(ECHO) " MSGMRG " $@ 225 $(ECHO) " MSGMRG " $@
214 $(QUIET) @for HLANG in $(LANGUAGES); do \ 226 $(QUIET) @for HLANG in $(LANGUAGES); do \
215 echo -n "Updating $$HLANG "; \ 227 echo -n "Updating $$HLANG "; \
216 if msgmerge po/$$HLANG.po po/$(PACKAGE).pot -o \ 228 if msgmerge po/$$HLANG.po $< -o \
217 po/$$HLANG.new.po; then \ 229 $(OUTPUT)po/$$HLANG.new.po; then \
218 mv -f po/$$HLANG.new.po po/$$HLANG.po; \ 230 mv -f $(OUTPUT)po/$$HLANG.new.po $(OUTPUT)po/$$HLANG.po; \
219 else \ 231 else \
220 echo "msgmerge for $$HLANG failed!"; \ 232 echo "msgmerge for $$HLANG failed!"; \
221 rm -f po/$$HLANG.new.po; \ 233 rm -f $(OUTPUT)po/$$HLANG.new.po; \
222 fi; \ 234 fi; \
223 done; 235 done;
224 236
225compile-bench: libcpupower.so.$(LIB_MAJ) 237compile-bench: $(OUTPUT)libcpupower.so.$(LIB_MAJ)
226 @V=$(V) confdir=$(confdir) $(MAKE) -C bench 238 @V=$(V) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT)
239
240# we compile into subdirectories. if the target directory is not the
241# source directory, they might not exists. So we depend the various
242# files onto their directories.
243DIRECTORY_DEPS = $(LIB_OBJS) $(UTIL_OBJS) $(GMO_FILES)
244$(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
245
246# In the second step, we make a rule to actually create these directories
247$(sort $(dir $(DIRECTORY_DEPS))):
248 $(ECHO) " MKDIR " $@
249 $(QUIET) $(MKDIR) -p $@ 2>/dev/null
227 250
228clean: 251clean:
229 -find . \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \ 252 -find $(OUTPUT) \( -not -type d \) -and \( -name '*~' -o -name '*.[oas]' \) -type f -print \
230 | xargs rm -f 253 | xargs rm -f
231 -rm -f $(UTIL_BINS) 254 -rm -f $(OUTPUT)cpupower
232 -rm -f $(IDLE_OBJS) 255 -rm -f $(OUTPUT)libcpupower.so*
233 -rm -f cpupower 256 -rm -rf $(OUTPUT)po/*.{gmo,pot}
234 -rm -f libcpupower.so* 257 $(MAKE) -C bench O=$(OUTPUT) clean
235 -rm -rf po/*.gmo po/*.pot
236 $(MAKE) -C bench clean
237 258
238 259
239install-lib: 260install-lib:
240 $(INSTALL) -d $(DESTDIR)${libdir} 261 $(INSTALL) -d $(DESTDIR)${libdir}
241 $(CP) libcpupower.so* $(DESTDIR)${libdir}/ 262 $(CP) $(OUTPUT)libcpupower.so* $(DESTDIR)${libdir}/
242 $(INSTALL) -d $(DESTDIR)${includedir} 263 $(INSTALL) -d $(DESTDIR)${includedir}
243 $(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h 264 $(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h
244 265
245install-tools: 266install-tools:
246 $(INSTALL) -d $(DESTDIR)${bindir} 267 $(INSTALL) -d $(DESTDIR)${bindir}
247 $(INSTALL_PROGRAM) cpupower $(DESTDIR)${bindir} 268 $(INSTALL_PROGRAM) $(OUTPUT)cpupower $(DESTDIR)${bindir}
248 269
249install-man: 270install-man:
250 $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1 271 $(INSTALL_DATA) -D man/cpupower.1 $(DESTDIR)${mandir}/man1/cpupower.1
@@ -257,13 +278,13 @@ install-man:
257install-gmo: 278install-gmo:
258 $(INSTALL) -d $(DESTDIR)${localedir} 279 $(INSTALL) -d $(DESTDIR)${localedir}
259 for HLANG in $(LANGUAGES); do \ 280 for HLANG in $(LANGUAGES); do \
260 echo '$(INSTALL_DATA) -D po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \ 281 echo '$(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo'; \
261 $(INSTALL_DATA) -D po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \ 282 $(INSTALL_DATA) -D $(OUTPUT)po/$$HLANG.gmo $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \
262 done; 283 done;
263 284
264install-bench: 285install-bench:
265 @#DESTDIR must be set from outside to survive 286 @#DESTDIR must be set from outside to survive
266 @sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench install 287 @sbindir=$(sbindir) bindir=$(bindir) docdir=$(docdir) confdir=$(confdir) $(MAKE) -C bench O=$(OUTPUT) install
267 288
268install: all install-lib install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH) 289install: all install-lib install-tools install-man $(INSTALL_NLS) $(INSTALL_BENCH)
269 290
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 @@
1LIBS = -L../ -lm -lcpupower 1OUTPUT := ./
2ifeq ("$(origin O)", "command line")
3ifneq ($(O),)
4 OUTPUT := $(O)/
5endif
6endif
2 7
3OBJS = main.o parse.o system.o benchmark.o 8LIBS = -L../ -L$(OUTPUT) -lm -lcpupower
9
10OBJS = $(OUTPUT)main.o $(OUTPUT)parse.o $(OUTPUT)system.o $(OUTPUT)benchmark.o
4CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\" 11CFLAGS += -D_GNU_SOURCE -I../lib -DDEFAULT_CONFIG_FILE=\"$(confdir)/cpufreq-bench.conf\"
5 12
6%.o : %.c 13$(OUTPUT)%.o : %.c
7 $(ECHO) " CC " $@ 14 $(ECHO) " CC " $@
8 $(QUIET) $(CC) -c $(CFLAGS) $< -o $@ 15 $(QUIET) $(CC) -c $(CFLAGS) $< -o $@
9 16
10cpufreq-bench: $(OBJS) 17$(OUTPUT)cpufreq-bench: $(OBJS)
11 $(ECHO) " CC " $@ 18 $(ECHO) " CC " $@
12 $(QUIET) $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS) 19 $(QUIET) $(CC) -o $@ $(CFLAGS) $(OBJS) $(LIBS)
13 20
14all: cpufreq-bench 21all: $(OUTPUT)cpufreq-bench
15 22
16install: 23install:
17 mkdir -p $(DESTDIR)/$(sbindir) 24 mkdir -p $(DESTDIR)/$(sbindir)
18 mkdir -p $(DESTDIR)/$(bindir) 25 mkdir -p $(DESTDIR)/$(bindir)
19 mkdir -p $(DESTDIR)/$(docdir) 26 mkdir -p $(DESTDIR)/$(docdir)
20 mkdir -p $(DESTDIR)/$(confdir) 27 mkdir -p $(DESTDIR)/$(confdir)
21 install -m 755 cpufreq-bench $(DESTDIR)/$(sbindir)/cpufreq-bench 28 install -m 755 $(OUTPUT)cpufreq-bench $(DESTDIR)/$(sbindir)/cpufreq-bench
22 install -m 755 cpufreq-bench_plot.sh $(DESTDIR)/$(bindir)/cpufreq-bench_plot.sh 29 install -m 755 cpufreq-bench_plot.sh $(DESTDIR)/$(bindir)/cpufreq-bench_plot.sh
23 install -m 644 README-BENCH $(DESTDIR)/$(docdir)/README-BENCH 30 install -m 644 README-BENCH $(DESTDIR)/$(docdir)/README-BENCH
24 install -m 755 cpufreq-bench_script.sh $(DESTDIR)/$(docdir)/cpufreq-bench_script.sh 31 install -m 755 cpufreq-bench_script.sh $(DESTDIR)/$(docdir)/cpufreq-bench_script.sh
25 install -m 644 example.cfg $(DESTDIR)/$(confdir)/cpufreq-bench.conf 32 install -m 644 example.cfg $(DESTDIR)/$(confdir)/cpufreq-bench.conf
26 33
27clean: 34clean:
28 rm -f *.o 35 rm -f $(OUTPUT)*.o
29 rm -f cpufreq-bench 36 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 @@
1OUTPUT=./
2ifeq ("$(origin O)", "command line")
3 OUTPUT := $(O)/
4endif
5
6DESTDIR =
7bindir = /usr/bin
8
9INSTALL = /usr/bin/install
10
11
1default: all 12default: all
2 13
3centrino-decode: centrino-decode.c 14$(OUTPUT)centrino-decode: centrino-decode.c
4 $(CC) $(CFLAGS) -o centrino-decode centrino-decode.c 15 $(CC) $(CFLAGS) -o $@ centrino-decode.c
5 16
6dump_psb: dump_psb.c 17$(OUTPUT)dump_psb: dump_psb.c
7 $(CC) $(CFLAGS) -o dump_psb dump_psb.c 18 $(CC) $(CFLAGS) -o $@ dump_psb.c
8 19
9intel_gsic: intel_gsic.c 20$(OUTPUT)intel_gsic: intel_gsic.c
10 $(CC) $(CFLAGS) -o intel_gsic -llrmi intel_gsic.c 21 $(CC) $(CFLAGS) -o $@ -llrmi intel_gsic.c
11 22
12powernow-k8-decode: powernow-k8-decode.c 23$(OUTPUT)powernow-k8-decode: powernow-k8-decode.c
13 $(CC) $(CFLAGS) -o powernow-k8-decode powernow-k8-decode.c 24 $(CC) $(CFLAGS) -o $@ powernow-k8-decode.c
14 25
15all: centrino-decode dump_psb intel_gsic powernow-k8-decode 26all: $(OUTPUT)centrino-decode $(OUTPUT)dump_psb $(OUTPUT)intel_gsic $(OUTPUT)powernow-k8-decode
16 27
17clean: 28clean:
18 rm -rf centrino-decode dump_psb intel_gsic powernow-k8-decode 29 rm -rf $(OUTPUT){centrino-decode,dump_psb,intel_gsic,powernow-k8-decode}
30
31install:
32 $(INSTALL) -d $(DESTDIR)${bindir}
33 $(INSTALL) $(OUTPUT)centrino-decode $(DESTDIR)${bindir}
34 $(INSTALL) $(OUTPUT)powernow-k8-decode $(DESTDIR)${bindir}
35 $(INSTALL) $(OUTPUT)dump_psb $(DESTDIR)${bindir}
36 $(INSTALL) $(OUTPUT)intel_gsic $(DESTDIR)${bindir}
19 37
20.PHONY: all default clean 38.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 @@
1OUTPUT=./
2ifeq ("$(origin O)", "command line")
3 OUTPUT := $(O)/
4endif
5
6DESTDIR =
7bindir = /usr/bin
8
9INSTALL = /usr/bin/install
10
11
1default: all 12default: all
2 13
3centrino-decode: ../i386/centrino-decode.c 14$(OUTPUT)centrino-decode: ../i386/centrino-decode.c
4 $(CC) $(CFLAGS) -o $@ $< 15 $(CC) $(CFLAGS) -o $@ $<
5 16
6powernow-k8-decode: ../i386/powernow-k8-decode.c 17$(OUTPUT)powernow-k8-decode: ../i386/powernow-k8-decode.c
7 $(CC) $(CFLAGS) -o $@ $< 18 $(CC) $(CFLAGS) -o $@ $<
8 19
9all: centrino-decode powernow-k8-decode 20all: $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode
10 21
11clean: 22clean:
12 rm -rf centrino-decode powernow-k8-decode 23 rm -rf $(OUTPUT)centrino-decode $(OUTPUT)powernow-k8-decode
24
25install:
26 $(INSTALL) -d $(DESTDIR)${bindir}
27 $(INSTALL) $(OUTPUT)centrino-decode $(DESTDIR)${bindir}
28 $(INSTALL) $(OUTPUT)powernow-k8-decode $(DESTDIR)${bindir}
13 29
14.PHONY: all default clean 30.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 @@
1.TH "cpupower-frequency-info" "1" "0.1" "Mattia Dongili" "" 1.TH "CPUPOWER\-FREQUENCY\-INFO" "1" "0.1" "" "cpupower Manual"
2.SH "NAME" 2.SH "NAME"
3.LP 3.LP
4cpupower frequency\-info \- Utility to retrieve cpufreq kernel information 4cpupower 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\fB\-m\fR \fB\-\-human\fR 50\fB\-m\fR \fB\-\-human\fR
51human\-readable output for the \-f, \-w, \-s and \-y parameters. 51human\-readable output for the \-f, \-w, \-s and \-y parameters.
52.TP 52.TP
53\fB\-h\fR \fB\-\-help\fR
54Prints out the help screen.
55.SH "REMARKS" 53.SH "REMARKS"
56.LP 54.LP
57By default only values of core zero are displayed. How to display settings of 55By 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 @@
1.TH "cpupower-freqency-set" "1" "0.1" "Mattia Dongili" "" 1.TH "CPUPOWER\-FREQUENCY\-SET" "1" "0.1" "" "cpupower Manual"
2.SH "NAME" 2.SH "NAME"
3.LP 3.LP
4cpupower frequency\-set \- A small tool which allows to modify cpufreq settings. 4cpupower 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\fB\-r\fR \fB\-\-related\fR 26\fB\-r\fR \fB\-\-related\fR
27modify all hardware-related CPUs at the same time 27modify all hardware-related CPUs at the same time
28.TP 28.TP
29\fB\-h\fR \fB\-\-help\fR
30Prints out the help screen.
31.SH "REMARKS" 29.SH "REMARKS"
32.LP 30.LP
33By default values are applied on all cores. How to modify single core 31By 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 @@
1.TH "CPUPOWER-IDLE-INFO" "1" "0.1" "" "cpupower Manual"
2.SH "NAME"
3.LP
4cpupower idle\-info \- Utility to retrieve cpu idle kernel information
5.SH "SYNTAX"
6.LP
7cpupower [ \-c cpulist ] idle\-info [\fIoptions\fP]
8.SH "DESCRIPTION"
9.LP
10A tool which prints out per cpu idle information helpful to developers and interested users.
11.SH "OPTIONS"
12.LP
13.TP
14\fB\-f\fR \fB\-\-silent\fR
15Only print a summary of all available C-states in the system.
16.TP
17\fB\-e\fR \fB\-\-proc\fR
18deprecated.
19Prints out idle information in old /proc/acpi/processor/*/power format. This
20interface has been removed from the kernel for quite some time, do not let
21further code depend on this option, best do not use it.
22
23.SH IDLE\-INFO DESCRIPTIONS
24CPU sleep state statistics and descriptions are retrieved from sysfs files,
25exported by the cpuidle kernel subsystem. The kernel only updates these
26statistics when it enters or leaves an idle state, therefore on a very idle or
27a very busy system, these statistics may not be accurate. They still provide a
28good overview about the usage and availability of processor sleep states on
29the platform.
30
31Be aware that the sleep states as exported by the hardware or BIOS and used by
32the Linux kernel may not exactly reflect the capabilities of the
33processor. This often is the case on the X86 architecture when the acpi_idle
34driver is used. It is also possible that the hardware overrules the kernel
35requests, due to internal activity monitors or other reasons.
36On recent X86 platforms it is often possible to read out hardware registers
37which monitor the duration of sleep states the processor resided in. The
38cpupower monitor tool (cpupower\-monitor(1)) can be used to show real sleep
39state residencies. Please refer to the architecture specific description
40section below.
41
42.SH IDLE\-INFO ARCHITECTURE SPECIFIC DESCRIPTIONS
43.SS "X86"
44POLL idle state
45
46If cpuidle is active, X86 platforms have one special idle state.
47The POLL idle state is not a real idle state, it does not save any
48power. Instead, a busy\-loop is executed doing nothing for a short period of
49time. This state is used if the kernel knows that work has to be processed
50very soon and entering any real hardware idle state may result in a slight
51performance penalty.
52
53There exist two different cpuidle drivers on the X86 architecture platform:
54
55"acpi_idle" cpuidle driver
56
57The acpi_idle cpuidle driver retrieves available sleep states (C\-states) from
58the ACPI BIOS tables (from the _CST ACPI function on recent platforms or from
59the FADT BIOS table on older ones).
60The C1 state is not retrieved from ACPI tables. If the C1 state is entered,
61the kernel will call the hlt instruction (or mwait on Intel).
62
63"intel_idle" cpuidle driver
64
65In kernel 2.6.36 the intel_idle driver was introduced.
66It only serves recent Intel CPUs (Nehalem, Westmere, Sandybridge, Atoms or
67newer). On older Intel CPUs the acpi_idle driver is still used (if the BIOS
68provides C\-state ACPI tables).
69The intel_idle driver knows the sleep state capabilities of the processor and
70ignores ACPI BIOS exported processor sleep states tables.
71
72.SH "REMARKS"
73.LP
74By default only values of core zero are displayed. How to display settings of
75other cores is described in the cpupower(1) manpage in the \-\-cpu option
76section.
77.SH REFERENCES
78http://www.acpi.info/spec.htm
79.SH "FILES"
80.nf
81\fI/sys/devices/system/cpu/cpu*/cpuidle/state*\fP
82\fI/sys/devices/system/cpu/cpuidle/*\fP
83.fi
84.SH "AUTHORS"
85.nf
86Thomas Renninger <trenn@suse.de>
87.fi
88.SH "SEE ALSO"
89.LP
90cpupower(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
107sleep states and can only be entered if all cores are idle. Look up Intel 107sleep states and can only be entered if all cores are idle. Look up Intel
108manuals (some are provided in the References section) for further details. 108manuals (some are provided in the References section) for further details.
109 109
110.SS "Ontario" "Liano" 110.SS "Fam_12h" "Fam_14h"
111AMD laptop and desktop processor (family 12h and 14h) sleep state counters. 111AMD laptop and desktop processor (family 12h and 14h) sleep state counters.
112The registers are accessed via PCI and therefore can still be read out while 112The registers are accessed via PCI and therefore can still be read out while
113cores have been offlined. 113cores 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)
35 printf(_("CPU %u: Can't read idle state info\n"), cpu); 35 printf(_("CPU %u: Can't read idle state info\n"), cpu);
36 return; 36 return;
37 } 37 }
38 tmp = sysfs_get_idlestate_name(cpu, idlestates - 1);
39 if (!tmp) {
40 printf(_("Could not determine max idle state %u\n"),
41 idlestates - 1);
42 return;
43 }
44
45 printf(_("Number of idle states: %d\n"), idlestates); 38 printf(_("Number of idle states: %d\n"), idlestates);
46
47 printf(_("Available idle states:")); 39 printf(_("Available idle states:"));
48 for (idlestate = 1; idlestate < idlestates; idlestate++) { 40 for (idlestate = 0; idlestate < idlestates; idlestate++) {
49 tmp = sysfs_get_idlestate_name(cpu, idlestate); 41 tmp = sysfs_get_idlestate_name(cpu, idlestate);
50 if (!tmp) 42 if (!tmp)
51 continue; 43 continue;
@@ -57,7 +49,7 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose)
57 if (!verbose) 49 if (!verbose)
58 return; 50 return;
59 51
60 for (idlestate = 1; idlestate < idlestates; idlestate++) { 52 for (idlestate = 0; idlestate < idlestates; idlestate++) {
61 tmp = sysfs_get_idlestate_name(cpu, idlestate); 53 tmp = sysfs_get_idlestate_name(cpu, idlestate);
62 if (!tmp) 54 if (!tmp)
63 continue; 55 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,
112int amd_pci_get_num_boost_states(int *active, int *states) 112int amd_pci_get_num_boost_states(int *active, int *states)
113{ 113{
114 struct pci_access *pci_acc; 114 struct pci_access *pci_acc;
115 int vendor_id = 0x1022;
116 int boost_dev_ids[4] = {0x1204, 0x1604, 0x1704, 0};
117 struct pci_dev *device; 115 struct pci_dev *device;
118 uint8_t val = 0; 116 uint8_t val = 0;
119 117
120 *active = *states = 0; 118 *active = *states = 0;
121 119
122 device = pci_acc_init(&pci_acc, vendor_id, boost_dev_ids); 120 device = pci_slot_func_init(&pci_acc, 0x18, 4);
123 121
124 if (device == NULL) 122 if (device == NULL)
125 return -ENODEV; 123 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,
66#define CPUPOWER_CAP_AMD_CBP 0x00000004 66#define CPUPOWER_CAP_AMD_CBP 0x00000004
67#define CPUPOWER_CAP_PERF_BIAS 0x00000008 67#define CPUPOWER_CAP_PERF_BIAS 0x00000008
68#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010 68#define CPUPOWER_CAP_HAS_TURBO_RATIO 0x00000010
69#define CPUPOWER_CAP_IS_SNB 0x00000011 69#define CPUPOWER_CAP_IS_SNB 0x00000020
70#define CPUPOWER_CAP_INTEL_IDA 0x00000012 70#define CPUPOWER_CAP_INTEL_IDA 0x00000040
71 71
72#define MAX_HW_PSTATES 10 72#define MAX_HW_PSTATES 10
73 73
@@ -132,8 +132,11 @@ extern unsigned long long msr_intel_get_turbo_ratio(unsigned int cpu);
132 132
133/* PCI stuff ****************************/ 133/* PCI stuff ****************************/
134extern int amd_pci_get_num_boost_states(int *active, int *states); 134extern int amd_pci_get_num_boost_states(int *active, int *states);
135extern struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id, 135extern struct pci_dev *pci_acc_init(struct pci_access **pacc, int domain,
136 int *dev_ids); 136 int bus, int slot, int func, int vendor,
137 int dev);
138extern struct pci_dev *pci_slot_func_init(struct pci_access **pacc,
139 int slot, int func);
137 140
138/* PCI stuff ****************************/ 141/* PCI stuff ****************************/
139 142
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 @@
10 * **pacc : if a valid pci_dev is returned 10 * **pacc : if a valid pci_dev is returned
11 * *pacc must be passed to pci_acc_cleanup to free it 11 * *pacc must be passed to pci_acc_cleanup to free it
12 * 12 *
13 * vendor_id : the pci vendor id matching the pci device to access 13 * domain: domain
14 * dev_ids : device ids matching the pci device to access 14 * bus: bus
15 * slot: slot
16 * func: func
17 * vendor: vendor
18 * device: device
19 * Pass -1 for one of the six above to match any
15 * 20 *
16 * Returns : 21 * Returns :
17 * struct pci_dev which can be used with pci_{read,write}_* functions 22 * struct pci_dev which can be used with pci_{read,write}_* functions
18 * to access the PCI config space of matching pci devices 23 * to access the PCI config space of matching pci devices
19 */ 24 */
20struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id, 25struct pci_dev *pci_acc_init(struct pci_access **pacc, int domain, int bus,
21 int *dev_ids) 26 int slot, int func, int vendor, int dev)
22{ 27{
23 struct pci_filter filter_nb_link = { -1, -1, -1, -1, vendor_id, 0}; 28 struct pci_filter filter_nb_link = { domain, bus, slot, func,
29 vendor, dev };
24 struct pci_dev *device; 30 struct pci_dev *device;
25 unsigned int i;
26 31
27 *pacc = pci_alloc(); 32 *pacc = pci_alloc();
28 if (*pacc == NULL) 33 if (*pacc == NULL)
@@ -31,14 +36,20 @@ struct pci_dev *pci_acc_init(struct pci_access **pacc, int vendor_id,
31 pci_init(*pacc); 36 pci_init(*pacc);
32 pci_scan_bus(*pacc); 37 pci_scan_bus(*pacc);
33 38
34 for (i = 0; dev_ids[i] != 0; i++) { 39 for (device = (*pacc)->devices; device; device = device->next) {
35 filter_nb_link.device = dev_ids[i]; 40 if (pci_filter_match(&filter_nb_link, device))
36 for (device = (*pacc)->devices; device; device = device->next) { 41 return device;
37 if (pci_filter_match(&filter_nb_link, device))
38 return device;
39 }
40 } 42 }
41 pci_cleanup(*pacc); 43 pci_cleanup(*pacc);
42 return NULL; 44 return NULL;
43} 45}
46
47/* Typically one wants to get a specific slot(device)/func of the root domain
48 and bus */
49struct pci_dev *pci_slot_func_init(struct pci_access **pacc, int slot,
50 int func)
51{
52 return pci_acc_init(pacc, 0, 0, slot, func, -1, -1);
53}
54
44#endif /* defined(__i386__) || defined(__x86_64__) */ 55#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 @@
20#include "idle_monitor/cpupower-monitor.h" 20#include "idle_monitor/cpupower-monitor.h"
21#include "helpers/helpers.h" 21#include "helpers/helpers.h"
22 22
23/******** PCI parts could go into own file and get shared ***************/
24
25#define PCI_NON_PC0_OFFSET 0xb0 23#define PCI_NON_PC0_OFFSET 0xb0
26#define PCI_PC1_OFFSET 0xb4 24#define PCI_PC1_OFFSET 0xb4
27#define PCI_PC6_OFFSET 0xb8 25#define PCI_PC6_OFFSET 0xb8
@@ -82,10 +80,7 @@ static cstate_t amd_fam14h_cstates[AMD_FAM14H_STATE_NUM] = {
82}; 80};
83 81
84static struct pci_access *pci_acc; 82static struct pci_access *pci_acc;
85static int pci_vendor_id = 0x1022;
86static int pci_dev_ids[2] = {0x1716, 0};
87static struct pci_dev *amd_fam14h_pci_dev; 83static struct pci_dev *amd_fam14h_pci_dev;
88
89static int nbp1_entered; 84static int nbp1_entered;
90 85
91struct timespec start_time; 86struct timespec start_time;
@@ -286,13 +281,13 @@ struct cpuidle_monitor *amd_fam14h_register(void)
286 if (cpupower_cpu_info.vendor != X86_VENDOR_AMD) 281 if (cpupower_cpu_info.vendor != X86_VENDOR_AMD)
287 return NULL; 282 return NULL;
288 283
289 if (cpupower_cpu_info.family == 0x14) { 284 if (cpupower_cpu_info.family == 0x14)
290 if (cpu_count <= 0 || cpu_count > 2) { 285 strncpy(amd_fam14h_monitor.name, "Fam_14h",
291 fprintf(stderr, "AMD fam14h: Invalid cpu count: %d\n", 286 MONITOR_NAME_LEN - 1);
292 cpu_count); 287 else if (cpupower_cpu_info.family == 0x12)
293 return NULL; 288 strncpy(amd_fam14h_monitor.name, "Fam_12h",
294 } 289 MONITOR_NAME_LEN - 1);
295 } else 290 else
296 return NULL; 291 return NULL;
297 292
298 /* We do not alloc for nbp1 machine wide counter */ 293 /* We do not alloc for nbp1 machine wide counter */
@@ -303,7 +298,9 @@ struct cpuidle_monitor *amd_fam14h_register(void)
303 sizeof(unsigned long long)); 298 sizeof(unsigned long long));
304 } 299 }
305 300
306 amd_fam14h_pci_dev = pci_acc_init(&pci_acc, pci_vendor_id, pci_dev_ids); 301 /* We need PCI device: Slot 18, Func 6, compare with BKDG
302 for fam 12h/14h */
303 amd_fam14h_pci_dev = pci_slot_func_init(&pci_acc, 0x18, 6);
307 if (amd_fam14h_pci_dev == NULL || pci_acc == NULL) 304 if (amd_fam14h_pci_dev == NULL || pci_acc == NULL)
308 return NULL; 305 return NULL;
309 306
@@ -325,7 +322,7 @@ static void amd_fam14h_unregister(void)
325} 322}
326 323
327struct cpuidle_monitor amd_fam14h_monitor = { 324struct cpuidle_monitor amd_fam14h_monitor = {
328 .name = "Ontario", 325 .name = "",
329 .hw_states = amd_fam14h_cstates, 326 .hw_states = amd_fam14h_cstates,
330 .hw_states_num = AMD_FAM14H_STATE_NUM, 327 .hw_states_num = AMD_FAM14H_STATE_NUM,
331 .start = amd_fam14h_start, 328 .start = amd_fam14h_start,
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 758ec2a08c40..95d6a6f7c33a 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -46,6 +46,7 @@ my %default = (
46 "DIE_ON_FAILURE" => 1, 46 "DIE_ON_FAILURE" => 1,
47 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND", 47 "SSH_EXEC" => "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND",
48 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE", 48 "SCP_TO_TARGET" => "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE",
49 "SCP_TO_TARGET_INSTALL" => "\${SCP_TO_TARGET}",
49 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot", 50 "REBOOT" => "ssh \$SSH_USER\@\$MACHINE reboot",
50 "STOP_AFTER_SUCCESS" => 10, 51 "STOP_AFTER_SUCCESS" => 10,
51 "STOP_AFTER_FAILURE" => 60, 52 "STOP_AFTER_FAILURE" => 60,
@@ -86,11 +87,13 @@ my $reboot_on_error;
86my $switch_to_good; 87my $switch_to_good;
87my $switch_to_test; 88my $switch_to_test;
88my $poweroff_on_error; 89my $poweroff_on_error;
90my $reboot_on_success;
89my $die_on_failure; 91my $die_on_failure;
90my $powercycle_after_reboot; 92my $powercycle_after_reboot;
91my $poweroff_after_halt; 93my $poweroff_after_halt;
92my $ssh_exec; 94my $ssh_exec;
93my $scp_to_target; 95my $scp_to_target;
96my $scp_to_target_install;
94my $power_off; 97my $power_off;
95my $grub_menu; 98my $grub_menu;
96my $grub_number; 99my $grub_number;
@@ -211,6 +214,7 @@ my %option_map = (
211 "SWITCH_TO_GOOD" => \$switch_to_good, 214 "SWITCH_TO_GOOD" => \$switch_to_good,
212 "SWITCH_TO_TEST" => \$switch_to_test, 215 "SWITCH_TO_TEST" => \$switch_to_test,
213 "POWEROFF_ON_ERROR" => \$poweroff_on_error, 216 "POWEROFF_ON_ERROR" => \$poweroff_on_error,
217 "REBOOT_ON_SUCCESS" => \$reboot_on_success,
214 "DIE_ON_FAILURE" => \$die_on_failure, 218 "DIE_ON_FAILURE" => \$die_on_failure,
215 "POWER_OFF" => \$power_off, 219 "POWER_OFF" => \$power_off,
216 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot, 220 "POWERCYCLE_AFTER_REBOOT" => \$powercycle_after_reboot,
@@ -243,6 +247,7 @@ my %option_map = (
243 "BUILD_TARGET" => \$build_target, 247 "BUILD_TARGET" => \$build_target,
244 "SSH_EXEC" => \$ssh_exec, 248 "SSH_EXEC" => \$ssh_exec,
245 "SCP_TO_TARGET" => \$scp_to_target, 249 "SCP_TO_TARGET" => \$scp_to_target,
250 "SCP_TO_TARGET_INSTALL" => \$scp_to_target_install,
246 "CHECKOUT" => \$checkout, 251 "CHECKOUT" => \$checkout,
247 "TARGET_IMAGE" => \$target_image, 252 "TARGET_IMAGE" => \$target_image,
248 "LOCALVERSION" => \$localversion, 253 "LOCALVERSION" => \$localversion,
@@ -1113,7 +1118,6 @@ sub reboot_to_good {
1113 1118
1114 if (defined($switch_to_good)) { 1119 if (defined($switch_to_good)) {
1115 run_command $switch_to_good; 1120 run_command $switch_to_good;
1116 return;
1117 } 1121 }
1118 1122
1119 reboot $time; 1123 reboot $time;
@@ -1349,8 +1353,7 @@ sub run_ssh {
1349} 1353}
1350 1354
1351sub run_scp { 1355sub run_scp {
1352 my ($src, $dst) = @_; 1356 my ($src, $dst, $cp_scp) = @_;
1353 my $cp_scp = $scp_to_target;
1354 1357
1355 $cp_scp =~ s/\$SRC_FILE/$src/g; 1358 $cp_scp =~ s/\$SRC_FILE/$src/g;
1356 $cp_scp =~ s/\$DST_FILE/$dst/g; 1359 $cp_scp =~ s/\$DST_FILE/$dst/g;
@@ -1358,6 +1361,22 @@ sub run_scp {
1358 return run_command "$cp_scp"; 1361 return run_command "$cp_scp";
1359} 1362}
1360 1363
1364sub run_scp_install {
1365 my ($src, $dst) = @_;
1366
1367 my $cp_scp = $scp_to_target_install;
1368
1369 return run_scp($src, $dst, $cp_scp);
1370}
1371
1372sub run_scp_mod {
1373 my ($src, $dst) = @_;
1374
1375 my $cp_scp = $scp_to_target;
1376
1377 return run_scp($src, $dst, $cp_scp);
1378}
1379
1361sub get_grub_index { 1380sub get_grub_index {
1362 1381
1363 if ($reboot_type ne "grub") { 1382 if ($reboot_type ne "grub") {
@@ -1460,6 +1479,7 @@ sub get_sha1 {
1460sub monitor { 1479sub monitor {
1461 my $booted = 0; 1480 my $booted = 0;
1462 my $bug = 0; 1481 my $bug = 0;
1482 my $bug_ignored = 0;
1463 my $skip_call_trace = 0; 1483 my $skip_call_trace = 0;
1464 my $loops; 1484 my $loops;
1465 1485
@@ -1531,9 +1551,13 @@ sub monitor {
1531 } 1551 }
1532 1552
1533 if ($full_line =~ /call trace:/i) { 1553 if ($full_line =~ /call trace:/i) {
1534 if (!$ignore_errors && !$bug && !$skip_call_trace) { 1554 if (!$bug && !$skip_call_trace) {
1535 $bug = 1; 1555 if ($ignore_errors) {
1536 $failure_start = time; 1556 $bug_ignored = 1;
1557 } else {
1558 $bug = 1;
1559 $failure_start = time;
1560 }
1537 } 1561 }
1538 } 1562 }
1539 1563
@@ -1595,6 +1619,10 @@ sub monitor {
1595 fail "failed - never got a boot prompt." and return 0; 1619 fail "failed - never got a boot prompt." and return 0;
1596 } 1620 }
1597 1621
1622 if ($bug_ignored) {
1623 doprint "WARNING: Call Trace detected but ignored due to IGNORE_ERRORS=1\n";
1624 }
1625
1598 return 1; 1626 return 1;
1599} 1627}
1600 1628
@@ -1621,7 +1649,7 @@ sub install {
1621 1649
1622 my $cp_target = eval_kernel_version $target_image; 1650 my $cp_target = eval_kernel_version $target_image;
1623 1651
1624 run_scp "$outputdir/$build_target", "$cp_target" or 1652 run_scp_install "$outputdir/$build_target", "$cp_target" or
1625 dodie "failed to copy image"; 1653 dodie "failed to copy image";
1626 1654
1627 my $install_mods = 0; 1655 my $install_mods = 0;
@@ -1643,7 +1671,7 @@ sub install {
1643 return; 1671 return;
1644 } 1672 }
1645 1673
1646 run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or 1674 run_command "$make INSTALL_MOD_STRIP=1 INSTALL_MOD_PATH=$tmpdir modules_install" or
1647 dodie "Failed to install modules"; 1675 dodie "Failed to install modules";
1648 1676
1649 my $modlib = "/lib/modules/$version"; 1677 my $modlib = "/lib/modules/$version";
@@ -1656,7 +1684,7 @@ sub install {
1656 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or 1684 run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or
1657 dodie "making tarball"; 1685 dodie "making tarball";
1658 1686
1659 run_scp "$tmpdir/$modtar", "/tmp" or 1687 run_scp_mod "$tmpdir/$modtar", "/tmp" or
1660 dodie "failed to copy modules"; 1688 dodie "failed to copy modules";
1661 1689
1662 unlink "$tmpdir/$modtar"; 1690 unlink "$tmpdir/$modtar";
@@ -3526,8 +3554,10 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
3526 die "failed to checkout $checkout"; 3554 die "failed to checkout $checkout";
3527 } 3555 }
3528 3556
3529 $no_reboot = 0; 3557 # A test may opt to not reboot the box
3530 3558 if ($reboot_on_success) {
3559 $no_reboot = 0;
3560 }
3531 3561
3532 if ($test_type eq "bisect") { 3562 if ($test_type eq "bisect") {
3533 bisect $i; 3563 bisect $i;
@@ -3572,8 +3602,12 @@ if ($opt{"POWEROFF_ON_SUCCESS"}) {
3572 halt; 3602 halt;
3573} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { 3603} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) {
3574 reboot_to_good; 3604 reboot_to_good;
3605} elsif (defined($switch_to_good)) {
3606 # still need to get to the good kernel
3607 run_command $switch_to_good;
3575} 3608}
3576 3609
3610
3577doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; 3611doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n";
3578 3612
3579exit 0; 3613exit 0;
diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf
index 5ea04c6a71bf..b682456afda8 100644
--- a/tools/testing/ktest/sample.conf
+++ b/tools/testing/ktest/sample.conf
@@ -710,10 +710,18 @@
710# The variables SSH_USER, MACHINE and SSH_COMMAND are defined 710# The variables SSH_USER, MACHINE and SSH_COMMAND are defined
711#SSH_EXEC = ssh $SSH_USER@$MACHINE $SSH_COMMAND"; 711#SSH_EXEC = ssh $SSH_USER@$MACHINE $SSH_COMMAND";
712 712
713# The way to copy a file to the target 713# The way to copy a file to the target (install and modules)
714# (default scp $SRC_FILE $SSH_USER@$MACHINE:$DST_FILE) 714# (default scp $SRC_FILE $SSH_USER@$MACHINE:$DST_FILE)
715# The variables SSH_USER, MACHINE, SRC_FILE and DST_FILE are defined. 715# The variables SSH_USER, MACHINE are defined by the config
716#SCP_TO_TARGET = scp $SRC_FILE $SSH_USER@$MACHINE:$DST_FILE 716# SRC_FILE and DST_FILE are ktest internal variables and
717# should only have '$' and not the '${}' notation.
718# (default scp $SRC_FILE ${SSH_USER}@${MACHINE}:$DST_FILE)
719#SCP_TO_TARGET = echo skip scp for $SRC_FILE $DST_FILE
720
721# If install needs to be different than modules, then this
722# option will override the SCP_TO_TARGET for installation.
723# (default ${SCP_TO_TARGET} )
724#SCP_TO_TARGET_INSTALL = scp $SRC_FILE tftp@tftpserver:$DST_FILE
717 725
718# The nice way to reboot the target 726# The nice way to reboot the target
719# (default ssh $SSH_USER@$MACHINE reboot) 727# (default ssh $SSH_USER@$MACHINE reboot)
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 4ec84018cc13..28bc57ee757c 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,10 +1,15 @@
1TARGETS = breakpoints 1TARGETS = breakpoints vm
2 2
3all: 3all:
4 for TARGET in $(TARGETS); do \ 4 for TARGET in $(TARGETS); do \
5 make -C $$TARGET; \ 5 make -C $$TARGET; \
6 done; 6 done;
7 7
8run_tests: all
9 for TARGET in $(TARGETS); do \
10 make -C $$TARGET run_tests; \
11 done;
12
8clean: 13clean:
9 for TARGET in $(TARGETS); do \ 14 for TARGET in $(TARGETS); do \
10 make -C $$TARGET clean; \ 15 make -C $$TARGET clean; \
diff --git a/tools/testing/selftests/breakpoints/Makefile b/tools/testing/selftests/breakpoints/Makefile
index f362722cdce7..931278035f5c 100644
--- a/tools/testing/selftests/breakpoints/Makefile
+++ b/tools/testing/selftests/breakpoints/Makefile
@@ -11,10 +11,13 @@ endif
11 11
12all: 12all:
13ifeq ($(ARCH),x86) 13ifeq ($(ARCH),x86)
14 gcc breakpoint_test.c -o run_test 14 gcc breakpoint_test.c -o breakpoint_test
15else 15else
16 echo "Not an x86 target, can't build breakpoints selftests" 16 echo "Not an x86 target, can't build breakpoints selftests"
17endif 17endif
18 18
19run_tests:
20 ./breakpoint_test
21
19clean: 22clean:
20 rm -fr run_test 23 rm -fr breakpoint_test
diff --git a/tools/testing/selftests/run_tests b/tools/testing/selftests/run_tests
deleted file mode 100644
index 320718a4e6bf..000000000000
--- a/tools/testing/selftests/run_tests
+++ /dev/null
@@ -1,8 +0,0 @@
1#!/bin/bash
2
3TARGETS=breakpoints
4
5for TARGET in $TARGETS
6do
7 $TARGET/run_test
8done
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
new file mode 100644
index 000000000000..b336b24aa6c0
--- /dev/null
+++ b/tools/testing/selftests/vm/Makefile
@@ -0,0 +1,14 @@
1# Makefile for vm selftests
2
3CC = $(CROSS_COMPILE)gcc
4CFLAGS = -Wall -Wextra
5
6all: hugepage-mmap hugepage-shm map_hugetlb
7%: %.c
8 $(CC) $(CFLAGS) -o $@ $^
9
10run_tests: all
11 /bin/sh ./run_vmtests
12
13clean:
14 $(RM) hugepage-mmap hugepage-shm map_hugetlb
diff --git a/tools/testing/selftests/vm/hugepage-mmap.c b/tools/testing/selftests/vm/hugepage-mmap.c
new file mode 100644
index 000000000000..a10f310d2362
--- /dev/null
+++ b/tools/testing/selftests/vm/hugepage-mmap.c
@@ -0,0 +1,92 @@
1/*
2 * hugepage-mmap:
3 *
4 * Example of using huge page memory in a user application using the mmap
5 * system call. Before running this application, make sure that the
6 * administrator has mounted the hugetlbfs filesystem (on some directory
7 * like /mnt) using the command mount -t hugetlbfs nodev /mnt. In this
8 * example, the app is requesting memory of size 256MB that is backed by
9 * huge pages.
10 *
11 * For the ia64 architecture, the Linux kernel reserves Region number 4 for
12 * huge pages. That means that if one requires a fixed address, a huge page
13 * aligned address starting with 0x800000... will be required. If a fixed
14 * address is not required, the kernel will select an address in the proper
15 * range.
16 * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
17 */
18
19#include <stdlib.h>
20#include <stdio.h>
21#include <unistd.h>
22#include <sys/mman.h>
23#include <fcntl.h>
24
25#define FILE_NAME "huge/hugepagefile"
26#define LENGTH (256UL*1024*1024)
27#define PROTECTION (PROT_READ | PROT_WRITE)
28
29/* Only ia64 requires this */
30#ifdef __ia64__
31#define ADDR (void *)(0x8000000000000000UL)
32#define FLAGS (MAP_SHARED | MAP_FIXED)
33#else
34#define ADDR (void *)(0x0UL)
35#define FLAGS (MAP_SHARED)
36#endif
37
38static void check_bytes(char *addr)
39{
40 printf("First hex is %x\n", *((unsigned int *)addr));
41}
42
43static void write_bytes(char *addr)
44{
45 unsigned long i;
46
47 for (i = 0; i < LENGTH; i++)
48 *(addr + i) = (char)i;
49}
50
51static int read_bytes(char *addr)
52{
53 unsigned long i;
54
55 check_bytes(addr);
56 for (i = 0; i < LENGTH; i++)
57 if (*(addr + i) != (char)i) {
58 printf("Mismatch at %lu\n", i);
59 return 1;
60 }
61 return 0;
62}
63
64int main(void)
65{
66 void *addr;
67 int fd, ret;
68
69 fd = open(FILE_NAME, O_CREAT | O_RDWR, 0755);
70 if (fd < 0) {
71 perror("Open failed");
72 exit(1);
73 }
74
75 addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, fd, 0);
76 if (addr == MAP_FAILED) {
77 perror("mmap");
78 unlink(FILE_NAME);
79 exit(1);
80 }
81
82 printf("Returned address is %p\n", addr);
83 check_bytes(addr);
84 write_bytes(addr);
85 ret = read_bytes(addr);
86
87 munmap(addr, LENGTH);
88 close(fd);
89 unlink(FILE_NAME);
90
91 return ret;
92}
diff --git a/tools/testing/selftests/vm/hugepage-shm.c b/tools/testing/selftests/vm/hugepage-shm.c
new file mode 100644
index 000000000000..0d0ef4fc0c04
--- /dev/null
+++ b/tools/testing/selftests/vm/hugepage-shm.c
@@ -0,0 +1,100 @@
1/*
2 * hugepage-shm:
3 *
4 * Example of using huge page memory in a user application using Sys V shared
5 * memory system calls. In this example the app is requesting 256MB of
6 * memory that is backed by huge pages. The application uses the flag
7 * SHM_HUGETLB in the shmget system call to inform the kernel that it is
8 * requesting huge pages.
9 *
10 * For the ia64 architecture, the Linux kernel reserves Region number 4 for
11 * huge pages. That means that if one requires a fixed address, a huge page
12 * aligned address starting with 0x800000... will be required. If a fixed
13 * address is not required, the kernel will select an address in the proper
14 * range.
15 * Other architectures, such as ppc64, i386 or x86_64 are not so constrained.
16 *
17 * Note: The default shared memory limit is quite low on many kernels,
18 * you may need to increase it via:
19 *
20 * echo 268435456 > /proc/sys/kernel/shmmax
21 *
22 * This will increase the maximum size per shared memory segment to 256MB.
23 * The other limit that you will hit eventually is shmall which is the
24 * total amount of shared memory in pages. To set it to 16GB on a system
25 * with a 4kB pagesize do:
26 *
27 * echo 4194304 > /proc/sys/kernel/shmall
28 */
29
30#include <stdlib.h>
31#include <stdio.h>
32#include <sys/types.h>
33#include <sys/ipc.h>
34#include <sys/shm.h>
35#include <sys/mman.h>
36
37#ifndef SHM_HUGETLB
38#define SHM_HUGETLB 04000
39#endif
40
41#define LENGTH (256UL*1024*1024)
42
43#define dprintf(x) printf(x)
44
45/* Only ia64 requires this */
46#ifdef __ia64__
47#define ADDR (void *)(0x8000000000000000UL)
48#define SHMAT_FLAGS (SHM_RND)
49#else
50#define ADDR (void *)(0x0UL)
51#define SHMAT_FLAGS (0)
52#endif
53
54int main(void)
55{
56 int shmid;
57 unsigned long i;
58 char *shmaddr;
59
60 shmid = shmget(2, LENGTH, SHM_HUGETLB | IPC_CREAT | SHM_R | SHM_W);
61 if (shmid < 0) {
62 perror("shmget");
63 exit(1);
64 }
65 printf("shmid: 0x%x\n", shmid);
66
67 shmaddr = shmat(shmid, ADDR, SHMAT_FLAGS);
68 if (shmaddr == (char *)-1) {
69 perror("Shared memory attach failure");
70 shmctl(shmid, IPC_RMID, NULL);
71 exit(2);
72 }
73 printf("shmaddr: %p\n", shmaddr);
74
75 dprintf("Starting the writes:\n");
76 for (i = 0; i < LENGTH; i++) {
77 shmaddr[i] = (char)(i);
78 if (!(i % (1024 * 1024)))
79 dprintf(".");
80 }
81 dprintf("\n");
82
83 dprintf("Starting the Check...");
84 for (i = 0; i < LENGTH; i++)
85 if (shmaddr[i] != (char)i) {
86 printf("\nIndex %lu mismatched\n", i);
87 exit(3);
88 }
89 dprintf("Done.\n");
90
91 if (shmdt((const void *)shmaddr) != 0) {
92 perror("Detach failure");
93 shmctl(shmid, IPC_RMID, NULL);
94 exit(4);
95 }
96
97 shmctl(shmid, IPC_RMID, NULL);
98
99 return 0;
100}
diff --git a/tools/testing/selftests/vm/map_hugetlb.c b/tools/testing/selftests/vm/map_hugetlb.c
new file mode 100644
index 000000000000..ac56639dd4a9
--- /dev/null
+++ b/tools/testing/selftests/vm/map_hugetlb.c
@@ -0,0 +1,79 @@
1/*
2 * Example of using hugepage memory in a user application using the mmap
3 * system call with MAP_HUGETLB flag. Before running this program make
4 * sure the administrator has allocated enough default sized huge pages
5 * to cover the 256 MB allocation.
6 *
7 * For ia64 architecture, Linux kernel reserves Region number 4 for hugepages.
8 * That means the addresses starting with 0x800000... will need to be
9 * specified. Specifying a fixed address is not required on ppc64, i386
10 * or x86_64.
11 */
12#include <stdlib.h>
13#include <stdio.h>
14#include <unistd.h>
15#include <sys/mman.h>
16#include <fcntl.h>
17
18#define LENGTH (256UL*1024*1024)
19#define PROTECTION (PROT_READ | PROT_WRITE)
20
21#ifndef MAP_HUGETLB
22#define MAP_HUGETLB 0x40000 /* arch specific */
23#endif
24
25/* Only ia64 requires this */
26#ifdef __ia64__
27#define ADDR (void *)(0x8000000000000000UL)
28#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_FIXED)
29#else
30#define ADDR (void *)(0x0UL)
31#define FLAGS (MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB)
32#endif
33
34static void check_bytes(char *addr)
35{
36 printf("First hex is %x\n", *((unsigned int *)addr));
37}
38
39static void write_bytes(char *addr)
40{
41 unsigned long i;
42
43 for (i = 0; i < LENGTH; i++)
44 *(addr + i) = (char)i;
45}
46
47static int read_bytes(char *addr)
48{
49 unsigned long i;
50
51 check_bytes(addr);
52 for (i = 0; i < LENGTH; i++)
53 if (*(addr + i) != (char)i) {
54 printf("Mismatch at %lu\n", i);
55 return 1;
56 }
57 return 0;
58}
59
60int main(void)
61{
62 void *addr;
63 int ret;
64
65 addr = mmap(ADDR, LENGTH, PROTECTION, FLAGS, 0, 0);
66 if (addr == MAP_FAILED) {
67 perror("mmap");
68 exit(1);
69 }
70
71 printf("Returned address is %p\n", addr);
72 check_bytes(addr);
73 write_bytes(addr);
74 ret = read_bytes(addr);
75
76 munmap(addr, LENGTH);
77
78 return ret;
79}
diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests
new file mode 100644
index 000000000000..8b40bd5e5cc2
--- /dev/null
+++ b/tools/testing/selftests/vm/run_vmtests
@@ -0,0 +1,77 @@
1#!/bin/bash
2#please run as root
3
4#we need 256M, below is the size in kB
5needmem=262144
6mnt=./huge
7
8#get pagesize and freepages from /proc/meminfo
9while read name size unit; do
10 if [ "$name" = "HugePages_Free:" ]; then
11 freepgs=$size
12 fi
13 if [ "$name" = "Hugepagesize:" ]; then
14 pgsize=$size
15 fi
16done < /proc/meminfo
17
18#set proper nr_hugepages
19if [ -n "$freepgs" ] && [ -n "$pgsize" ]; then
20 nr_hugepgs=`cat /proc/sys/vm/nr_hugepages`
21 needpgs=`expr $needmem / $pgsize`
22 if [ $freepgs -lt $needpgs ]; then
23 lackpgs=$(( $needpgs - $freepgs ))
24 echo $(( $lackpgs + $nr_hugepgs )) > /proc/sys/vm/nr_hugepages
25 if [ $? -ne 0 ]; then
26 echo "Please run this test as root"
27 exit 1
28 fi
29 fi
30else
31 echo "no hugetlbfs support in kernel?"
32 exit 1
33fi
34
35mkdir $mnt
36mount -t hugetlbfs none $mnt
37
38echo "--------------------"
39echo "runing hugepage-mmap"
40echo "--------------------"
41./hugepage-mmap
42if [ $? -ne 0 ]; then
43 echo "[FAIL]"
44else
45 echo "[PASS]"
46fi
47
48shmmax=`cat /proc/sys/kernel/shmmax`
49shmall=`cat /proc/sys/kernel/shmall`
50echo 268435456 > /proc/sys/kernel/shmmax
51echo 4194304 > /proc/sys/kernel/shmall
52echo "--------------------"
53echo "runing hugepage-shm"
54echo "--------------------"
55./hugepage-shm
56if [ $? -ne 0 ]; then
57 echo "[FAIL]"
58else
59 echo "[PASS]"
60fi
61echo $shmmax > /proc/sys/kernel/shmmax
62echo $shmall > /proc/sys/kernel/shmall
63
64echo "--------------------"
65echo "runing map_hugetlb"
66echo "--------------------"
67./map_hugetlb
68if [ $? -ne 0 ]; then
69 echo "[FAIL]"
70else
71 echo "[PASS]"
72fi
73
74#cleanup
75umount $mnt
76rm -rf $mnt
77echo $nr_hugepgs > /proc/sys/vm/nr_hugepages
diff --git a/tools/virtio/linux/hrtimer.h b/tools/virtio/linux/hrtimer.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/virtio/linux/hrtimer.h
diff --git a/tools/virtio/linux/module.h b/tools/virtio/linux/module.h
new file mode 100644
index 000000000000..e69de29bb2d1
--- /dev/null
+++ b/tools/virtio/linux/module.h
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
index b4fbc91c41b4..7579f19e61e0 100644
--- a/tools/virtio/linux/virtio.h
+++ b/tools/virtio/linux/virtio.h
@@ -181,6 +181,9 @@ struct virtqueue {
181#define smp_mb() mb() 181#define smp_mb() mb()
182# define smp_rmb() barrier() 182# define smp_rmb() barrier()
183# define smp_wmb() barrier() 183# define smp_wmb() barrier()
184/* Weak barriers should be used. If not - it's a bug */
185# define rmb() abort()
186# define wmb() abort()
184#else 187#else
185#error Please fill in barrier macros 188#error Please fill in barrier macros
186#endif 189#endif
diff --git a/tools/vm/Makefile b/tools/vm/Makefile
new file mode 100644
index 000000000000..8e30e5c40f8a
--- /dev/null
+++ b/tools/vm/Makefile
@@ -0,0 +1,11 @@
1# Makefile for vm tools
2
3CC = $(CROSS_COMPILE)gcc
4CFLAGS = -Wall -Wextra
5
6all: page-types slabinfo
7%: %.c
8 $(CC) $(CFLAGS) -o $@ $^
9
10clean:
11 $(RM) page-types slabinfo
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c
new file mode 100644
index 000000000000..7dab7b25b5c6
--- /dev/null
+++ b/tools/vm/page-types.c
@@ -0,0 +1,1102 @@
1/*
2 * page-types: Tool for querying page flags
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; version 2.
7 *
8 * This program is distributed in the hope that it will be useful, but WITHOUT
9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11 * more details.
12 *
13 * You should find a copy of v2 of the GNU General Public License somewhere on
14 * your Linux system; if not, write to the Free Software Foundation, Inc., 59
15 * Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16 *
17 * Copyright (C) 2009 Intel corporation
18 *
19 * Authors: Wu Fengguang <fengguang.wu@intel.com>
20 */
21
22#define _LARGEFILE64_SOURCE
23#include <stdio.h>
24#include <stdlib.h>
25#include <unistd.h>
26#include <stdint.h>
27#include <stdarg.h>
28#include <string.h>
29#include <getopt.h>
30#include <limits.h>
31#include <assert.h>
32#include <sys/types.h>
33#include <sys/errno.h>
34#include <sys/fcntl.h>
35#include <sys/mount.h>
36#include <sys/statfs.h>
37#include "../../include/linux/magic.h"
38
39
40#ifndef MAX_PATH
41# define MAX_PATH 256
42#endif
43
44#ifndef STR
45# define _STR(x) #x
46# define STR(x) _STR(x)
47#endif
48
49/*
50 * pagemap kernel ABI bits
51 */
52
53#define PM_ENTRY_BYTES sizeof(uint64_t)
54#define PM_STATUS_BITS 3
55#define PM_STATUS_OFFSET (64 - PM_STATUS_BITS)
56#define PM_STATUS_MASK (((1LL << PM_STATUS_BITS) - 1) << PM_STATUS_OFFSET)
57#define PM_STATUS(nr) (((nr) << PM_STATUS_OFFSET) & PM_STATUS_MASK)
58#define PM_PSHIFT_BITS 6
59#define PM_PSHIFT_OFFSET (PM_STATUS_OFFSET - PM_PSHIFT_BITS)
60#define PM_PSHIFT_MASK (((1LL << PM_PSHIFT_BITS) - 1) << PM_PSHIFT_OFFSET)
61#define PM_PSHIFT(x) (((u64) (x) << PM_PSHIFT_OFFSET) & PM_PSHIFT_MASK)
62#define PM_PFRAME_MASK ((1LL << PM_PSHIFT_OFFSET) - 1)
63#define PM_PFRAME(x) ((x) & PM_PFRAME_MASK)
64
65#define PM_PRESENT PM_STATUS(4LL)
66#define PM_SWAP PM_STATUS(2LL)
67
68
69/*
70 * kernel page flags
71 */
72
73#define KPF_BYTES 8
74#define PROC_KPAGEFLAGS "/proc/kpageflags"
75
76/* copied from kpageflags_read() */
77#define KPF_LOCKED 0
78#define KPF_ERROR 1
79#define KPF_REFERENCED 2
80#define KPF_UPTODATE 3
81#define KPF_DIRTY 4
82#define KPF_LRU 5
83#define KPF_ACTIVE 6
84#define KPF_SLAB 7
85#define KPF_WRITEBACK 8
86#define KPF_RECLAIM 9
87#define KPF_BUDDY 10
88
89/* [11-20] new additions in 2.6.31 */
90#define KPF_MMAP 11
91#define KPF_ANON 12
92#define KPF_SWAPCACHE 13
93#define KPF_SWAPBACKED 14
94#define KPF_COMPOUND_HEAD 15
95#define KPF_COMPOUND_TAIL 16
96#define KPF_HUGE 17
97#define KPF_UNEVICTABLE 18
98#define KPF_HWPOISON 19
99#define KPF_NOPAGE 20
100#define KPF_KSM 21
101#define KPF_THP 22
102
103/* [32-] kernel hacking assistances */
104#define KPF_RESERVED 32
105#define KPF_MLOCKED 33
106#define KPF_MAPPEDTODISK 34
107#define KPF_PRIVATE 35
108#define KPF_PRIVATE_2 36
109#define KPF_OWNER_PRIVATE 37
110#define KPF_ARCH 38
111#define KPF_UNCACHED 39
112
113/* [48-] take some arbitrary free slots for expanding overloaded flags
114 * not part of kernel API
115 */
116#define KPF_READAHEAD 48
117#define KPF_SLOB_FREE 49
118#define KPF_SLUB_FROZEN 50
119#define KPF_SLUB_DEBUG 51
120
121#define KPF_ALL_BITS ((uint64_t)~0ULL)
122#define KPF_HACKERS_BITS (0xffffULL << 32)
123#define KPF_OVERLOADED_BITS (0xffffULL << 48)
124#define BIT(name) (1ULL << KPF_##name)
125#define BITS_COMPOUND (BIT(COMPOUND_HEAD) | BIT(COMPOUND_TAIL))
126
127static const char * const page_flag_names[] = {
128 [KPF_LOCKED] = "L:locked",
129 [KPF_ERROR] = "E:error",
130 [KPF_REFERENCED] = "R:referenced",
131 [KPF_UPTODATE] = "U:uptodate",
132 [KPF_DIRTY] = "D:dirty",
133 [KPF_LRU] = "l:lru",
134 [KPF_ACTIVE] = "A:active",
135 [KPF_SLAB] = "S:slab",
136 [KPF_WRITEBACK] = "W:writeback",
137 [KPF_RECLAIM] = "I:reclaim",
138 [KPF_BUDDY] = "B:buddy",
139
140 [KPF_MMAP] = "M:mmap",
141 [KPF_ANON] = "a:anonymous",
142 [KPF_SWAPCACHE] = "s:swapcache",
143 [KPF_SWAPBACKED] = "b:swapbacked",
144 [KPF_COMPOUND_HEAD] = "H:compound_head",
145 [KPF_COMPOUND_TAIL] = "T:compound_tail",
146 [KPF_HUGE] = "G:huge",
147 [KPF_UNEVICTABLE] = "u:unevictable",
148 [KPF_HWPOISON] = "X:hwpoison",
149 [KPF_NOPAGE] = "n:nopage",
150 [KPF_KSM] = "x:ksm",
151 [KPF_THP] = "t:thp",
152
153 [KPF_RESERVED] = "r:reserved",
154 [KPF_MLOCKED] = "m:mlocked",
155 [KPF_MAPPEDTODISK] = "d:mappedtodisk",
156 [KPF_PRIVATE] = "P:private",
157 [KPF_PRIVATE_2] = "p:private_2",
158 [KPF_OWNER_PRIVATE] = "O:owner_private",
159 [KPF_ARCH] = "h:arch",
160 [KPF_UNCACHED] = "c:uncached",
161
162 [KPF_READAHEAD] = "I:readahead",
163 [KPF_SLOB_FREE] = "P:slob_free",
164 [KPF_SLUB_FROZEN] = "A:slub_frozen",
165 [KPF_SLUB_DEBUG] = "E:slub_debug",
166};
167
168
169static const char * const debugfs_known_mountpoints[] = {
170 "/sys/kernel/debug",
171 "/debug",
172 0,
173};
174
175/*
176 * data structures
177 */
178
179static int opt_raw; /* for kernel developers */
180static int opt_list; /* list pages (in ranges) */
181static int opt_no_summary; /* don't show summary */
182static pid_t opt_pid; /* process to walk */
183
184#define MAX_ADDR_RANGES 1024
185static int nr_addr_ranges;
186static unsigned long opt_offset[MAX_ADDR_RANGES];
187static unsigned long opt_size[MAX_ADDR_RANGES];
188
189#define MAX_VMAS 10240
190static int nr_vmas;
191static unsigned long pg_start[MAX_VMAS];
192static unsigned long pg_end[MAX_VMAS];
193
194#define MAX_BIT_FILTERS 64
195static int nr_bit_filters;
196static uint64_t opt_mask[MAX_BIT_FILTERS];
197static uint64_t opt_bits[MAX_BIT_FILTERS];
198
199static int page_size;
200
201static int pagemap_fd;
202static int kpageflags_fd;
203
204static int opt_hwpoison;
205static int opt_unpoison;
206
207static char hwpoison_debug_fs[MAX_PATH+1];
208static int hwpoison_inject_fd;
209static int hwpoison_forget_fd;
210
211#define HASH_SHIFT 13
212#define HASH_SIZE (1 << HASH_SHIFT)
213#define HASH_MASK (HASH_SIZE - 1)
214#define HASH_KEY(flags) (flags & HASH_MASK)
215
216static unsigned long total_pages;
217static unsigned long nr_pages[HASH_SIZE];
218static uint64_t page_flags[HASH_SIZE];
219
220
221/*
222 * helper functions
223 */
224
225#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
226
227#define min_t(type, x, y) ({ \
228 type __min1 = (x); \
229 type __min2 = (y); \
230 __min1 < __min2 ? __min1 : __min2; })
231
232#define max_t(type, x, y) ({ \
233 type __max1 = (x); \
234 type __max2 = (y); \
235 __max1 > __max2 ? __max1 : __max2; })
236
237static unsigned long pages2mb(unsigned long pages)
238{
239 return (pages * page_size) >> 20;
240}
241
242static void fatal(const char *x, ...)
243{
244 va_list ap;
245
246 va_start(ap, x);
247 vfprintf(stderr, x, ap);
248 va_end(ap);
249 exit(EXIT_FAILURE);
250}
251
252static int checked_open(const char *pathname, int flags)
253{
254 int fd = open(pathname, flags);
255
256 if (fd < 0) {
257 perror(pathname);
258 exit(EXIT_FAILURE);
259 }
260
261 return fd;
262}
263
264/*
265 * pagemap/kpageflags routines
266 */
267
268static unsigned long do_u64_read(int fd, char *name,
269 uint64_t *buf,
270 unsigned long index,
271 unsigned long count)
272{
273 long bytes;
274
275 if (index > ULONG_MAX / 8)
276 fatal("index overflow: %lu\n", index);
277
278 if (lseek(fd, index * 8, SEEK_SET) < 0) {
279 perror(name);
280 exit(EXIT_FAILURE);
281 }
282
283 bytes = read(fd, buf, count * 8);
284 if (bytes < 0) {
285 perror(name);
286 exit(EXIT_FAILURE);
287 }
288 if (bytes % 8)
289 fatal("partial read: %lu bytes\n", bytes);
290
291 return bytes / 8;
292}
293
294static unsigned long kpageflags_read(uint64_t *buf,
295 unsigned long index,
296 unsigned long pages)
297{
298 return do_u64_read(kpageflags_fd, PROC_KPAGEFLAGS, buf, index, pages);
299}
300
301static unsigned long pagemap_read(uint64_t *buf,
302 unsigned long index,
303 unsigned long pages)
304{
305 return do_u64_read(pagemap_fd, "/proc/pid/pagemap", buf, index, pages);
306}
307
308static unsigned long pagemap_pfn(uint64_t val)
309{
310 unsigned long pfn;
311
312 if (val & PM_PRESENT)
313 pfn = PM_PFRAME(val);
314 else
315 pfn = 0;
316
317 return pfn;
318}
319
320
321/*
322 * page flag names
323 */
324
325static char *page_flag_name(uint64_t flags)
326{
327 static char buf[65];
328 int present;
329 int i, j;
330
331 for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
332 present = (flags >> i) & 1;
333 if (!page_flag_names[i]) {
334 if (present)
335 fatal("unknown flag bit %d\n", i);
336 continue;
337 }
338 buf[j++] = present ? page_flag_names[i][0] : '_';
339 }
340
341 return buf;
342}
343
344static char *page_flag_longname(uint64_t flags)
345{
346 static char buf[1024];
347 int i, n;
348
349 for (i = 0, n = 0; i < ARRAY_SIZE(page_flag_names); i++) {
350 if (!page_flag_names[i])
351 continue;
352 if ((flags >> i) & 1)
353 n += snprintf(buf + n, sizeof(buf) - n, "%s,",
354 page_flag_names[i] + 2);
355 }
356 if (n)
357 n--;
358 buf[n] = '\0';
359
360 return buf;
361}
362
363
364/*
365 * page list and summary
366 */
367
368static void show_page_range(unsigned long voffset,
369 unsigned long offset, uint64_t flags)
370{
371 static uint64_t flags0;
372 static unsigned long voff;
373 static unsigned long index;
374 static unsigned long count;
375
376 if (flags == flags0 && offset == index + count &&
377 (!opt_pid || voffset == voff + count)) {
378 count++;
379 return;
380 }
381
382 if (count) {
383 if (opt_pid)
384 printf("%lx\t", voff);
385 printf("%lx\t%lx\t%s\n",
386 index, count, page_flag_name(flags0));
387 }
388
389 flags0 = flags;
390 index = offset;
391 voff = voffset;
392 count = 1;
393}
394
395static void show_page(unsigned long voffset,
396 unsigned long offset, uint64_t flags)
397{
398 if (opt_pid)
399 printf("%lx\t", voffset);
400 printf("%lx\t%s\n", offset, page_flag_name(flags));
401}
402
403static void show_summary(void)
404{
405 int i;
406
407 printf(" flags\tpage-count MB"
408 " symbolic-flags\t\t\tlong-symbolic-flags\n");
409
410 for (i = 0; i < ARRAY_SIZE(nr_pages); i++) {
411 if (nr_pages[i])
412 printf("0x%016llx\t%10lu %8lu %s\t%s\n",
413 (unsigned long long)page_flags[i],
414 nr_pages[i],
415 pages2mb(nr_pages[i]),
416 page_flag_name(page_flags[i]),
417 page_flag_longname(page_flags[i]));
418 }
419
420 printf(" total\t%10lu %8lu\n",
421 total_pages, pages2mb(total_pages));
422}
423
424
425/*
426 * page flag filters
427 */
428
429static int bit_mask_ok(uint64_t flags)
430{
431 int i;
432
433 for (i = 0; i < nr_bit_filters; i++) {
434 if (opt_bits[i] == KPF_ALL_BITS) {
435 if ((flags & opt_mask[i]) == 0)
436 return 0;
437 } else {
438 if ((flags & opt_mask[i]) != opt_bits[i])
439 return 0;
440 }
441 }
442
443 return 1;
444}
445
446static uint64_t expand_overloaded_flags(uint64_t flags)
447{
448 /* SLOB/SLUB overload several page flags */
449 if (flags & BIT(SLAB)) {
450 if (flags & BIT(PRIVATE))
451 flags ^= BIT(PRIVATE) | BIT(SLOB_FREE);
452 if (flags & BIT(ACTIVE))
453 flags ^= BIT(ACTIVE) | BIT(SLUB_FROZEN);
454 if (flags & BIT(ERROR))
455 flags ^= BIT(ERROR) | BIT(SLUB_DEBUG);
456 }
457
458 /* PG_reclaim is overloaded as PG_readahead in the read path */
459 if ((flags & (BIT(RECLAIM) | BIT(WRITEBACK))) == BIT(RECLAIM))
460 flags ^= BIT(RECLAIM) | BIT(READAHEAD);
461
462 return flags;
463}
464
465static uint64_t well_known_flags(uint64_t flags)
466{
467 /* hide flags intended only for kernel hacker */
468 flags &= ~KPF_HACKERS_BITS;
469
470 /* hide non-hugeTLB compound pages */
471 if ((flags & BITS_COMPOUND) && !(flags & BIT(HUGE)))
472 flags &= ~BITS_COMPOUND;
473
474 return flags;
475}
476
477static uint64_t kpageflags_flags(uint64_t flags)
478{
479 flags = expand_overloaded_flags(flags);
480
481 if (!opt_raw)
482 flags = well_known_flags(flags);
483
484 return flags;
485}
486
487/* verify that a mountpoint is actually a debugfs instance */
488static int debugfs_valid_mountpoint(const char *debugfs)
489{
490 struct statfs st_fs;
491
492 if (statfs(debugfs, &st_fs) < 0)
493 return -ENOENT;
494 else if (st_fs.f_type != (long) DEBUGFS_MAGIC)
495 return -ENOENT;
496
497 return 0;
498}
499
500/* find the path to the mounted debugfs */
501static const char *debugfs_find_mountpoint(void)
502{
503 const char **ptr;
504 char type[100];
505 FILE *fp;
506
507 ptr = debugfs_known_mountpoints;
508 while (*ptr) {
509 if (debugfs_valid_mountpoint(*ptr) == 0) {
510 strcpy(hwpoison_debug_fs, *ptr);
511 return hwpoison_debug_fs;
512 }
513 ptr++;
514 }
515
516 /* give up and parse /proc/mounts */
517 fp = fopen("/proc/mounts", "r");
518 if (fp == NULL)
519 perror("Can't open /proc/mounts for read");
520
521 while (fscanf(fp, "%*s %"
522 STR(MAX_PATH)
523 "s %99s %*s %*d %*d\n",
524 hwpoison_debug_fs, type) == 2) {
525 if (strcmp(type, "debugfs") == 0)
526 break;
527 }
528 fclose(fp);
529
530 if (strcmp(type, "debugfs") != 0)
531 return NULL;
532
533 return hwpoison_debug_fs;
534}
535
536/* mount the debugfs somewhere if it's not mounted */
537
538static void debugfs_mount(void)
539{
540 const char **ptr;
541
542 /* see if it's already mounted */
543 if (debugfs_find_mountpoint())
544 return;
545
546 ptr = debugfs_known_mountpoints;
547 while (*ptr) {
548 if (mount(NULL, *ptr, "debugfs", 0, NULL) == 0) {
549 /* save the mountpoint */
550 strcpy(hwpoison_debug_fs, *ptr);
551 break;
552 }
553 ptr++;
554 }
555
556 if (*ptr == NULL) {
557 perror("mount debugfs");
558 exit(EXIT_FAILURE);
559 }
560}
561
562/*
563 * page actions
564 */
565
566static void prepare_hwpoison_fd(void)
567{
568 char buf[MAX_PATH + 1];
569
570 debugfs_mount();
571
572 if (opt_hwpoison && !hwpoison_inject_fd) {
573 snprintf(buf, MAX_PATH, "%s/hwpoison/corrupt-pfn",
574 hwpoison_debug_fs);
575 hwpoison_inject_fd = checked_open(buf, O_WRONLY);
576 }
577
578 if (opt_unpoison && !hwpoison_forget_fd) {
579 snprintf(buf, MAX_PATH, "%s/hwpoison/unpoison-pfn",
580 hwpoison_debug_fs);
581 hwpoison_forget_fd = checked_open(buf, O_WRONLY);
582 }
583}
584
585static int hwpoison_page(unsigned long offset)
586{
587 char buf[100];
588 int len;
589
590 len = sprintf(buf, "0x%lx\n", offset);
591 len = write(hwpoison_inject_fd, buf, len);
592 if (len < 0) {
593 perror("hwpoison inject");
594 return len;
595 }
596 return 0;
597}
598
599static int unpoison_page(unsigned long offset)
600{
601 char buf[100];
602 int len;
603
604 len = sprintf(buf, "0x%lx\n", offset);
605 len = write(hwpoison_forget_fd, buf, len);
606 if (len < 0) {
607 perror("hwpoison forget");
608 return len;
609 }
610 return 0;
611}
612
613/*
614 * page frame walker
615 */
616
617static int hash_slot(uint64_t flags)
618{
619 int k = HASH_KEY(flags);
620 int i;
621
622 /* Explicitly reserve slot 0 for flags 0: the following logic
623 * cannot distinguish an unoccupied slot from slot (flags==0).
624 */
625 if (flags == 0)
626 return 0;
627
628 /* search through the remaining (HASH_SIZE-1) slots */
629 for (i = 1; i < ARRAY_SIZE(page_flags); i++, k++) {
630 if (!k || k >= ARRAY_SIZE(page_flags))
631 k = 1;
632 if (page_flags[k] == 0) {
633 page_flags[k] = flags;
634 return k;
635 }
636 if (page_flags[k] == flags)
637 return k;
638 }
639
640 fatal("hash table full: bump up HASH_SHIFT?\n");
641 exit(EXIT_FAILURE);
642}
643
644static void add_page(unsigned long voffset,
645 unsigned long offset, uint64_t flags)
646{
647 flags = kpageflags_flags(flags);
648
649 if (!bit_mask_ok(flags))
650 return;
651
652 if (opt_hwpoison)
653 hwpoison_page(offset);
654 if (opt_unpoison)
655 unpoison_page(offset);
656
657 if (opt_list == 1)
658 show_page_range(voffset, offset, flags);
659 else if (opt_list == 2)
660 show_page(voffset, offset, flags);
661
662 nr_pages[hash_slot(flags)]++;
663 total_pages++;
664}
665
666#define KPAGEFLAGS_BATCH (64 << 10) /* 64k pages */
667static void walk_pfn(unsigned long voffset,
668 unsigned long index,
669 unsigned long count)
670{
671 uint64_t buf[KPAGEFLAGS_BATCH];
672 unsigned long batch;
673 long pages;
674 unsigned long i;
675
676 while (count) {
677 batch = min_t(unsigned long, count, KPAGEFLAGS_BATCH);
678 pages = kpageflags_read(buf, index, batch);
679 if (pages == 0)
680 break;
681
682 for (i = 0; i < pages; i++)
683 add_page(voffset + i, index + i, buf[i]);
684
685 index += pages;
686 count -= pages;
687 }
688}
689
690#define PAGEMAP_BATCH (64 << 10)
691static void walk_vma(unsigned long index, unsigned long count)
692{
693 uint64_t buf[PAGEMAP_BATCH];
694 unsigned long batch;
695 unsigned long pages;
696 unsigned long pfn;
697 unsigned long i;
698
699 while (count) {
700 batch = min_t(unsigned long, count, PAGEMAP_BATCH);
701 pages = pagemap_read(buf, index, batch);
702 if (pages == 0)
703 break;
704
705 for (i = 0; i < pages; i++) {
706 pfn = pagemap_pfn(buf[i]);
707 if (pfn)
708 walk_pfn(index + i, pfn, 1);
709 }
710
711 index += pages;
712 count -= pages;
713 }
714}
715
716static void walk_task(unsigned long index, unsigned long count)
717{
718 const unsigned long end = index + count;
719 unsigned long start;
720 int i = 0;
721
722 while (index < end) {
723
724 while (pg_end[i] <= index)
725 if (++i >= nr_vmas)
726 return;
727 if (pg_start[i] >= end)
728 return;
729
730 start = max_t(unsigned long, pg_start[i], index);
731 index = min_t(unsigned long, pg_end[i], end);
732
733 assert(start < index);
734 walk_vma(start, index - start);
735 }
736}
737
738static void add_addr_range(unsigned long offset, unsigned long size)
739{
740 if (nr_addr_ranges >= MAX_ADDR_RANGES)
741 fatal("too many addr ranges\n");
742
743 opt_offset[nr_addr_ranges] = offset;
744 opt_size[nr_addr_ranges] = min_t(unsigned long, size, ULONG_MAX-offset);
745 nr_addr_ranges++;
746}
747
748static void walk_addr_ranges(void)
749{
750 int i;
751
752 kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY);
753
754 if (!nr_addr_ranges)
755 add_addr_range(0, ULONG_MAX);
756
757 for (i = 0; i < nr_addr_ranges; i++)
758 if (!opt_pid)
759 walk_pfn(0, opt_offset[i], opt_size[i]);
760 else
761 walk_task(opt_offset[i], opt_size[i]);
762
763 close(kpageflags_fd);
764}
765
766
767/*
768 * user interface
769 */
770
771static const char *page_flag_type(uint64_t flag)
772{
773 if (flag & KPF_HACKERS_BITS)
774 return "(r)";
775 if (flag & KPF_OVERLOADED_BITS)
776 return "(o)";
777 return " ";
778}
779
780static void usage(void)
781{
782 int i, j;
783
784 printf(
785"page-types [options]\n"
786" -r|--raw Raw mode, for kernel developers\n"
787" -d|--describe flags Describe flags\n"
788" -a|--addr addr-spec Walk a range of pages\n"
789" -b|--bits bits-spec Walk pages with specified bits\n"
790" -p|--pid pid Walk process address space\n"
791#if 0 /* planned features */
792" -f|--file filename Walk file address space\n"
793#endif
794" -l|--list Show page details in ranges\n"
795" -L|--list-each Show page details one by one\n"
796" -N|--no-summary Don't show summary info\n"
797" -X|--hwpoison hwpoison pages\n"
798" -x|--unpoison unpoison pages\n"
799" -h|--help Show this usage message\n"
800"flags:\n"
801" 0x10 bitfield format, e.g.\n"
802" anon bit-name, e.g.\n"
803" 0x10,anon comma-separated list, e.g.\n"
804"addr-spec:\n"
805" N one page at offset N (unit: pages)\n"
806" N+M pages range from N to N+M-1\n"
807" N,M pages range from N to M-1\n"
808" N, pages range from N to end\n"
809" ,M pages range from 0 to M-1\n"
810"bits-spec:\n"
811" bit1,bit2 (flags & (bit1|bit2)) != 0\n"
812" bit1,bit2=bit1 (flags & (bit1|bit2)) == bit1\n"
813" bit1,~bit2 (flags & (bit1|bit2)) == bit1\n"
814" =bit1,bit2 flags == (bit1|bit2)\n"
815"bit-names:\n"
816 );
817
818 for (i = 0, j = 0; i < ARRAY_SIZE(page_flag_names); i++) {
819 if (!page_flag_names[i])
820 continue;
821 printf("%16s%s", page_flag_names[i] + 2,
822 page_flag_type(1ULL << i));
823 if (++j > 3) {
824 j = 0;
825 putchar('\n');
826 }
827 }
828 printf("\n "
829 "(r) raw mode bits (o) overloaded bits\n");
830}
831
832static unsigned long long parse_number(const char *str)
833{
834 unsigned long long n;
835
836 n = strtoll(str, NULL, 0);
837
838 if (n == 0 && str[0] != '0')
839 fatal("invalid name or number: %s\n", str);
840
841 return n;
842}
843
844static void parse_pid(const char *str)
845{
846 FILE *file;
847 char buf[5000];
848
849 opt_pid = parse_number(str);
850
851 sprintf(buf, "/proc/%d/pagemap", opt_pid);
852 pagemap_fd = checked_open(buf, O_RDONLY);
853
854 sprintf(buf, "/proc/%d/maps", opt_pid);
855 file = fopen(buf, "r");
856 if (!file) {
857 perror(buf);
858 exit(EXIT_FAILURE);
859 }
860
861 while (fgets(buf, sizeof(buf), file) != NULL) {
862 unsigned long vm_start;
863 unsigned long vm_end;
864 unsigned long long pgoff;
865 int major, minor;
866 char r, w, x, s;
867 unsigned long ino;
868 int n;
869
870 n = sscanf(buf, "%lx-%lx %c%c%c%c %llx %x:%x %lu",
871 &vm_start,
872 &vm_end,
873 &r, &w, &x, &s,
874 &pgoff,
875 &major, &minor,
876 &ino);
877 if (n < 10) {
878 fprintf(stderr, "unexpected line: %s\n", buf);
879 continue;
880 }
881 pg_start[nr_vmas] = vm_start / page_size;
882 pg_end[nr_vmas] = vm_end / page_size;
883 if (++nr_vmas >= MAX_VMAS) {
884 fprintf(stderr, "too many VMAs\n");
885 break;
886 }
887 }
888 fclose(file);
889}
890
891static void parse_file(const char *name)
892{
893}
894
895static void parse_addr_range(const char *optarg)
896{
897 unsigned long offset;
898 unsigned long size;
899 char *p;
900
901 p = strchr(optarg, ',');
902 if (!p)
903 p = strchr(optarg, '+');
904
905 if (p == optarg) {
906 offset = 0;
907 size = parse_number(p + 1);
908 } else if (p) {
909 offset = parse_number(optarg);
910 if (p[1] == '\0')
911 size = ULONG_MAX;
912 else {
913 size = parse_number(p + 1);
914 if (*p == ',') {
915 if (size < offset)
916 fatal("invalid range: %lu,%lu\n",
917 offset, size);
918 size -= offset;
919 }
920 }
921 } else {
922 offset = parse_number(optarg);
923 size = 1;
924 }
925
926 add_addr_range(offset, size);
927}
928
929static void add_bits_filter(uint64_t mask, uint64_t bits)
930{
931 if (nr_bit_filters >= MAX_BIT_FILTERS)
932 fatal("too much bit filters\n");
933
934 opt_mask[nr_bit_filters] = mask;
935 opt_bits[nr_bit_filters] = bits;
936 nr_bit_filters++;
937}
938
939static uint64_t parse_flag_name(const char *str, int len)
940{
941 int i;
942
943 if (!*str || !len)
944 return 0;
945
946 if (len <= 8 && !strncmp(str, "compound", len))
947 return BITS_COMPOUND;
948
949 for (i = 0; i < ARRAY_SIZE(page_flag_names); i++) {
950 if (!page_flag_names[i])
951 continue;
952 if (!strncmp(str, page_flag_names[i] + 2, len))
953 return 1ULL << i;
954 }
955
956 return parse_number(str);
957}
958
959static uint64_t parse_flag_names(const char *str, int all)
960{
961 const char *p = str;
962 uint64_t flags = 0;
963
964 while (1) {
965 if (*p == ',' || *p == '=' || *p == '\0') {
966 if ((*str != '~') || (*str == '~' && all && *++str))
967 flags |= parse_flag_name(str, p - str);
968 if (*p != ',')
969 break;
970 str = p + 1;
971 }
972 p++;
973 }
974
975 return flags;
976}
977
978static void parse_bits_mask(const char *optarg)
979{
980 uint64_t mask;
981 uint64_t bits;
982 const char *p;
983
984 p = strchr(optarg, '=');
985 if (p == optarg) {
986 mask = KPF_ALL_BITS;
987 bits = parse_flag_names(p + 1, 0);
988 } else if (p) {
989 mask = parse_flag_names(optarg, 0);
990 bits = parse_flag_names(p + 1, 0);
991 } else if (strchr(optarg, '~')) {
992 mask = parse_flag_names(optarg, 1);
993 bits = parse_flag_names(optarg, 0);
994 } else {
995 mask = parse_flag_names(optarg, 0);
996 bits = KPF_ALL_BITS;
997 }
998
999 add_bits_filter(mask, bits);
1000}
1001
1002static void describe_flags(const char *optarg)
1003{
1004 uint64_t flags = parse_flag_names(optarg, 0);
1005
1006 printf("0x%016llx\t%s\t%s\n",
1007 (unsigned long long)flags,
1008 page_flag_name(flags),
1009 page_flag_longname(flags));
1010}
1011
1012static const struct option opts[] = {
1013 { "raw" , 0, NULL, 'r' },
1014 { "pid" , 1, NULL, 'p' },
1015 { "file" , 1, NULL, 'f' },
1016 { "addr" , 1, NULL, 'a' },
1017 { "bits" , 1, NULL, 'b' },
1018 { "describe" , 1, NULL, 'd' },
1019 { "list" , 0, NULL, 'l' },
1020 { "list-each" , 0, NULL, 'L' },
1021 { "no-summary", 0, NULL, 'N' },
1022 { "hwpoison" , 0, NULL, 'X' },
1023 { "unpoison" , 0, NULL, 'x' },
1024 { "help" , 0, NULL, 'h' },
1025 { NULL , 0, NULL, 0 }
1026};
1027
1028int main(int argc, char *argv[])
1029{
1030 int c;
1031
1032 page_size = getpagesize();
1033
1034 while ((c = getopt_long(argc, argv,
1035 "rp:f:a:b:d:lLNXxh", opts, NULL)) != -1) {
1036 switch (c) {
1037 case 'r':
1038 opt_raw = 1;
1039 break;
1040 case 'p':
1041 parse_pid(optarg);
1042 break;
1043 case 'f':
1044 parse_file(optarg);
1045 break;
1046 case 'a':
1047 parse_addr_range(optarg);
1048 break;
1049 case 'b':
1050 parse_bits_mask(optarg);
1051 break;
1052 case 'd':
1053 describe_flags(optarg);
1054 exit(0);
1055 case 'l':
1056 opt_list = 1;
1057 break;
1058 case 'L':
1059 opt_list = 2;
1060 break;
1061 case 'N':
1062 opt_no_summary = 1;
1063 break;
1064 case 'X':
1065 opt_hwpoison = 1;
1066 prepare_hwpoison_fd();
1067 break;
1068 case 'x':
1069 opt_unpoison = 1;
1070 prepare_hwpoison_fd();
1071 break;
1072 case 'h':
1073 usage();
1074 exit(0);
1075 default:
1076 usage();
1077 exit(1);
1078 }
1079 }
1080
1081 if (opt_list && opt_pid)
1082 printf("voffset\t");
1083 if (opt_list == 1)
1084 printf("offset\tlen\tflags\n");
1085 if (opt_list == 2)
1086 printf("offset\tflags\n");
1087
1088 walk_addr_ranges();
1089
1090 if (opt_list == 1)
1091 show_page_range(0, 0, 0); /* drain the buffer */
1092
1093 if (opt_no_summary)
1094 return 0;
1095
1096 if (opt_list)
1097 printf("\n\n");
1098
1099 show_summary();
1100
1101 return 0;
1102}
diff --git a/tools/slub/slabinfo.c b/tools/vm/slabinfo.c
index 164cbcf61106..164cbcf61106 100644
--- a/tools/slub/slabinfo.c
+++ b/tools/vm/slabinfo.c