aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/hv/Makefile4
-rw-r--r--tools/hv/hv_fcopy_daemon.c10
-rw-r--r--tools/hv/hv_kvp_daemon.c41
-rw-r--r--tools/lib/lockdep/.gitignore1
-rw-r--r--tools/lib/lockdep/Makefile2
-rw-r--r--tools/power/acpi/common/cmfsize.c2
-rw-r--r--tools/power/acpi/common/getopt.c2
-rw-r--r--tools/power/acpi/os_specific/service_layers/oslibcfs.c2
-rw-r--r--tools/power/acpi/os_specific/service_layers/oslinuxtbl.c2
-rw-r--r--tools/power/acpi/os_specific/service_layers/osunixdir.c2
-rw-r--r--tools/power/acpi/os_specific/service_layers/osunixmap.c2
-rw-r--r--tools/power/acpi/os_specific/service_layers/osunixxf.c2
-rw-r--r--tools/power/acpi/tools/acpidump/acpidump.h2
-rw-r--r--tools/power/acpi/tools/acpidump/apdump.c2
-rw-r--r--tools/power/acpi/tools/acpidump/apfiles.c2
-rw-r--r--tools/power/acpi/tools/acpidump/apmain.c2
-rw-r--r--tools/power/cpupower/Makefile2
-rw-r--r--tools/power/x86/turbostat/turbostat.8126
-rw-r--r--tools/power/x86/turbostat/turbostat.c662
-rwxr-xr-xtools/testing/ktest/ktest.pl259
-rw-r--r--tools/testing/selftests/powerpc/Makefile2
-rw-r--r--tools/testing/selftests/powerpc/copyloops/.gitignore4
-rw-r--r--tools/testing/selftests/powerpc/mm/.gitignore3
-rw-r--r--tools/testing/selftests/powerpc/mm/Makefile9
-rw-r--r--tools/testing/selftests/powerpc/mm/subpage_prot.c220
-rw-r--r--tools/testing/selftests/powerpc/pmu/.gitignore3
-rw-r--r--tools/testing/selftests/powerpc/pmu/ebb/.gitignore22
-rw-r--r--tools/testing/selftests/powerpc/primitives/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/stringloops/.gitignore1
-rw-r--r--tools/testing/selftests/powerpc/stringloops/Makefile20
-rw-r--r--tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h7
-rw-r--r--tools/testing/selftests/powerpc/stringloops/memcmp.c103
l---------tools/testing/selftests/powerpc/stringloops/memcmp_64.S1
-rw-r--r--tools/testing/selftests/powerpc/tm/.gitignore1
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/cpus2use.sh2
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh18
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh9
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/parse-build.sh20
-rwxr-xr-xtools/testing/selftests/rcutorture/bin/parse-console.sh2
-rw-r--r--tools/usb/ffs-aio-example/multibuff/host_app/test.c14
-rw-r--r--tools/usb/ffs-aio-example/simple/device_app/aio_simple.c2
-rw-r--r--tools/usb/ffs-aio-example/simple/host_app/test.c17
-rw-r--r--tools/vm/page-types.c1
43 files changed, 1267 insertions, 344 deletions
diff --git a/tools/hv/Makefile b/tools/hv/Makefile
index bd22f786a60c..99ffe61051a7 100644
--- a/tools/hv/Makefile
+++ b/tools/hv/Makefile
@@ -5,9 +5,9 @@ PTHREAD_LIBS = -lpthread
WARNINGS = -Wall -Wextra
CFLAGS = $(WARNINGS) -g $(PTHREAD_LIBS)
-all: hv_kvp_daemon hv_vss_daemon
+all: hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon
%: %.c
$(CC) $(CFLAGS) -o $@ $^
clean:
- $(RM) hv_kvp_daemon hv_vss_daemon
+ $(RM) hv_kvp_daemon hv_vss_daemon hv_fcopy_daemon
diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
index f437d739f37d..9445d8f264a4 100644
--- a/tools/hv/hv_fcopy_daemon.c
+++ b/tools/hv/hv_fcopy_daemon.c
@@ -43,15 +43,9 @@ static int hv_start_fcopy(struct hv_start_fcopy *smsg)
int error = HV_E_FAIL;
char *q, *p;
- /*
- * If possile append a path seperator to the path.
- */
- if (strlen((char *)smsg->path_name) < (W_MAX_PATH - 2))
- strcat((char *)smsg->path_name, "/");
-
p = (char *)smsg->path_name;
snprintf(target_fname, sizeof(target_fname), "%s/%s",
- (char *)smsg->path_name, smsg->file_name);
+ (char *)smsg->path_name, (char *)smsg->file_name);
syslog(LOG_INFO, "Target file name: %s", target_fname);
/*
@@ -137,7 +131,7 @@ void print_usage(char *argv[])
int main(int argc, char *argv[])
{
- int fd, fcopy_fd, len;
+ int fcopy_fd, len;
int error;
int daemonize = 1, long_index = 0, opt;
int version = FCOPY_CURRENT_VERSION;
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 6a6432a20a1d..408bb076a234 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -147,7 +147,6 @@ static void kvp_release_lock(int pool)
static void kvp_update_file(int pool)
{
FILE *filep;
- size_t bytes_written;
/*
* We are going to write our in-memory registry out to
@@ -163,8 +162,7 @@ static void kvp_update_file(int pool)
exit(EXIT_FAILURE);
}
- bytes_written = fwrite(kvp_file_info[pool].records,
- sizeof(struct kvp_record),
+ fwrite(kvp_file_info[pool].records, sizeof(struct kvp_record),
kvp_file_info[pool].num_records, filep);
if (ferror(filep) || fclose(filep)) {
@@ -310,7 +308,7 @@ static int kvp_file_init(void)
return 0;
}
-static int kvp_key_delete(int pool, const char *key, int key_size)
+static int kvp_key_delete(int pool, const __u8 *key, int key_size)
{
int i;
int j, k;
@@ -353,8 +351,8 @@ static int kvp_key_delete(int pool, const char *key, int key_size)
return 1;
}
-static int kvp_key_add_or_modify(int pool, const char *key, int key_size, const char *value,
- int value_size)
+static int kvp_key_add_or_modify(int pool, const __u8 *key, int key_size,
+ const __u8 *value, int value_size)
{
int i;
int num_records;
@@ -407,7 +405,7 @@ static int kvp_key_add_or_modify(int pool, const char *key, int key_size, const
return 0;
}
-static int kvp_get_value(int pool, const char *key, int key_size, char *value,
+static int kvp_get_value(int pool, const __u8 *key, int key_size, __u8 *value,
int value_size)
{
int i;
@@ -439,8 +437,8 @@ static int kvp_get_value(int pool, const char *key, int key_size, char *value,
return 1;
}
-static int kvp_pool_enumerate(int pool, int index, char *key, int key_size,
- char *value, int value_size)
+static int kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size,
+ __u8 *value, int value_size)
{
struct kvp_record *record;
@@ -661,7 +659,7 @@ static char *kvp_if_name_to_mac(char *if_name)
char *p, *x;
char buf[256];
char addr_file[256];
- int i;
+ unsigned int i;
char *mac_addr = NULL;
snprintf(addr_file, sizeof(addr_file), "%s%s%s", "/sys/class/net/",
@@ -700,7 +698,7 @@ static char *kvp_mac_to_if_name(char *mac)
char buf[256];
char *kvp_net_dir = "/sys/class/net/";
char dev_id[256];
- int i;
+ unsigned int i;
dir = opendir(kvp_net_dir);
if (dir == NULL)
@@ -750,7 +748,7 @@ static char *kvp_mac_to_if_name(char *mac)
static void kvp_process_ipconfig_file(char *cmd,
- char *config_buf, int len,
+ char *config_buf, unsigned int len,
int element_size, int offset)
{
char buf[256];
@@ -768,7 +766,7 @@ static void kvp_process_ipconfig_file(char *cmd,
if (offset == 0)
memset(config_buf, 0, len);
while ((p = fgets(buf, sizeof(buf), file)) != NULL) {
- if ((len - strlen(config_buf)) < (element_size + 1))
+ if (len < strlen(config_buf) + element_size + 1)
break;
x = strchr(p, '\n');
@@ -916,7 +914,7 @@ static int kvp_process_ip_address(void *addrp,
static int
kvp_get_ip_info(int family, char *if_name, int op,
- void *out_buffer, int length)
+ void *out_buffer, unsigned int length)
{
struct ifaddrs *ifap;
struct ifaddrs *curp;
@@ -1019,8 +1017,7 @@ kvp_get_ip_info(int family, char *if_name, int op,
weight += hweight32(&w[i]);
sprintf(cidr_mask, "/%d", weight);
- if ((length - sn_offset) <
- (strlen(cidr_mask) + 1))
+ if (length < sn_offset + strlen(cidr_mask) + 1)
goto gather_ipaddr;
if (sn_offset == 0)
@@ -1308,16 +1305,17 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
if (error)
goto setval_error;
+ /*
+ * The dhcp_enabled flag is only for IPv4. In the case the host only
+ * injects an IPv6 address, the flag is true, but we still need to
+ * proceed to parse and pass the IPv6 information to the
+ * disto-specific script hv_set_ifconfig.
+ */
if (new_val->dhcp_enabled) {
error = kvp_write_file(file, "BOOTPROTO", "", "dhcp");
if (error)
goto setval_error;
- /*
- * We are done!.
- */
- goto setval_done;
-
} else {
error = kvp_write_file(file, "BOOTPROTO", "", "none");
if (error)
@@ -1345,7 +1343,6 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
if (error)
goto setval_error;
-setval_done:
fclose(file);
/*
diff --git a/tools/lib/lockdep/.gitignore b/tools/lib/lockdep/.gitignore
new file mode 100644
index 000000000000..cc0e7a9f99e3
--- /dev/null
+++ b/tools/lib/lockdep/.gitignore
@@ -0,0 +1 @@
+liblockdep.so.*
diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
index 52f9279c6c13..4b866c54f624 100644
--- a/tools/lib/lockdep/Makefile
+++ b/tools/lib/lockdep/Makefile
@@ -104,7 +104,7 @@ N =
export Q VERBOSE
-INCLUDES = -I. -I/usr/local/include -I./uinclude -I./include -I../../include $(CONFIG_INCLUDES)
+INCLUDES = -I. -I./uinclude -I./include -I../../include $(CONFIG_INCLUDES)
# Set compile option CFLAGS if not set elsewhere
CFLAGS ?= -g -DCONFIG_LOCKDEP -DCONFIG_STACKTRACE -DCONFIG_PROVE_LOCKING -DBITS_PER_LONG=__WORDSIZE -DLIBLOCKDEP_VERSION='"$(LIBLOCKDEP_VERSION)"' -rdynamic -O0 -g
diff --git a/tools/power/acpi/common/cmfsize.c b/tools/power/acpi/common/cmfsize.c
index f4b953354ff7..eec688041500 100644
--- a/tools/power/acpi/common/cmfsize.c
+++ b/tools/power/acpi/common/cmfsize.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/common/getopt.c b/tools/power/acpi/common/getopt.c
index 2f0f34a36db4..5da129e10aa2 100644
--- a/tools/power/acpi/common/getopt.c
+++ b/tools/power/acpi/common/getopt.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/os_specific/service_layers/oslibcfs.c b/tools/power/acpi/os_specific/service_layers/oslibcfs.c
index c13ff9c51d74..b51e40a9a120 100644
--- a/tools/power/acpi/os_specific/service_layers/oslibcfs.c
+++ b/tools/power/acpi/os_specific/service_layers/oslibcfs.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
index 0dc2485dedf5..92f1fd700344 100644
--- a/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
+++ b/tools/power/acpi/os_specific/service_layers/oslinuxtbl.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/os_specific/service_layers/osunixdir.c b/tools/power/acpi/os_specific/service_layers/osunixdir.c
index 733f9e490fc4..e153fcb12b1a 100644
--- a/tools/power/acpi/os_specific/service_layers/osunixdir.c
+++ b/tools/power/acpi/os_specific/service_layers/osunixdir.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/os_specific/service_layers/osunixmap.c b/tools/power/acpi/os_specific/service_layers/osunixmap.c
index 99b47b6194a3..3853a7350440 100644
--- a/tools/power/acpi/os_specific/service_layers/osunixmap.c
+++ b/tools/power/acpi/os_specific/service_layers/osunixmap.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/os_specific/service_layers/osunixxf.c b/tools/power/acpi/os_specific/service_layers/osunixxf.c
index 7ccb073f8316..6858c0893c91 100644
--- a/tools/power/acpi/os_specific/service_layers/osunixxf.c
+++ b/tools/power/acpi/os_specific/service_layers/osunixxf.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h
index a2d37d610639..84bdef0136cb 100644
--- a/tools/power/acpi/tools/acpidump/acpidump.h
+++ b/tools/power/acpi/tools/acpidump/acpidump.h
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c
index 24d32968802d..c736adf5fb55 100644
--- a/tools/power/acpi/tools/acpidump/apdump.c
+++ b/tools/power/acpi/tools/acpidump/apdump.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c
index d470046a6d81..8f2fe168228e 100644
--- a/tools/power/acpi/tools/acpidump/apfiles.c
+++ b/tools/power/acpi/tools/acpidump/apfiles.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c
index 853b4da22c3e..d0ba6535f5af 100644
--- a/tools/power/acpi/tools/acpidump/apmain.c
+++ b/tools/power/acpi/tools/acpidump/apmain.c
@@ -5,7 +5,7 @@
*****************************************************************************/
/*
- * Copyright (C) 2000 - 2014, Intel Corp.
+ * Copyright (C) 2000 - 2015, Intel Corp.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index 2e2ba2efa0d9..3ed7c0476d48 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -209,7 +209,7 @@ $(OUTPUT)%.o: %.c
$(OUTPUT)cpupower: $(UTIL_OBJS) $(OUTPUT)libcpupower.so.$(LIB_MAJ)
$(ECHO) " CC " $@
- $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -lrt -lpci -L$(OUTPUT) -o $@
+ $(QUIET) $(CC) $(CFLAGS) $(LDFLAGS) $(UTIL_OBJS) -lcpupower -Wl,-rpath=./ -lrt -lpci -L$(OUTPUT) -o $@
$(QUIET) $(STRIPCMD) $@
$(OUTPUT)po/$(PACKAGE).pot: $(UTIL_SRC)
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8
index 56bfb523c5bb..feea7ad9500b 100644
--- a/tools/power/x86/turbostat/turbostat.8
+++ b/tools/power/x86/turbostat/turbostat.8
@@ -9,40 +9,50 @@ turbostat \- Report processor frequency and idle statistics
.br
.B turbostat
.RB [ Options ]
-.RB [ "\-i interval_sec" ]
+.RB [ "\--interval seconds" ]
.SH DESCRIPTION
\fBturbostat \fP reports processor topology, frequency,
-idle power-state statistics, temperature and power on modern X86 processors.
-Either \fBcommand\fP is forked and statistics are printed
-upon its completion, or statistics are printed periodically.
-
-\fBturbostat \fP
-must be run on root, and
-minimally requires that the processor
-supports an "invariant" TSC, plus the APERF and MPERF MSRs.
-Additional information is reported depending on hardware counter support.
-
+idle power-state statistics, temperature and power on X86 processors.
+There are two ways to invoke turbostat.
+The first method is to supply a
+\fBcommand\fP, which is forked and statistics are printed
+upon its completion.
+The second method is to omit the command,
+and turbostat displays statistics every 5 seconds.
+The 5-second interval can be changed using the --interval option.
+
+Some information is not available on older processors.
.SS Options
-The \fB-p\fP option limits output to the 1st thread in 1st core of each package.
+\fB--Counter MSR#\fP shows the delta of the specified 64-bit MSR counter.
+.PP
+\fB--counter MSR#\fP shows the delta of the specified 32-bit MSR counter.
+.PP
+\fB--Dump\fP displays the raw counter values.
+.PP
+\fB--debug\fP displays additional system configuration information. Invoking this parameter
+more than once may also enable internal turbostat debug information.
+.PP
+\fB--interval seconds\fP overrides the default 5-second measurement interval.
+.PP
+\fB--help\fP displays usage for the most common parameters.
.PP
-The \fB-P\fP option limits output to the 1st thread in each Package.
+\fB--Joules\fP displays energy in Joules, rather than dividing Joules by time to print power in Watts.
.PP
-The \fB-S\fP option limits output to a 1-line System Summary for each interval.
+\fB--MSR MSR#\fP shows the specified 64-bit MSR value.
.PP
-The \fB-v\fP option increases verbosity.
+\fB--msr MSR#\fP shows the specified 32-bit MSR value.
.PP
-The \fB-c MSR#\fP option includes the delta of the specified 32-bit MSR counter.
+\fB--Package\fP limits output to the system summary plus the 1st thread in each Package.
.PP
-The \fB-C MSR#\fP option includes the delta of the specified 64-bit MSR counter.
+\fB--processor\fP limits output to the system summary plus the 1st thread in each processor of each package. Ie. it skips hyper-threaded siblings.
.PP
-The \fB-m MSR#\fP option includes the the specified 32-bit MSR value.
+\fB--Summary\fP limits output to a 1-line System Summary for each interval.
.PP
-The \fB-M MSR#\fP option includes the the specified 64-bit MSR value.
+\fB--TCC temperature\fP sets the Thermal Control Circuit temperature for systems which do not export that value. This is used for making sense of the Digital Thermal Sensor outputs, as they return degrees Celsius below the TCC activation temperature.
.PP
-The \fB-i interval_sec\fP option prints statistics every \fiinterval_sec\fP seconds.
-The default is 5 seconds.
+\fB--version\fP displays the version.
.PP
-The \fBcommand\fP parameter forks \fBcommand\fP and upon its exit,
+The \fBcommand\fP parameter forks \fBcommand\fP, and upon its exit,
displays the statistics gathered since it was forked.
.PP
.SH FIELD DESCRIPTIONS
@@ -52,7 +62,7 @@ displays the statistics gathered since it was forked.
\fBCPU\fP Linux CPU (logical processor) number.
Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology.
\fBAVG_MHz\fP number of cycles executed divided by time elapsed.
-\fB%Buzy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state.
+\fB%Busy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state.
\fBBzy_MHz\fP average clock rate while the CPU was busy (in "c0" state).
\fBTSC_MHz\fP average MHz that the TSC ran during the entire interval.
\fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states.
@@ -68,7 +78,7 @@ Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading T
.fi
.PP
.SH EXAMPLE
-Without any parameters, turbostat prints out counters ever 5 seconds.
+Without any parameters, turbostat displays statistics ever 5 seconds.
(override interval with "-i sec" option, or specify a command
for turbostat to fork).
@@ -91,19 +101,19 @@ Subsequent rows show per-CPU statistics.
3 3 3 0.20 1596 3492 0 0.44 0.00 99.37 0.00 23
3 7 5 0.31 1596 3492 0 0.33
.fi
-.SH VERBOSE EXAMPLE
-The "-v" option adds verbosity to the output:
+.SH DEBUG EXAMPLE
+The "--debug" option prints additional system information before measurements:
.nf
-[root@ivy]# turbostat -v
-turbostat v3.0 November 23, 2012 - Len Brown <lenb@kernel.org>
+turbostat version 4.0 10-Feb, 2015 - Len Brown <lenb@kernel.org>
CPUID(0): GenuineIntel 13 CPUID levels; family:model:stepping 0x6:3a:9 (6:58:9)
CPUID(6): APERF, DTS, PTM, EPB
-RAPL: 851 sec. Joule Counter Range
+RAPL: 851 sec. Joule Counter Range, at 77 Watts
cpu0: MSR_NHM_PLATFORM_INFO: 0x81010f0012300
16 * 100 = 1600 MHz max efficiency
35 * 100 = 3500 MHz TSC frequency
-cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e008402 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, locked: pkg-cstate-limit=2: pc6-noret)
+cpu0: MSR_IA32_POWER_CTL: 0x0014005d (C1E auto-promotion: DISabled)
+cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x1e008402 (UNdemote-C3, UNdemote-C1, demote-C3, demote-C1, locked: pkg-cstate-limit=2: pc6n)
cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x25262727
37 * 100 = 3700 MHz max turbo 4 active cores
38 * 100 = 3800 MHz max turbo 3 active cores
@@ -112,9 +122,9 @@ cpu0: MSR_NHM_TURBO_RATIO_LIMIT: 0x25262727
cpu0: MSR_IA32_ENERGY_PERF_BIAS: 0x00000006 (balanced)
cpu0: MSR_RAPL_POWER_UNIT: 0x000a1003 (0.125000 Watts, 0.000015 Joules, 0.000977 sec.)
cpu0: MSR_PKG_POWER_INFO: 0x01e00268 (77 W TDP, RAPL 60 - 0 W, 0.000000 sec.)
-cpu0: MSR_PKG_POWER_LIMIT: 0x830000148268 (UNlocked)
+cpu0: MSR_PKG_POWER_LIMIT: 0x30000148268 (UNlocked)
cpu0: PKG Limit #1: ENabled (77.000000 Watts, 1.000000 sec, clamp DISabled)
-cpu0: PKG Limit #2: ENabled (96.000000 Watts, 0.000977* sec, clamp DISabled)
+cpu0: PKG Limit #2: DISabled (96.000000 Watts, 0.000977* sec, clamp DISabled)
cpu0: MSR_PP0_POLICY: 0
cpu0: MSR_PP0_POWER_LIMIT: 0x00000000 (UNlocked)
cpu0: Cores Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled)
@@ -123,19 +133,20 @@ cpu0: MSR_PP1_POWER_LIMIT: 0x00000000 (UNlocked)
cpu0: GFX Limit: DISabled (0.000000 Watts, 0.000977 sec, clamp DISabled)
cpu0: MSR_IA32_TEMPERATURE_TARGET: 0x00691400 (105 C)
cpu0: MSR_IA32_PACKAGE_THERM_STATUS: 0x884e0000 (27 C)
-cpu0: MSR_IA32_THERM_STATUS: 0x88560000 (19 C +/- 1)
-cpu1: MSR_IA32_THERM_STATUS: 0x88560000 (19 C +/- 1)
-cpu2: MSR_IA32_THERM_STATUS: 0x88540000 (21 C +/- 1)
+cpu0: MSR_IA32_THERM_STATUS: 0x88580000 (17 C +/- 1)
+cpu1: MSR_IA32_THERM_STATUS: 0x885a0000 (15 C +/- 1)
+cpu2: MSR_IA32_THERM_STATUS: 0x88570000 (18 C +/- 1)
cpu3: MSR_IA32_THERM_STATUS: 0x884e0000 (27 C +/- 1)
...
.fi
The \fBmax efficiency\fP frequency, a.k.a. Low Frequency Mode, is the frequency
-available at the minimum package voltage. The \fBTSC frequency\fP is the nominal
-maximum frequency of the processor if turbo-mode were not available. This frequency
+available at the minimum package voltage. The \fBTSC frequency\fP is the base
+frequency of the processor -- this should match the brand string
+in /proc/cpuinfo. This base frequency
should be sustainable on all CPUs indefinitely, given nominal power and cooling.
The remaining rows show what maximum turbo frequency is possible
-depending on the number of idle cores. Note that this information is
-not available on all processors.
+depending on the number of idle cores. Note that not all information is
+available on all processors.
.SH FORK EXAMPLE
If turbostat is invoked with a command, it will fork that command
and output the statistics gathered when the command exits.
@@ -176,6 +187,11 @@ not including any non-busy idle time.
.B "turbostat "
must be run as root.
+Alternatively, non-root users can be enabled to run turbostat this way:
+
+# setcap cap_sys_rawio=ep ./turbostat
+
+# chmod +r /dev/cpu/*/msr
.B "turbostat "
reads hardware counters, but doesn't write them.
@@ -184,15 +200,33 @@ multiple invocations of itself.
\fBturbostat \fP
may work poorly on Linux-2.6.20 through 2.6.29,
-as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF
+as \fBacpi-cpufreq \fPperiodically cleared the APERF and MPERF MSRs
in those kernels.
-If the TSC column does not make sense, then
-the other numbers will also make no sense.
-Turbostat is lightweight, and its data collection is not atomic.
-These issues are usually caused by an extremely short measurement
-interval (much less than 1 second), or system activity that prevents
-turbostat from being able to run on all CPUS to quickly collect data.
+AVG_MHz = APERF_delta/measurement_interval. This is the actual
+number of elapsed cycles divided by the entire sample interval --
+including idle time. Note that this calculation is resilient
+to systems lacking a non-stop TSC.
+
+TSC_MHz = TSC_delta/measurement_interval.
+On a system with an invariant TSC, this value will be constant
+and will closely match the base frequency value shown
+in the brand string in /proc/cpuinfo. On a system where
+the TSC stops in idle, TSC_MHz will drop
+below the processor's base frequency.
+
+%Busy = MPERF_delta/TSC_delta
+
+Bzy_MHz = TSC_delta/APERF_delta/MPERF_delta/measurement_interval
+
+Note that these calculations depend on TSC_delta, so they
+are not reliable during intervals when TSC_MHz is not running at the base frequency.
+
+Turbostat data collection is not atomic.
+Extremely short measurement intervals (much less than 1 second),
+or system activity that prevents turbostat from being able
+to run on all CPUS to quickly collect data, will result in
+inconsistent results.
The APERF, MPERF MSRs are defined to count non-halted cycles.
Although it is not guaranteed by the architecture, turbostat assumes
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c
index 5b1b807265a1..2d089cac8580 100644
--- a/tools/power/x86/turbostat/turbostat.c
+++ b/tools/power/x86/turbostat/turbostat.c
@@ -33,24 +33,29 @@
#include <signal.h>
#include <sys/time.h>
#include <stdlib.h>
+#include <getopt.h>
#include <dirent.h>
#include <string.h>
#include <ctype.h>
#include <sched.h>
#include <cpuid.h>
+#include <linux/capability.h>
+#include <errno.h>
char *proc_stat = "/proc/stat";
-unsigned int interval_sec = 5; /* set with -i interval_sec */
-unsigned int verbose; /* set with -v */
-unsigned int rapl_verbose; /* set with -R */
-unsigned int rapl_joules; /* set with -J */
-unsigned int thermal_verbose; /* set with -T */
-unsigned int summary_only; /* set with -S */
-unsigned int dump_only; /* set with -s */
+unsigned int interval_sec = 5;
+unsigned int debug;
+unsigned int rapl_joules;
+unsigned int summary_only;
+unsigned int dump_only;
unsigned int skip_c0;
unsigned int skip_c1;
unsigned int do_nhm_cstates;
unsigned int do_snb_cstates;
+unsigned int do_pc2;
+unsigned int do_pc3;
+unsigned int do_pc6;
+unsigned int do_pc7;
unsigned int do_c8_c9_c10;
unsigned int do_slm_cstates;
unsigned int use_c1_residency_msr;
@@ -59,8 +64,8 @@ unsigned int has_epb;
unsigned int units = 1000000; /* MHz etc */
unsigned int genuine_intel;
unsigned int has_invariant_tsc;
-unsigned int do_nehalem_platform_info;
-unsigned int do_nehalem_turbo_ratio_limit;
+unsigned int do_nhm_platform_info;
+unsigned int do_nhm_turbo_ratio_limit;
unsigned int do_ivt_turbo_ratio_limit;
unsigned int extra_msr_offset32;
unsigned int extra_msr_offset64;
@@ -81,6 +86,9 @@ unsigned int tcc_activation_temp;
unsigned int tcc_activation_temp_override;
double rapl_power_units, rapl_energy_units, rapl_time_units;
double rapl_joule_counter_range;
+unsigned int do_core_perf_limit_reasons;
+unsigned int do_gfx_perf_limit_reasons;
+unsigned int do_ring_perf_limit_reasons;
#define RAPL_PKG (1 << 0)
/* 0x610 MSR_PKG_POWER_LIMIT */
@@ -251,15 +259,13 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr)
sprintf(pathname, "/dev/cpu/%d/msr", cpu);
fd = open(pathname, O_RDONLY);
if (fd < 0)
- return -1;
+ err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname);
retval = pread(fd, msr, sizeof *msr, offset);
close(fd);
- if (retval != sizeof *msr) {
- fprintf(stderr, "%s offset 0x%llx read failed\n", pathname, (unsigned long long)offset);
- return -1;
- }
+ if (retval != sizeof *msr)
+ err(-1, "%s offset 0x%llx read failed", pathname, (unsigned long long)offset);
return 0;
}
@@ -281,7 +287,7 @@ void print_header(void)
outp += sprintf(outp, " CPU");
if (has_aperf)
outp += sprintf(outp, " Avg_MHz");
- if (do_nhm_cstates)
+ if (has_aperf)
outp += sprintf(outp, " %%Busy");
if (has_aperf)
outp += sprintf(outp, " Bzy_MHz");
@@ -310,13 +316,13 @@ void print_header(void)
if (do_ptm)
outp += sprintf(outp, " PkgTmp");
- if (do_snb_cstates)
+ if (do_pc2)
outp += sprintf(outp, " Pkg%%pc2");
- if (do_nhm_cstates && !do_slm_cstates)
+ if (do_pc3)
outp += sprintf(outp, " Pkg%%pc3");
- if (do_nhm_cstates && !do_slm_cstates)
+ if (do_pc6)
outp += sprintf(outp, " Pkg%%pc6");
- if (do_snb_cstates)
+ if (do_pc7)
outp += sprintf(outp, " Pkg%%pc7");
if (do_c8_c9_c10) {
outp += sprintf(outp, " Pkg%%pc8");
@@ -337,7 +343,7 @@ void print_header(void)
outp += sprintf(outp, " PKG_%%");
if (do_rapl & RAPL_DRAM_PERF_STATUS)
outp += sprintf(outp, " RAM_%%");
- } else {
+ } else if (do_rapl && rapl_joules) {
if (do_rapl & RAPL_PKG)
outp += sprintf(outp, " Pkg_J");
if (do_rapl & RAPL_CORES)
@@ -391,9 +397,12 @@ int dump_counters(struct thread_data *t, struct core_data *c,
if (p) {
outp += sprintf(outp, "package: %d\n", p->package_id);
outp += sprintf(outp, "pc2: %016llX\n", p->pc2);
- outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
- outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
- outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
+ if (do_pc3)
+ outp += sprintf(outp, "pc3: %016llX\n", p->pc3);
+ if (do_pc6)
+ outp += sprintf(outp, "pc6: %016llX\n", p->pc6);
+ if (do_pc7)
+ outp += sprintf(outp, "pc7: %016llX\n", p->pc7);
outp += sprintf(outp, "pc8: %016llX\n", p->pc8);
outp += sprintf(outp, "pc9: %016llX\n", p->pc9);
outp += sprintf(outp, "pc10: %016llX\n", p->pc10);
@@ -457,25 +466,25 @@ int format_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, "%8d", t->cpu_id);
}
- /* AvgMHz */
+ /* Avg_MHz */
if (has_aperf)
outp += sprintf(outp, "%8.0f",
1.0 / units * t->aperf / interval_float);
- /* %c0 */
- if (do_nhm_cstates) {
+ /* %Busy */
+ if (has_aperf) {
if (!skip_c0)
outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc);
else
outp += sprintf(outp, "********");
}
- /* BzyMHz */
+ /* Bzy_MHz */
if (has_aperf)
outp += sprintf(outp, "%8.0f",
1.0 * t->tsc / units * t->aperf / t->mperf / interval_float);
- /* TSC */
+ /* TSC_MHz */
outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float);
/* SMI */
@@ -525,13 +534,13 @@ int format_counters(struct thread_data *t, struct core_data *c,
if (do_ptm)
outp += sprintf(outp, "%8d", p->pkg_temp_c);
- if (do_snb_cstates)
+ if (do_pc2)
outp += sprintf(outp, "%8.2f", 100.0 * p->pc2/t->tsc);
- if (do_nhm_cstates && !do_slm_cstates)
+ if (do_pc3)
outp += sprintf(outp, "%8.2f", 100.0 * p->pc3/t->tsc);
- if (do_nhm_cstates && !do_slm_cstates)
+ if (do_pc6)
outp += sprintf(outp, "%8.2f", 100.0 * p->pc6/t->tsc);
- if (do_snb_cstates)
+ if (do_pc7)
outp += sprintf(outp, "%8.2f", 100.0 * p->pc7/t->tsc);
if (do_c8_c9_c10) {
outp += sprintf(outp, "%8.2f", 100.0 * p->pc8/t->tsc);
@@ -561,7 +570,7 @@ int format_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
if (do_rapl & RAPL_DRAM_PERF_STATUS)
outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
- } else {
+ } else if (do_rapl && rapl_joules) {
if (do_rapl & RAPL_PKG)
outp += sprintf(outp, fmt8,
p->energy_pkg * rapl_energy_units);
@@ -578,8 +587,8 @@ int format_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float);
if (do_rapl & RAPL_DRAM_PERF_STATUS)
outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float);
- outp += sprintf(outp, fmt8, interval_float);
+ outp += sprintf(outp, fmt8, interval_float);
}
done:
outp += sprintf(outp, "\n");
@@ -628,9 +637,12 @@ void
delta_package(struct pkg_data *new, struct pkg_data *old)
{
old->pc2 = new->pc2 - old->pc2;
- old->pc3 = new->pc3 - old->pc3;
- old->pc6 = new->pc6 - old->pc6;
- old->pc7 = new->pc7 - old->pc7;
+ if (do_pc3)
+ old->pc3 = new->pc3 - old->pc3;
+ if (do_pc6)
+ old->pc6 = new->pc6 - old->pc6;
+ if (do_pc7)
+ old->pc7 = new->pc7 - old->pc7;
old->pc8 = new->pc8 - old->pc8;
old->pc9 = new->pc9 - old->pc9;
old->pc10 = new->pc10 - old->pc10;
@@ -670,24 +682,26 @@ delta_thread(struct thread_data *new, struct thread_data *old,
old->c1 = new->c1 - old->c1;
- if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
- old->aperf = new->aperf - old->aperf;
- old->mperf = new->mperf - old->mperf;
- } else {
+ if (has_aperf) {
+ if ((new->aperf > old->aperf) && (new->mperf > old->mperf)) {
+ old->aperf = new->aperf - old->aperf;
+ old->mperf = new->mperf - old->mperf;
+ } else {
- if (!aperf_mperf_unstable) {
- fprintf(stderr, "%s: APERF or MPERF went backwards *\n", progname);
- fprintf(stderr, "* Frequency results do not cover entire interval *\n");
- fprintf(stderr, "* fix this by running Linux-2.6.30 or later *\n");
+ if (!aperf_mperf_unstable) {
+ fprintf(stderr, "%s: APERF or MPERF went backwards *\n", progname);
+ fprintf(stderr, "* Frequency results do not cover entire interval *\n");
+ fprintf(stderr, "* fix this by running Linux-2.6.30 or later *\n");
- aperf_mperf_unstable = 1;
+ aperf_mperf_unstable = 1;
+ }
+ /*
+ * mperf delta is likely a huge "positive" number
+ * can not use it for calculating c0 time
+ */
+ skip_c0 = 1;
+ skip_c1 = 1;
}
- /*
- * mperf delta is likely a huge "positive" number
- * can not use it for calculating c0 time
- */
- skip_c0 = 1;
- skip_c1 = 1;
}
@@ -712,7 +726,7 @@ delta_thread(struct thread_data *new, struct thread_data *old,
}
if (old->mperf == 0) {
- if (verbose > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
+ if (debug > 1) fprintf(stderr, "cpu%d MPERF 0!\n", old->cpu_id);
old->mperf = 1; /* divide by 0 protection */
}
@@ -769,9 +783,12 @@ void clear_counters(struct thread_data *t, struct core_data *c, struct pkg_data
c->core_temp_c = 0;
p->pc2 = 0;
- p->pc3 = 0;
- p->pc6 = 0;
- p->pc7 = 0;
+ if (do_pc3)
+ p->pc3 = 0;
+ if (do_pc6)
+ p->pc6 = 0;
+ if (do_pc7)
+ p->pc7 = 0;
p->pc8 = 0;
p->pc9 = 0;
p->pc10 = 0;
@@ -810,9 +827,12 @@ int sum_counters(struct thread_data *t, struct core_data *c,
return 0;
average.packages.pc2 += p->pc2;
- average.packages.pc3 += p->pc3;
- average.packages.pc6 += p->pc6;
- average.packages.pc7 += p->pc7;
+ if (do_pc3)
+ average.packages.pc3 += p->pc3;
+ if (do_pc6)
+ average.packages.pc6 += p->pc6;
+ if (do_pc7)
+ average.packages.pc7 += p->pc7;
average.packages.pc8 += p->pc8;
average.packages.pc9 += p->pc9;
average.packages.pc10 += p->pc10;
@@ -854,9 +874,12 @@ void compute_average(struct thread_data *t, struct core_data *c,
average.cores.c7 /= topo.num_cores;
average.packages.pc2 /= topo.num_packages;
- average.packages.pc3 /= topo.num_packages;
- average.packages.pc6 /= topo.num_packages;
- average.packages.pc7 /= topo.num_packages;
+ if (do_pc3)
+ average.packages.pc3 /= topo.num_packages;
+ if (do_pc6)
+ average.packages.pc6 /= topo.num_packages;
+ if (do_pc7)
+ average.packages.pc7 /= topo.num_packages;
average.packages.pc8 /= topo.num_packages;
average.packages.pc9 /= topo.num_packages;
@@ -956,18 +979,18 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
return 0;
- if (do_nhm_cstates && !do_slm_cstates) {
+ if (do_pc3)
if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3))
return -9;
+ if (do_pc6)
if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6))
return -10;
- }
- if (do_snb_cstates) {
+ if (do_pc2)
if (get_msr(cpu, MSR_PKG_C2_RESIDENCY, &p->pc2))
return -11;
+ if (do_pc7)
if (get_msr(cpu, MSR_PKG_C7_RESIDENCY, &p->pc7))
return -12;
- }
if (do_c8_c9_c10) {
if (get_msr(cpu, MSR_PKG_C8_RESIDENCY, &p->pc8))
return -13;
@@ -1014,12 +1037,43 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
return 0;
}
+/*
+ * MSR_PKG_CST_CONFIG_CONTROL decoding for pkg_cstate_limit:
+ * If you change the values, note they are used both in comparisons
+ * (>= PCL__7) and to index pkg_cstate_limit_strings[].
+ */
+
+#define PCLUKN 0 /* Unknown */
+#define PCLRSV 1 /* Reserved */
+#define PCL__0 2 /* PC0 */
+#define PCL__1 3 /* PC1 */
+#define PCL__2 4 /* PC2 */
+#define PCL__3 5 /* PC3 */
+#define PCL__4 6 /* PC4 */
+#define PCL__6 7 /* PC6 */
+#define PCL_6N 8 /* PC6 No Retention */
+#define PCL_6R 9 /* PC6 Retention */
+#define PCL__7 10 /* PC7 */
+#define PCL_7S 11 /* PC7 Shrink */
+#define PCLUNL 12 /* Unlimited */
+
+int pkg_cstate_limit = PCLUKN;
+char *pkg_cstate_limit_strings[] = { "reserved", "unknown", "pc0", "pc1", "pc2",
+ "pc3", "pc4", "pc6", "pc6n", "pc6r", "pc7", "pc7s", "unlimited"};
+
+int nhm_pkg_cstate_limits[8] = {PCL__0, PCL__1, PCL__3, PCL__6, PCL__7, PCLRSV, PCLRSV, PCLUNL};
+int snb_pkg_cstate_limits[8] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCL__7, PCL_7S, PCLRSV, PCLUNL};
+int hsw_pkg_cstate_limits[8] = {PCL__0, PCL__2, PCL__3, PCL__6, PCL__7, PCL_7S, PCLRSV, PCLUNL};
+int slv_pkg_cstate_limits[8] = {PCL__0, PCL__1, PCLRSV, PCLRSV, PCL__4, PCLRSV, PCL__6, PCL__7};
+int amt_pkg_cstate_limits[8] = {PCL__0, PCL__1, PCL__2, PCLRSV, PCLRSV, PCLRSV, PCL__6, PCL__7};
+int phi_pkg_cstate_limits[8] = {PCL__0, PCL__2, PCL_6N, PCL_6R, PCLRSV, PCLRSV, PCLRSV, PCLUNL};
+
void print_verbose_header(void)
{
unsigned long long msr;
unsigned int ratio;
- if (!do_nehalem_platform_info)
+ if (!do_nhm_platform_info)
return;
get_msr(0, MSR_NHM_PLATFORM_INFO, &msr);
@@ -1093,46 +1147,16 @@ print_nhm_turbo_ratio_limits:
fprintf(stderr, "cpu0: MSR_NHM_SNB_PKG_CST_CFG_CTL: 0x%08llx", msr);
- fprintf(stderr, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: ",
+ fprintf(stderr, " (%s%s%s%s%slocked: pkg-cstate-limit=%d: %s)\n",
(msr & SNB_C3_AUTO_UNDEMOTE) ? "UNdemote-C3, " : "",
(msr & SNB_C1_AUTO_UNDEMOTE) ? "UNdemote-C1, " : "",
(msr & NHM_C3_AUTO_DEMOTE) ? "demote-C3, " : "",
(msr & NHM_C1_AUTO_DEMOTE) ? "demote-C1, " : "",
(msr & (1 << 15)) ? "" : "UN",
- (unsigned int)msr & 7);
-
-
- switch(msr & 0x7) {
- case 0:
- fprintf(stderr, do_slm_cstates ? "no pkg states" : "pc0");
- break;
- case 1:
- fprintf(stderr, do_slm_cstates ? "no pkg states" : do_snb_cstates ? "pc2" : "pc0");
- break;
- case 2:
- fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc6-noret" : "pc3");
- break;
- case 3:
- fprintf(stderr, do_slm_cstates ? "invalid" : "pc6");
- break;
- case 4:
- fprintf(stderr, do_slm_cstates ? "pc4" : "pc7");
- break;
- case 5:
- fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc7s" : "invalid");
- break;
- case 6:
- fprintf(stderr, do_slm_cstates ? "pc6" : "invalid");
- break;
- case 7:
- fprintf(stderr, do_slm_cstates ? "pc7" : "unlimited");
- break;
- default:
- fprintf(stderr, "invalid");
- }
- fprintf(stderr, ")\n");
+ (unsigned int)msr & 7,
+ pkg_cstate_limit_strings[pkg_cstate_limit]);
- if (!do_nehalem_turbo_ratio_limit)
+ if (!do_nhm_turbo_ratio_limit)
return;
get_msr(0, MSR_NHM_TURBO_RATIO_LIMIT, &msr);
@@ -1178,6 +1202,7 @@ print_nhm_turbo_ratio_limits:
if (ratio)
fprintf(stderr, "%d * %.0f = %.0f MHz max turbo 1 active cores\n",
ratio, bclk, ratio * bclk);
+
}
void free_all_buffers(void)
@@ -1458,18 +1483,66 @@ void check_dev_msr()
struct stat sb;
if (stat("/dev/cpu/0/msr", &sb))
- err(-5, "no /dev/cpu/0/msr\n"
- "Try \"# modprobe msr\"");
+ err(-5, "no /dev/cpu/0/msr, Try \"# modprobe msr\" ");
}
-void check_super_user()
+void check_permissions()
{
- if (getuid() != 0)
- errx(-6, "must be root");
+ struct __user_cap_header_struct cap_header_data;
+ cap_user_header_t cap_header = &cap_header_data;
+ struct __user_cap_data_struct cap_data_data;
+ cap_user_data_t cap_data = &cap_data_data;
+ extern int capget(cap_user_header_t hdrp, cap_user_data_t datap);
+ int do_exit = 0;
+
+ /* check for CAP_SYS_RAWIO */
+ cap_header->pid = getpid();
+ cap_header->version = _LINUX_CAPABILITY_VERSION;
+ if (capget(cap_header, cap_data) < 0)
+ err(-6, "capget(2) failed");
+
+ if ((cap_data->effective & (1 << CAP_SYS_RAWIO)) == 0) {
+ do_exit++;
+ warnx("capget(CAP_SYS_RAWIO) failed,"
+ " try \"# setcap cap_sys_rawio=ep %s\"", progname);
+ }
+
+ /* test file permissions */
+ if (euidaccess("/dev/cpu/0/msr", R_OK)) {
+ do_exit++;
+ warn("/dev/cpu/0/msr open failed, try chown or chmod +r /dev/cpu/*/msr");
+ }
+
+ /* if all else fails, thell them to be root */
+ if (do_exit)
+ if (getuid() != 0)
+ warnx("... or simply run as root");
+
+ if (do_exit)
+ exit(-6);
}
-int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
+/*
+ * NHM adds support for additional MSRs:
+ *
+ * MSR_SMI_COUNT 0x00000034
+ *
+ * MSR_NHM_PLATFORM_INFO 0x000000ce
+ * MSR_NHM_SNB_PKG_CST_CFG_CTL 0x000000e2
+ *
+ * MSR_PKG_C3_RESIDENCY 0x000003f8
+ * MSR_PKG_C6_RESIDENCY 0x000003f9
+ * MSR_CORE_C3_RESIDENCY 0x000003fc
+ * MSR_CORE_C6_RESIDENCY 0x000003fd
+ *
+ * Side effect:
+ * sets global pkg_cstate_limit to decode MSR_NHM_SNB_PKG_CST_CFG_CTL
+ */
+int probe_nhm_msrs(unsigned int family, unsigned int model)
{
+ unsigned long long msr;
+ int *pkg_cstate_limits;
+
if (!genuine_intel)
return 0;
@@ -1482,24 +1555,54 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model)
case 0x1F: /* Core i7 and i5 Processor - Nehalem */
case 0x25: /* Westmere Client - Clarkdale, Arrandale */
case 0x2C: /* Westmere EP - Gulftown */
+ case 0x2E: /* Nehalem-EX Xeon - Beckton */
+ case 0x2F: /* Westmere-EX Xeon - Eagleton */
+ pkg_cstate_limits = nhm_pkg_cstate_limits;
+ break;
case 0x2A: /* SNB */
case 0x2D: /* SNB Xeon */
case 0x3A: /* IVB */
case 0x3E: /* IVB Xeon */
+ pkg_cstate_limits = snb_pkg_cstate_limits;
+ break;
case 0x3C: /* HSW */
case 0x3F: /* HSX */
case 0x45: /* HSW */
case 0x46: /* HSW */
- case 0x37: /* BYT */
- case 0x4D: /* AVN */
case 0x3D: /* BDW */
+ case 0x47: /* BDW */
case 0x4F: /* BDX */
case 0x56: /* BDX-DE */
- return 1;
+ pkg_cstate_limits = hsw_pkg_cstate_limits;
+ break;
+ case 0x37: /* BYT */
+ case 0x4D: /* AVN */
+ pkg_cstate_limits = slv_pkg_cstate_limits;
+ break;
+ case 0x4C: /* AMT */
+ pkg_cstate_limits = amt_pkg_cstate_limits;
+ break;
+ case 0x57: /* PHI */
+ pkg_cstate_limits = phi_pkg_cstate_limits;
+ break;
+ default:
+ return 0;
+ }
+ get_msr(0, MSR_NHM_SNB_PKG_CST_CFG_CTL, &msr);
+
+ pkg_cstate_limit = pkg_cstate_limits[msr & 0x7];
+
+ return 1;
+}
+int has_nhm_turbo_ratio_limit(unsigned int family, unsigned int model)
+{
+ switch (model) {
+ /* Nehalem compatible, but do not include turbo-ratio limit support */
case 0x2E: /* Nehalem-EX Xeon - Beckton */
case 0x2F: /* Westmere-EX Xeon - Eagleton */
- default:
return 0;
+ default:
+ return 1;
}
}
int has_ivt_turbo_ratio_limit(unsigned int family, unsigned int model)
@@ -1564,6 +1667,103 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p)
return 0;
}
+/*
+ * print_perf_limit()
+ */
+int print_perf_limit(struct thread_data *t, struct core_data *c, struct pkg_data *p)
+{
+ unsigned long long msr;
+ int cpu;
+
+ cpu = t->cpu_id;
+
+ /* per-package */
+ if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE) || !(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE))
+ return 0;
+
+ if (cpu_migrate(cpu)) {
+ fprintf(stderr, "Could not migrate to CPU %d\n", cpu);
+ return -1;
+ }
+
+ if (do_core_perf_limit_reasons) {
+ get_msr(cpu, MSR_CORE_PERF_LIMIT_REASONS, &msr);
+ fprintf(stderr, "cpu%d: MSR_CORE_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
+ fprintf(stderr, " (Active: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)",
+ (msr & 1 << 0) ? "PROCHOT, " : "",
+ (msr & 1 << 1) ? "ThermStatus, " : "",
+ (msr & 1 << 2) ? "bit2, " : "",
+ (msr & 1 << 4) ? "Graphics, " : "",
+ (msr & 1 << 5) ? "Auto-HWP, " : "",
+ (msr & 1 << 6) ? "VR-Therm, " : "",
+ (msr & 1 << 8) ? "Amps, " : "",
+ (msr & 1 << 9) ? "CorePwr, " : "",
+ (msr & 1 << 10) ? "PkgPwrL1, " : "",
+ (msr & 1 << 11) ? "PkgPwrL2, " : "",
+ (msr & 1 << 12) ? "MultiCoreTurbo, " : "",
+ (msr & 1 << 13) ? "Transitions, " : "",
+ (msr & 1 << 14) ? "bit14, " : "",
+ (msr & 1 << 15) ? "bit15, " : "");
+ fprintf(stderr, " (Logged: %s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",
+ (msr & 1 << 16) ? "PROCHOT, " : "",
+ (msr & 1 << 17) ? "ThermStatus, " : "",
+ (msr & 1 << 18) ? "bit18, " : "",
+ (msr & 1 << 20) ? "Graphics, " : "",
+ (msr & 1 << 21) ? "Auto-HWP, " : "",
+ (msr & 1 << 22) ? "VR-Therm, " : "",
+ (msr & 1 << 24) ? "Amps, " : "",
+ (msr & 1 << 25) ? "CorePwr, " : "",
+ (msr & 1 << 26) ? "PkgPwrL1, " : "",
+ (msr & 1 << 27) ? "PkgPwrL2, " : "",
+ (msr & 1 << 28) ? "MultiCoreTurbo, " : "",
+ (msr & 1 << 29) ? "Transitions, " : "",
+ (msr & 1 << 30) ? "bit30, " : "",
+ (msr & 1 << 31) ? "bit31, " : "");
+
+ }
+ if (do_gfx_perf_limit_reasons) {
+ get_msr(cpu, MSR_GFX_PERF_LIMIT_REASONS, &msr);
+ fprintf(stderr, "cpu%d: MSR_GFX_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
+ fprintf(stderr, " (Active: %s%s%s%s%s%s%s%s)",
+ (msr & 1 << 0) ? "PROCHOT, " : "",
+ (msr & 1 << 1) ? "ThermStatus, " : "",
+ (msr & 1 << 4) ? "Graphics, " : "",
+ (msr & 1 << 6) ? "VR-Therm, " : "",
+ (msr & 1 << 8) ? "Amps, " : "",
+ (msr & 1 << 9) ? "GFXPwr, " : "",
+ (msr & 1 << 10) ? "PkgPwrL1, " : "",
+ (msr & 1 << 11) ? "PkgPwrL2, " : "");
+ fprintf(stderr, " (Logged: %s%s%s%s%s%s%s%s)\n",
+ (msr & 1 << 16) ? "PROCHOT, " : "",
+ (msr & 1 << 17) ? "ThermStatus, " : "",
+ (msr & 1 << 20) ? "Graphics, " : "",
+ (msr & 1 << 22) ? "VR-Therm, " : "",
+ (msr & 1 << 24) ? "Amps, " : "",
+ (msr & 1 << 25) ? "GFXPwr, " : "",
+ (msr & 1 << 26) ? "PkgPwrL1, " : "",
+ (msr & 1 << 27) ? "PkgPwrL2, " : "");
+ }
+ if (do_ring_perf_limit_reasons) {
+ get_msr(cpu, MSR_RING_PERF_LIMIT_REASONS, &msr);
+ fprintf(stderr, "cpu%d: MSR_RING_PERF_LIMIT_REASONS, 0x%08llx", cpu, msr);
+ fprintf(stderr, " (Active: %s%s%s%s%s%s)",
+ (msr & 1 << 0) ? "PROCHOT, " : "",
+ (msr & 1 << 1) ? "ThermStatus, " : "",
+ (msr & 1 << 6) ? "VR-Therm, " : "",
+ (msr & 1 << 8) ? "Amps, " : "",
+ (msr & 1 << 10) ? "PkgPwrL1, " : "",
+ (msr & 1 << 11) ? "PkgPwrL2, " : "");
+ fprintf(stderr, " (Logged: %s%s%s%s%s%s)\n",
+ (msr & 1 << 16) ? "PROCHOT, " : "",
+ (msr & 1 << 17) ? "ThermStatus, " : "",
+ (msr & 1 << 22) ? "VR-Therm, " : "",
+ (msr & 1 << 24) ? "Amps, " : "",
+ (msr & 1 << 26) ? "PkgPwrL1, " : "",
+ (msr & 1 << 27) ? "PkgPwrL2, " : "");
+ }
+ return 0;
+}
+
#define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */
#define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */
@@ -1609,6 +1809,7 @@ void rapl_probe(unsigned int family, unsigned int model)
case 0x45: /* HSW */
case 0x46: /* HSW */
case 0x3D: /* BDW */
+ case 0x47: /* BDW */
do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO;
break;
case 0x3F: /* HSX */
@@ -1647,12 +1848,33 @@ void rapl_probe(unsigned int family, unsigned int model)
tdp = get_tdp(model);
rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp;
- if (verbose)
+ if (debug)
fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp);
return;
}
+void perf_limit_reasons_probe(family, model)
+{
+ if (!genuine_intel)
+ return;
+
+ if (family != 6)
+ return;
+
+ switch (model) {
+ case 0x3C: /* HSW */
+ case 0x45: /* HSW */
+ case 0x46: /* HSW */
+ do_gfx_perf_limit_reasons = 1;
+ case 0x3F: /* HSX */
+ do_core_perf_limit_reasons = 1;
+ do_ring_perf_limit_reasons = 1;
+ default:
+ return;
+ }
+}
+
int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p)
{
unsigned long long msr;
@@ -1751,7 +1973,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr))
return -1;
- if (verbose) {
+ if (debug) {
fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx "
"(%f Watts, %f Joules, %f sec.)\n", cpu, msr,
rapl_power_units, rapl_energy_units, rapl_time_units);
@@ -1808,7 +2030,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
print_power_limit_msr(cpu, msr, "DRAM Limit");
}
if (do_rapl & RAPL_CORE_POLICY) {
- if (verbose) {
+ if (debug) {
if (get_msr(cpu, MSR_PP0_POLICY, &msr))
return -7;
@@ -1816,7 +2038,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
}
}
if (do_rapl & RAPL_CORES) {
- if (verbose) {
+ if (debug) {
if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr))
return -9;
@@ -1826,7 +2048,7 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
}
}
if (do_rapl & RAPL_GFX) {
- if (verbose) {
+ if (debug) {
if (get_msr(cpu, MSR_PP1_POLICY, &msr))
return -8;
@@ -1842,8 +2064,15 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p)
return 0;
}
+/*
+ * SNB adds support for additional MSRs:
+ *
+ * MSR_PKG_C7_RESIDENCY 0x000003fa
+ * MSR_CORE_C7_RESIDENCY 0x000003fe
+ * MSR_PKG_C2_RESIDENCY 0x0000060d
+ */
-int is_snb(unsigned int family, unsigned int model)
+int has_snb_msrs(unsigned int family, unsigned int model)
{
if (!genuine_intel)
return 0;
@@ -1858,6 +2087,7 @@ int is_snb(unsigned int family, unsigned int model)
case 0x45: /* HSW */
case 0x46: /* HSW */
case 0x3D: /* BDW */
+ case 0x47: /* BDW */
case 0x4F: /* BDX */
case 0x56: /* BDX-DE */
return 1;
@@ -1865,7 +2095,14 @@ int is_snb(unsigned int family, unsigned int model)
return 0;
}
-int has_c8_c9_c10(unsigned int family, unsigned int model)
+/*
+ * HSW adds support for additional MSRs:
+ *
+ * MSR_PKG_C8_RESIDENCY 0x00000630
+ * MSR_PKG_C9_RESIDENCY 0x00000631
+ * MSR_PKG_C10_RESIDENCY 0x00000632
+ */
+int has_hsw_msrs(unsigned int family, unsigned int model)
{
if (!genuine_intel)
return 0;
@@ -1917,7 +2154,7 @@ double slm_bclk(void)
double discover_bclk(unsigned int family, unsigned int model)
{
- if (is_snb(family, model))
+ if (has_snb_msrs(family, model))
return 100.00;
else if (is_slm(family, model))
return slm_bclk();
@@ -1965,7 +2202,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
}
/* Temperature Target MSR is Nehalem and newer only */
- if (!do_nehalem_platform_info)
+ if (!do_nhm_platform_info)
goto guess;
if (get_msr(0, MSR_IA32_TEMPERATURE_TARGET, &msr))
@@ -1973,7 +2210,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk
target_c_local = (msr >> 16) & 0xFF;
- if (verbose)
+ if (debug)
fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n",
cpu, msr, target_c_local);
@@ -2003,7 +2240,7 @@ void check_cpuid()
if (ebx == 0x756e6547 && edx == 0x49656e69 && ecx == 0x6c65746e)
genuine_intel = 1;
- if (verbose)
+ if (debug)
fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ",
(char *)&ebx, (char *)&edx, (char *)&ecx);
@@ -2014,7 +2251,7 @@ void check_cpuid()
if (family == 6 || family == 0xf)
model += ((fms >> 16) & 0xf) << 4;
- if (verbose)
+ if (debug)
fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n",
max_level, family, model, stepping, family, model, stepping);
@@ -2029,18 +2266,15 @@ void check_cpuid()
ebx = ecx = edx = 0;
__get_cpuid(0x80000000, &max_level, &ebx, &ecx, &edx);
- if (max_level < 0x80000007)
- errx(1, "CPUID: no invariant TSC (max_level 0x%x)", max_level);
+ if (max_level >= 0x80000007) {
- /*
- * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
- * this check is valid for both Intel and AMD
- */
- __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
- has_invariant_tsc = edx & (1 << 8);
-
- if (!has_invariant_tsc)
- errx(1, "No invariant TSC");
+ /*
+ * Non-Stop TSC is advertised by CPUID.EAX=0x80000007: EDX.bit8
+ * this check is valid for both Intel and AMD
+ */
+ __get_cpuid(0x80000007, &eax, &ebx, &ecx, &edx);
+ has_invariant_tsc = edx & (1 << 8);
+ }
/*
* APERF/MPERF is advertised by CPUID.EAX=0x6: ECX.bit0
@@ -2053,36 +2287,51 @@ void check_cpuid()
do_ptm = eax & (1 << 6);
has_epb = ecx & (1 << 3);
- if (verbose)
- fprintf(stderr, "CPUID(6): %s%s%s%s\n",
- has_aperf ? "APERF" : "No APERF!",
- do_dts ? ", DTS" : "",
- do_ptm ? ", PTM": "",
- has_epb ? ", EPB": "");
-
- if (!has_aperf)
- errx(-1, "No APERF");
-
- do_nehalem_platform_info = genuine_intel && has_invariant_tsc;
- do_nhm_cstates = genuine_intel; /* all Intel w/ non-stop TSC have NHM counters */
- do_smi = do_nhm_cstates;
- do_snb_cstates = is_snb(family, model);
- do_c8_c9_c10 = has_c8_c9_c10(family, model);
+ if (debug)
+ fprintf(stderr, "CPUID(6): %sAPERF, %sDTS, %sPTM, %sEPB\n",
+ has_aperf ? "" : "No ",
+ do_dts ? "" : "No ",
+ do_ptm ? "" : "No ",
+ has_epb ? "" : "No ");
+
+ do_nhm_platform_info = do_nhm_cstates = do_smi = probe_nhm_msrs(family, model);
+ do_snb_cstates = has_snb_msrs(family, model);
+ do_pc2 = do_snb_cstates && (pkg_cstate_limit >= PCL__2);
+ do_pc3 = (pkg_cstate_limit >= PCL__3);
+ do_pc6 = (pkg_cstate_limit >= PCL__6);
+ do_pc7 = do_snb_cstates && (pkg_cstate_limit >= PCL__7);
+ do_c8_c9_c10 = has_hsw_msrs(family, model);
do_slm_cstates = is_slm(family, model);
bclk = discover_bclk(family, model);
- do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model);
+ do_nhm_turbo_ratio_limit = do_nhm_platform_info && has_nhm_turbo_ratio_limit(family, model);
do_ivt_turbo_ratio_limit = has_ivt_turbo_ratio_limit(family, model);
rapl_probe(family, model);
+ perf_limit_reasons_probe(family, model);
return;
}
-void usage()
+void help()
{
- errx(1, "%s: [-v][-R][-T][-p|-P|-S][-c MSR#][-C MSR#][-m MSR#][-M MSR#][-i interval_sec | command ...]\n",
- progname);
+ fprintf(stderr,
+ "Usage: turbostat [OPTIONS][(--interval seconds) | COMMAND ...]\n"
+ "\n"
+ "Turbostat forks the specified COMMAND and prints statistics\n"
+ "when COMMAND completes.\n"
+ "If no COMMAND is specified, turbostat wakes every 5-seconds\n"
+ "to print statistics, until interrupted.\n"
+ "--debug run in \"debug\" mode\n"
+ "--interval sec Override default 5-second measurement interval\n"
+ "--help print this help message\n"
+ "--counter msr print 32-bit counter at address \"msr\"\n"
+ "--Counter msr print 64-bit Counter at address \"msr\"\n"
+ "--msr msr print 32-bit value at address \"msr\"\n"
+ "--MSR msr print 64-bit Value at address \"msr\"\n"
+ "--version print version information\n"
+ "\n"
+ "For more help, run \"man turbostat\"\n");
}
@@ -2121,7 +2370,7 @@ void topology_probe()
if (!summary_only && topo.num_cpus > 1)
show_cpu = 1;
- if (verbose > 1)
+ if (debug > 1)
fprintf(stderr, "num_cpus %d max_cpu_num %d\n", topo.num_cpus, topo.max_cpu_num);
cpus = calloc(1, (topo.max_cpu_num + 1) * sizeof(struct cpu_topology));
@@ -2156,7 +2405,7 @@ void topology_probe()
int siblings;
if (cpu_is_not_present(i)) {
- if (verbose > 1)
+ if (debug > 1)
fprintf(stderr, "cpu%d NOT PRESENT\n", i);
continue;
}
@@ -2171,26 +2420,26 @@ void topology_probe()
siblings = get_num_ht_siblings(i);
if (siblings > max_siblings)
max_siblings = siblings;
- if (verbose > 1)
+ if (debug > 1)
fprintf(stderr, "cpu %d pkg %d core %d\n",
i, cpus[i].physical_package_id, cpus[i].core_id);
}
topo.num_cores_per_pkg = max_core_id + 1;
- if (verbose > 1)
+ if (debug > 1)
fprintf(stderr, "max_core_id %d, sizing for %d cores per package\n",
max_core_id, topo.num_cores_per_pkg);
if (!summary_only && topo.num_cores_per_pkg > 1)
show_core = 1;
topo.num_packages = max_package_id + 1;
- if (verbose > 1)
+ if (debug > 1)
fprintf(stderr, "max_package_id %d, sizing for %d packages\n",
max_package_id, topo.num_packages);
if (!summary_only && topo.num_packages > 1)
show_pkg = 1;
topo.num_threads_per_core = max_siblings;
- if (verbose > 1)
+ if (debug > 1)
fprintf(stderr, "max_siblings %d\n", max_siblings);
free(cpus);
@@ -2299,25 +2548,27 @@ void setup_all_buffers(void)
void turbostat_init()
{
- check_cpuid();
-
check_dev_msr();
- check_super_user();
+ check_permissions();
+ check_cpuid();
setup_all_buffers();
- if (verbose)
+ if (debug)
print_verbose_header();
- if (verbose)
+ if (debug)
for_all_cpus(print_epb, ODD_COUNTERS);
- if (verbose)
+ if (debug)
+ for_all_cpus(print_perf_limit, ODD_COUNTERS);
+
+ if (debug)
for_all_cpus(print_rapl, ODD_COUNTERS);
for_all_cpus(set_temperature_target, ODD_COUNTERS);
- if (verbose)
+ if (debug)
for_all_cpus(print_thermal, ODD_COUNTERS);
}
@@ -2382,56 +2633,82 @@ int get_and_dump_counters(void)
return status;
}
+void print_version() {
+ fprintf(stderr, "turbostat version 4.1 10-Feb, 2015"
+ " - Len Brown <lenb@kernel.org>\n");
+}
+
void cmdline(int argc, char **argv)
{
int opt;
+ int option_index = 0;
+ static struct option long_options[] = {
+ {"Counter", required_argument, 0, 'C'},
+ {"counter", required_argument, 0, 'c'},
+ {"Dump", no_argument, 0, 'D'},
+ {"debug", no_argument, 0, 'd'},
+ {"interval", required_argument, 0, 'i'},
+ {"help", no_argument, 0, 'h'},
+ {"Joules", no_argument, 0, 'J'},
+ {"MSR", required_argument, 0, 'M'},
+ {"msr", required_argument, 0, 'm'},
+ {"Package", no_argument, 0, 'p'},
+ {"processor", no_argument, 0, 'p'},
+ {"Summary", no_argument, 0, 'S'},
+ {"TCC", required_argument, 0, 'T'},
+ {"version", no_argument, 0, 'v' },
+ {0, 0, 0, 0 }
+ };
progname = argv[0];
- while ((opt = getopt(argc, argv, "+pPsSvi:c:C:m:M:RJT:")) != -1) {
+ while ((opt = getopt_long_only(argc, argv, "C:c:Ddhi:JM:m:PpST:v",
+ long_options, &option_index)) != -1) {
switch (opt) {
- case 'p':
- show_core_only++;
+ case 'C':
+ sscanf(optarg, "%x", &extra_delta_offset64);
break;
- case 'P':
- show_pkg_only++;
+ case 'c':
+ sscanf(optarg, "%x", &extra_delta_offset32);
break;
- case 's':
+ case 'D':
dump_only++;
break;
- case 'S':
- summary_only++;
- break;
- case 'v':
- verbose++;
+ case 'd':
+ debug++;
break;
+ case 'h':
+ default:
+ help();
+ exit(1);
case 'i':
interval_sec = atoi(optarg);
break;
- case 'c':
- sscanf(optarg, "%x", &extra_delta_offset32);
+ case 'J':
+ rapl_joules++;
break;
- case 'C':
- sscanf(optarg, "%x", &extra_delta_offset64);
+ case 'M':
+ sscanf(optarg, "%x", &extra_msr_offset64);
break;
case 'm':
sscanf(optarg, "%x", &extra_msr_offset32);
break;
- case 'M':
- sscanf(optarg, "%x", &extra_msr_offset64);
+ case 'P':
+ show_pkg_only++;
break;
- case 'R':
- rapl_verbose++;
+ case 'p':
+ show_core_only++;
+ break;
+ case 'S':
+ summary_only++;
break;
case 'T':
tcc_activation_temp_override = atoi(optarg);
break;
- case 'J':
- rapl_joules++;
+ case 'v':
+ print_version();
+ exit(0);
break;
-
- default:
- usage();
}
}
}
@@ -2440,9 +2717,8 @@ int main(int argc, char **argv)
{
cmdline(argc, argv);
- if (verbose)
- fprintf(stderr, "turbostat v3.7 Feb 6, 2014"
- " - Len Brown <lenb@kernel.org>\n");
+ if (debug)
+ print_version();
turbostat_init();
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index b9cd036f0442..d08e214ec6e7 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -178,6 +178,7 @@ my $checkout;
my $localversion;
my $iteration = 0;
my $successes = 0;
+my $stty_orig;
my $bisect_good;
my $bisect_bad;
@@ -197,6 +198,11 @@ my $patchcheck_start;
my $patchcheck_cherry;
my $patchcheck_end;
+my $build_time;
+my $install_time;
+my $reboot_time;
+my $test_time;
+
# set when a test is something other that just building or install
# which would require more options.
my $buildonly = 1;
@@ -554,6 +560,66 @@ sub get_mandatory_config {
}
}
+sub show_time {
+ my ($time) = @_;
+
+ my $hours = 0;
+ my $minutes = 0;
+
+ if ($time > 3600) {
+ $hours = int($time / 3600);
+ $time -= $hours * 3600;
+ }
+ if ($time > 60) {
+ $minutes = int($time / 60);
+ $time -= $minutes * 60;
+ }
+
+ if ($hours > 0) {
+ doprint "$hours hour";
+ doprint "s" if ($hours > 1);
+ doprint " ";
+ }
+
+ if ($minutes > 0) {
+ doprint "$minutes minute";
+ doprint "s" if ($minutes > 1);
+ doprint " ";
+ }
+
+ doprint "$time second";
+ doprint "s" if ($time != 1);
+}
+
+sub print_times {
+ doprint "\n";
+ if ($build_time) {
+ doprint "Build time: ";
+ show_time($build_time);
+ doprint "\n";
+ }
+ if ($install_time) {
+ doprint "Install time: ";
+ show_time($install_time);
+ doprint "\n";
+ }
+ if ($reboot_time) {
+ doprint "Reboot time: ";
+ show_time($reboot_time);
+ doprint "\n";
+ }
+ if ($test_time) {
+ doprint "Test time: ";
+ show_time($test_time);
+ doprint "\n";
+ }
+ # reset for iterations like bisect
+ $build_time = 0;
+ $install_time = 0;
+ $reboot_time = 0;
+ $test_time = 0;
+}
+
sub get_mandatory_configs {
get_mandatory_config("MACHINE");
get_mandatory_config("BUILD_DIR");
@@ -1341,23 +1407,83 @@ sub dodie {
print " See $opt{LOG_FILE} for more info.\n";
}
+ if ($monitor_cnt) {
+ # restore terminal settings
+ system("stty $stty_orig");
+ }
+
die @_, "\n";
}
+sub create_pty {
+ my ($ptm, $pts) = @_;
+ my $tmp;
+ my $TIOCSPTLCK = 0x40045431;
+ my $TIOCGPTN = 0x80045430;
+
+ sysopen($ptm, "/dev/ptmx", O_RDWR | O_NONBLOCK) or
+ dodie "Cant open /dev/ptmx";
+
+ # unlockpt()
+ $tmp = pack("i", 0);
+ ioctl($ptm, $TIOCSPTLCK, $tmp) or
+ dodie "ioctl TIOCSPTLCK for /dev/ptmx failed";
+
+ # ptsname()
+ ioctl($ptm, $TIOCGPTN, $tmp) or
+ dodie "ioctl TIOCGPTN for /dev/ptmx failed";
+ $tmp = unpack("i", $tmp);
+
+ sysopen($pts, "/dev/pts/$tmp", O_RDWR | O_NONBLOCK) or
+ dodie "Can't open /dev/pts/$tmp";
+}
+
+sub exec_console {
+ my ($ptm, $pts) = @_;
+
+ close($ptm);
+
+ close(\*STDIN);
+ close(\*STDOUT);
+ close(\*STDERR);
+
+ open(\*STDIN, '<&', $pts);
+ open(\*STDOUT, '>&', $pts);
+ open(\*STDERR, '>&', $pts);
+
+ close($pts);
+
+ exec $console or
+ die "Can't open console $console";
+}
+
sub open_console {
- my ($fp) = @_;
+ my ($ptm) = @_;
+ my $pts = \*PTSFD;
+ my $pid;
- my $flags;
+ # save terminal settings
+ $stty_orig = `stty -g`;
- my $pid = open($fp, "$console|") or
- dodie "Can't open console $console";
+ # place terminal in cbreak mode so that stdin can be read one character at
+ # a time without having to wait for a newline
+ system("stty -icanon -echo -icrnl");
- $flags = fcntl($fp, F_GETFL, 0) or
- dodie "Can't get flags for the socket: $!";
- $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or
- dodie "Can't set flags for the socket: $!";
+ create_pty($ptm, $pts);
+
+ $pid = fork;
+
+ if (!$pid) {
+ # child
+ exec_console($ptm, $pts)
+ }
+
+ # parent
+ close($pts);
return $pid;
+
+ open(PTSFD, "Stop perl from warning about single use of PTSFD");
}
sub close_console {
@@ -1368,6 +1494,9 @@ sub close_console {
print "closing!\n";
close($fp);
+
+ # restore terminal settings
+ system("stty $stty_orig");
}
sub start_monitor {
@@ -1519,6 +1648,8 @@ sub fail {
$name = " ($test_name)";
}
+ print_times;
+
doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n";
doprint "KTEST RESULT: TEST $i$name Failed: ", @_, "\n";
@@ -1534,10 +1665,14 @@ sub fail {
sub run_command {
my ($command, $redirect) = @_;
+ my $start_time;
+ my $end_time;
my $dolog = 0;
my $dord = 0;
my $pid;
+ $start_time = time;
+
$command =~ s/\$SSH_USER/$ssh_user/g;
$command =~ s/\$MACHINE/$machine/g;
@@ -1570,6 +1705,15 @@ sub run_command {
close(LOG) if ($dolog);
close(RD) if ($dord);
+ $end_time = time;
+ my $delta = $end_time - $start_time;
+
+ if ($delta == 1) {
+ doprint "[1 second] ";
+ } else {
+ doprint "[$delta seconds] ";
+ }
+
if ($failed) {
doprint "FAILED!\n";
} else {
@@ -1694,7 +1838,9 @@ sub wait_for_input
{
my ($fp, $time) = @_;
my $rin;
- my $ready;
+ my $rout;
+ my $nr;
+ my $buf;
my $line;
my $ch;
@@ -1704,21 +1850,36 @@ sub wait_for_input
$rin = '';
vec($rin, fileno($fp), 1) = 1;
- ($ready, $time) = select($rin, undef, undef, $time);
+ vec($rin, fileno(\*STDIN), 1) = 1;
- $line = "";
+ while (1) {
+ $nr = select($rout=$rin, undef, undef, $time);
- # try to read one char at a time
- while (sysread $fp, $ch, 1) {
- $line .= $ch;
- last if ($ch eq "\n");
- }
+ if ($nr <= 0) {
+ return undef;
+ }
- if (!length($line)) {
- return undef;
- }
+ # copy data from stdin to the console
+ if (vec($rout, fileno(\*STDIN), 1) == 1) {
+ sysread(\*STDIN, $buf, 1000);
+ syswrite($fp, $buf, 1000);
+ next;
+ }
- return $line;
+ $line = "";
+
+ # try to read one char at a time
+ while (sysread $fp, $ch, 1) {
+ $line .= $ch;
+ last if ($ch eq "\n");
+ }
+
+ if (!length($line)) {
+ return undef;
+ }
+
+ return $line;
+ }
}
sub reboot_to {
@@ -1766,6 +1927,8 @@ sub monitor {
my $skip_call_trace = 0;
my $loops;
+ my $start_time = time;
+
wait_for_monitor 5;
my $line;
@@ -1890,6 +2053,9 @@ sub monitor {
}
}
+ my $end_time = time;
+ $reboot_time = $end_time - $start_time;
+
close(DMESG);
if ($bug) {
@@ -1938,6 +2104,8 @@ sub install {
return if ($no_install);
+ my $start_time = time;
+
if (defined($pre_install)) {
my $cp_pre_install = eval_kernel_version $pre_install;
run_command "$cp_pre_install" or
@@ -1969,6 +2137,8 @@ sub install {
if (!$install_mods) {
do_post_install;
doprint "No modules needed\n";
+ my $end_time = time;
+ $install_time = $end_time - $start_time;
return;
}
@@ -1996,6 +2166,9 @@ sub install {
run_ssh "rm -f /tmp/$modtar";
do_post_install;
+
+ my $end_time = time;
+ $install_time = $end_time - $start_time;
}
sub get_version {
@@ -2008,7 +2181,7 @@ sub get_version {
$have_version = 1;
}
-sub start_monitor_and_boot {
+sub start_monitor_and_install {
# Make sure the stable kernel has finished booting
# Install bisects, don't need console
@@ -2208,6 +2381,8 @@ sub build {
unlink $buildlog;
+ my $start_time = time;
+
# Failed builds should not reboot the target
my $save_no_reboot = $no_reboot;
$no_reboot = 1;
@@ -2293,6 +2468,9 @@ sub build {
$no_reboot = $save_no_reboot;
+ my $end_time = time;
+ $build_time = $end_time - $start_time;
+
return 1;
}
@@ -2323,6 +2501,8 @@ sub success {
$name = " ($test_name)";
}
+ print_times;
+
doprint "\n\n*******************************************\n";
doprint "*******************************************\n";
doprint "KTEST RESULT: TEST $i$name SUCCESS!!!! **\n";
@@ -2383,6 +2563,8 @@ sub do_run_test {
my $bug = 0;
my $bug_ignored = 0;
+ my $start_time = time;
+
wait_for_monitor 1;
doprint "run test $run_test\n";
@@ -2449,6 +2631,9 @@ sub do_run_test {
waitpid $child_pid, 0;
$child_exit = $?;
+ my $end_time = time;
+ $test_time = $end_time - $start_time;
+
if (!$bug && $in_bisect) {
if (defined($bisect_ret_good)) {
if ($child_exit == $bisect_ret_good) {
@@ -2549,7 +2734,7 @@ sub run_bisect_test {
dodie "Failed on build" if $failed;
# Now boot the box
- start_monitor_and_boot or $failed = 1;
+ start_monitor_and_install or $failed = 1;
if ($type ne "boot") {
if ($failed && $bisect_skip) {
@@ -2755,6 +2940,7 @@ sub bisect {
do {
$result = run_bisect $type;
$test = run_git_bisect "git bisect $result";
+ print_times;
} while ($test);
run_command "git bisect log" or
@@ -3168,6 +3354,7 @@ sub config_bisect {
do {
$ret = run_config_bisect \%good_configs, \%bad_configs;
+ print_times;
} while (!$ret);
return $ret if ($ret < 0);
@@ -3260,7 +3447,7 @@ sub patchcheck {
my $sha1 = $item;
$sha1 =~ s/^([[:xdigit:]]+).*/$1/;
- doprint "\nProcessing commit $item\n\n";
+ doprint "\nProcessing commit \"$item\"\n\n";
run_command "git checkout $sha1" or
die "Failed to checkout $sha1";
@@ -3291,16 +3478,18 @@ sub patchcheck {
my $failed = 0;
- start_monitor_and_boot or $failed = 1;
+ start_monitor_and_install or $failed = 1;
if (!$failed && $type ne "boot"){
do_run_test or $failed = 1;
}
end_monitor;
- return 0 if ($failed);
-
+ if ($failed) {
+ print_times;
+ return 0;
+ }
patchcheck_reboot;
-
+ print_times;
}
$in_patchcheck = 0;
success $i;
@@ -3753,7 +3942,7 @@ sub make_min_config {
my $failed = 0;
build "oldconfig" or $failed = 1;
if (!$failed) {
- start_monitor_and_boot or $failed = 1;
+ start_monitor_and_install or $failed = 1;
if ($type eq "test" && !$failed) {
do_run_test or $failed = 1;
@@ -4000,6 +4189,11 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
$iteration = $i;
+ $build_time = 0;
+ $install_time = 0;
+ $reboot_time = 0;
+ $test_time = 0;
+
undef %force_config;
my $makecmd = set_test_option("MAKE_CMD", $i);
@@ -4157,15 +4351,20 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
if ($test_type ne "build") {
my $failed = 0;
- start_monitor_and_boot or $failed = 1;
+ start_monitor_and_install or $failed = 1;
if (!$failed && $test_type ne "boot" && defined($run_test)) {
do_run_test or $failed = 1;
}
end_monitor;
- next if ($failed);
+ if ($failed) {
+ print_times;
+ next;
+ }
}
+ print_times;
+
success $i;
}
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile
index f6ff90a76bd7..1d5e7ad2c460 100644
--- a/tools/testing/selftests/powerpc/Makefile
+++ b/tools/testing/selftests/powerpc/Makefile
@@ -13,7 +13,7 @@ CFLAGS := -Wall -O2 -flto -Wall -Werror -DGIT_VERSION='"$(GIT_VERSION)"' -I$(CUR
export CC CFLAGS
-TARGETS = pmu copyloops mm tm primitives
+TARGETS = pmu copyloops mm tm primitives stringloops
endif
diff --git a/tools/testing/selftests/powerpc/copyloops/.gitignore b/tools/testing/selftests/powerpc/copyloops/.gitignore
new file mode 100644
index 000000000000..25a192f62c4d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/copyloops/.gitignore
@@ -0,0 +1,4 @@
+copyuser_64
+copyuser_power7
+memcpy_64
+memcpy_power7
diff --git a/tools/testing/selftests/powerpc/mm/.gitignore b/tools/testing/selftests/powerpc/mm/.gitignore
new file mode 100644
index 000000000000..b43ade0ec861
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mm/.gitignore
@@ -0,0 +1,3 @@
+hugetlb_vs_thp_test
+subpage_prot
+tempfile
diff --git a/tools/testing/selftests/powerpc/mm/Makefile b/tools/testing/selftests/powerpc/mm/Makefile
index 357ccbd6bad9..a14c538dd7f8 100644
--- a/tools/testing/selftests/powerpc/mm/Makefile
+++ b/tools/testing/selftests/powerpc/mm/Makefile
@@ -1,9 +1,9 @@
noarg:
$(MAKE) -C ../
-PROGS := hugetlb_vs_thp_test
+PROGS := hugetlb_vs_thp_test subpage_prot
-all: $(PROGS)
+all: $(PROGS) tempfile
$(PROGS): ../harness.c
@@ -12,7 +12,10 @@ run_tests: all
./$$PROG; \
done;
+tempfile:
+ dd if=/dev/zero of=tempfile bs=64k count=1
+
clean:
- rm -f $(PROGS)
+ rm -f $(PROGS) tempfile
.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/mm/subpage_prot.c b/tools/testing/selftests/powerpc/mm/subpage_prot.c
new file mode 100644
index 000000000000..440180ff8089
--- /dev/null
+++ b/tools/testing/selftests/powerpc/mm/subpage_prot.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright IBM Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2.1 of the GNU Lesser General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/mman.h>
+#include <sys/ptrace.h>
+#include <sys/syscall.h>
+#include <ucontext.h>
+#include <unistd.h>
+
+#include "utils.h"
+
+char *file_name;
+
+int in_test;
+volatile int faulted;
+volatile void *dar;
+int errors;
+
+static void segv(int signum, siginfo_t *info, void *ctxt_v)
+{
+ ucontext_t *ctxt = (ucontext_t *)ctxt_v;
+ struct pt_regs *regs = ctxt->uc_mcontext.regs;
+
+ if (!in_test) {
+ fprintf(stderr, "Segfault outside of test !\n");
+ exit(1);
+ }
+
+ faulted = 1;
+ dar = (void *)regs->dar;
+ regs->nip += 4;
+}
+
+static inline void do_read(const volatile void *addr)
+{
+ int ret;
+
+ asm volatile("lwz %0,0(%1); twi 0,%0,0; isync;\n"
+ : "=r" (ret) : "r" (addr) : "memory");
+}
+
+static inline void do_write(const volatile void *addr)
+{
+ int val = 0x1234567;
+
+ asm volatile("stw %0,0(%1); sync; \n"
+ : : "r" (val), "r" (addr) : "memory");
+}
+
+static inline void check_faulted(void *addr, long page, long subpage, int write)
+{
+ int want_fault = (subpage == ((page + 3) % 16));
+
+ if (write)
+ want_fault |= (subpage == ((page + 1) % 16));
+
+ if (faulted != want_fault) {
+ printf("Failed at 0x%p (p=%ld,sp=%ld,w=%d), want=%s, got=%s !\n",
+ addr, page, subpage, write,
+ want_fault ? "fault" : "pass",
+ faulted ? "fault" : "pass");
+ ++errors;
+ }
+
+ if (faulted) {
+ if (dar != addr) {
+ printf("Fault expected at 0x%p and happened at 0x%p !\n",
+ addr, dar);
+ }
+ faulted = 0;
+ asm volatile("sync" : : : "memory");
+ }
+}
+
+static int run_test(void *addr, unsigned long size)
+{
+ unsigned int *map;
+ long i, j, pages, err;
+
+ pages = size / 0x10000;
+ map = malloc(pages * 4);
+ assert(map);
+
+ /*
+ * for each page, mark subpage i % 16 read only and subpage
+ * (i + 3) % 16 inaccessible
+ */
+ for (i = 0; i < pages; i++) {
+ map[i] = (0x40000000 >> (((i + 1) * 2) % 32)) |
+ (0xc0000000 >> (((i + 3) * 2) % 32));
+ }
+
+ err = syscall(__NR_subpage_prot, addr, size, map);
+ if (err) {
+ perror("subpage_perm");
+ return 1;
+ }
+ free(map);
+
+ in_test = 1;
+ errors = 0;
+ for (i = 0; i < pages; i++) {
+ for (j = 0; j < 16; j++, addr += 0x1000) {
+ do_read(addr);
+ check_faulted(addr, i, j, 0);
+ do_write(addr);
+ check_faulted(addr, i, j, 1);
+ }
+ }
+
+ in_test = 0;
+ if (errors) {
+ printf("%d errors detected\n", errors);
+ return 1;
+ }
+
+ return 0;
+}
+
+int test_anon(void)
+{
+ unsigned long align;
+ struct sigaction act = {
+ .sa_sigaction = segv,
+ .sa_flags = SA_SIGINFO
+ };
+ void *mallocblock;
+ unsigned long mallocsize;
+
+ if (getpagesize() != 0x10000) {
+ fprintf(stderr, "Kernel page size must be 64K!\n");
+ return 1;
+ }
+
+ sigaction(SIGSEGV, &act, NULL);
+
+ mallocsize = 4 * 16 * 1024 * 1024;
+
+ FAIL_IF(posix_memalign(&mallocblock, 64 * 1024, mallocsize));
+
+ align = (unsigned long)mallocblock;
+ if (align & 0xffff)
+ align = (align | 0xffff) + 1;
+
+ mallocblock = (void *)align;
+
+ printf("allocated malloc block of 0x%lx bytes at 0x%p\n",
+ mallocsize, mallocblock);
+
+ printf("testing malloc block...\n");
+
+ return run_test(mallocblock, mallocsize);
+}
+
+int test_file(void)
+{
+ struct sigaction act = {
+ .sa_sigaction = segv,
+ .sa_flags = SA_SIGINFO
+ };
+ void *fileblock;
+ off_t filesize;
+ int fd;
+
+ fd = open(file_name, O_RDWR);
+ if (fd == -1) {
+ perror("failed to open file");
+ return 1;
+ }
+ sigaction(SIGSEGV, &act, NULL);
+
+ filesize = lseek(fd, 0, SEEK_END);
+ if (filesize & 0xffff)
+ filesize &= ~0xfffful;
+
+ fileblock = mmap(NULL, filesize, PROT_READ | PROT_WRITE,
+ MAP_SHARED, fd, 0);
+ if (fileblock == MAP_FAILED) {
+ perror("failed to map file");
+ return 1;
+ }
+ printf("allocated %s for 0x%lx bytes at 0x%p\n",
+ file_name, filesize, fileblock);
+
+ printf("testing file map...\n");
+
+ return run_test(fileblock, filesize);
+}
+
+int main(int argc, char *argv[])
+{
+ test_harness(test_anon, "subpage_prot_anon");
+
+ if (argc > 1)
+ file_name = argv[1];
+ else
+ file_name = "tempfile";
+
+ test_harness(test_file, "subpage_prot_file");
+
+ return 0;
+}
diff --git a/tools/testing/selftests/powerpc/pmu/.gitignore b/tools/testing/selftests/powerpc/pmu/.gitignore
new file mode 100644
index 000000000000..e748f336eed3
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/.gitignore
@@ -0,0 +1,3 @@
+count_instructions
+l3_bank_test
+per_event_excludes
diff --git a/tools/testing/selftests/powerpc/pmu/ebb/.gitignore b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
new file mode 100644
index 000000000000..42bddbed8b64
--- /dev/null
+++ b/tools/testing/selftests/powerpc/pmu/ebb/.gitignore
@@ -0,0 +1,22 @@
+reg_access_test
+event_attributes_test
+cycles_test
+cycles_with_freeze_test
+pmc56_overflow_test
+ebb_vs_cpu_event_test
+cpu_event_vs_ebb_test
+cpu_event_pinned_vs_ebb_test
+task_event_vs_ebb_test
+task_event_pinned_vs_ebb_test
+multi_ebb_procs_test
+multi_counter_test
+pmae_handling_test
+close_clears_pmcc_test
+instruction_count_test
+fork_cleanup_test
+ebb_on_child_test
+ebb_on_willing_child_test
+back_to_back_ebbs_test
+lost_exception_test
+no_handler_test
+cycles_with_mmcr2_test
diff --git a/tools/testing/selftests/powerpc/primitives/.gitignore b/tools/testing/selftests/powerpc/primitives/.gitignore
new file mode 100644
index 000000000000..4cc4e31bed1d
--- /dev/null
+++ b/tools/testing/selftests/powerpc/primitives/.gitignore
@@ -0,0 +1 @@
+load_unaligned_zeropad
diff --git a/tools/testing/selftests/powerpc/stringloops/.gitignore b/tools/testing/selftests/powerpc/stringloops/.gitignore
new file mode 100644
index 000000000000..0b43da74ee46
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/.gitignore
@@ -0,0 +1 @@
+memcmp
diff --git a/tools/testing/selftests/powerpc/stringloops/Makefile b/tools/testing/selftests/powerpc/stringloops/Makefile
new file mode 100644
index 000000000000..506d77346477
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/Makefile
@@ -0,0 +1,20 @@
+# The loops are all 64-bit code
+CFLAGS += -m64
+CFLAGS += -I$(CURDIR)
+
+PROGS := memcmp
+EXTRA_SOURCES := memcmp_64.S ../harness.c
+
+all: $(PROGS)
+
+$(PROGS): $(EXTRA_SOURCES)
+
+run_tests: all
+ @-for PROG in $(PROGS); do \
+ ./$$PROG; \
+ done;
+
+clean:
+ rm -f $(PROGS) *.o
+
+.PHONY: all run_tests clean
diff --git a/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h
new file mode 100644
index 000000000000..11bece87e880
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/asm/ppc_asm.h
@@ -0,0 +1,7 @@
+#include <ppc-asm.h>
+
+#ifndef r1
+#define r1 sp
+#endif
+
+#define _GLOBAL(A) FUNC_START(test_ ## A)
diff --git a/tools/testing/selftests/powerpc/stringloops/memcmp.c b/tools/testing/selftests/powerpc/stringloops/memcmp.c
new file mode 100644
index 000000000000..17417dd70708
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/memcmp.c
@@ -0,0 +1,103 @@
+#include <malloc.h>
+#include <stdlib.h>
+#include <string.h>
+#include "../utils.h"
+
+#define SIZE 256
+#define ITERATIONS 10000
+
+int test_memcmp(const void *s1, const void *s2, size_t n);
+
+/* test all offsets and lengths */
+static void test_one(char *s1, char *s2)
+{
+ unsigned long offset, size;
+
+ for (offset = 0; offset < SIZE; offset++) {
+ for (size = 0; size < (SIZE-offset); size++) {
+ int x, y;
+ unsigned long i;
+
+ y = memcmp(s1+offset, s2+offset, size);
+ x = test_memcmp(s1+offset, s2+offset, size);
+
+ if (((x ^ y) < 0) && /* Trick to compare sign */
+ ((x | y) != 0)) { /* check for zero */
+ printf("memcmp returned %d, should have returned %d (offset %ld size %ld)\n", x, y, offset, size);
+
+ for (i = offset; i < offset+size; i++)
+ printf("%02x ", s1[i]);
+ printf("\n");
+
+ for (i = offset; i < offset+size; i++)
+ printf("%02x ", s2[i]);
+ printf("\n");
+ abort();
+ }
+ }
+ }
+}
+
+static int testcase(void)
+{
+ char *s1;
+ char *s2;
+ unsigned long i;
+
+ s1 = memalign(128, SIZE);
+ if (!s1) {
+ perror("memalign");
+ exit(1);
+ }
+
+ s2 = memalign(128, SIZE);
+ if (!s2) {
+ perror("memalign");
+ exit(1);
+ }
+
+ srandom(1);
+
+ for (i = 0; i < ITERATIONS; i++) {
+ unsigned long j;
+ unsigned long change;
+
+ for (j = 0; j < SIZE; j++)
+ s1[j] = random();
+
+ memcpy(s2, s1, SIZE);
+
+ /* change one byte */
+ change = random() % SIZE;
+ s2[change] = random() & 0xff;
+
+ test_one(s1, s2);
+ }
+
+ srandom(1);
+
+ for (i = 0; i < ITERATIONS; i++) {
+ unsigned long j;
+ unsigned long change;
+
+ for (j = 0; j < SIZE; j++)
+ s1[j] = random();
+
+ memcpy(s2, s1, SIZE);
+
+ /* change multiple bytes, 1/8 of total */
+ for (j = 0; j < SIZE / 8; j++) {
+ change = random() % SIZE;
+ s2[change] = random() & 0xff;
+ }
+
+ test_one(s1, s2);
+ }
+
+ return 0;
+}
+
+int main(void)
+{
+ return test_harness(testcase, "memcmp");
+}
diff --git a/tools/testing/selftests/powerpc/stringloops/memcmp_64.S b/tools/testing/selftests/powerpc/stringloops/memcmp_64.S
new file mode 120000
index 000000000000..9bc87e438ae9
--- /dev/null
+++ b/tools/testing/selftests/powerpc/stringloops/memcmp_64.S
@@ -0,0 +1 @@
+../../../../../arch/powerpc/lib/memcmp_64.S \ No newline at end of file
diff --git a/tools/testing/selftests/powerpc/tm/.gitignore b/tools/testing/selftests/powerpc/tm/.gitignore
new file mode 100644
index 000000000000..33d02cc54a3e
--- /dev/null
+++ b/tools/testing/selftests/powerpc/tm/.gitignore
@@ -0,0 +1 @@
+tm-resched-dscr
diff --git a/tools/testing/selftests/rcutorture/bin/cpus2use.sh b/tools/testing/selftests/rcutorture/bin/cpus2use.sh
index abe14b7f36e9..bb99cde3f5f9 100755
--- a/tools/testing/selftests/rcutorture/bin/cpus2use.sh
+++ b/tools/testing/selftests/rcutorture/bin/cpus2use.sh
@@ -24,7 +24,7 @@
ncpus=`grep '^processor' /proc/cpuinfo | wc -l`
idlecpus=`mpstat | tail -1 | \
- awk -v ncpus=$ncpus '{ print ncpus * ($7 + $12) / 100 }'`
+ awk -v ncpus=$ncpus '{ print ncpus * ($7 + $NF) / 100 }'`
awk -v ncpus=$ncpus -v idlecpus=$idlecpus < /dev/null '
BEGIN {
cpus2use = idlecpus;
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh
index d6cc07fc137f..559e01ac86be 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-recheck-rcu.sh
@@ -30,6 +30,7 @@ else
echo Unreadable results directory: $i
exit 1
fi
+. tools/testing/selftests/rcutorture/bin/functions.sh
configfile=`echo $i | sed -e 's/^.*\///'`
ngps=`grep ver: $i/console.log 2> /dev/null | tail -1 | sed -e 's/^.* ver: //' -e 's/ .*$//'`
@@ -48,4 +49,21 @@ else
title="$title ($ngpsps per second)"
fi
echo $title
+ nclosecalls=`grep --binary-files=text 'torture: Reader Batch' $i/console.log | tail -1 | awk '{for (i=NF-8;i<=NF;i++) sum+=$i; } END {print sum}'`
+ if test -z "$nclosecalls"
+ then
+ exit 0
+ fi
+ if test "$nclosecalls" -eq 0
+ then
+ exit 0
+ fi
+ # Compute number of close calls per tenth of an hour
+ nclosecalls10=`awk -v nclosecalls=$nclosecalls -v dur=$dur 'BEGIN { print int(nclosecalls * 36000 / dur) }' < /dev/null`
+ if test $nclosecalls10 -gt 5 -a $nclosecalls -gt 1
+ then
+ print_bug $nclosecalls "Reader Batch close calls in" $(($dur/60)) minute run: $i
+ else
+ print_warning $nclosecalls "Reader Batch close calls in" $(($dur/60)) minute run: $i
+ fi
fi
diff --git a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
index 8ca9f21f2efc..5236e073919d 100755
--- a/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
+++ b/tools/testing/selftests/rcutorture/bin/kvm-test-1-run.sh
@@ -8,9 +8,9 @@
#
# Usage: kvm-test-1-run.sh config builddir resdir minutes qemu-args boot_args
#
-# qemu-args defaults to "-nographic", along with arguments specifying the
-# number of CPUs and other options generated from
-# the underlying CPU architecture.
+# qemu-args defaults to "-enable-kvm -soundhw pcspk -nographic", along with
+# arguments specifying the number of CPUs and other
+# options generated from the underlying CPU architecture.
# boot_args defaults to value returned by the per_version_boot_params
# shell function.
#
@@ -138,7 +138,7 @@ then
fi
# Generate -smp qemu argument.
-qemu_args="-nographic $qemu_args"
+qemu_args="-enable-kvm -soundhw pcspk -nographic $qemu_args"
cpu_count=`configNR_CPUS.sh $config_template`
cpu_count=`configfrag_boot_cpus "$boot_args" "$config_template" "$cpu_count"`
vcpus=`identify_qemu_vcpus`
@@ -168,6 +168,7 @@ then
touch $resdir/buildonly
exit 0
fi
+echo "NOTE: $QEMU either did not run or was interactive" > $builddir/console.log
echo $QEMU $qemu_args -m 512 -kernel $resdir/bzImage -append \"$qemu_append $boot_args\" > $resdir/qemu-cmd
( $QEMU $qemu_args -m 512 -kernel $resdir/bzImage -append "$qemu_append $boot_args"; echo $? > $resdir/qemu-retval ) &
qemu_pid=$!
diff --git a/tools/testing/selftests/rcutorture/bin/parse-build.sh b/tools/testing/selftests/rcutorture/bin/parse-build.sh
index 499d1e598e42..a6b57622c2e5 100755
--- a/tools/testing/selftests/rcutorture/bin/parse-build.sh
+++ b/tools/testing/selftests/rcutorture/bin/parse-build.sh
@@ -26,12 +26,15 @@
#
# Authors: Paul E. McKenney <paulmck@linux.vnet.ibm.com>
-T=$1
+F=$1
title=$2
+T=/tmp/parse-build.sh.$$
+trap 'rm -rf $T' 0
+mkdir $T
. functions.sh
-if grep -q CC < $T
+if grep -q CC < $F
then
:
else
@@ -39,18 +42,21 @@ else
exit 1
fi
-if grep -q "error:" < $T
+if grep -q "error:" < $F
then
print_bug $title build errors:
- grep "error:" < $T
+ grep "error:" < $F
exit 2
fi
-exit 0
-if egrep -q "rcu[^/]*\.c.*warning:|rcu.*\.h.*warning:" < $T
+grep warning: < $F > $T/warnings
+grep "include/linux/*rcu*\.h:" $T/warnings > $T/hwarnings
+grep "kernel/rcu/[^/]*:" $T/warnings > $T/cwarnings
+cat $T/hwarnings $T/cwarnings > $T/rcuwarnings
+if test -s $T/rcuwarnings
then
print_warning $title build errors:
- egrep "rcu[^/]*\.c.*warning:|rcu.*\.h.*warning:" < $T
+ cat $T/rcuwarnings
exit 2
fi
exit 0
diff --git a/tools/testing/selftests/rcutorture/bin/parse-console.sh b/tools/testing/selftests/rcutorture/bin/parse-console.sh
index f962ba4cf68b..d8f35cf116be 100755
--- a/tools/testing/selftests/rcutorture/bin/parse-console.sh
+++ b/tools/testing/selftests/rcutorture/bin/parse-console.sh
@@ -36,7 +36,7 @@ if grep -Pq '\x00' < $file
then
print_warning Console output contains nul bytes, old qemu still running?
fi
-egrep 'Badness|WARNING:|Warn|BUG|===========|Call Trace:|Oops:' < $file | grep -v 'ODEBUG: ' | grep -v 'Warning: unable to open an initial console' > $T
+egrep 'Badness|WARNING:|Warn|BUG|===========|Call Trace:|Oops:|Stall ended before state dump start' < $file | grep -v 'ODEBUG: ' | grep -v 'Warning: unable to open an initial console' > $T
if test -s $T
then
print_warning Assertion failure in $file $title
diff --git a/tools/usb/ffs-aio-example/multibuff/host_app/test.c b/tools/usb/ffs-aio-example/multibuff/host_app/test.c
index daa3abe6bebd..2cbcce6e8dd7 100644
--- a/tools/usb/ffs-aio-example/multibuff/host_app/test.c
+++ b/tools/usb/ffs-aio-example/multibuff/host_app/test.c
@@ -33,11 +33,6 @@
#define VENDOR 0x1d6b
#define PRODUCT 0x0105
-/* endpoints indexes */
-
-#define EP_BULK_IN (1 | LIBUSB_ENDPOINT_IN)
-#define EP_BULK_OUT (2 | LIBUSB_ENDPOINT_OUT)
-
#define BUF_LEN 8192
/*
@@ -159,14 +154,21 @@ void test_exit(struct test_state *state)
int main(void)
{
struct test_state state;
+ struct libusb_config_descriptor *conf;
+ struct libusb_interface_descriptor const *iface;
+ unsigned char addr;
if (test_init(&state))
return 1;
+ libusb_get_config_descriptor(state.found, 0, &conf);
+ iface = &conf->interface[0].altsetting[0];
+ addr = iface->endpoint[0].bEndpointAddress;
+
while (1) {
static unsigned char buffer[BUF_LEN];
int bytes;
- libusb_bulk_transfer(state.handle, EP_BULK_IN, buffer, BUF_LEN,
+ libusb_bulk_transfer(state.handle, addr, buffer, BUF_LEN,
&bytes, 500);
}
test_exit(&state);
diff --git a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c
index adc310a6d489..1f44a29818bf 100644
--- a/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c
+++ b/tools/usb/ffs-aio-example/simple/device_app/aio_simple.c
@@ -103,12 +103,14 @@ static const struct {
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 1 | USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = htole16(512),
},
.bulk_source = {
.bLength = sizeof(descriptors.hs_descs.bulk_source),
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 2 | USB_DIR_OUT,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = htole16(512),
},
},
};
diff --git a/tools/usb/ffs-aio-example/simple/host_app/test.c b/tools/usb/ffs-aio-example/simple/host_app/test.c
index acd6332811f3..aed86ffff280 100644
--- a/tools/usb/ffs-aio-example/simple/host_app/test.c
+++ b/tools/usb/ffs-aio-example/simple/host_app/test.c
@@ -33,11 +33,6 @@
#define VENDOR 0x1d6b
#define PRODUCT 0x0105
-/* endpoints indexes */
-
-#define EP_BULK_IN (1 | LIBUSB_ENDPOINT_IN)
-#define EP_BULK_OUT (2 | LIBUSB_ENDPOINT_OUT)
-
#define BUF_LEN 8192
/*
@@ -159,16 +154,24 @@ void test_exit(struct test_state *state)
int main(void)
{
struct test_state state;
+ struct libusb_config_descriptor *conf;
+ struct libusb_interface_descriptor const *iface;
+ unsigned char in_addr, out_addr;
if (test_init(&state))
return 1;
+ libusb_get_config_descriptor(state.found, 0, &conf);
+ iface = &conf->interface[0].altsetting[0];
+ in_addr = iface->endpoint[0].bEndpointAddress;
+ out_addr = iface->endpoint[1].bEndpointAddress;
+
while (1) {
static unsigned char buffer[BUF_LEN];
int bytes;
- libusb_bulk_transfer(state.handle, EP_BULK_IN, buffer, BUF_LEN,
+ libusb_bulk_transfer(state.handle, in_addr, buffer, BUF_LEN,
&bytes, 500);
- libusb_bulk_transfer(state.handle, EP_BULK_OUT, buffer, BUF_LEN,
+ libusb_bulk_transfer(state.handle, out_addr, buffer, BUF_LEN,
&bytes, 500);
}
test_exit(&state);
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c
index 264fbc297e0b..8bdf16b8ba60 100644
--- a/tools/vm/page-types.c
+++ b/tools/vm/page-types.c
@@ -133,6 +133,7 @@ static const char * const page_flag_names[] = {
[KPF_KSM] = "x:ksm",
[KPF_THP] = "t:thp",
[KPF_BALLOON] = "o:balloon",
+ [KPF_ZERO_PAGE] = "z:zero_page",
[KPF_RESERVED] = "r:reserved",
[KPF_MLOCKED] = "m:mlocked",