aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/hv/hv_kvp_daemon.c40
-rw-r--r--tools/power/cpupower/.gitignore7
-rw-r--r--tools/power/cpupower/Makefile3
-rw-r--r--tools/power/cpupower/debug/i386/Makefile5
-rw-r--r--tools/power/cpupower/man/cpupower-monitor.115
-rw-r--r--tools/power/cpupower/utils/helpers/cpuid.c2
-rw-r--r--tools/power/cpupower/utils/helpers/helpers.h18
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.c19
-rw-r--r--tools/power/cpupower/utils/helpers/topology.c53
-rw-r--r--tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c21
-rw-r--r--tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h17
-rw-r--r--tools/power/cpupower/utils/idle_monitor/snb_idle.c10
-rw-r--r--tools/testing/selftests/vm/Makefile4
-rw-r--r--tools/testing/selftests/vm/thuge-gen.c254
14 files changed, 393 insertions, 75 deletions
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 5959affd8820..d25a46925e61 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -43,6 +43,7 @@
43#include <sys/stat.h> 43#include <sys/stat.h>
44#include <fcntl.h> 44#include <fcntl.h>
45#include <dirent.h> 45#include <dirent.h>
46#include <net/if.h>
46 47
47/* 48/*
48 * KVP protocol: The user mode component first registers with the 49 * KVP protocol: The user mode component first registers with the
@@ -88,6 +89,7 @@ static char *os_major = "";
88static char *os_minor = ""; 89static char *os_minor = "";
89static char *processor_arch; 90static char *processor_arch;
90static char *os_build; 91static char *os_build;
92static char *os_version;
91static char *lic_version = "Unknown version"; 93static char *lic_version = "Unknown version";
92static struct utsname uts_buf; 94static struct utsname uts_buf;
93 95
@@ -297,7 +299,7 @@ static int kvp_file_init(void)
297 return 0; 299 return 0;
298} 300}
299 301
300static int kvp_key_delete(int pool, __u8 *key, int key_size) 302static int kvp_key_delete(int pool, const char *key, int key_size)
301{ 303{
302 int i; 304 int i;
303 int j, k; 305 int j, k;
@@ -340,7 +342,7 @@ static int kvp_key_delete(int pool, __u8 *key, int key_size)
340 return 1; 342 return 1;
341} 343}
342 344
343static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value, 345static int kvp_key_add_or_modify(int pool, const char *key, int key_size, const char *value,
344 int value_size) 346 int value_size)
345{ 347{
346 int i; 348 int i;
@@ -394,7 +396,7 @@ static int kvp_key_add_or_modify(int pool, __u8 *key, int key_size, __u8 *value,
394 return 0; 396 return 0;
395} 397}
396 398
397static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value, 399static int kvp_get_value(int pool, const char *key, int key_size, char *value,
398 int value_size) 400 int value_size)
399{ 401{
400 int i; 402 int i;
@@ -426,8 +428,8 @@ static int kvp_get_value(int pool, __u8 *key, int key_size, __u8 *value,
426 return 1; 428 return 1;
427} 429}
428 430
429static int kvp_pool_enumerate(int pool, int index, __u8 *key, int key_size, 431static int kvp_pool_enumerate(int pool, int index, char *key, int key_size,
430 __u8 *value, int value_size) 432 char *value, int value_size)
431{ 433{
432 struct kvp_record *record; 434 struct kvp_record *record;
433 435
@@ -453,7 +455,9 @@ void kvp_get_os_info(void)
453 char *p, buf[512]; 455 char *p, buf[512];
454 456
455 uname(&uts_buf); 457 uname(&uts_buf);
456 os_build = uts_buf.release; 458 os_version = uts_buf.release;
459 os_build = strdup(uts_buf.release);
460
457 os_name = uts_buf.sysname; 461 os_name = uts_buf.sysname;
458 processor_arch = uts_buf.machine; 462 processor_arch = uts_buf.machine;
459 463
@@ -462,7 +466,7 @@ void kvp_get_os_info(void)
462 * string to be of the form: x.y.z 466 * string to be of the form: x.y.z
463 * Strip additional information we may have. 467 * Strip additional information we may have.
464 */ 468 */
465 p = strchr(os_build, '-'); 469 p = strchr(os_version, '-');
466 if (p) 470 if (p)
467 *p = '\0'; 471 *p = '\0';
468 472
@@ -879,7 +883,7 @@ static int kvp_process_ip_address(void *addrp,
879 addr_length = INET6_ADDRSTRLEN; 883 addr_length = INET6_ADDRSTRLEN;
880 } 884 }
881 885
882 if ((length - *offset) < addr_length + 1) 886 if ((length - *offset) < addr_length + 2)
883 return HV_E_FAIL; 887 return HV_E_FAIL;
884 if (str == NULL) { 888 if (str == NULL) {
885 strcpy(buffer, "inet_ntop failed\n"); 889 strcpy(buffer, "inet_ntop failed\n");
@@ -887,11 +891,13 @@ static int kvp_process_ip_address(void *addrp,
887 } 891 }
888 if (*offset == 0) 892 if (*offset == 0)
889 strcpy(buffer, tmp); 893 strcpy(buffer, tmp);
890 else 894 else {
895 strcat(buffer, ";");
891 strcat(buffer, tmp); 896 strcat(buffer, tmp);
892 strcat(buffer, ";"); 897 }
893 898
894 *offset += strlen(str) + 1; 899 *offset += strlen(str) + 1;
900
895 return 0; 901 return 0;
896} 902}
897 903
@@ -953,7 +959,9 @@ kvp_get_ip_info(int family, char *if_name, int op,
953 * supported address families; if not we gather info on 959 * supported address families; if not we gather info on
954 * the specified address family. 960 * the specified address family.
955 */ 961 */
956 if ((family != 0) && (curp->ifa_addr->sa_family != family)) { 962 if ((((family != 0) &&
963 (curp->ifa_addr->sa_family != family))) ||
964 (curp->ifa_flags & IFF_LOOPBACK)) {
957 curp = curp->ifa_next; 965 curp = curp->ifa_next;
958 continue; 966 continue;
959 } 967 }
@@ -1478,13 +1486,19 @@ int main(void)
1478 len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0, 1486 len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0,
1479 addr_p, &addr_l); 1487 addr_p, &addr_l);
1480 1488
1481 if (len < 0 || addr.nl_pid) { 1489 if (len < 0) {
1482 syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", 1490 syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
1483 addr.nl_pid, errno, strerror(errno)); 1491 addr.nl_pid, errno, strerror(errno));
1484 close(fd); 1492 close(fd);
1485 return -1; 1493 return -1;
1486 } 1494 }
1487 1495
1496 if (addr.nl_pid) {
1497 syslog(LOG_WARNING, "Received packet from untrusted pid:%u",
1498 addr.nl_pid);
1499 continue;
1500 }
1501
1488 incoming_msg = (struct nlmsghdr *)kvp_recv_buffer; 1502 incoming_msg = (struct nlmsghdr *)kvp_recv_buffer;
1489 incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg); 1503 incoming_cn_msg = (struct cn_msg *)NLMSG_DATA(incoming_msg);
1490 hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data; 1504 hv_msg = (struct hv_kvp_msg *)incoming_cn_msg->data;
@@ -1649,7 +1663,7 @@ int main(void)
1649 strcpy(key_name, "OSMinorVersion"); 1663 strcpy(key_name, "OSMinorVersion");
1650 break; 1664 break;
1651 case OSVersion: 1665 case OSVersion:
1652 strcpy(key_value, os_build); 1666 strcpy(key_value, os_version);
1653 strcpy(key_name, "OSVersion"); 1667 strcpy(key_name, "OSVersion");
1654 break; 1668 break;
1655 case ProcessorArchitecture: 1669 case ProcessorArchitecture:
diff --git a/tools/power/cpupower/.gitignore b/tools/power/cpupower/.gitignore
index 8a83dd2ffc11..d42073f12609 100644
--- a/tools/power/cpupower/.gitignore
+++ b/tools/power/cpupower/.gitignore
@@ -20,3 +20,10 @@ utils/cpufreq-set.o
20utils/cpufreq-aperf.o 20utils/cpufreq-aperf.o
21cpupower 21cpupower
22bench/cpufreq-bench 22bench/cpufreq-bench
23debug/kernel/Module.symvers
24debug/i386/centrino-decode
25debug/i386/dump_psb
26debug/i386/intel_gsic
27debug/i386/powernow-k8-decode
28debug/x86_64/centrino-decode
29debug/x86_64/powernow-k8-decode
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index cf397bd26d0c..d875a74a3bdf 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -253,7 +253,8 @@ clean:
253 | xargs rm -f 253 | xargs rm -f
254 -rm -f $(OUTPUT)cpupower 254 -rm -f $(OUTPUT)cpupower
255 -rm -f $(OUTPUT)libcpupower.so* 255 -rm -f $(OUTPUT)libcpupower.so*
256 -rm -rf $(OUTPUT)po/*.{gmo,pot} 256 -rm -rf $(OUTPUT)po/*.gmo
257 -rm -rf $(OUTPUT)po/*.pot
257 $(MAKE) -C bench O=$(OUTPUT) clean 258 $(MAKE) -C bench O=$(OUTPUT) clean
258 259
259 260
diff --git a/tools/power/cpupower/debug/i386/Makefile b/tools/power/cpupower/debug/i386/Makefile
index 3ba158f0e287..c05cc0ac80c7 100644
--- a/tools/power/cpupower/debug/i386/Makefile
+++ b/tools/power/cpupower/debug/i386/Makefile
@@ -26,7 +26,10 @@ $(OUTPUT)powernow-k8-decode: powernow-k8-decode.c
26all: $(OUTPUT)centrino-decode $(OUTPUT)dump_psb $(OUTPUT)intel_gsic $(OUTPUT)powernow-k8-decode 26all: $(OUTPUT)centrino-decode $(OUTPUT)dump_psb $(OUTPUT)intel_gsic $(OUTPUT)powernow-k8-decode
27 27
28clean: 28clean:
29 rm -rf $(OUTPUT){centrino-decode,dump_psb,intel_gsic,powernow-k8-decode} 29 rm -rf $(OUTPUT)centrino-decode
30 rm -rf $(OUTPUT)dump_psb
31 rm -rf $(OUTPUT)intel_gsic
32 rm -rf $(OUTPUT)powernow-k8-decode
30 33
31install: 34install:
32 $(INSTALL) -d $(DESTDIR)${bindir} 35 $(INSTALL) -d $(DESTDIR)${bindir}
diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1
index 1141c2073719..e01c35d13b6e 100644
--- a/tools/power/cpupower/man/cpupower-monitor.1
+++ b/tools/power/cpupower/man/cpupower-monitor.1
@@ -7,11 +7,11 @@ cpupower\-monitor \- Report processor frequency and idle statistics
7.RB "\-l" 7.RB "\-l"
8 8
9.B cpupower monitor 9.B cpupower monitor
10.RB [ "\-m <mon1>," [ "<mon2>,..." ] ] 10.RB [ -c ] [ "\-m <mon1>," [ "<mon2>,..." ] ]
11.RB [ "\-i seconds" ] 11.RB [ "\-i seconds" ]
12.br 12.br
13.B cpupower monitor 13.B cpupower monitor
14.RB [ "\-m <mon1>," [ "<mon2>,..." ] ] 14.RB [ -c ][ "\-m <mon1>," [ "<mon2>,..." ] ]
15.RB command 15.RB command
16.br 16.br
17.SH DESCRIPTION 17.SH DESCRIPTION
@@ -64,6 +64,17 @@ Only display specific monitors. Use the monitor string(s) provided by \-l option
64Measure intervall. 64Measure intervall.
65.RE 65.RE
66.PP 66.PP
67\-c
68.RS 4
69Schedule the process on every core before starting and ending measuring.
70This could be needed for the Idle_Stats monitor when no other MSR based
71monitor (has to be run on the core that is measured) is run in parallel.
72This is to wake up the processors from deeper sleep states and let the
73kernel re
74-account its cpuidle (C-state) information before reading the
75cpuidle timings from sysfs.
76.RE
77.PP
67command 78command
68.RS 4 79.RS 4
69Measure idle and frequency characteristics of an arbitrary command/workload. 80Measure idle and frequency characteristics of an arbitrary command/workload.
diff --git a/tools/power/cpupower/utils/helpers/cpuid.c b/tools/power/cpupower/utils/helpers/cpuid.c
index 906895d21cce..93b0aa74ca03 100644
--- a/tools/power/cpupower/utils/helpers/cpuid.c
+++ b/tools/power/cpupower/utils/helpers/cpuid.c
@@ -158,6 +158,8 @@ out:
158 cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; 158 cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
159 case 0x2A: /* SNB */ 159 case 0x2A: /* SNB */
160 case 0x2D: /* SNB Xeon */ 160 case 0x2D: /* SNB Xeon */
161 case 0x3A: /* IVB */
162 case 0x3E: /* IVB Xeon */
161 cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO; 163 cpu_info->caps |= CPUPOWER_CAP_HAS_TURBO_RATIO;
162 cpu_info->caps |= CPUPOWER_CAP_IS_SNB; 164 cpu_info->caps |= CPUPOWER_CAP_IS_SNB;
163 break; 165 break;
diff --git a/tools/power/cpupower/utils/helpers/helpers.h b/tools/power/cpupower/utils/helpers/helpers.h
index 2eb584cf2f55..aa9e95486a2d 100644
--- a/tools/power/cpupower/utils/helpers/helpers.h
+++ b/tools/power/cpupower/utils/helpers/helpers.h
@@ -92,6 +92,14 @@ extern int get_cpu_info(unsigned int cpu, struct cpupower_cpu_info *cpu_info);
92extern struct cpupower_cpu_info cpupower_cpu_info; 92extern struct cpupower_cpu_info cpupower_cpu_info;
93/* cpuid and cpuinfo helpers **************************/ 93/* cpuid and cpuinfo helpers **************************/
94 94
95struct cpuid_core_info {
96 int pkg;
97 int core;
98 int cpu;
99
100 /* flags */
101 unsigned int is_online:1;
102};
95 103
96/* CPU topology/hierarchy parsing ******************/ 104/* CPU topology/hierarchy parsing ******************/
97struct cpupower_topology { 105struct cpupower_topology {
@@ -101,18 +109,12 @@ struct cpupower_topology {
101 unsigned int threads; /* per core */ 109 unsigned int threads; /* per core */
102 110
103 /* Array gets mallocated with cores entries, holding per core info */ 111 /* Array gets mallocated with cores entries, holding per core info */
104 struct { 112 struct cpuid_core_info *core_info;
105 int pkg;
106 int core;
107 int cpu;
108
109 /* flags */
110 unsigned int is_online:1;
111 } *core_info;
112}; 113};
113 114
114extern int get_cpu_topology(struct cpupower_topology *cpu_top); 115extern int get_cpu_topology(struct cpupower_topology *cpu_top);
115extern void cpu_topology_release(struct cpupower_topology cpu_top); 116extern void cpu_topology_release(struct cpupower_topology cpu_top);
117
116/* CPU topology/hierarchy parsing ******************/ 118/* CPU topology/hierarchy parsing ******************/
117 119
118/* X86 ONLY ****************************************/ 120/* X86 ONLY ****************************************/
diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c
index 96e28c124b5c..38ab91629463 100644
--- a/tools/power/cpupower/utils/helpers/sysfs.c
+++ b/tools/power/cpupower/utils/helpers/sysfs.c
@@ -37,25 +37,6 @@ unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen)
37 return (unsigned int) numread; 37 return (unsigned int) numread;
38} 38}
39 39
40static unsigned int sysfs_write_file(const char *path,
41 const char *value, size_t len)
42{
43 int fd;
44 ssize_t numwrite;
45
46 fd = open(path, O_WRONLY);
47 if (fd == -1)
48 return 0;
49
50 numwrite = write(fd, value, len);
51 if (numwrite < 1) {
52 close(fd);
53 return 0;
54 }
55 close(fd);
56 return (unsigned int) numwrite;
57}
58
59/* 40/*
60 * Detect whether a CPU is online 41 * Detect whether a CPU is online
61 * 42 *
diff --git a/tools/power/cpupower/utils/helpers/topology.c b/tools/power/cpupower/utils/helpers/topology.c
index 4eae2c47ba48..c13120af519b 100644
--- a/tools/power/cpupower/utils/helpers/topology.c
+++ b/tools/power/cpupower/utils/helpers/topology.c
@@ -20,9 +20,8 @@
20#include <helpers/sysfs.h> 20#include <helpers/sysfs.h>
21 21
22/* returns -1 on failure, 0 on success */ 22/* returns -1 on failure, 0 on success */
23int sysfs_topology_read_file(unsigned int cpu, const char *fname) 23static int sysfs_topology_read_file(unsigned int cpu, const char *fname, int *result)
24{ 24{
25 unsigned long value;
26 char linebuf[MAX_LINE_LEN]; 25 char linebuf[MAX_LINE_LEN];
27 char *endp; 26 char *endp;
28 char path[SYSFS_PATH_MAX]; 27 char path[SYSFS_PATH_MAX];
@@ -31,20 +30,12 @@ int sysfs_topology_read_file(unsigned int cpu, const char *fname)
31 cpu, fname); 30 cpu, fname);
32 if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0) 31 if (sysfs_read_file(path, linebuf, MAX_LINE_LEN) == 0)
33 return -1; 32 return -1;
34 value = strtoul(linebuf, &endp, 0); 33 *result = strtol(linebuf, &endp, 0);
35 if (endp == linebuf || errno == ERANGE) 34 if (endp == linebuf || errno == ERANGE)
36 return -1; 35 return -1;
37 return value; 36 return 0;
38} 37}
39 38
40struct cpuid_core_info {
41 unsigned int pkg;
42 unsigned int thread;
43 unsigned int cpu;
44 /* flags */
45 unsigned int is_online:1;
46};
47
48static int __compare(const void *t1, const void *t2) 39static int __compare(const void *t1, const void *t2)
49{ 40{
50 struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1; 41 struct cpuid_core_info *top1 = (struct cpuid_core_info *)t1;
@@ -53,9 +44,9 @@ static int __compare(const void *t1, const void *t2)
53 return -1; 44 return -1;
54 else if (top1->pkg > top2->pkg) 45 else if (top1->pkg > top2->pkg)
55 return 1; 46 return 1;
56 else if (top1->thread < top2->thread) 47 else if (top1->core < top2->core)
57 return -1; 48 return -1;
58 else if (top1->thread > top2->thread) 49 else if (top1->core > top2->core)
59 return 1; 50 return 1;
60 else if (top1->cpu < top2->cpu) 51 else if (top1->cpu < top2->cpu)
61 return -1; 52 return -1;
@@ -73,28 +64,42 @@ static int __compare(const void *t1, const void *t2)
73 */ 64 */
74int get_cpu_topology(struct cpupower_topology *cpu_top) 65int get_cpu_topology(struct cpupower_topology *cpu_top)
75{ 66{
76 int cpu, cpus = sysconf(_SC_NPROCESSORS_CONF); 67 int cpu, last_pkg, cpus = sysconf(_SC_NPROCESSORS_CONF);
77 68
78 cpu_top->core_info = malloc(sizeof(struct cpupower_topology) * cpus); 69 cpu_top->core_info = malloc(sizeof(struct cpuid_core_info) * cpus);
79 if (cpu_top->core_info == NULL) 70 if (cpu_top->core_info == NULL)
80 return -ENOMEM; 71 return -ENOMEM;
81 cpu_top->pkgs = cpu_top->cores = 0; 72 cpu_top->pkgs = cpu_top->cores = 0;
82 for (cpu = 0; cpu < cpus; cpu++) { 73 for (cpu = 0; cpu < cpus; cpu++) {
83 cpu_top->core_info[cpu].cpu = cpu; 74 cpu_top->core_info[cpu].cpu = cpu;
84 cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu); 75 cpu_top->core_info[cpu].is_online = sysfs_is_cpu_online(cpu);
85 cpu_top->core_info[cpu].pkg = 76 if(sysfs_topology_read_file(
86 sysfs_topology_read_file(cpu, "physical_package_id"); 77 cpu,
87 if ((int)cpu_top->core_info[cpu].pkg != -1 && 78 "physical_package_id",
88 cpu_top->core_info[cpu].pkg > cpu_top->pkgs) 79 &(cpu_top->core_info[cpu].pkg)) < 0)
89 cpu_top->pkgs = cpu_top->core_info[cpu].pkg; 80 return -1;
90 cpu_top->core_info[cpu].core = 81 if(sysfs_topology_read_file(
91 sysfs_topology_read_file(cpu, "core_id"); 82 cpu,
83 "core_id",
84 &(cpu_top->core_info[cpu].core)) < 0)
85 return -1;
92 } 86 }
93 cpu_top->pkgs++;
94 87
95 qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info), 88 qsort(cpu_top->core_info, cpus, sizeof(struct cpuid_core_info),
96 __compare); 89 __compare);
97 90
91 /* Count the number of distinct pkgs values. This works
92 because the primary sort of the core_info struct was just
93 done by pkg value. */
94 last_pkg = cpu_top->core_info[0].pkg;
95 for(cpu = 1; cpu < cpus; cpu++) {
96 if(cpu_top->core_info[cpu].pkg != last_pkg) {
97 last_pkg = cpu_top->core_info[cpu].pkg;
98 cpu_top->pkgs++;
99 }
100 }
101 cpu_top->pkgs++;
102
98 /* Intel's cores count is not consecutively numbered, there may 103 /* Intel's cores count is not consecutively numbered, there may
99 * be a core_id of 3, but none of 2. Assume there always is 0 104 * be a core_id of 3, but none of 2. Assume there always is 0
100 * Get amount of cores by counting duplicates in a package 105 * Get amount of cores by counting duplicates in a package
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
index 0d6571e418db..c4bae9203a69 100644
--- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.c
@@ -39,6 +39,7 @@ static int mode;
39static int interval = 1; 39static int interval = 1;
40static char *show_monitors_param; 40static char *show_monitors_param;
41static struct cpupower_topology cpu_top; 41static struct cpupower_topology cpu_top;
42static unsigned int wake_cpus;
42 43
43/* ToDo: Document this in the manpage */ 44/* ToDo: Document this in the manpage */
44static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', }; 45static char range_abbr[RANGE_MAX] = { 'T', 'C', 'P', 'M', };
@@ -84,7 +85,7 @@ int fill_string_with_spaces(char *s, int n)
84void print_header(int topology_depth) 85void print_header(int topology_depth)
85{ 86{
86 int unsigned mon; 87 int unsigned mon;
87 int state, need_len, pr_mon_len; 88 int state, need_len;
88 cstate_t s; 89 cstate_t s;
89 char buf[128] = ""; 90 char buf[128] = "";
90 int percent_width = 4; 91 int percent_width = 4;
@@ -93,7 +94,6 @@ void print_header(int topology_depth)
93 printf("%s|", buf); 94 printf("%s|", buf);
94 95
95 for (mon = 0; mon < avail_monitors; mon++) { 96 for (mon = 0; mon < avail_monitors; mon++) {
96 pr_mon_len = 0;
97 need_len = monitors[mon]->hw_states_num * (percent_width + 3) 97 need_len = monitors[mon]->hw_states_num * (percent_width + 3)
98 - 1; 98 - 1;
99 if (mon != 0) { 99 if (mon != 0) {
@@ -315,16 +315,28 @@ int fork_it(char **argv)
315int do_interval_measure(int i) 315int do_interval_measure(int i)
316{ 316{
317 unsigned int num; 317 unsigned int num;
318 int cpu;
319
320 if (wake_cpus)
321 for (cpu = 0; cpu < cpu_count; cpu++)
322 bind_cpu(cpu);
318 323
319 for (num = 0; num < avail_monitors; num++) { 324 for (num = 0; num < avail_monitors; num++) {
320 dprint("HW C-state residency monitor: %s - States: %d\n", 325 dprint("HW C-state residency monitor: %s - States: %d\n",
321 monitors[num]->name, monitors[num]->hw_states_num); 326 monitors[num]->name, monitors[num]->hw_states_num);
322 monitors[num]->start(); 327 monitors[num]->start();
323 } 328 }
329
324 sleep(i); 330 sleep(i);
331
332 if (wake_cpus)
333 for (cpu = 0; cpu < cpu_count; cpu++)
334 bind_cpu(cpu);
335
325 for (num = 0; num < avail_monitors; num++) 336 for (num = 0; num < avail_monitors; num++)
326 monitors[num]->stop(); 337 monitors[num]->stop();
327 338
339
328 return 0; 340 return 0;
329} 341}
330 342
@@ -333,7 +345,7 @@ static void cmdline(int argc, char *argv[])
333 int opt; 345 int opt;
334 progname = basename(argv[0]); 346 progname = basename(argv[0]);
335 347
336 while ((opt = getopt(argc, argv, "+li:m:")) != -1) { 348 while ((opt = getopt(argc, argv, "+lci:m:")) != -1) {
337 switch (opt) { 349 switch (opt) {
338 case 'l': 350 case 'l':
339 if (mode) 351 if (mode)
@@ -352,6 +364,9 @@ static void cmdline(int argc, char *argv[])
352 mode = show; 364 mode = show;
353 show_monitors_param = optarg; 365 show_monitors_param = optarg;
354 break; 366 break;
367 case 'c':
368 wake_cpus = 1;
369 break;
355 default: 370 default:
356 print_wrong_arg_exit(); 371 print_wrong_arg_exit();
357 } 372 }
diff --git a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
index 9312ee1f2dbc..9e43f3371fbc 100644
--- a/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
+++ b/tools/power/cpupower/utils/idle_monitor/cpupower-monitor.h
@@ -65,4 +65,21 @@ extern long long timespec_diff_us(struct timespec start, struct timespec end);
65 "could be inaccurate\n"), mes, ov); \ 65 "could be inaccurate\n"), mes, ov); \
66} 66}
67 67
68
69/* Taken over from x86info project sources -> return 0 on success */
70#include <sched.h>
71#include <sys/types.h>
72#include <unistd.h>
73static inline int bind_cpu(int cpu)
74{
75 cpu_set_t set;
76
77 if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
78 CPU_ZERO(&set);
79 CPU_SET(cpu, &set);
80 return sched_setaffinity(getpid(), sizeof(set), &set);
81 }
82 return 1;
83}
84
68#endif /* __CPUIDLE_INFO_HW__ */ 85#endif /* __CPUIDLE_INFO_HW__ */
diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
index a1bc07cd53e1..a99b43b97d6d 100644
--- a/tools/power/cpupower/utils/idle_monitor/snb_idle.c
+++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
@@ -150,9 +150,15 @@ static struct cpuidle_monitor *snb_register(void)
150 || cpupower_cpu_info.family != 6) 150 || cpupower_cpu_info.family != 6)
151 return NULL; 151 return NULL;
152 152
153 if (cpupower_cpu_info.model != 0x2A 153 switch (cpupower_cpu_info.model) {
154 && cpupower_cpu_info.model != 0x2D) 154 case 0x2A: /* SNB */
155 case 0x2D: /* SNB Xeon */
156 case 0x3A: /* IVB */
157 case 0x3E: /* IVB Xeon */
158 break;
159 default:
155 return NULL; 160 return NULL;
161 }
156 162
157 is_valid = calloc(cpu_count, sizeof(int)); 163 is_valid = calloc(cpu_count, sizeof(int));
158 for (num = 0; num < SNB_CSTATE_COUNT; num++) { 164 for (num = 0; num < SNB_CSTATE_COUNT; num++) {
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
index b336b24aa6c0..7300d0702efe 100644
--- a/tools/testing/selftests/vm/Makefile
+++ b/tools/testing/selftests/vm/Makefile
@@ -1,9 +1,9 @@
1# Makefile for vm selftests 1# Makefile for vm selftests
2 2
3CC = $(CROSS_COMPILE)gcc 3CC = $(CROSS_COMPILE)gcc
4CFLAGS = -Wall -Wextra 4CFLAGS = -Wall
5 5
6all: hugepage-mmap hugepage-shm map_hugetlb 6all: hugepage-mmap hugepage-shm map_hugetlb thuge-gen
7%: %.c 7%: %.c
8 $(CC) $(CFLAGS) -o $@ $^ 8 $(CC) $(CFLAGS) -o $@ $^
9 9
diff --git a/tools/testing/selftests/vm/thuge-gen.c b/tools/testing/selftests/vm/thuge-gen.c
new file mode 100644
index 000000000000..c87957295f74
--- /dev/null
+++ b/tools/testing/selftests/vm/thuge-gen.c
@@ -0,0 +1,254 @@
1/* Test selecting other page sizes for mmap/shmget.
2
3 Before running this huge pages for each huge page size must have been
4 reserved.
5 For large pages beyond MAX_ORDER (like 1GB on x86) boot options must be used.
6 Also shmmax must be increased.
7 And you need to run as root to work around some weird permissions in shm.
8 And nothing using huge pages should run in parallel.
9 When the program aborts you may need to clean up the shm segments with
10 ipcrm -m by hand, like this
11 sudo ipcs | awk '$1 == "0x00000000" {print $2}' | xargs -n1 sudo ipcrm -m
12 (warning this will remove all if someone else uses them) */
13
14#define _GNU_SOURCE 1
15#include <sys/mman.h>
16#include <stdlib.h>
17#include <stdio.h>
18#include <sys/ipc.h>
19#include <sys/shm.h>
20#include <sys/stat.h>
21#include <glob.h>
22#include <assert.h>
23#include <unistd.h>
24#include <stdarg.h>
25#include <string.h>
26
27#define err(x) perror(x), exit(1)
28
29#define MAP_HUGE_2MB (21 << MAP_HUGE_SHIFT)
30#define MAP_HUGE_1GB (30 << MAP_HUGE_SHIFT)
31#define MAP_HUGE_SHIFT 26
32#define MAP_HUGE_MASK 0x3f
33#define MAP_HUGETLB 0x40000
34
35#define SHM_HUGETLB 04000 /* segment will use huge TLB pages */
36#define SHM_HUGE_SHIFT 26
37#define SHM_HUGE_MASK 0x3f
38#define SHM_HUGE_2MB (21 << SHM_HUGE_SHIFT)
39#define SHM_HUGE_1GB (30 << SHM_HUGE_SHIFT)
40
41#define NUM_PAGESIZES 5
42
43#define NUM_PAGES 4
44
45#define Dprintf(fmt...) // printf(fmt)
46
47unsigned long page_sizes[NUM_PAGESIZES];
48int num_page_sizes;
49
50int ilog2(unsigned long v)
51{
52 int l = 0;
53 while ((1UL << l) < v)
54 l++;
55 return l;
56}
57
58void find_pagesizes(void)
59{
60 glob_t g;
61 int i;
62 glob("/sys/kernel/mm/hugepages/hugepages-*kB", 0, NULL, &g);
63 assert(g.gl_pathc <= NUM_PAGESIZES);
64 for (i = 0; i < g.gl_pathc; i++) {
65 sscanf(g.gl_pathv[i], "/sys/kernel/mm/hugepages/hugepages-%lukB",
66 &page_sizes[i]);
67 page_sizes[i] <<= 10;
68 printf("Found %luMB\n", page_sizes[i] >> 20);
69 }
70 num_page_sizes = g.gl_pathc;
71 globfree(&g);
72}
73
74unsigned long default_huge_page_size(void)
75{
76 unsigned long hps = 0;
77 char *line = NULL;
78 size_t linelen = 0;
79 FILE *f = fopen("/proc/meminfo", "r");
80 if (!f)
81 return 0;
82 while (getline(&line, &linelen, f) > 0) {
83 if (sscanf(line, "Hugepagesize: %lu kB", &hps) == 1) {
84 hps <<= 10;
85 break;
86 }
87 }
88 free(line);
89 return hps;
90}
91
92void show(unsigned long ps)
93{
94 char buf[100];
95 if (ps == getpagesize())
96 return;
97 printf("%luMB: ", ps >> 20);
98 fflush(stdout);
99 snprintf(buf, sizeof buf,
100 "cat /sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages",
101 ps >> 10);
102 system(buf);
103}
104
105unsigned long read_sysfs(int warn, char *fmt, ...)
106{
107 char *line = NULL;
108 size_t linelen = 0;
109 char buf[100];
110 FILE *f;
111 va_list ap;
112 unsigned long val = 0;
113
114 va_start(ap, fmt);
115 vsnprintf(buf, sizeof buf, fmt, ap);
116 va_end(ap);
117
118 f = fopen(buf, "r");
119 if (!f) {
120 if (warn)
121 printf("missing %s\n", buf);
122 return 0;
123 }
124 if (getline(&line, &linelen, f) > 0) {
125 sscanf(line, "%lu", &val);
126 }
127 fclose(f);
128 free(line);
129 return val;
130}
131
132unsigned long read_free(unsigned long ps)
133{
134 return read_sysfs(ps != getpagesize(),
135 "/sys/kernel/mm/hugepages/hugepages-%lukB/free_hugepages",
136 ps >> 10);
137}
138
139void test_mmap(unsigned long size, unsigned flags)
140{
141 char *map;
142 unsigned long before, after;
143 int err;
144
145 before = read_free(size);
146 map = mmap(NULL, size*NUM_PAGES, PROT_READ|PROT_WRITE,
147 MAP_PRIVATE|MAP_ANONYMOUS|MAP_HUGETLB|flags, 0, 0);
148
149 if (map == (char *)-1) err("mmap");
150 memset(map, 0xff, size*NUM_PAGES);
151 after = read_free(size);
152 Dprintf("before %lu after %lu diff %ld size %lu\n",
153 before, after, before - after, size);
154 assert(size == getpagesize() || (before - after) == NUM_PAGES);
155 show(size);
156 err = munmap(map, size);
157 assert(!err);
158}
159
160void test_shmget(unsigned long size, unsigned flags)
161{
162 int id;
163 unsigned long before, after;
164 int err;
165
166 before = read_free(size);
167 id = shmget(IPC_PRIVATE, size * NUM_PAGES, IPC_CREAT|0600|flags);
168 if (id < 0) err("shmget");
169
170 struct shm_info i;
171 if (shmctl(id, SHM_INFO, (void *)&i) < 0) err("shmctl");
172 Dprintf("alloc %lu res %lu\n", i.shm_tot, i.shm_rss);
173
174
175 Dprintf("id %d\n", id);
176 char *map = shmat(id, NULL, 0600);
177 if (map == (char*)-1) err("shmat");
178
179 shmctl(id, IPC_RMID, NULL);
180
181 memset(map, 0xff, size*NUM_PAGES);
182 after = read_free(size);
183
184 Dprintf("before %lu after %lu diff %ld size %lu\n",
185 before, after, before - after, size);
186 assert(size == getpagesize() || (before - after) == NUM_PAGES);
187 show(size);
188 err = shmdt(map);
189 assert(!err);
190}
191
192void sanity_checks(void)
193{
194 int i;
195 unsigned long largest = getpagesize();
196
197 for (i = 0; i < num_page_sizes; i++) {
198 if (page_sizes[i] > largest)
199 largest = page_sizes[i];
200
201 if (read_free(page_sizes[i]) < NUM_PAGES) {
202 printf("Not enough huge pages for page size %lu MB, need %u\n",
203 page_sizes[i] >> 20,
204 NUM_PAGES);
205 exit(0);
206 }
207 }
208
209 if (read_sysfs(0, "/proc/sys/kernel/shmmax") < NUM_PAGES * largest) {
210 printf("Please do echo %lu > /proc/sys/kernel/shmmax", largest * NUM_PAGES);
211 exit(0);
212 }
213
214#if defined(__x86_64__)
215 if (largest != 1U<<30) {
216 printf("No GB pages available on x86-64\n"
217 "Please boot with hugepagesz=1G hugepages=%d\n", NUM_PAGES);
218 exit(0);
219 }
220#endif
221}
222
223int main(void)
224{
225 int i;
226 unsigned default_hps = default_huge_page_size();
227
228 find_pagesizes();
229
230 sanity_checks();
231
232 for (i = 0; i < num_page_sizes; i++) {
233 unsigned long ps = page_sizes[i];
234 int arg = ilog2(ps) << MAP_HUGE_SHIFT;
235 printf("Testing %luMB mmap with shift %x\n", ps >> 20, arg);
236 test_mmap(ps, MAP_HUGETLB | arg);
237 }
238 printf("Testing default huge mmap\n");
239 test_mmap(default_hps, SHM_HUGETLB);
240
241 puts("Testing non-huge shmget");
242 test_shmget(getpagesize(), 0);
243
244 for (i = 0; i < num_page_sizes; i++) {
245 unsigned long ps = page_sizes[i];
246 int arg = ilog2(ps) << SHM_HUGE_SHIFT;
247 printf("Testing %luMB shmget with shift %x\n", ps >> 20, arg);
248 test_shmget(ps, SHM_HUGETLB | arg);
249 }
250 puts("default huge shmget");
251 test_shmget(default_hps, SHM_HUGETLB);
252
253 return 0;
254}