diff options
author | Ingo Molnar <mingo@kernel.org> | 2014-04-14 10:44:42 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2014-04-14 10:44:42 -0400 |
commit | 740c699a8d316c8bf8593f19e2ca47795e690622 (patch) | |
tree | a78886955770a477945c5d84e06b2e7678733b54 /tools | |
parent | e69af4657e7764d03ad555f0b583d9c4217bcefa (diff) | |
parent | c9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff) |
Merge tag 'v3.15-rc1' into perf/urgent
Pick up the latest fixes.
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Diffstat (limited to 'tools')
24 files changed, 826 insertions, 298 deletions
diff --git a/tools/Makefile b/tools/Makefile index feec3ad5fd09..bcae806b0c39 100644 --- a/tools/Makefile +++ b/tools/Makefile | |||
@@ -7,6 +7,7 @@ help: | |||
7 | @echo ' cgroup - cgroup tools' | 7 | @echo ' cgroup - cgroup tools' |
8 | @echo ' cpupower - a tool for all things x86 CPU power' | 8 | @echo ' cpupower - a tool for all things x86 CPU power' |
9 | @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' | 9 | @echo ' firewire - the userspace part of nosy, an IEEE-1394 traffic sniffer' |
10 | @echo ' hv - tools used when in Hyper-V clients' | ||
10 | @echo ' lguest - a minimal 32-bit x86 hypervisor' | 11 | @echo ' lguest - a minimal 32-bit x86 hypervisor' |
11 | @echo ' perf - Linux performance measurement and analysis tool' | 12 | @echo ' perf - Linux performance measurement and analysis tool' |
12 | @echo ' selftests - various kernel selftests' | 13 | @echo ' selftests - various kernel selftests' |
@@ -40,7 +41,7 @@ acpi: FORCE | |||
40 | cpupower: FORCE | 41 | cpupower: FORCE |
41 | $(call descend,power/$@) | 42 | $(call descend,power/$@) |
42 | 43 | ||
43 | cgroup firewire guest usb virtio vm net: FORCE | 44 | cgroup firewire hv guest usb virtio vm net: FORCE |
44 | $(call descend,$@) | 45 | $(call descend,$@) |
45 | 46 | ||
46 | libapikfs: FORCE | 47 | libapikfs: FORCE |
@@ -64,7 +65,7 @@ acpi_install: | |||
64 | cpupower_install: | 65 | cpupower_install: |
65 | $(call descend,power/$(@:_install=),install) | 66 | $(call descend,power/$(@:_install=),install) |
66 | 67 | ||
67 | cgroup_install firewire_install lguest_install perf_install usb_install virtio_install vm_install net_install: | 68 | cgroup_install firewire_install hv_install lguest_install perf_install usb_install virtio_install vm_install net_install: |
68 | $(call descend,$(@:_install=),install) | 69 | $(call descend,$(@:_install=),install) |
69 | 70 | ||
70 | selftests_install: | 71 | selftests_install: |
@@ -76,7 +77,7 @@ turbostat_install x86_energy_perf_policy_install: | |||
76 | tmon_install: | 77 | tmon_install: |
77 | $(call descend,thermal/$(@:_install=),install) | 78 | $(call descend,thermal/$(@:_install=),install) |
78 | 79 | ||
79 | install: acpi_install cgroup_install cpupower_install firewire_install lguest_install \ | 80 | install: acpi_install cgroup_install cpupower_install hv_install firewire_install lguest_install \ |
80 | perf_install selftests_install turbostat_install usb_install \ | 81 | perf_install selftests_install turbostat_install usb_install \ |
81 | virtio_install vm_install net_install x86_energy_perf_policy_install \ | 82 | virtio_install vm_install net_install x86_energy_perf_policy_install \ |
82 | tmon | 83 | tmon |
@@ -87,7 +88,7 @@ acpi_clean: | |||
87 | cpupower_clean: | 88 | cpupower_clean: |
88 | $(call descend,power/cpupower,clean) | 89 | $(call descend,power/cpupower,clean) |
89 | 90 | ||
90 | cgroup_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean: | 91 | cgroup_clean hv_clean firewire_clean lguest_clean usb_clean virtio_clean vm_clean net_clean: |
91 | $(call descend,$(@:_clean=),clean) | 92 | $(call descend,$(@:_clean=),clean) |
92 | 93 | ||
93 | libapikfs_clean: | 94 | libapikfs_clean: |
@@ -105,7 +106,7 @@ turbostat_clean x86_energy_perf_policy_clean: | |||
105 | tmon_clean: | 106 | tmon_clean: |
106 | $(call descend,thermal/tmon,clean) | 107 | $(call descend,thermal/tmon,clean) |
107 | 108 | ||
108 | clean: acpi_clean cgroup_clean cpupower_clean firewire_clean lguest_clean \ | 109 | clean: acpi_clean cgroup_clean cpupower_clean hv_clean firewire_clean lguest_clean \ |
109 | perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \ | 110 | perf_clean selftests_clean turbostat_clean usb_clean virtio_clean \ |
110 | vm_clean net_clean x86_energy_perf_policy_clean tmon_clean | 111 | vm_clean net_clean x86_energy_perf_policy_clean tmon_clean |
111 | 112 | ||
diff --git a/tools/hv/Makefile b/tools/hv/Makefile new file mode 100644 index 000000000000..bd22f786a60c --- /dev/null +++ b/tools/hv/Makefile | |||
@@ -0,0 +1,13 @@ | |||
1 | # Makefile for Hyper-V tools | ||
2 | |||
3 | CC = $(CROSS_COMPILE)gcc | ||
4 | PTHREAD_LIBS = -lpthread | ||
5 | WARNINGS = -Wall -Wextra | ||
6 | CFLAGS = $(WARNINGS) -g $(PTHREAD_LIBS) | ||
7 | |||
8 | all: hv_kvp_daemon hv_vss_daemon | ||
9 | %: %.c | ||
10 | $(CC) $(CFLAGS) -o $@ $^ | ||
11 | |||
12 | clean: | ||
13 | $(RM) hv_kvp_daemon hv_vss_daemon | ||
diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c new file mode 100644 index 000000000000..4ecc4fd0bc1b --- /dev/null +++ b/tools/hv/hv_fcopy_daemon.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * An implementation of host to guest copy functionality for Linux. | ||
3 | * | ||
4 | * Copyright (C) 2014, Microsoft, Inc. | ||
5 | * | ||
6 | * Author : K. Y. Srinivasan <kys@microsoft.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License version 2 as published | ||
10 | * by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or | ||
15 | * NON INFRINGEMENT. See the GNU General Public License for more | ||
16 | * details. | ||
17 | */ | ||
18 | |||
19 | |||
20 | #include <sys/types.h> | ||
21 | #include <sys/socket.h> | ||
22 | #include <sys/poll.h> | ||
23 | #include <linux/types.h> | ||
24 | #include <linux/kdev_t.h> | ||
25 | #include <stdio.h> | ||
26 | #include <stdlib.h> | ||
27 | #include <unistd.h> | ||
28 | #include <string.h> | ||
29 | #include <ctype.h> | ||
30 | #include <errno.h> | ||
31 | #include <linux/hyperv.h> | ||
32 | #include <syslog.h> | ||
33 | #include <sys/stat.h> | ||
34 | #include <fcntl.h> | ||
35 | #include <dirent.h> | ||
36 | |||
37 | static int target_fd; | ||
38 | static char target_fname[W_MAX_PATH]; | ||
39 | |||
40 | static int hv_start_fcopy(struct hv_start_fcopy *smsg) | ||
41 | { | ||
42 | int error = HV_E_FAIL; | ||
43 | char *q, *p; | ||
44 | |||
45 | /* | ||
46 | * If possile append a path seperator to the path. | ||
47 | */ | ||
48 | if (strlen((char *)smsg->path_name) < (W_MAX_PATH - 2)) | ||
49 | strcat((char *)smsg->path_name, "/"); | ||
50 | |||
51 | p = (char *)smsg->path_name; | ||
52 | snprintf(target_fname, sizeof(target_fname), "%s/%s", | ||
53 | (char *)smsg->path_name, smsg->file_name); | ||
54 | |||
55 | syslog(LOG_INFO, "Target file name: %s", target_fname); | ||
56 | /* | ||
57 | * Check to see if the path is already in place; if not, | ||
58 | * create if required. | ||
59 | */ | ||
60 | while ((q = strchr(p, '/')) != NULL) { | ||
61 | if (q == p) { | ||
62 | p++; | ||
63 | continue; | ||
64 | } | ||
65 | *q = '\0'; | ||
66 | if (access((char *)smsg->path_name, F_OK)) { | ||
67 | if (smsg->copy_flags & CREATE_PATH) { | ||
68 | if (mkdir((char *)smsg->path_name, 0755)) { | ||
69 | syslog(LOG_ERR, "Failed to create %s", | ||
70 | (char *)smsg->path_name); | ||
71 | goto done; | ||
72 | } | ||
73 | } else { | ||
74 | syslog(LOG_ERR, "Invalid path: %s", | ||
75 | (char *)smsg->path_name); | ||
76 | goto done; | ||
77 | } | ||
78 | } | ||
79 | p = q + 1; | ||
80 | *q = '/'; | ||
81 | } | ||
82 | |||
83 | if (!access(target_fname, F_OK)) { | ||
84 | syslog(LOG_INFO, "File: %s exists", target_fname); | ||
85 | if (!smsg->copy_flags & OVER_WRITE) | ||
86 | goto done; | ||
87 | } | ||
88 | |||
89 | target_fd = open(target_fname, O_RDWR | O_CREAT | O_CLOEXEC, 0744); | ||
90 | if (target_fd == -1) { | ||
91 | syslog(LOG_INFO, "Open Failed: %s", strerror(errno)); | ||
92 | goto done; | ||
93 | } | ||
94 | |||
95 | error = 0; | ||
96 | done: | ||
97 | return error; | ||
98 | } | ||
99 | |||
100 | static int hv_copy_data(struct hv_do_fcopy *cpmsg) | ||
101 | { | ||
102 | ssize_t bytes_written; | ||
103 | |||
104 | bytes_written = pwrite(target_fd, cpmsg->data, cpmsg->size, | ||
105 | cpmsg->offset); | ||
106 | |||
107 | if (bytes_written != cpmsg->size) | ||
108 | return HV_E_FAIL; | ||
109 | |||
110 | return 0; | ||
111 | } | ||
112 | |||
113 | static int hv_copy_finished(void) | ||
114 | { | ||
115 | close(target_fd); | ||
116 | return 0; | ||
117 | } | ||
118 | static int hv_copy_cancel(void) | ||
119 | { | ||
120 | close(target_fd); | ||
121 | unlink(target_fname); | ||
122 | return 0; | ||
123 | |||
124 | } | ||
125 | |||
126 | int main(void) | ||
127 | { | ||
128 | int fd, fcopy_fd, len; | ||
129 | int error; | ||
130 | int version = FCOPY_CURRENT_VERSION; | ||
131 | char *buffer[4096 * 2]; | ||
132 | struct hv_fcopy_hdr *in_msg; | ||
133 | |||
134 | if (daemon(1, 0)) { | ||
135 | syslog(LOG_ERR, "daemon() failed; error: %s", strerror(errno)); | ||
136 | exit(EXIT_FAILURE); | ||
137 | } | ||
138 | |||
139 | openlog("HV_FCOPY", 0, LOG_USER); | ||
140 | syslog(LOG_INFO, "HV_FCOPY starting; pid is:%d", getpid()); | ||
141 | |||
142 | fcopy_fd = open("/dev/vmbus/hv_fcopy", O_RDWR); | ||
143 | |||
144 | if (fcopy_fd < 0) { | ||
145 | syslog(LOG_ERR, "open /dev/vmbus/hv_fcopy failed; error: %d %s", | ||
146 | errno, strerror(errno)); | ||
147 | exit(EXIT_FAILURE); | ||
148 | } | ||
149 | |||
150 | /* | ||
151 | * Register with the kernel. | ||
152 | */ | ||
153 | if ((write(fcopy_fd, &version, sizeof(int))) != sizeof(int)) { | ||
154 | syslog(LOG_ERR, "Registration failed: %s", strerror(errno)); | ||
155 | exit(EXIT_FAILURE); | ||
156 | } | ||
157 | |||
158 | while (1) { | ||
159 | /* | ||
160 | * In this loop we process fcopy messages after the | ||
161 | * handshake is complete. | ||
162 | */ | ||
163 | len = pread(fcopy_fd, buffer, (4096 * 2), 0); | ||
164 | if (len < 0) { | ||
165 | syslog(LOG_ERR, "pread failed: %s", strerror(errno)); | ||
166 | exit(EXIT_FAILURE); | ||
167 | } | ||
168 | in_msg = (struct hv_fcopy_hdr *)buffer; | ||
169 | |||
170 | switch (in_msg->operation) { | ||
171 | case START_FILE_COPY: | ||
172 | error = hv_start_fcopy((struct hv_start_fcopy *)in_msg); | ||
173 | break; | ||
174 | case WRITE_TO_FILE: | ||
175 | error = hv_copy_data((struct hv_do_fcopy *)in_msg); | ||
176 | break; | ||
177 | case COMPLETE_FCOPY: | ||
178 | error = hv_copy_finished(); | ||
179 | break; | ||
180 | case CANCEL_FCOPY: | ||
181 | error = hv_copy_cancel(); | ||
182 | break; | ||
183 | |||
184 | default: | ||
185 | syslog(LOG_ERR, "Unknown operation: %d", | ||
186 | in_msg->operation); | ||
187 | |||
188 | } | ||
189 | |||
190 | if (pwrite(fcopy_fd, &error, sizeof(int), 0) != sizeof(int)) { | ||
191 | syslog(LOG_ERR, "pwrite failed: %s", strerror(errno)); | ||
192 | exit(EXIT_FAILURE); | ||
193 | } | ||
194 | } | ||
195 | } | ||
diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c index 520de3304571..6a213b8cd7b9 100644 --- a/tools/hv/hv_vss_daemon.c +++ b/tools/hv/hv_vss_daemon.c | |||
@@ -87,6 +87,8 @@ static int vss_operate(int operation) | |||
87 | continue; | 87 | continue; |
88 | if (strcmp(ent->mnt_type, "iso9660") == 0) | 88 | if (strcmp(ent->mnt_type, "iso9660") == 0) |
89 | continue; | 89 | continue; |
90 | if (strcmp(ent->mnt_type, "vfat") == 0) | ||
91 | continue; | ||
90 | if (strcmp(ent->mnt_dir, "/") == 0) { | 92 | if (strcmp(ent->mnt_dir, "/") == 0) { |
91 | root_seen = 1; | 93 | root_seen = 1; |
92 | continue; | 94 | continue; |
diff --git a/tools/net/bpf_dbg.c b/tools/net/bpf_dbg.c index 65dc757f7f7b..bb31813e43dd 100644 --- a/tools/net/bpf_dbg.c +++ b/tools/net/bpf_dbg.c | |||
@@ -87,9 +87,6 @@ | |||
87 | __attribute__ ((format (printf, (pos_fmtstr), (pos_fmtargs)))) | 87 | __attribute__ ((format (printf, (pos_fmtstr), (pos_fmtargs)))) |
88 | #endif | 88 | #endif |
89 | 89 | ||
90 | #define CMD(_name, _func) { .name = _name, .func = _func, } | ||
91 | #define OP(_op, _name) [_op] = _name | ||
92 | |||
93 | enum { | 90 | enum { |
94 | CMD_OK, | 91 | CMD_OK, |
95 | CMD_ERR, | 92 | CMD_ERR, |
@@ -145,32 +142,32 @@ static size_t pcap_map_size = 0; | |||
145 | static char *pcap_ptr_va_start, *pcap_ptr_va_curr; | 142 | static char *pcap_ptr_va_start, *pcap_ptr_va_curr; |
146 | 143 | ||
147 | static const char * const op_table[] = { | 144 | static const char * const op_table[] = { |
148 | OP(BPF_ST, "st"), | 145 | [BPF_ST] = "st", |
149 | OP(BPF_STX, "stx"), | 146 | [BPF_STX] = "stx", |
150 | OP(BPF_LD_B, "ldb"), | 147 | [BPF_LD_B] = "ldb", |
151 | OP(BPF_LD_H, "ldh"), | 148 | [BPF_LD_H] = "ldh", |
152 | OP(BPF_LD_W, "ld"), | 149 | [BPF_LD_W] = "ld", |
153 | OP(BPF_LDX, "ldx"), | 150 | [BPF_LDX] = "ldx", |
154 | OP(BPF_LDX_B, "ldxb"), | 151 | [BPF_LDX_B] = "ldxb", |
155 | OP(BPF_JMP_JA, "ja"), | 152 | [BPF_JMP_JA] = "ja", |
156 | OP(BPF_JMP_JEQ, "jeq"), | 153 | [BPF_JMP_JEQ] = "jeq", |
157 | OP(BPF_JMP_JGT, "jgt"), | 154 | [BPF_JMP_JGT] = "jgt", |
158 | OP(BPF_JMP_JGE, "jge"), | 155 | [BPF_JMP_JGE] = "jge", |
159 | OP(BPF_JMP_JSET, "jset"), | 156 | [BPF_JMP_JSET] = "jset", |
160 | OP(BPF_ALU_ADD, "add"), | 157 | [BPF_ALU_ADD] = "add", |
161 | OP(BPF_ALU_SUB, "sub"), | 158 | [BPF_ALU_SUB] = "sub", |
162 | OP(BPF_ALU_MUL, "mul"), | 159 | [BPF_ALU_MUL] = "mul", |
163 | OP(BPF_ALU_DIV, "div"), | 160 | [BPF_ALU_DIV] = "div", |
164 | OP(BPF_ALU_MOD, "mod"), | 161 | [BPF_ALU_MOD] = "mod", |
165 | OP(BPF_ALU_NEG, "neg"), | 162 | [BPF_ALU_NEG] = "neg", |
166 | OP(BPF_ALU_AND, "and"), | 163 | [BPF_ALU_AND] = "and", |
167 | OP(BPF_ALU_OR, "or"), | 164 | [BPF_ALU_OR] = "or", |
168 | OP(BPF_ALU_XOR, "xor"), | 165 | [BPF_ALU_XOR] = "xor", |
169 | OP(BPF_ALU_LSH, "lsh"), | 166 | [BPF_ALU_LSH] = "lsh", |
170 | OP(BPF_ALU_RSH, "rsh"), | 167 | [BPF_ALU_RSH] = "rsh", |
171 | OP(BPF_MISC_TAX, "tax"), | 168 | [BPF_MISC_TAX] = "tax", |
172 | OP(BPF_MISC_TXA, "txa"), | 169 | [BPF_MISC_TXA] = "txa", |
173 | OP(BPF_RET, "ret"), | 170 | [BPF_RET] = "ret", |
174 | }; | 171 | }; |
175 | 172 | ||
176 | static __check_format_printf(1, 2) int rl_printf(const char *fmt, ...) | 173 | static __check_format_printf(1, 2) int rl_printf(const char *fmt, ...) |
@@ -1127,7 +1124,6 @@ static int cmd_step(char *num) | |||
1127 | static int cmd_select(char *num) | 1124 | static int cmd_select(char *num) |
1128 | { | 1125 | { |
1129 | unsigned int which, i; | 1126 | unsigned int which, i; |
1130 | struct pcap_pkthdr *hdr; | ||
1131 | bool have_next = true; | 1127 | bool have_next = true; |
1132 | 1128 | ||
1133 | if (!pcap_loaded() || strlen(num) == 0) | 1129 | if (!pcap_loaded() || strlen(num) == 0) |
@@ -1144,7 +1140,7 @@ static int cmd_select(char *num) | |||
1144 | 1140 | ||
1145 | for (i = 0; i < which && (have_next = pcap_next_pkt()); i++) | 1141 | for (i = 0; i < which && (have_next = pcap_next_pkt()); i++) |
1146 | /* noop */; | 1142 | /* noop */; |
1147 | if (!have_next || (hdr = pcap_curr_pkt()) == NULL) { | 1143 | if (!have_next || pcap_curr_pkt() == NULL) { |
1148 | rl_printf("no packet #%u available!\n", which); | 1144 | rl_printf("no packet #%u available!\n", which); |
1149 | pcap_reset_pkt(); | 1145 | pcap_reset_pkt(); |
1150 | return CMD_ERR; | 1146 | return CMD_ERR; |
@@ -1177,9 +1173,8 @@ static int cmd_breakpoint(char *subcmd) | |||
1177 | static int cmd_run(char *num) | 1173 | static int cmd_run(char *num) |
1178 | { | 1174 | { |
1179 | static uint32_t pass = 0, fail = 0; | 1175 | static uint32_t pass = 0, fail = 0; |
1180 | struct pcap_pkthdr *hdr; | ||
1181 | bool has_limit = true; | 1176 | bool has_limit = true; |
1182 | int ret, pkts = 0, i = 0; | 1177 | int pkts = 0, i = 0; |
1183 | 1178 | ||
1184 | if (!bpf_prog_loaded() || !pcap_loaded()) | 1179 | if (!bpf_prog_loaded() || !pcap_loaded()) |
1185 | return CMD_ERR; | 1180 | return CMD_ERR; |
@@ -1189,10 +1184,10 @@ static int cmd_run(char *num) | |||
1189 | has_limit = false; | 1184 | has_limit = false; |
1190 | 1185 | ||
1191 | do { | 1186 | do { |
1192 | hdr = pcap_curr_pkt(); | 1187 | struct pcap_pkthdr *hdr = pcap_curr_pkt(); |
1193 | ret = bpf_run_all(bpf_image, bpf_prog_len, | 1188 | int ret = bpf_run_all(bpf_image, bpf_prog_len, |
1194 | (uint8_t *) hdr + sizeof(*hdr), | 1189 | (uint8_t *) hdr + sizeof(*hdr), |
1195 | hdr->caplen, hdr->len); | 1190 | hdr->caplen, hdr->len); |
1196 | if (ret > 0) | 1191 | if (ret > 0) |
1197 | pass++; | 1192 | pass++; |
1198 | else if (ret == 0) | 1193 | else if (ret == 0) |
@@ -1245,14 +1240,14 @@ static int cmd_quit(char *dontcare) | |||
1245 | } | 1240 | } |
1246 | 1241 | ||
1247 | static const struct shell_cmd cmds[] = { | 1242 | static const struct shell_cmd cmds[] = { |
1248 | CMD("load", cmd_load), | 1243 | { .name = "load", .func = cmd_load }, |
1249 | CMD("select", cmd_select), | 1244 | { .name = "select", .func = cmd_select }, |
1250 | CMD("step", cmd_step), | 1245 | { .name = "step", .func = cmd_step }, |
1251 | CMD("run", cmd_run), | 1246 | { .name = "run", .func = cmd_run }, |
1252 | CMD("breakpoint", cmd_breakpoint), | 1247 | { .name = "breakpoint", .func = cmd_breakpoint }, |
1253 | CMD("disassemble", cmd_disassemble), | 1248 | { .name = "disassemble", .func = cmd_disassemble }, |
1254 | CMD("dump", cmd_dump), | 1249 | { .name = "dump", .func = cmd_dump }, |
1255 | CMD("quit", cmd_quit), | 1250 | { .name = "quit", .func = cmd_quit }, |
1256 | }; | 1251 | }; |
1257 | 1252 | ||
1258 | static int execf(char *arg) | 1253 | static int execf(char *arg) |
@@ -1280,7 +1275,6 @@ out: | |||
1280 | static char *shell_comp_gen(const char *buf, int state) | 1275 | static char *shell_comp_gen(const char *buf, int state) |
1281 | { | 1276 | { |
1282 | static int list_index, len; | 1277 | static int list_index, len; |
1283 | const char *name; | ||
1284 | 1278 | ||
1285 | if (!state) { | 1279 | if (!state) { |
1286 | list_index = 0; | 1280 | list_index = 0; |
@@ -1288,9 +1282,9 @@ static char *shell_comp_gen(const char *buf, int state) | |||
1288 | } | 1282 | } |
1289 | 1283 | ||
1290 | for (; list_index < array_size(cmds); ) { | 1284 | for (; list_index < array_size(cmds); ) { |
1291 | name = cmds[list_index].name; | 1285 | const char *name = cmds[list_index].name; |
1292 | list_index++; | ||
1293 | 1286 | ||
1287 | list_index++; | ||
1294 | if (strncmp(name, buf, len) == 0) | 1288 | if (strncmp(name, buf, len) == 0) |
1295 | return strdup(name); | 1289 | return strdup(name); |
1296 | } | 1290 | } |
@@ -1322,16 +1316,9 @@ static void init_shell(FILE *fin, FILE *fout) | |||
1322 | { | 1316 | { |
1323 | char file[128]; | 1317 | char file[128]; |
1324 | 1318 | ||
1325 | memset(file, 0, sizeof(file)); | 1319 | snprintf(file, sizeof(file), "%s/.bpf_dbg_history", getenv("HOME")); |
1326 | snprintf(file, sizeof(file) - 1, | ||
1327 | "%s/.bpf_dbg_history", getenv("HOME")); | ||
1328 | |||
1329 | read_history(file); | 1320 | read_history(file); |
1330 | 1321 | ||
1331 | memset(file, 0, sizeof(file)); | ||
1332 | snprintf(file, sizeof(file) - 1, | ||
1333 | "%s/.bpf_dbg_init", getenv("HOME")); | ||
1334 | |||
1335 | rl_instream = fin; | 1322 | rl_instream = fin; |
1336 | rl_outstream = fout; | 1323 | rl_outstream = fout; |
1337 | 1324 | ||
@@ -1348,37 +1335,41 @@ static void init_shell(FILE *fin, FILE *fout) | |||
1348 | rl_bind_key_in_map('\t', rl_complete, emacs_meta_keymap); | 1335 | rl_bind_key_in_map('\t', rl_complete, emacs_meta_keymap); |
1349 | rl_bind_key_in_map('\033', rl_complete, emacs_meta_keymap); | 1336 | rl_bind_key_in_map('\033', rl_complete, emacs_meta_keymap); |
1350 | 1337 | ||
1338 | snprintf(file, sizeof(file), "%s/.bpf_dbg_init", getenv("HOME")); | ||
1351 | rl_read_init_file(file); | 1339 | rl_read_init_file(file); |
1340 | |||
1352 | rl_prep_terminal(0); | 1341 | rl_prep_terminal(0); |
1353 | rl_set_signals(); | 1342 | rl_set_signals(); |
1354 | 1343 | ||
1355 | signal(SIGINT, intr_shell); | 1344 | signal(SIGINT, intr_shell); |
1356 | } | 1345 | } |
1357 | 1346 | ||
1358 | static void exit_shell(void) | 1347 | static void exit_shell(FILE *fin, FILE *fout) |
1359 | { | 1348 | { |
1360 | char file[128]; | 1349 | char file[128]; |
1361 | 1350 | ||
1362 | memset(file, 0, sizeof(file)); | 1351 | snprintf(file, sizeof(file), "%s/.bpf_dbg_history", getenv("HOME")); |
1363 | snprintf(file, sizeof(file) - 1, | ||
1364 | "%s/.bpf_dbg_history", getenv("HOME")); | ||
1365 | |||
1366 | write_history(file); | 1352 | write_history(file); |
1353 | |||
1367 | clear_history(); | 1354 | clear_history(); |
1368 | rl_deprep_terminal(); | 1355 | rl_deprep_terminal(); |
1369 | 1356 | ||
1370 | try_close_pcap(); | 1357 | try_close_pcap(); |
1358 | |||
1359 | if (fin != stdin) | ||
1360 | fclose(fin); | ||
1361 | if (fout != stdout) | ||
1362 | fclose(fout); | ||
1371 | } | 1363 | } |
1372 | 1364 | ||
1373 | static int run_shell_loop(FILE *fin, FILE *fout) | 1365 | static int run_shell_loop(FILE *fin, FILE *fout) |
1374 | { | 1366 | { |
1375 | char *buf; | 1367 | char *buf; |
1376 | int ret; | ||
1377 | 1368 | ||
1378 | init_shell(fin, fout); | 1369 | init_shell(fin, fout); |
1379 | 1370 | ||
1380 | while ((buf = readline("> ")) != NULL) { | 1371 | while ((buf = readline("> ")) != NULL) { |
1381 | ret = execf(buf); | 1372 | int ret = execf(buf); |
1382 | if (ret == CMD_EX) | 1373 | if (ret == CMD_EX) |
1383 | break; | 1374 | break; |
1384 | if (ret == CMD_OK && strlen(buf) > 0) | 1375 | if (ret == CMD_OK && strlen(buf) > 0) |
@@ -1387,7 +1378,7 @@ static int run_shell_loop(FILE *fin, FILE *fout) | |||
1387 | free(buf); | 1378 | free(buf); |
1388 | } | 1379 | } |
1389 | 1380 | ||
1390 | exit_shell(); | 1381 | exit_shell(fin, fout); |
1391 | return 0; | 1382 | return 0; |
1392 | } | 1383 | } |
1393 | 1384 | ||
diff --git a/tools/perf/config/Makefile.arch b/tools/perf/config/Makefile.arch index fef8ae922800..4b06719ee984 100644 --- a/tools/perf/config/Makefile.arch +++ b/tools/perf/config/Makefile.arch | |||
@@ -5,7 +5,8 @@ ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ | |||
5 | -e s/arm.*/arm/ -e s/sa110/arm/ \ | 5 | -e s/arm.*/arm/ -e s/sa110/arm/ \ |
6 | -e s/s390x/s390/ -e s/parisc64/parisc/ \ | 6 | -e s/s390x/s390/ -e s/parisc64/parisc/ \ |
7 | -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ | 7 | -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ |
8 | -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ ) | 8 | -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ \ |
9 | -e s/tile.*/tile/ ) | ||
9 | 10 | ||
10 | # Additional ARCH settings for x86 | 11 | # Additional ARCH settings for x86 |
11 | ifeq ($(ARCH),i386) | 12 | ifeq ($(ARCH),i386) |
diff --git a/tools/perf/perf.h b/tools/perf/perf.h index e18a8b5e6953..5c11ecad02a9 100644 --- a/tools/perf/perf.h +++ b/tools/perf/perf.h | |||
@@ -145,6 +145,14 @@ | |||
145 | #define CPUINFO_PROC "core ID" | 145 | #define CPUINFO_PROC "core ID" |
146 | #endif | 146 | #endif |
147 | 147 | ||
148 | #ifdef __tile__ | ||
149 | #define mb() asm volatile ("mf" ::: "memory") | ||
150 | #define wmb() asm volatile ("mf" ::: "memory") | ||
151 | #define rmb() asm volatile ("mf" ::: "memory") | ||
152 | #define cpu_relax() asm volatile ("mfspr zero, PASS" ::: "memory") | ||
153 | #define CPUINFO_PROC "model name" | ||
154 | #endif | ||
155 | |||
148 | #define barrier() asm volatile ("" ::: "memory") | 156 | #define barrier() asm volatile ("" ::: "memory") |
149 | 157 | ||
150 | #ifndef cpu_relax | 158 | #ifndef cpu_relax |
diff --git a/tools/power/x86/turbostat/turbostat.8 b/tools/power/x86/turbostat/turbostat.8 index b4ddb748356c..56bfb523c5bb 100644 --- a/tools/power/x86/turbostat/turbostat.8 +++ b/tools/power/x86/turbostat/turbostat.8 | |||
@@ -47,21 +47,22 @@ displays the statistics gathered since it was forked. | |||
47 | .PP | 47 | .PP |
48 | .SH FIELD DESCRIPTIONS | 48 | .SH FIELD DESCRIPTIONS |
49 | .nf | 49 | .nf |
50 | \fBpk\fP processor package number. | 50 | \fBPackage\fP processor package number. |
51 | \fBcor\fP processor core number. | 51 | \fBCore\fP processor core number. |
52 | \fBCPU\fP Linux CPU (logical processor) number. | 52 | \fBCPU\fP Linux CPU (logical processor) number. |
53 | Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology. | 53 | Note that multiple CPUs per core indicate support for Intel(R) Hyper-Threading Technology. |
54 | \fB%c0\fP percent of the interval that the CPU retired instructions. | 54 | \fBAVG_MHz\fP number of cycles executed divided by time elapsed. |
55 | \fBGHz\fP average clock rate while the CPU was in c0 state. | 55 | \fB%Buzy\fP percent of the interval that the CPU retired instructions, aka. % of time in "C0" state. |
56 | \fBTSC\fP average GHz that the TSC ran during the entire interval. | 56 | \fBBzy_MHz\fP average clock rate while the CPU was busy (in "c0" state). |
57 | \fB%c1, %c3, %c6, %c7\fP show the percentage residency in hardware core idle states. | 57 | \fBTSC_MHz\fP average MHz that the TSC ran during the entire interval. |
58 | \fBCTMP\fP Degrees Celsius reported by the per-core Digital Thermal Sensor. | 58 | \fBCPU%c1, CPU%c3, CPU%c6, CPU%c7\fP show the percentage residency in hardware core idle states. |
59 | \fBPTMP\fP Degrees Celsius reported by the per-package Package Thermal Monitor. | 59 | \fBCoreTmp\fP Degrees Celsius reported by the per-core Digital Thermal Sensor. |
60 | \fB%pc2, %pc3, %pc6, %pc7\fP percentage residency in hardware package idle states. | 60 | \fBPkgTtmp\fP Degrees Celsius reported by the per-package Package Thermal Monitor. |
61 | \fBPkg_W\fP Watts consumed by the whole package. | 61 | \fBPkg%pc2, Pkg%pc3, Pkg%pc6, Pkg%pc7\fP percentage residency in hardware package idle states. |
62 | \fBCor_W\fP Watts consumed by the core part of the package. | 62 | \fBPkgWatt\fP Watts consumed by the whole package. |
63 | \fBGFX_W\fP Watts consumed by the Graphics part of the package -- available only on client processors. | 63 | \fBCorWatt\fP Watts consumed by the core part of the package. |
64 | \fBRAM_W\fP Watts consumed by the DRAM DIMMS -- available only on server processors. | 64 | \fBGFXWatt\fP Watts consumed by the Graphics part of the package -- available only on client processors. |
65 | \fBRAMWatt\fP Watts consumed by the DRAM DIMMS -- available only on server processors. | ||
65 | \fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package. | 66 | \fBPKG_%\fP percent of the interval that RAPL throttling was active on the Package. |
66 | \fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM. | 67 | \fBRAM_%\fP percent of the interval that RAPL throttling was active on DRAM. |
67 | .fi | 68 | .fi |
@@ -78,29 +79,17 @@ For Watts columns, the summary is a system total. | |||
78 | Subsequent rows show per-CPU statistics. | 79 | Subsequent rows show per-CPU statistics. |
79 | 80 | ||
80 | .nf | 81 | .nf |
81 | [root@sandy]# ./turbostat | 82 | [root@ivy]# ./turbostat |
82 | cor CPU %c0 GHz TSC %c1 %c3 %c6 %c7 CTMP PTMP %pc2 %pc3 %pc6 %pc7 Pkg_W Cor_W GFX_W | 83 | Core CPU Avg_MHz %Busy Bzy_MHz TSC_MHz SMI CPU%c1 CPU%c3 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt |
83 | 0.06 0.80 2.29 0.11 0.00 0.00 99.83 47 40 0.26 0.01 0.44 98.78 3.49 0.12 0.14 | 84 | - - 6 0.36 1596 3492 0 0.59 0.01 99.04 0.00 23 24 23.82 0.01 72.47 0.00 6.40 1.01 0.00 |
84 | 0 0 0.07 0.80 2.29 0.07 0.00 0.00 99.86 40 40 0.26 0.01 0.44 98.78 3.49 0.12 0.14 | 85 | 0 0 9 0.58 1596 3492 0 0.28 0.01 99.13 0.00 23 24 23.82 0.01 72.47 0.00 6.40 1.01 0.00 |
85 | 0 4 0.03 0.80 2.29 0.12 | 86 | 0 4 1 0.07 1596 3492 0 0.79 |
86 | 1 1 0.04 0.80 2.29 0.25 0.01 0.00 99.71 40 | 87 | 1 1 10 0.65 1596 3492 0 0.59 0.00 98.76 0.00 23 |
87 | 1 5 0.16 0.80 2.29 0.13 | 88 | 1 5 5 0.28 1596 3492 0 0.95 |
88 | 2 2 0.05 0.80 2.29 0.06 0.01 0.00 99.88 40 | 89 | 2 2 10 0.66 1596 3492 0 0.41 0.01 98.92 0.00 23 |
89 | 2 6 0.03 0.80 2.29 0.08 | 90 | 2 6 2 0.10 1597 3492 0 0.97 |
90 | 3 3 0.05 0.80 2.29 0.08 0.00 0.00 99.87 47 | 91 | 3 3 3 0.20 1596 3492 0 0.44 0.00 99.37 0.00 23 |
91 | 3 7 0.04 0.84 2.29 0.09 | 92 | 3 7 5 0.31 1596 3492 0 0.33 |
92 | .fi | ||
93 | .SH SUMMARY EXAMPLE | ||
94 | The "-s" option prints the column headers just once, | ||
95 | and then the one line system summary for each sample interval. | ||
96 | |||
97 | .nf | ||
98 | [root@wsm]# turbostat -S | ||
99 | %c0 GHz TSC %c1 %c3 %c6 CTMP %pc3 %pc6 | ||
100 | 1.40 2.81 3.38 10.78 43.47 44.35 42 13.67 2.09 | ||
101 | 1.34 2.90 3.38 11.48 58.96 28.23 41 19.89 0.15 | ||
102 | 1.55 2.72 3.38 26.73 37.66 34.07 42 2.53 2.80 | ||
103 | 1.37 2.83 3.38 16.95 60.05 21.63 42 5.76 0.20 | ||
104 | .fi | 93 | .fi |
105 | .SH VERBOSE EXAMPLE | 94 | .SH VERBOSE EXAMPLE |
106 | The "-v" option adds verbosity to the output: | 95 | The "-v" option adds verbosity to the output: |
@@ -154,55 +143,35 @@ eg. Here a cycle soaker is run on 1 CPU (see %c0) for a few seconds | |||
154 | until ^C while the other CPUs are mostly idle: | 143 | until ^C while the other CPUs are mostly idle: |
155 | 144 | ||
156 | .nf | 145 | .nf |
157 | [root@x980 lenb]# ./turbostat cat /dev/zero > /dev/null | 146 | root@ivy: turbostat cat /dev/zero > /dev/null |
158 | ^C | 147 | ^C |
159 | cor CPU %c0 GHz TSC %c1 %c3 %c6 %pc3 %pc6 | 148 | Core CPU Avg_MHz %Busy Bzy_MHz TSC_MHz SMI CPU%c1 CPU%c3 CPU%c6 CPU%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt |
160 | 8.86 3.61 3.38 15.06 31.19 44.89 0.00 0.00 | 149 | - - 496 12.75 3886 3492 0 13.16 0.04 74.04 0.00 36 36 0.00 0.00 0.00 0.00 23.15 17.65 0.00 |
161 | 0 0 1.46 3.22 3.38 16.84 29.48 52.22 0.00 0.00 | 150 | 0 0 22 0.57 3830 3492 0 0.83 0.02 98.59 0.00 27 36 0.00 0.00 0.00 0.00 23.15 17.65 0.00 |
162 | 0 6 0.21 3.06 3.38 18.09 | 151 | 0 4 9 0.24 3829 3492 0 1.15 |
163 | 1 2 0.53 3.33 3.38 2.80 46.40 50.27 | 152 | 1 1 4 0.09 3783 3492 0 99.91 0.00 0.00 0.00 36 |
164 | 1 8 0.89 3.47 3.38 2.44 | 153 | 1 5 3880 99.82 3888 3492 0 0.18 |
165 | 2 4 1.36 3.43 3.38 9.04 23.71 65.89 | 154 | 2 2 17 0.44 3813 3492 0 0.77 0.04 98.75 0.00 28 |
166 | 2 10 0.18 2.86 3.38 10.22 | 155 | 2 6 12 0.32 3823 3492 0 0.89 |
167 | 8 1 0.04 2.87 3.38 99.96 0.01 0.00 | 156 | 3 3 16 0.43 3844 3492 0 0.63 0.11 98.84 0.00 30 |
168 | 8 7 99.72 3.63 3.38 0.27 | 157 | 3 7 4 0.11 3827 3492 0 0.94 |
169 | 9 3 0.31 3.21 3.38 7.64 56.55 35.50 | 158 | 30.372243 sec |
170 | 9 9 0.08 2.95 3.38 7.88 | 159 | |
171 | 10 5 1.42 3.43 3.38 2.14 30.99 65.44 | ||
172 | 10 11 0.16 2.88 3.38 3.40 | ||
173 | .fi | 160 | .fi |
174 | Above the cycle soaker drives cpu7 up its 3.6 GHz turbo limit | 161 | Above the cycle soaker drives cpu5 up its 3.8 GHz turbo limit |
175 | while the other processors are generally in various states of idle. | 162 | while the other processors are generally in various states of idle. |
176 | 163 | ||
177 | Note that cpu1 and cpu7 are HT siblings within core8. | 164 | Note that cpu1 and cpu5 are HT siblings within core1. |
178 | As cpu7 is very busy, it prevents its sibling, cpu1, | 165 | As cpu5 is very busy, it prevents its sibling, cpu1, |
179 | from entering a c-state deeper than c1. | 166 | from entering a c-state deeper than c1. |
180 | 167 | ||
181 | Note that turbostat reports average GHz of 3.63, while | 168 | Note that the Avg_MHz column reflects the total number of cycles executed |
182 | the arithmetic average of the GHz column above is lower. | 169 | divided by the measurement interval. If the %Busy column is 100%, |
183 | This is a weighted average, where the weight is %c0. ie. it is the total number of | 170 | then the processor was running at that speed the entire interval. |
184 | un-halted cycles elapsed per time divided by the number of CPUs. | 171 | The Avg_MHz multiplied by the %Busy results in the Bzy_MHz -- |
185 | .SH SMI COUNTING EXAMPLE | 172 | which is the average frequency while the processor was executing -- |
186 | On Intel Nehalem and newer processors, MSR 0x34 is a System Management Mode Interrupt (SMI) counter. | 173 | not including any non-busy idle time. |
187 | This counter is shown by default under the "SMI" column. | 174 | |
188 | .nf | ||
189 | [root@x980 ~]# turbostat | ||
190 | cor CPU %c0 GHz TSC SMI %c1 %c3 %c6 CTMP %pc3 %pc6 | ||
191 | 0.11 1.91 3.38 0 1.84 0.26 97.79 29 0.82 83.87 | ||
192 | 0 0 0.40 1.63 3.38 0 10.27 0.12 89.20 20 0.82 83.88 | ||
193 | 0 6 0.06 1.63 3.38 0 10.61 | ||
194 | 1 2 0.37 2.63 3.38 0 0.02 0.10 99.51 22 | ||
195 | 1 8 0.01 1.62 3.38 0 0.39 | ||
196 | 2 4 0.07 1.62 3.38 0 0.04 0.07 99.82 23 | ||
197 | 2 10 0.02 1.62 3.38 0 0.09 | ||
198 | 8 1 0.23 1.64 3.38 0 0.10 1.07 98.60 24 | ||
199 | 8 7 0.02 1.64 3.38 0 0.31 | ||
200 | 9 3 0.03 1.62 3.38 0 0.03 0.05 99.89 29 | ||
201 | 9 9 0.02 1.62 3.38 0 0.05 | ||
202 | 10 5 0.07 1.62 3.38 0 0.08 0.12 99.73 27 | ||
203 | 10 11 0.03 1.62 3.38 0 0.13 | ||
204 | ^C | ||
205 | .fi | ||
206 | .SH NOTES | 175 | .SH NOTES |
207 | 176 | ||
208 | .B "turbostat " | 177 | .B "turbostat " |
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 77eb130168da..7c9d8e71eb9e 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -56,7 +56,7 @@ unsigned int do_slm_cstates; | |||
56 | unsigned int use_c1_residency_msr; | 56 | unsigned int use_c1_residency_msr; |
57 | unsigned int has_aperf; | 57 | unsigned int has_aperf; |
58 | unsigned int has_epb; | 58 | unsigned int has_epb; |
59 | unsigned int units = 1000000000; /* Ghz etc */ | 59 | unsigned int units = 1000000; /* MHz etc */ |
60 | unsigned int genuine_intel; | 60 | unsigned int genuine_intel; |
61 | unsigned int has_invariant_tsc; | 61 | unsigned int has_invariant_tsc; |
62 | unsigned int do_nehalem_platform_info; | 62 | unsigned int do_nehalem_platform_info; |
@@ -264,88 +264,93 @@ int get_msr(int cpu, off_t offset, unsigned long long *msr) | |||
264 | return 0; | 264 | return 0; |
265 | } | 265 | } |
266 | 266 | ||
267 | /* | ||
268 | * Example Format w/ field column widths: | ||
269 | * | ||
270 | * Package Core CPU Avg_MHz Bzy_MHz TSC_MHz SMI %Busy CPU_%c1 CPU_%c3 CPU_%c6 CPU_%c7 CoreTmp PkgTmp Pkg%pc2 Pkg%pc3 Pkg%pc6 Pkg%pc7 PkgWatt CorWatt GFXWatt | ||
271 | * 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 | ||
272 | */ | ||
273 | |||
267 | void print_header(void) | 274 | void print_header(void) |
268 | { | 275 | { |
269 | if (show_pkg) | 276 | if (show_pkg) |
270 | outp += sprintf(outp, "pk"); | 277 | outp += sprintf(outp, "Package "); |
271 | if (show_pkg) | ||
272 | outp += sprintf(outp, " "); | ||
273 | if (show_core) | 278 | if (show_core) |
274 | outp += sprintf(outp, "cor"); | 279 | outp += sprintf(outp, " Core "); |
275 | if (show_cpu) | 280 | if (show_cpu) |
276 | outp += sprintf(outp, " CPU"); | 281 | outp += sprintf(outp, " CPU "); |
277 | if (show_pkg || show_core || show_cpu) | 282 | if (has_aperf) |
278 | outp += sprintf(outp, " "); | 283 | outp += sprintf(outp, "Avg_MHz "); |
279 | if (do_nhm_cstates) | 284 | if (do_nhm_cstates) |
280 | outp += sprintf(outp, " %%c0"); | 285 | outp += sprintf(outp, " %%Busy "); |
281 | if (has_aperf) | 286 | if (has_aperf) |
282 | outp += sprintf(outp, " GHz"); | 287 | outp += sprintf(outp, "Bzy_MHz "); |
283 | outp += sprintf(outp, " TSC"); | 288 | outp += sprintf(outp, "TSC_MHz "); |
284 | if (do_smi) | 289 | if (do_smi) |
285 | outp += sprintf(outp, " SMI"); | 290 | outp += sprintf(outp, " SMI "); |
286 | if (extra_delta_offset32) | 291 | if (extra_delta_offset32) |
287 | outp += sprintf(outp, " count 0x%03X", extra_delta_offset32); | 292 | outp += sprintf(outp, " count 0x%03X ", extra_delta_offset32); |
288 | if (extra_delta_offset64) | 293 | if (extra_delta_offset64) |
289 | outp += sprintf(outp, " COUNT 0x%03X", extra_delta_offset64); | 294 | outp += sprintf(outp, " COUNT 0x%03X ", extra_delta_offset64); |
290 | if (extra_msr_offset32) | 295 | if (extra_msr_offset32) |
291 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset32); | 296 | outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset32); |
292 | if (extra_msr_offset64) | 297 | if (extra_msr_offset64) |
293 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); | 298 | outp += sprintf(outp, " MSR 0x%03X ", extra_msr_offset64); |
294 | if (do_nhm_cstates) | 299 | if (do_nhm_cstates) |
295 | outp += sprintf(outp, " %%c1"); | 300 | outp += sprintf(outp, " CPU%%c1 "); |
296 | if (do_nhm_cstates && !do_slm_cstates) | 301 | if (do_nhm_cstates && !do_slm_cstates) |
297 | outp += sprintf(outp, " %%c3"); | 302 | outp += sprintf(outp, " CPU%%c3 "); |
298 | if (do_nhm_cstates) | 303 | if (do_nhm_cstates) |
299 | outp += sprintf(outp, " %%c6"); | 304 | outp += sprintf(outp, " CPU%%c6 "); |
300 | if (do_snb_cstates) | 305 | if (do_snb_cstates) |
301 | outp += sprintf(outp, " %%c7"); | 306 | outp += sprintf(outp, " CPU%%c7 "); |
302 | 307 | ||
303 | if (do_dts) | 308 | if (do_dts) |
304 | outp += sprintf(outp, " CTMP"); | 309 | outp += sprintf(outp, "CoreTmp "); |
305 | if (do_ptm) | 310 | if (do_ptm) |
306 | outp += sprintf(outp, " PTMP"); | 311 | outp += sprintf(outp, " PkgTmp "); |
307 | 312 | ||
308 | if (do_snb_cstates) | 313 | if (do_snb_cstates) |
309 | outp += sprintf(outp, " %%pc2"); | 314 | outp += sprintf(outp, "Pkg%%pc2 "); |
310 | if (do_nhm_cstates && !do_slm_cstates) | 315 | if (do_nhm_cstates && !do_slm_cstates) |
311 | outp += sprintf(outp, " %%pc3"); | 316 | outp += sprintf(outp, "Pkg%%pc3 "); |
312 | if (do_nhm_cstates && !do_slm_cstates) | 317 | if (do_nhm_cstates && !do_slm_cstates) |
313 | outp += sprintf(outp, " %%pc6"); | 318 | outp += sprintf(outp, "Pkg%%pc6 "); |
314 | if (do_snb_cstates) | 319 | if (do_snb_cstates) |
315 | outp += sprintf(outp, " %%pc7"); | 320 | outp += sprintf(outp, "Pkg%%pc7 "); |
316 | if (do_c8_c9_c10) { | 321 | if (do_c8_c9_c10) { |
317 | outp += sprintf(outp, " %%pc8"); | 322 | outp += sprintf(outp, "Pkg%%pc8 "); |
318 | outp += sprintf(outp, " %%pc9"); | 323 | outp += sprintf(outp, "Pkg%%pc9 "); |
319 | outp += sprintf(outp, " %%pc10"); | 324 | outp += sprintf(outp, "Pk%%pc10 "); |
320 | } | 325 | } |
321 | 326 | ||
322 | if (do_rapl && !rapl_joules) { | 327 | if (do_rapl && !rapl_joules) { |
323 | if (do_rapl & RAPL_PKG) | 328 | if (do_rapl & RAPL_PKG) |
324 | outp += sprintf(outp, " Pkg_W"); | 329 | outp += sprintf(outp, "PkgWatt "); |
325 | if (do_rapl & RAPL_CORES) | 330 | if (do_rapl & RAPL_CORES) |
326 | outp += sprintf(outp, " Cor_W"); | 331 | outp += sprintf(outp, "CorWatt "); |
327 | if (do_rapl & RAPL_GFX) | 332 | if (do_rapl & RAPL_GFX) |
328 | outp += sprintf(outp, " GFX_W"); | 333 | outp += sprintf(outp, "GFXWatt "); |
329 | if (do_rapl & RAPL_DRAM) | 334 | if (do_rapl & RAPL_DRAM) |
330 | outp += sprintf(outp, " RAM_W"); | 335 | outp += sprintf(outp, "RAMWatt "); |
331 | if (do_rapl & RAPL_PKG_PERF_STATUS) | 336 | if (do_rapl & RAPL_PKG_PERF_STATUS) |
332 | outp += sprintf(outp, " PKG_%%"); | 337 | outp += sprintf(outp, " PKG_%% "); |
333 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 338 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
334 | outp += sprintf(outp, " RAM_%%"); | 339 | outp += sprintf(outp, " RAM_%% "); |
335 | } else { | 340 | } else { |
336 | if (do_rapl & RAPL_PKG) | 341 | if (do_rapl & RAPL_PKG) |
337 | outp += sprintf(outp, " Pkg_J"); | 342 | outp += sprintf(outp, " Pkg_J "); |
338 | if (do_rapl & RAPL_CORES) | 343 | if (do_rapl & RAPL_CORES) |
339 | outp += sprintf(outp, " Cor_J"); | 344 | outp += sprintf(outp, " Cor_J "); |
340 | if (do_rapl & RAPL_GFX) | 345 | if (do_rapl & RAPL_GFX) |
341 | outp += sprintf(outp, " GFX_J"); | 346 | outp += sprintf(outp, " GFX_J "); |
342 | if (do_rapl & RAPL_DRAM) | 347 | if (do_rapl & RAPL_DRAM) |
343 | outp += sprintf(outp, " RAM_W"); | 348 | outp += sprintf(outp, " RAM_W "); |
344 | if (do_rapl & RAPL_PKG_PERF_STATUS) | 349 | if (do_rapl & RAPL_PKG_PERF_STATUS) |
345 | outp += sprintf(outp, " PKG_%%"); | 350 | outp += sprintf(outp, " PKG_%% "); |
346 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 351 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
347 | outp += sprintf(outp, " RAM_%%"); | 352 | outp += sprintf(outp, " RAM_%% "); |
348 | outp += sprintf(outp, " time"); | 353 | outp += sprintf(outp, " time "); |
349 | 354 | ||
350 | } | 355 | } |
351 | outp += sprintf(outp, "\n"); | 356 | outp += sprintf(outp, "\n"); |
@@ -410,25 +415,12 @@ int dump_counters(struct thread_data *t, struct core_data *c, | |||
410 | 415 | ||
411 | /* | 416 | /* |
412 | * column formatting convention & formats | 417 | * column formatting convention & formats |
413 | * package: "pk" 2 columns %2d | ||
414 | * core: "cor" 3 columns %3d | ||
415 | * CPU: "CPU" 3 columns %3d | ||
416 | * Pkg_W: %6.2 | ||
417 | * Cor_W: %6.2 | ||
418 | * GFX_W: %5.2 | ||
419 | * RAM_W: %5.2 | ||
420 | * GHz: "GHz" 3 columns %3.2 | ||
421 | * TSC: "TSC" 3 columns %3.2 | ||
422 | * SMI: "SMI" 4 columns %4d | ||
423 | * percentage " %pc3" %6.2 | ||
424 | * Perf Status percentage: %5.2 | ||
425 | * "CTMP" 4 columns %4d | ||
426 | */ | 418 | */ |
427 | int format_counters(struct thread_data *t, struct core_data *c, | 419 | int format_counters(struct thread_data *t, struct core_data *c, |
428 | struct pkg_data *p) | 420 | struct pkg_data *p) |
429 | { | 421 | { |
430 | double interval_float; | 422 | double interval_float; |
431 | char *fmt5, *fmt6; | 423 | char *fmt8; |
432 | 424 | ||
433 | /* if showing only 1st thread in core and this isn't one, bail out */ | 425 | /* if showing only 1st thread in core and this isn't one, bail out */ |
434 | if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) | 426 | if (show_core_only && !(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) |
@@ -443,65 +435,52 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
443 | /* topo columns, print blanks on 1st (average) line */ | 435 | /* topo columns, print blanks on 1st (average) line */ |
444 | if (t == &average.threads) { | 436 | if (t == &average.threads) { |
445 | if (show_pkg) | 437 | if (show_pkg) |
446 | outp += sprintf(outp, " "); | 438 | outp += sprintf(outp, " -"); |
447 | if (show_pkg && show_core) | ||
448 | outp += sprintf(outp, " "); | ||
449 | if (show_core) | 439 | if (show_core) |
450 | outp += sprintf(outp, " "); | 440 | outp += sprintf(outp, " -"); |
451 | if (show_cpu) | 441 | if (show_cpu) |
452 | outp += sprintf(outp, " " " "); | 442 | outp += sprintf(outp, " -"); |
453 | } else { | 443 | } else { |
454 | if (show_pkg) { | 444 | if (show_pkg) { |
455 | if (p) | 445 | if (p) |
456 | outp += sprintf(outp, "%2d", p->package_id); | 446 | outp += sprintf(outp, "%8d", p->package_id); |
457 | else | 447 | else |
458 | outp += sprintf(outp, " "); | 448 | outp += sprintf(outp, " -"); |
459 | } | 449 | } |
460 | if (show_pkg && show_core) | ||
461 | outp += sprintf(outp, " "); | ||
462 | if (show_core) { | 450 | if (show_core) { |
463 | if (c) | 451 | if (c) |
464 | outp += sprintf(outp, "%3d", c->core_id); | 452 | outp += sprintf(outp, "%8d", c->core_id); |
465 | else | 453 | else |
466 | outp += sprintf(outp, " "); | 454 | outp += sprintf(outp, " -"); |
467 | } | 455 | } |
468 | if (show_cpu) | 456 | if (show_cpu) |
469 | outp += sprintf(outp, " %3d", t->cpu_id); | 457 | outp += sprintf(outp, "%8d", t->cpu_id); |
470 | } | 458 | } |
459 | |||
460 | /* AvgMHz */ | ||
461 | if (has_aperf) | ||
462 | outp += sprintf(outp, "%8.0f", | ||
463 | 1.0 / units * t->aperf / interval_float); | ||
464 | |||
471 | /* %c0 */ | 465 | /* %c0 */ |
472 | if (do_nhm_cstates) { | 466 | if (do_nhm_cstates) { |
473 | if (show_pkg || show_core || show_cpu) | ||
474 | outp += sprintf(outp, " "); | ||
475 | if (!skip_c0) | 467 | if (!skip_c0) |
476 | outp += sprintf(outp, "%6.2f", 100.0 * t->mperf/t->tsc); | 468 | outp += sprintf(outp, "%8.2f", 100.0 * t->mperf/t->tsc); |
477 | else | 469 | else |
478 | outp += sprintf(outp, " ****"); | 470 | outp += sprintf(outp, "********"); |
479 | } | 471 | } |
480 | 472 | ||
481 | /* GHz */ | 473 | /* BzyMHz */ |
482 | if (has_aperf) { | 474 | if (has_aperf) |
483 | if (!aperf_mperf_unstable) { | 475 | outp += sprintf(outp, "%8.0f", |
484 | outp += sprintf(outp, " %3.2f", | 476 | 1.0 * t->tsc / units * t->aperf / t->mperf / interval_float); |
485 | 1.0 * t->tsc / units * t->aperf / | ||
486 | t->mperf / interval_float); | ||
487 | } else { | ||
488 | if (t->aperf > t->tsc || t->mperf > t->tsc) { | ||
489 | outp += sprintf(outp, " ***"); | ||
490 | } else { | ||
491 | outp += sprintf(outp, "%3.1f*", | ||
492 | 1.0 * t->tsc / | ||
493 | units * t->aperf / | ||
494 | t->mperf / interval_float); | ||
495 | } | ||
496 | } | ||
497 | } | ||
498 | 477 | ||
499 | /* TSC */ | 478 | /* TSC */ |
500 | outp += sprintf(outp, "%5.2f", 1.0 * t->tsc/units/interval_float); | 479 | outp += sprintf(outp, "%8.0f", 1.0 * t->tsc/units/interval_float); |
501 | 480 | ||
502 | /* SMI */ | 481 | /* SMI */ |
503 | if (do_smi) | 482 | if (do_smi) |
504 | outp += sprintf(outp, "%4d", t->smi_count); | 483 | outp += sprintf(outp, "%8d", t->smi_count); |
505 | 484 | ||
506 | /* delta */ | 485 | /* delta */ |
507 | if (extra_delta_offset32) | 486 | if (extra_delta_offset32) |
@@ -520,9 +499,9 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
520 | 499 | ||
521 | if (do_nhm_cstates) { | 500 | if (do_nhm_cstates) { |
522 | if (!skip_c1) | 501 | if (!skip_c1) |
523 | outp += sprintf(outp, " %6.2f", 100.0 * t->c1/t->tsc); | 502 | outp += sprintf(outp, "%8.2f", 100.0 * t->c1/t->tsc); |
524 | else | 503 | else |
525 | outp += sprintf(outp, " ****"); | 504 | outp += sprintf(outp, "********"); |
526 | } | 505 | } |
527 | 506 | ||
528 | /* print per-core data only for 1st thread in core */ | 507 | /* print per-core data only for 1st thread in core */ |
@@ -530,79 +509,76 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
530 | goto done; | 509 | goto done; |
531 | 510 | ||
532 | if (do_nhm_cstates && !do_slm_cstates) | 511 | if (do_nhm_cstates && !do_slm_cstates) |
533 | outp += sprintf(outp, " %6.2f", 100.0 * c->c3/t->tsc); | 512 | outp += sprintf(outp, "%8.2f", 100.0 * c->c3/t->tsc); |
534 | if (do_nhm_cstates) | 513 | if (do_nhm_cstates) |
535 | outp += sprintf(outp, " %6.2f", 100.0 * c->c6/t->tsc); | 514 | outp += sprintf(outp, "%8.2f", 100.0 * c->c6/t->tsc); |
536 | if (do_snb_cstates) | 515 | if (do_snb_cstates) |
537 | outp += sprintf(outp, " %6.2f", 100.0 * c->c7/t->tsc); | 516 | outp += sprintf(outp, "%8.2f", 100.0 * c->c7/t->tsc); |
538 | 517 | ||
539 | if (do_dts) | 518 | if (do_dts) |
540 | outp += sprintf(outp, " %4d", c->core_temp_c); | 519 | outp += sprintf(outp, "%8d", c->core_temp_c); |
541 | 520 | ||
542 | /* print per-package data only for 1st core in package */ | 521 | /* print per-package data only for 1st core in package */ |
543 | if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) | 522 | if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) |
544 | goto done; | 523 | goto done; |
545 | 524 | ||
546 | if (do_ptm) | 525 | if (do_ptm) |
547 | outp += sprintf(outp, " %4d", p->pkg_temp_c); | 526 | outp += sprintf(outp, "%8d", p->pkg_temp_c); |
548 | 527 | ||
549 | if (do_snb_cstates) | 528 | if (do_snb_cstates) |
550 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc); | 529 | outp += sprintf(outp, "%8.2f", 100.0 * p->pc2/t->tsc); |
551 | if (do_nhm_cstates && !do_slm_cstates) | 530 | if (do_nhm_cstates && !do_slm_cstates) |
552 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc3/t->tsc); | 531 | outp += sprintf(outp, "%8.2f", 100.0 * p->pc3/t->tsc); |
553 | if (do_nhm_cstates && !do_slm_cstates) | 532 | if (do_nhm_cstates && !do_slm_cstates) |
554 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc); | 533 | outp += sprintf(outp, "%8.2f", 100.0 * p->pc6/t->tsc); |
555 | if (do_snb_cstates) | 534 | if (do_snb_cstates) |
556 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); | 535 | outp += sprintf(outp, "%8.2f", 100.0 * p->pc7/t->tsc); |
557 | if (do_c8_c9_c10) { | 536 | if (do_c8_c9_c10) { |
558 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc8/t->tsc); | 537 | outp += sprintf(outp, "%8.2f", 100.0 * p->pc8/t->tsc); |
559 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc9/t->tsc); | 538 | outp += sprintf(outp, "%8.2f", 100.0 * p->pc9/t->tsc); |
560 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc10/t->tsc); | 539 | outp += sprintf(outp, "%8.2f", 100.0 * p->pc10/t->tsc); |
561 | } | 540 | } |
562 | 541 | ||
563 | /* | 542 | /* |
564 | * If measurement interval exceeds minimum RAPL Joule Counter range, | 543 | * If measurement interval exceeds minimum RAPL Joule Counter range, |
565 | * indicate that results are suspect by printing "**" in fraction place. | 544 | * indicate that results are suspect by printing "**" in fraction place. |
566 | */ | 545 | */ |
567 | if (interval_float < rapl_joule_counter_range) { | 546 | if (interval_float < rapl_joule_counter_range) |
568 | fmt5 = " %5.2f"; | 547 | fmt8 = "%8.2f"; |
569 | fmt6 = " %6.2f"; | 548 | else |
570 | } else { | 549 | fmt8 = " %6.0f**"; |
571 | fmt5 = " %3.0f**"; | ||
572 | fmt6 = " %4.0f**"; | ||
573 | } | ||
574 | 550 | ||
575 | if (do_rapl && !rapl_joules) { | 551 | if (do_rapl && !rapl_joules) { |
576 | if (do_rapl & RAPL_PKG) | 552 | if (do_rapl & RAPL_PKG) |
577 | outp += sprintf(outp, fmt6, p->energy_pkg * rapl_energy_units / interval_float); | 553 | outp += sprintf(outp, fmt8, p->energy_pkg * rapl_energy_units / interval_float); |
578 | if (do_rapl & RAPL_CORES) | 554 | if (do_rapl & RAPL_CORES) |
579 | outp += sprintf(outp, fmt6, p->energy_cores * rapl_energy_units / interval_float); | 555 | outp += sprintf(outp, fmt8, p->energy_cores * rapl_energy_units / interval_float); |
580 | if (do_rapl & RAPL_GFX) | 556 | if (do_rapl & RAPL_GFX) |
581 | outp += sprintf(outp, fmt5, p->energy_gfx * rapl_energy_units / interval_float); | 557 | outp += sprintf(outp, fmt8, p->energy_gfx * rapl_energy_units / interval_float); |
582 | if (do_rapl & RAPL_DRAM) | 558 | if (do_rapl & RAPL_DRAM) |
583 | outp += sprintf(outp, fmt5, p->energy_dram * rapl_energy_units / interval_float); | 559 | outp += sprintf(outp, fmt8, p->energy_dram * rapl_energy_units / interval_float); |
584 | if (do_rapl & RAPL_PKG_PERF_STATUS) | 560 | if (do_rapl & RAPL_PKG_PERF_STATUS) |
585 | outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); | 561 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); |
586 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 562 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
587 | outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); | 563 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); |
588 | } else { | 564 | } else { |
589 | if (do_rapl & RAPL_PKG) | 565 | if (do_rapl & RAPL_PKG) |
590 | outp += sprintf(outp, fmt6, | 566 | outp += sprintf(outp, fmt8, |
591 | p->energy_pkg * rapl_energy_units); | 567 | p->energy_pkg * rapl_energy_units); |
592 | if (do_rapl & RAPL_CORES) | 568 | if (do_rapl & RAPL_CORES) |
593 | outp += sprintf(outp, fmt6, | 569 | outp += sprintf(outp, fmt8, |
594 | p->energy_cores * rapl_energy_units); | 570 | p->energy_cores * rapl_energy_units); |
595 | if (do_rapl & RAPL_GFX) | 571 | if (do_rapl & RAPL_GFX) |
596 | outp += sprintf(outp, fmt5, | 572 | outp += sprintf(outp, fmt8, |
597 | p->energy_gfx * rapl_energy_units); | 573 | p->energy_gfx * rapl_energy_units); |
598 | if (do_rapl & RAPL_DRAM) | 574 | if (do_rapl & RAPL_DRAM) |
599 | outp += sprintf(outp, fmt5, | 575 | outp += sprintf(outp, fmt8, |
600 | p->energy_dram * rapl_energy_units); | 576 | p->energy_dram * rapl_energy_units); |
601 | if (do_rapl & RAPL_PKG_PERF_STATUS) | 577 | if (do_rapl & RAPL_PKG_PERF_STATUS) |
602 | outp += sprintf(outp, fmt5, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); | 578 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_pkg_perf_status * rapl_time_units / interval_float); |
603 | if (do_rapl & RAPL_DRAM_PERF_STATUS) | 579 | if (do_rapl & RAPL_DRAM_PERF_STATUS) |
604 | outp += sprintf(outp, fmt5, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); | 580 | outp += sprintf(outp, fmt8, 100.0 * p->rapl_dram_perf_status * rapl_time_units / interval_float); |
605 | outp += sprintf(outp, fmt5, interval_float); | 581 | outp += sprintf(outp, fmt8, interval_float); |
606 | 582 | ||
607 | } | 583 | } |
608 | done: | 584 | done: |
@@ -1516,6 +1492,9 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) | |||
1516 | case 0x46: /* HSW */ | 1492 | case 0x46: /* HSW */ |
1517 | case 0x37: /* BYT */ | 1493 | case 0x37: /* BYT */ |
1518 | case 0x4D: /* AVN */ | 1494 | case 0x4D: /* AVN */ |
1495 | case 0x3D: /* BDW */ | ||
1496 | case 0x4F: /* BDX */ | ||
1497 | case 0x56: /* BDX-DE */ | ||
1519 | return 1; | 1498 | return 1; |
1520 | case 0x2E: /* Nehalem-EX Xeon - Beckton */ | 1499 | case 0x2E: /* Nehalem-EX Xeon - Beckton */ |
1521 | case 0x2F: /* Westmere-EX Xeon - Eagleton */ | 1500 | case 0x2F: /* Westmere-EX Xeon - Eagleton */ |
@@ -1629,9 +1608,12 @@ void rapl_probe(unsigned int family, unsigned int model) | |||
1629 | case 0x3C: /* HSW */ | 1608 | case 0x3C: /* HSW */ |
1630 | case 0x45: /* HSW */ | 1609 | case 0x45: /* HSW */ |
1631 | case 0x46: /* HSW */ | 1610 | case 0x46: /* HSW */ |
1611 | case 0x3D: /* BDW */ | ||
1632 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; | 1612 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; |
1633 | break; | 1613 | break; |
1634 | case 0x3F: /* HSX */ | 1614 | case 0x3F: /* HSX */ |
1615 | case 0x4F: /* BDX */ | ||
1616 | case 0x56: /* BDX-DE */ | ||
1635 | do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; | 1617 | do_rapl = RAPL_PKG | RAPL_DRAM | RAPL_DRAM_PERF_STATUS | RAPL_PKG_PERF_STATUS | RAPL_PKG_POWER_INFO; |
1636 | break; | 1618 | break; |
1637 | case 0x2D: | 1619 | case 0x2D: |
@@ -1875,6 +1857,9 @@ int is_snb(unsigned int family, unsigned int model) | |||
1875 | case 0x3F: /* HSW */ | 1857 | case 0x3F: /* HSW */ |
1876 | case 0x45: /* HSW */ | 1858 | case 0x45: /* HSW */ |
1877 | case 0x46: /* HSW */ | 1859 | case 0x46: /* HSW */ |
1860 | case 0x3D: /* BDW */ | ||
1861 | case 0x4F: /* BDX */ | ||
1862 | case 0x56: /* BDX-DE */ | ||
1878 | return 1; | 1863 | return 1; |
1879 | } | 1864 | } |
1880 | return 0; | 1865 | return 0; |
@@ -1886,7 +1871,8 @@ int has_c8_c9_c10(unsigned int family, unsigned int model) | |||
1886 | return 0; | 1871 | return 0; |
1887 | 1872 | ||
1888 | switch (model) { | 1873 | switch (model) { |
1889 | case 0x45: | 1874 | case 0x45: /* HSW */ |
1875 | case 0x3D: /* BDW */ | ||
1890 | return 1; | 1876 | return 1; |
1891 | } | 1877 | } |
1892 | return 0; | 1878 | return 0; |
@@ -2455,7 +2441,7 @@ int main(int argc, char **argv) | |||
2455 | cmdline(argc, argv); | 2441 | cmdline(argc, argv); |
2456 | 2442 | ||
2457 | if (verbose) | 2443 | if (verbose) |
2458 | fprintf(stderr, "turbostat v3.6 Dec 2, 2013" | 2444 | fprintf(stderr, "turbostat v3.7 Feb 6, 2014" |
2459 | " - Len Brown <lenb@kernel.org>\n"); | 2445 | " - Len Brown <lenb@kernel.org>\n"); |
2460 | 2446 | ||
2461 | turbostat_init(); | 2447 | turbostat_init(); |
diff --git a/tools/testing/ktest/examples/kvm.conf b/tools/testing/ktest/examples/kvm.conf index 831c7c5395f1..fbc134f9ac6e 100644 --- a/tools/testing/ktest/examples/kvm.conf +++ b/tools/testing/ktest/examples/kvm.conf | |||
@@ -10,6 +10,10 @@ MACHINE = Guest | |||
10 | # Use virsh to read the serial console of the guest | 10 | # Use virsh to read the serial console of the guest |
11 | CONSOLE = virsh console ${MACHINE} | 11 | CONSOLE = virsh console ${MACHINE} |
12 | 12 | ||
13 | # Use SIGKILL to terminate virsh console. We can't kill virsh console | ||
14 | # by the default signal, SIGINT. | ||
15 | CLOSE_CONSOLE_SIGNAL = KILL | ||
16 | |||
13 | #*************************************# | 17 | #*************************************# |
14 | # This part is the same as test.conf # | 18 | # This part is the same as test.conf # |
15 | #*************************************# | 19 | #*************************************# |
diff --git a/tools/testing/selftests/powerpc/Makefile b/tools/testing/selftests/powerpc/Makefile index bd24ae5aaeab..316194f26ff4 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 | |||
13 | 13 | ||
14 | export CC CFLAGS | 14 | export CC CFLAGS |
15 | 15 | ||
16 | TARGETS = pmu | 16 | TARGETS = pmu copyloops |
17 | 17 | ||
18 | endif | 18 | endif |
19 | 19 | ||
diff --git a/tools/testing/selftests/powerpc/copyloops/Makefile b/tools/testing/selftests/powerpc/copyloops/Makefile new file mode 100644 index 000000000000..6f2d3be227f9 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/Makefile | |||
@@ -0,0 +1,29 @@ | |||
1 | # The loops are all 64-bit code | ||
2 | CFLAGS += -m64 | ||
3 | CFLAGS += -I$(CURDIR) | ||
4 | CFLAGS += -D SELFTEST | ||
5 | |||
6 | # Use our CFLAGS for the implicit .S rule | ||
7 | ASFLAGS = $(CFLAGS) | ||
8 | |||
9 | PROGS := copyuser_64 copyuser_power7 memcpy_64 memcpy_power7 | ||
10 | EXTRA_SOURCES := validate.c ../harness.c | ||
11 | |||
12 | all: $(PROGS) | ||
13 | |||
14 | copyuser_64: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_base | ||
15 | copyuser_power7: CPPFLAGS += -D COPY_LOOP=test___copy_tofrom_user_power7 | ||
16 | memcpy_64: CPPFLAGS += -D COPY_LOOP=test_memcpy | ||
17 | memcpy_power7: CPPFLAGS += -D COPY_LOOP=test_memcpy_power7 | ||
18 | |||
19 | $(PROGS): $(EXTRA_SOURCES) | ||
20 | |||
21 | run_tests: all | ||
22 | @-for PROG in $(PROGS); do \ | ||
23 | ./$$PROG; \ | ||
24 | done; | ||
25 | |||
26 | clean: | ||
27 | rm -f $(PROGS) *.o | ||
28 | |||
29 | .PHONY: all run_tests clean | ||
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h new file mode 100644 index 000000000000..ccd9c84c4e3f --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/asm/ppc_asm.h | |||
@@ -0,0 +1,86 @@ | |||
1 | #include <ppc-asm.h> | ||
2 | |||
3 | #define CONFIG_ALTIVEC | ||
4 | |||
5 | #define r1 1 | ||
6 | |||
7 | #define vr0 0 | ||
8 | #define vr1 1 | ||
9 | #define vr2 2 | ||
10 | #define vr3 3 | ||
11 | #define vr4 4 | ||
12 | #define vr5 5 | ||
13 | #define vr6 6 | ||
14 | #define vr7 7 | ||
15 | #define vr8 8 | ||
16 | #define vr9 9 | ||
17 | #define vr10 10 | ||
18 | #define vr11 11 | ||
19 | #define vr12 12 | ||
20 | #define vr13 13 | ||
21 | #define vr14 14 | ||
22 | #define vr15 15 | ||
23 | #define vr16 16 | ||
24 | #define vr17 17 | ||
25 | #define vr18 18 | ||
26 | #define vr19 19 | ||
27 | #define vr20 20 | ||
28 | #define vr21 21 | ||
29 | #define vr22 22 | ||
30 | #define vr23 23 | ||
31 | #define vr24 24 | ||
32 | #define vr25 25 | ||
33 | #define vr26 26 | ||
34 | #define vr27 27 | ||
35 | #define vr28 28 | ||
36 | #define vr29 29 | ||
37 | #define vr30 30 | ||
38 | #define vr31 31 | ||
39 | |||
40 | #define R14 r14 | ||
41 | #define R15 r15 | ||
42 | #define R16 r16 | ||
43 | #define R17 r17 | ||
44 | #define R18 r18 | ||
45 | #define R19 r19 | ||
46 | #define R20 r20 | ||
47 | #define R21 r21 | ||
48 | #define R22 r22 | ||
49 | |||
50 | #define STACKFRAMESIZE 256 | ||
51 | #define STK_PARAM(i) (48 + ((i)-3)*8) | ||
52 | #define STK_REG(i) (112 + ((i)-14)*8) | ||
53 | |||
54 | #define _GLOBAL(A) FUNC_START(test_ ## A) | ||
55 | |||
56 | #define PPC_MTOCRF(A, B) mtocrf A, B | ||
57 | |||
58 | FUNC_START(enter_vmx_usercopy) | ||
59 | li r3,1 | ||
60 | blr | ||
61 | |||
62 | FUNC_START(exit_vmx_usercopy) | ||
63 | li r3,0 | ||
64 | blr | ||
65 | |||
66 | FUNC_START(enter_vmx_copy) | ||
67 | li r3,1 | ||
68 | blr | ||
69 | |||
70 | FUNC_START(exit_vmx_copy) | ||
71 | blr | ||
72 | |||
73 | FUNC_START(memcpy_power7) | ||
74 | blr | ||
75 | |||
76 | FUNC_START(__copy_tofrom_user_power7) | ||
77 | blr | ||
78 | |||
79 | FUNC_START(__copy_tofrom_user_base) | ||
80 | blr | ||
81 | |||
82 | #define BEGIN_FTR_SECTION | ||
83 | #define FTR_SECTION_ELSE | ||
84 | #define ALT_FTR_SECTION_END_IFCLR(x) | ||
85 | #define ALT_FTR_SECTION_END(x, y) | ||
86 | #define END_FTR_SECTION_IFCLR(x) | ||
diff --git a/tools/testing/selftests/powerpc/copyloops/asm/processor.h b/tools/testing/selftests/powerpc/copyloops/asm/processor.h new file mode 100644 index 000000000000..e69de29bb2d1 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/asm/processor.h | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/copyuser_64.S b/tools/testing/selftests/powerpc/copyloops/copyuser_64.S new file mode 120000 index 000000000000..f1c418a2521a --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/copyuser_64.S | |||
@@ -0,0 +1 @@ | |||
../../../../../arch/powerpc/lib/copyuser_64.S \ No newline at end of file | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S b/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S new file mode 120000 index 000000000000..478689598298 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/copyuser_power7.S | |||
@@ -0,0 +1 @@ | |||
../../../../../arch/powerpc/lib/copyuser_power7.S \ No newline at end of file | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/memcpy_64.S b/tools/testing/selftests/powerpc/copyloops/memcpy_64.S new file mode 120000 index 000000000000..cce33fb6f9d8 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/memcpy_64.S | |||
@@ -0,0 +1 @@ | |||
../../../../../arch/powerpc/lib/memcpy_64.S \ No newline at end of file | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S b/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S new file mode 120000 index 000000000000..0d6fbfaf3d59 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/memcpy_power7.S | |||
@@ -0,0 +1 @@ | |||
../../../../../arch/powerpc/lib/memcpy_power7.S \ No newline at end of file | |||
diff --git a/tools/testing/selftests/powerpc/copyloops/validate.c b/tools/testing/selftests/powerpc/copyloops/validate.c new file mode 100644 index 000000000000..1750ff57ee58 --- /dev/null +++ b/tools/testing/selftests/powerpc/copyloops/validate.c | |||
@@ -0,0 +1,99 @@ | |||
1 | #include <malloc.h> | ||
2 | #include <string.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <stdbool.h> | ||
5 | |||
6 | #include "../utils.h" | ||
7 | |||
8 | #define MAX_LEN 8192 | ||
9 | #define MAX_OFFSET 16 | ||
10 | #define MIN_REDZONE 128 | ||
11 | #define BUFLEN (MAX_LEN+MAX_OFFSET+2*MIN_REDZONE) | ||
12 | #define POISON 0xa5 | ||
13 | |||
14 | unsigned long COPY_LOOP(void *to, const void *from, unsigned long size); | ||
15 | |||
16 | static void do_one(char *src, char *dst, unsigned long src_off, | ||
17 | unsigned long dst_off, unsigned long len, void *redzone, | ||
18 | void *fill) | ||
19 | { | ||
20 | char *srcp, *dstp; | ||
21 | unsigned long ret; | ||
22 | unsigned long i; | ||
23 | |||
24 | srcp = src + MIN_REDZONE + src_off; | ||
25 | dstp = dst + MIN_REDZONE + dst_off; | ||
26 | |||
27 | memset(src, POISON, BUFLEN); | ||
28 | memset(dst, POISON, BUFLEN); | ||
29 | memcpy(srcp, fill, len); | ||
30 | |||
31 | ret = COPY_LOOP(dstp, srcp, len); | ||
32 | if (ret && ret != (unsigned long)dstp) { | ||
33 | printf("(%p,%p,%ld) returned %ld\n", dstp, srcp, len, ret); | ||
34 | abort(); | ||
35 | } | ||
36 | |||
37 | if (memcmp(dstp, srcp, len)) { | ||
38 | printf("(%p,%p,%ld) miscompare\n", dstp, srcp, len); | ||
39 | printf("src: "); | ||
40 | for (i = 0; i < len; i++) | ||
41 | printf("%02x ", srcp[i]); | ||
42 | printf("\ndst: "); | ||
43 | for (i = 0; i < len; i++) | ||
44 | printf("%02x ", dstp[i]); | ||
45 | printf("\n"); | ||
46 | abort(); | ||
47 | } | ||
48 | |||
49 | if (memcmp(dst, redzone, dstp - dst)) { | ||
50 | printf("(%p,%p,%ld) redzone before corrupted\n", | ||
51 | dstp, srcp, len); | ||
52 | abort(); | ||
53 | } | ||
54 | |||
55 | if (memcmp(dstp+len, redzone, dst+BUFLEN-(dstp+len))) { | ||
56 | printf("(%p,%p,%ld) redzone after corrupted\n", | ||
57 | dstp, srcp, len); | ||
58 | abort(); | ||
59 | } | ||
60 | } | ||
61 | |||
62 | int test_copy_loop(void) | ||
63 | { | ||
64 | char *src, *dst, *redzone, *fill; | ||
65 | unsigned long len, src_off, dst_off; | ||
66 | unsigned long i; | ||
67 | |||
68 | src = memalign(BUFLEN, BUFLEN); | ||
69 | dst = memalign(BUFLEN, BUFLEN); | ||
70 | redzone = malloc(BUFLEN); | ||
71 | fill = malloc(BUFLEN); | ||
72 | |||
73 | if (!src || !dst || !redzone || !fill) { | ||
74 | fprintf(stderr, "malloc failed\n"); | ||
75 | exit(1); | ||
76 | } | ||
77 | |||
78 | memset(redzone, POISON, BUFLEN); | ||
79 | |||
80 | /* Fill with sequential bytes */ | ||
81 | for (i = 0; i < BUFLEN; i++) | ||
82 | fill[i] = i & 0xff; | ||
83 | |||
84 | for (len = 1; len < MAX_LEN; len++) { | ||
85 | for (src_off = 0; src_off < MAX_OFFSET; src_off++) { | ||
86 | for (dst_off = 0; dst_off < MAX_OFFSET; dst_off++) { | ||
87 | do_one(src, dst, src_off, dst_off, len, | ||
88 | redzone, fill); | ||
89 | } | ||
90 | } | ||
91 | } | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | int main(void) | ||
97 | { | ||
98 | return test_harness(test_copy_loop, str(COPY_LOOP)); | ||
99 | } | ||
diff --git a/tools/testing/selftests/powerpc/utils.h b/tools/testing/selftests/powerpc/utils.h index 5851c4b0f553..0de064406dab 100644 --- a/tools/testing/selftests/powerpc/utils.h +++ b/tools/testing/selftests/powerpc/utils.h | |||
@@ -31,4 +31,7 @@ do { \ | |||
31 | } \ | 31 | } \ |
32 | } while (0) | 32 | } while (0) |
33 | 33 | ||
34 | #define _str(s) #s | ||
35 | #define str(s) _str(s) | ||
36 | |||
34 | #endif /* _SELFTESTS_POWERPC_UTILS_H */ | 37 | #endif /* _SELFTESTS_POWERPC_UTILS_H */ |
diff --git a/tools/virtio/linux/kmemleak.h b/tools/virtio/linux/kmemleak.h new file mode 100644 index 000000000000..c07072270e2f --- /dev/null +++ b/tools/virtio/linux/kmemleak.h | |||
@@ -0,0 +1,3 @@ | |||
1 | static inline void kmemleak_ignore(const void *ptr) | ||
2 | { | ||
3 | } | ||
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h index 844783040703..5a2d1f0f6bc7 100644 --- a/tools/virtio/linux/virtio.h +++ b/tools/virtio/linux/virtio.h | |||
@@ -63,7 +63,7 @@ int virtqueue_add_inbuf(struct virtqueue *vq, | |||
63 | void *data, | 63 | void *data, |
64 | gfp_t gfp); | 64 | gfp_t gfp); |
65 | 65 | ||
66 | void virtqueue_kick(struct virtqueue *vq); | 66 | bool virtqueue_kick(struct virtqueue *vq); |
67 | 67 | ||
68 | void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len); | 68 | void *virtqueue_get_buf(struct virtqueue *vq, unsigned int *len); |
69 | 69 | ||
@@ -79,7 +79,7 @@ struct virtqueue *vring_new_virtqueue(unsigned int index, | |||
79 | struct virtio_device *vdev, | 79 | struct virtio_device *vdev, |
80 | bool weak_barriers, | 80 | bool weak_barriers, |
81 | void *pages, | 81 | void *pages, |
82 | void (*notify)(struct virtqueue *vq), | 82 | bool (*notify)(struct virtqueue *vq), |
83 | void (*callback)(struct virtqueue *vq), | 83 | void (*callback)(struct virtqueue *vq), |
84 | const char *name); | 84 | const char *name); |
85 | void vring_del_virtqueue(struct virtqueue *vq); | 85 | void vring_del_virtqueue(struct virtqueue *vq); |
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c index bdb71a26ae35..00ea679b3826 100644 --- a/tools/virtio/virtio_test.c +++ b/tools/virtio/virtio_test.c | |||
@@ -172,7 +172,7 @@ static void run_test(struct vdev_info *dev, struct vq_info *vq, | |||
172 | GFP_ATOMIC); | 172 | GFP_ATOMIC); |
173 | if (likely(r == 0)) { | 173 | if (likely(r == 0)) { |
174 | ++started; | 174 | ++started; |
175 | if (unlikely(!virtqueue_kick(vq->vq)) | 175 | if (unlikely(!virtqueue_kick(vq->vq))) |
176 | r = -1; | 176 | r = -1; |
177 | } | 177 | } |
178 | } else | 178 | } else |
diff --git a/tools/vm/page-types.c b/tools/vm/page-types.c index f9be24d9efac..05654f5e48d5 100644 --- a/tools/vm/page-types.c +++ b/tools/vm/page-types.c | |||
@@ -19,7 +19,8 @@ | |||
19 | * Authors: Wu Fengguang <fengguang.wu@intel.com> | 19 | * Authors: Wu Fengguang <fengguang.wu@intel.com> |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define _LARGEFILE64_SOURCE | 22 | #define _FILE_OFFSET_BITS 64 |
23 | #define _GNU_SOURCE | ||
23 | #include <stdio.h> | 24 | #include <stdio.h> |
24 | #include <stdlib.h> | 25 | #include <stdlib.h> |
25 | #include <unistd.h> | 26 | #include <unistd.h> |
@@ -29,11 +30,14 @@ | |||
29 | #include <getopt.h> | 30 | #include <getopt.h> |
30 | #include <limits.h> | 31 | #include <limits.h> |
31 | #include <assert.h> | 32 | #include <assert.h> |
33 | #include <ftw.h> | ||
34 | #include <time.h> | ||
32 | #include <sys/types.h> | 35 | #include <sys/types.h> |
33 | #include <sys/errno.h> | 36 | #include <sys/errno.h> |
34 | #include <sys/fcntl.h> | 37 | #include <sys/fcntl.h> |
35 | #include <sys/mount.h> | 38 | #include <sys/mount.h> |
36 | #include <sys/statfs.h> | 39 | #include <sys/statfs.h> |
40 | #include <sys/mman.h> | ||
37 | #include "../../include/uapi/linux/magic.h" | 41 | #include "../../include/uapi/linux/magic.h" |
38 | #include "../../include/uapi/linux/kernel-page-flags.h" | 42 | #include "../../include/uapi/linux/kernel-page-flags.h" |
39 | #include <api/fs/debugfs.h> | 43 | #include <api/fs/debugfs.h> |
@@ -158,6 +162,7 @@ static int opt_raw; /* for kernel developers */ | |||
158 | static int opt_list; /* list pages (in ranges) */ | 162 | static int opt_list; /* list pages (in ranges) */ |
159 | static int opt_no_summary; /* don't show summary */ | 163 | static int opt_no_summary; /* don't show summary */ |
160 | static pid_t opt_pid; /* process to walk */ | 164 | static pid_t opt_pid; /* process to walk */ |
165 | const char * opt_file; | ||
161 | 166 | ||
162 | #define MAX_ADDR_RANGES 1024 | 167 | #define MAX_ADDR_RANGES 1024 |
163 | static int nr_addr_ranges; | 168 | static int nr_addr_ranges; |
@@ -253,12 +258,7 @@ static unsigned long do_u64_read(int fd, char *name, | |||
253 | if (index > ULONG_MAX / 8) | 258 | if (index > ULONG_MAX / 8) |
254 | fatal("index overflow: %lu\n", index); | 259 | fatal("index overflow: %lu\n", index); |
255 | 260 | ||
256 | if (lseek(fd, index * 8, SEEK_SET) < 0) { | 261 | bytes = pread(fd, buf, count * 8, (off_t)index * 8); |
257 | perror(name); | ||
258 | exit(EXIT_FAILURE); | ||
259 | } | ||
260 | |||
261 | bytes = read(fd, buf, count * 8); | ||
262 | if (bytes < 0) { | 262 | if (bytes < 0) { |
263 | perror(name); | 263 | perror(name); |
264 | exit(EXIT_FAILURE); | 264 | exit(EXIT_FAILURE); |
@@ -343,8 +343,8 @@ static char *page_flag_longname(uint64_t flags) | |||
343 | * page list and summary | 343 | * page list and summary |
344 | */ | 344 | */ |
345 | 345 | ||
346 | static void show_page_range(unsigned long voffset, | 346 | static void show_page_range(unsigned long voffset, unsigned long offset, |
347 | unsigned long offset, uint64_t flags) | 347 | unsigned long size, uint64_t flags) |
348 | { | 348 | { |
349 | static uint64_t flags0; | 349 | static uint64_t flags0; |
350 | static unsigned long voff; | 350 | static unsigned long voff; |
@@ -352,14 +352,16 @@ static void show_page_range(unsigned long voffset, | |||
352 | static unsigned long count; | 352 | static unsigned long count; |
353 | 353 | ||
354 | if (flags == flags0 && offset == index + count && | 354 | if (flags == flags0 && offset == index + count && |
355 | (!opt_pid || voffset == voff + count)) { | 355 | size && voffset == voff + count) { |
356 | count++; | 356 | count += size; |
357 | return; | 357 | return; |
358 | } | 358 | } |
359 | 359 | ||
360 | if (count) { | 360 | if (count) { |
361 | if (opt_pid) | 361 | if (opt_pid) |
362 | printf("%lx\t", voff); | 362 | printf("%lx\t", voff); |
363 | if (opt_file) | ||
364 | printf("%lu\t", voff); | ||
363 | printf("%lx\t%lx\t%s\n", | 365 | printf("%lx\t%lx\t%s\n", |
364 | index, count, page_flag_name(flags0)); | 366 | index, count, page_flag_name(flags0)); |
365 | } | 367 | } |
@@ -367,7 +369,12 @@ static void show_page_range(unsigned long voffset, | |||
367 | flags0 = flags; | 369 | flags0 = flags; |
368 | index = offset; | 370 | index = offset; |
369 | voff = voffset; | 371 | voff = voffset; |
370 | count = 1; | 372 | count = size; |
373 | } | ||
374 | |||
375 | static void flush_page_range(void) | ||
376 | { | ||
377 | show_page_range(0, 0, 0, 0); | ||
371 | } | 378 | } |
372 | 379 | ||
373 | static void show_page(unsigned long voffset, | 380 | static void show_page(unsigned long voffset, |
@@ -375,6 +382,8 @@ static void show_page(unsigned long voffset, | |||
375 | { | 382 | { |
376 | if (opt_pid) | 383 | if (opt_pid) |
377 | printf("%lx\t", voffset); | 384 | printf("%lx\t", voffset); |
385 | if (opt_file) | ||
386 | printf("%lu\t", voffset); | ||
378 | printf("%lx\t%s\n", offset, page_flag_name(flags)); | 387 | printf("%lx\t%s\n", offset, page_flag_name(flags)); |
379 | } | 388 | } |
380 | 389 | ||
@@ -565,7 +574,7 @@ static void add_page(unsigned long voffset, | |||
565 | unpoison_page(offset); | 574 | unpoison_page(offset); |
566 | 575 | ||
567 | if (opt_list == 1) | 576 | if (opt_list == 1) |
568 | show_page_range(voffset, offset, flags); | 577 | show_page_range(voffset, offset, 1, flags); |
569 | else if (opt_list == 2) | 578 | else if (opt_list == 2) |
570 | show_page(voffset, offset, flags); | 579 | show_page(voffset, offset, flags); |
571 | 580 | ||
@@ -667,7 +676,7 @@ static void walk_addr_ranges(void) | |||
667 | 676 | ||
668 | for (i = 0; i < nr_addr_ranges; i++) | 677 | for (i = 0; i < nr_addr_ranges; i++) |
669 | if (!opt_pid) | 678 | if (!opt_pid) |
670 | walk_pfn(0, opt_offset[i], opt_size[i], 0); | 679 | walk_pfn(opt_offset[i], opt_offset[i], opt_size[i], 0); |
671 | else | 680 | else |
672 | walk_task(opt_offset[i], opt_size[i]); | 681 | walk_task(opt_offset[i], opt_size[i]); |
673 | 682 | ||
@@ -699,9 +708,7 @@ static void usage(void) | |||
699 | " -a|--addr addr-spec Walk a range of pages\n" | 708 | " -a|--addr addr-spec Walk a range of pages\n" |
700 | " -b|--bits bits-spec Walk pages with specified bits\n" | 709 | " -b|--bits bits-spec Walk pages with specified bits\n" |
701 | " -p|--pid pid Walk process address space\n" | 710 | " -p|--pid pid Walk process address space\n" |
702 | #if 0 /* planned features */ | ||
703 | " -f|--file filename Walk file address space\n" | 711 | " -f|--file filename Walk file address space\n" |
704 | #endif | ||
705 | " -l|--list Show page details in ranges\n" | 712 | " -l|--list Show page details in ranges\n" |
706 | " -L|--list-each Show page details one by one\n" | 713 | " -L|--list-each Show page details one by one\n" |
707 | " -N|--no-summary Don't show summary info\n" | 714 | " -N|--no-summary Don't show summary info\n" |
@@ -799,8 +806,130 @@ static void parse_pid(const char *str) | |||
799 | fclose(file); | 806 | fclose(file); |
800 | } | 807 | } |
801 | 808 | ||
809 | static void show_file(const char *name, const struct stat *st) | ||
810 | { | ||
811 | unsigned long long size = st->st_size; | ||
812 | char atime[64], mtime[64]; | ||
813 | long now = time(NULL); | ||
814 | |||
815 | printf("%s\tInode: %u\tSize: %llu (%llu pages)\n", | ||
816 | name, (unsigned)st->st_ino, | ||
817 | size, (size + page_size - 1) / page_size); | ||
818 | |||
819 | strftime(atime, sizeof(atime), "%c", localtime(&st->st_atime)); | ||
820 | strftime(mtime, sizeof(mtime), "%c", localtime(&st->st_mtime)); | ||
821 | |||
822 | printf("Modify: %s (%ld seconds ago)\nAccess: %s (%ld seconds ago)\n", | ||
823 | mtime, now - st->st_mtime, | ||
824 | atime, now - st->st_atime); | ||
825 | } | ||
826 | |||
827 | static void walk_file(const char *name, const struct stat *st) | ||
828 | { | ||
829 | uint8_t vec[PAGEMAP_BATCH]; | ||
830 | uint64_t buf[PAGEMAP_BATCH], flags; | ||
831 | unsigned long nr_pages, pfn, i; | ||
832 | int fd; | ||
833 | off_t off; | ||
834 | ssize_t len; | ||
835 | void *ptr; | ||
836 | int first = 1; | ||
837 | |||
838 | fd = checked_open(name, O_RDONLY|O_NOATIME|O_NOFOLLOW); | ||
839 | |||
840 | for (off = 0; off < st->st_size; off += len) { | ||
841 | nr_pages = (st->st_size - off + page_size - 1) / page_size; | ||
842 | if (nr_pages > PAGEMAP_BATCH) | ||
843 | nr_pages = PAGEMAP_BATCH; | ||
844 | len = nr_pages * page_size; | ||
845 | |||
846 | ptr = mmap(NULL, len, PROT_READ, MAP_SHARED, fd, off); | ||
847 | if (ptr == MAP_FAILED) | ||
848 | fatal("mmap failed: %s", name); | ||
849 | |||
850 | /* determine cached pages */ | ||
851 | if (mincore(ptr, len, vec)) | ||
852 | fatal("mincore failed: %s", name); | ||
853 | |||
854 | /* turn off readahead */ | ||
855 | if (madvise(ptr, len, MADV_RANDOM)) | ||
856 | fatal("madvice failed: %s", name); | ||
857 | |||
858 | /* populate ptes */ | ||
859 | for (i = 0; i < nr_pages ; i++) { | ||
860 | if (vec[i] & 1) | ||
861 | (void)*(volatile int *)(ptr + i * page_size); | ||
862 | } | ||
863 | |||
864 | /* turn off harvesting reference bits */ | ||
865 | if (madvise(ptr, len, MADV_SEQUENTIAL)) | ||
866 | fatal("madvice failed: %s", name); | ||
867 | |||
868 | if (pagemap_read(buf, (unsigned long)ptr / page_size, | ||
869 | nr_pages) != nr_pages) | ||
870 | fatal("cannot read pagemap"); | ||
871 | |||
872 | munmap(ptr, len); | ||
873 | |||
874 | for (i = 0; i < nr_pages; i++) { | ||
875 | pfn = pagemap_pfn(buf[i]); | ||
876 | if (!pfn) | ||
877 | continue; | ||
878 | if (!kpageflags_read(&flags, pfn, 1)) | ||
879 | continue; | ||
880 | if (first && opt_list) { | ||
881 | first = 0; | ||
882 | flush_page_range(); | ||
883 | show_file(name, st); | ||
884 | } | ||
885 | add_page(off / page_size + i, pfn, flags, buf[i]); | ||
886 | } | ||
887 | } | ||
888 | |||
889 | close(fd); | ||
890 | } | ||
891 | |||
892 | int walk_tree(const char *name, const struct stat *st, int type, struct FTW *f) | ||
893 | { | ||
894 | (void)f; | ||
895 | switch (type) { | ||
896 | case FTW_F: | ||
897 | if (S_ISREG(st->st_mode)) | ||
898 | walk_file(name, st); | ||
899 | break; | ||
900 | case FTW_DNR: | ||
901 | fprintf(stderr, "cannot read dir: %s\n", name); | ||
902 | break; | ||
903 | } | ||
904 | return 0; | ||
905 | } | ||
906 | |||
907 | static void walk_page_cache(void) | ||
908 | { | ||
909 | struct stat st; | ||
910 | |||
911 | kpageflags_fd = checked_open(PROC_KPAGEFLAGS, O_RDONLY); | ||
912 | pagemap_fd = checked_open("/proc/self/pagemap", O_RDONLY); | ||
913 | |||
914 | if (stat(opt_file, &st)) | ||
915 | fatal("stat failed: %s\n", opt_file); | ||
916 | |||
917 | if (S_ISREG(st.st_mode)) { | ||
918 | walk_file(opt_file, &st); | ||
919 | } else if (S_ISDIR(st.st_mode)) { | ||
920 | /* do not follow symlinks and mountpoints */ | ||
921 | if (nftw(opt_file, walk_tree, 64, FTW_MOUNT | FTW_PHYS) < 0) | ||
922 | fatal("nftw failed: %s\n", opt_file); | ||
923 | } else | ||
924 | fatal("unhandled file type: %s\n", opt_file); | ||
925 | |||
926 | close(kpageflags_fd); | ||
927 | close(pagemap_fd); | ||
928 | } | ||
929 | |||
802 | static void parse_file(const char *name) | 930 | static void parse_file(const char *name) |
803 | { | 931 | { |
932 | opt_file = name; | ||
804 | } | 933 | } |
805 | 934 | ||
806 | static void parse_addr_range(const char *optarg) | 935 | static void parse_addr_range(const char *optarg) |
@@ -991,15 +1120,20 @@ int main(int argc, char *argv[]) | |||
991 | 1120 | ||
992 | if (opt_list && opt_pid) | 1121 | if (opt_list && opt_pid) |
993 | printf("voffset\t"); | 1122 | printf("voffset\t"); |
1123 | if (opt_list && opt_file) | ||
1124 | printf("foffset\t"); | ||
994 | if (opt_list == 1) | 1125 | if (opt_list == 1) |
995 | printf("offset\tlen\tflags\n"); | 1126 | printf("offset\tlen\tflags\n"); |
996 | if (opt_list == 2) | 1127 | if (opt_list == 2) |
997 | printf("offset\tflags\n"); | 1128 | printf("offset\tflags\n"); |
998 | 1129 | ||
999 | walk_addr_ranges(); | 1130 | if (opt_file) |
1131 | walk_page_cache(); | ||
1132 | else | ||
1133 | walk_addr_ranges(); | ||
1000 | 1134 | ||
1001 | if (opt_list == 1) | 1135 | if (opt_list == 1) |
1002 | show_page_range(0, 0, 0); /* drain the buffer */ | 1136 | flush_page_range(); |
1003 | 1137 | ||
1004 | if (opt_no_summary) | 1138 | if (opt_no_summary) |
1005 | return 0; | 1139 | return 0; |