aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2015-01-12 04:51:13 -0500
committerThomas Gleixner <tglx@linutronix.de>2015-01-12 04:51:13 -0500
commit2f5eaf66e580f64032b365a00157b6b58c266b37 (patch)
tree7852017c864f0eb3833782e2a017952bd8531458 /tools
parentc291ee622165cb2c8d4e7af63fffd499354a23be (diff)
parent91d1179212161f220938198b742c328ad38fd0a3 (diff)
Merge tag 'irqchip-urgent-3.19' of git://git.infradead.org/users/jcooper/linux into irq/urgent
irqchip urgent fixes for v3.19 from Jason Cooper - mtk-sysirq: Fix error handling - hip04: Fix cpu map for 16bit value - gic-v3-its: Clear a warning regarding decimal constants - omap-intc: Fix legacy DMA regression - atmel-aic-common: Retain priority when changing type
Diffstat (limited to 'tools')
-rw-r--r--tools/hv/hv_fcopy_daemon.c33
-rw-r--r--tools/hv/hv_kvp_daemon.c48
-rw-r--r--tools/hv/hv_vss_daemon.c95
-rw-r--r--tools/include/asm-generic/bitops.h27
-rw-r--r--tools/include/asm-generic/bitops/__ffs.h43
-rw-r--r--tools/include/asm-generic/bitops/__fls.h1
-rw-r--r--tools/include/asm-generic/bitops/atomic.h22
-rw-r--r--tools/include/asm-generic/bitops/find.h33
-rw-r--r--tools/include/asm-generic/bitops/fls.h1
-rw-r--r--tools/include/asm-generic/bitops/fls64.h1
-rw-r--r--tools/include/linux/bitops.h53
-rw-r--r--tools/include/linux/log2.h185
-rw-r--r--tools/lib/api/fs/fs.c34
-rw-r--r--tools/lib/api/fs/fs.h3
-rw-r--r--tools/lib/util/find_next_bit.c89
-rw-r--r--tools/perf/Documentation/perf.txt4
-rw-r--r--tools/perf/MANIFEST16
-rw-r--r--tools/perf/Makefile.perf15
-rw-r--r--tools/perf/bench/mem-memcpy.c286
-rw-r--r--tools/perf/bench/mem-memset.c304
-rw-r--r--tools/perf/builtin-buildid-cache.c13
-rw-r--r--tools/perf/builtin-kvm.c3
-rw-r--r--tools/perf/builtin-trace.c14
-rw-r--r--tools/perf/perf.c14
-rw-r--r--tools/perf/tests/attr/base-record2
-rw-r--r--tools/perf/tests/attr/base-stat2
-rw-r--r--tools/perf/ui/browsers/hists.c2
-rw-r--r--tools/perf/ui/hist.c4
-rw-r--r--tools/perf/util/build-id.c9
-rw-r--r--tools/perf/util/callchain.c2
-rw-r--r--tools/perf/util/config.c10
-rw-r--r--tools/perf/util/evlist.c57
-rw-r--r--tools/perf/util/evlist.h1
-rw-r--r--tools/perf/util/include/asm/hash.h6
-rw-r--r--tools/perf/util/include/linux/bitops.h162
-rw-r--r--tools/perf/util/machine.c72
-rw-r--r--tools/perf/util/record.c11
-rw-r--r--tools/perf/util/srcline.c12
-rw-r--r--tools/perf/util/symbol-minimal.c8
-rw-r--r--tools/perf/util/util.c26
-rw-r--r--tools/perf/util/util.h34
-rwxr-xr-xtools/testing/ktest/ktest.pl37
-rw-r--r--tools/testing/selftests/Makefile15
-rw-r--r--tools/testing/selftests/README.txt61
-rw-r--r--tools/testing/selftests/breakpoints/breakpoint_test.c10
-rw-r--r--tools/testing/selftests/exec/.gitignore9
-rw-r--r--tools/testing/selftests/exec/Makefile25
-rw-r--r--tools/testing/selftests/exec/execveat.c397
-rwxr-xr-xtools/testing/selftests/ftrace/ftracetest43
-rw-r--r--tools/testing/selftests/ftrace/test.d/00basic/basic4.tc5
-rw-r--r--tools/testing/selftests/ftrace/test.d/event/event-enable.tc53
-rw-r--r--tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc53
-rw-r--r--tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc47
-rw-r--r--tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc89
-rw-r--r--tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc52
-rw-r--r--tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc80
-rw-r--r--tools/testing/selftests/ftrace/test.d/functions16
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc1
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc1
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc1
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc55
-rw-r--r--tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc1
-rw-r--r--tools/testing/selftests/ipc/msgque.c26
-rw-r--r--tools/testing/selftests/kcmp/Makefile22
-rw-r--r--tools/testing/selftests/kcmp/kcmp_test.c27
-rw-r--r--tools/testing/selftests/kselftest.h62
-rw-r--r--tools/testing/selftests/mount/unprivileged-remount-test.c204
-rw-r--r--tools/testing/selftests/net/Makefile8
-rwxr-xr-xtools/testing/selftests/net/test_bpf.sh10
-rw-r--r--tools/testing/selftests/size/.gitignore1
-rw-r--r--tools/testing/selftests/size/Makefile12
-rw-r--r--tools/testing/selftests/size/get_size.c100
-rw-r--r--tools/testing/selftests/timers/posix_timers.c14
-rw-r--r--tools/testing/selftests/user/Makefile8
-rwxr-xr-xtools/testing/selftests/user/test_user_copy.sh10
-rw-r--r--tools/thermal/tmon/sysfs.c6
-rw-r--r--tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c2
-rw-r--r--tools/usb/usbip/libsrc/list.h2
-rw-r--r--tools/usb/usbip/src/usbipd.c2
-rw-r--r--tools/virtio/Makefile2
-rw-r--r--tools/virtio/linux/virtio.h23
-rw-r--r--tools/virtio/linux/virtio_byteorder.h8
-rw-r--r--tools/virtio/linux/virtio_config.h72
-rw-r--r--tools/virtio/uapi/linux/virtio_types.h1
-rw-r--r--tools/virtio/virtio_test.c20
-rw-r--r--tools/virtio/vringh_test.c21
-rw-r--r--tools/vm/Makefile4
-rw-r--r--tools/vm/page_owner_sort.c144
88 files changed, 2653 insertions, 966 deletions
diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
index 8f96b3ee0724..f437d739f37d 100644
--- a/tools/hv/hv_fcopy_daemon.c
+++ b/tools/hv/hv_fcopy_daemon.c
@@ -33,6 +33,7 @@
33#include <sys/stat.h> 33#include <sys/stat.h>
34#include <fcntl.h> 34#include <fcntl.h>
35#include <dirent.h> 35#include <dirent.h>
36#include <getopt.h>
36 37
37static int target_fd; 38static int target_fd;
38static char target_fname[W_MAX_PATH]; 39static char target_fname[W_MAX_PATH];
@@ -126,15 +127,43 @@ static int hv_copy_cancel(void)
126 127
127} 128}
128 129
129int main(void) 130void print_usage(char *argv[])
131{
132 fprintf(stderr, "Usage: %s [options]\n"
133 "Options are:\n"
134 " -n, --no-daemon stay in foreground, don't daemonize\n"
135 " -h, --help print this help\n", argv[0]);
136}
137
138int main(int argc, char *argv[])
130{ 139{
131 int fd, fcopy_fd, len; 140 int fd, fcopy_fd, len;
132 int error; 141 int error;
142 int daemonize = 1, long_index = 0, opt;
133 int version = FCOPY_CURRENT_VERSION; 143 int version = FCOPY_CURRENT_VERSION;
134 char *buffer[4096 * 2]; 144 char *buffer[4096 * 2];
135 struct hv_fcopy_hdr *in_msg; 145 struct hv_fcopy_hdr *in_msg;
136 146
137 if (daemon(1, 0)) { 147 static struct option long_options[] = {
148 {"help", no_argument, 0, 'h' },
149 {"no-daemon", no_argument, 0, 'n' },
150 {0, 0, 0, 0 }
151 };
152
153 while ((opt = getopt_long(argc, argv, "hn", long_options,
154 &long_index)) != -1) {
155 switch (opt) {
156 case 'n':
157 daemonize = 0;
158 break;
159 case 'h':
160 default:
161 print_usage(argv);
162 exit(EXIT_FAILURE);
163 }
164 }
165
166 if (daemonize && daemon(1, 0)) {
138 syslog(LOG_ERR, "daemon() failed; error: %s", strerror(errno)); 167 syslog(LOG_ERR, "daemon() failed; error: %s", strerror(errno));
139 exit(EXIT_FAILURE); 168 exit(EXIT_FAILURE);
140 } 169 }
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 4088b816a3ee..6a6432a20a1d 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -43,6 +43,7 @@
43#include <fcntl.h> 43#include <fcntl.h>
44#include <dirent.h> 44#include <dirent.h>
45#include <net/if.h> 45#include <net/if.h>
46#include <getopt.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
@@ -1417,7 +1418,15 @@ netlink_send(int fd, struct cn_msg *msg)
1417 return sendmsg(fd, &message, 0); 1418 return sendmsg(fd, &message, 0);
1418} 1419}
1419 1420
1420int main(void) 1421void print_usage(char *argv[])
1422{
1423 fprintf(stderr, "Usage: %s [options]\n"
1424 "Options are:\n"
1425 " -n, --no-daemon stay in foreground, don't daemonize\n"
1426 " -h, --help print this help\n", argv[0]);
1427}
1428
1429int main(int argc, char *argv[])
1421{ 1430{
1422 int fd, len, nl_group; 1431 int fd, len, nl_group;
1423 int error; 1432 int error;
@@ -1435,9 +1444,30 @@ int main(void)
1435 struct hv_kvp_ipaddr_value *kvp_ip_val; 1444 struct hv_kvp_ipaddr_value *kvp_ip_val;
1436 char *kvp_recv_buffer; 1445 char *kvp_recv_buffer;
1437 size_t kvp_recv_buffer_len; 1446 size_t kvp_recv_buffer_len;
1447 int daemonize = 1, long_index = 0, opt;
1448
1449 static struct option long_options[] = {
1450 {"help", no_argument, 0, 'h' },
1451 {"no-daemon", no_argument, 0, 'n' },
1452 {0, 0, 0, 0 }
1453 };
1454
1455 while ((opt = getopt_long(argc, argv, "hn", long_options,
1456 &long_index)) != -1) {
1457 switch (opt) {
1458 case 'n':
1459 daemonize = 0;
1460 break;
1461 case 'h':
1462 default:
1463 print_usage(argv);
1464 exit(EXIT_FAILURE);
1465 }
1466 }
1438 1467
1439 if (daemon(1, 0)) 1468 if (daemonize && daemon(1, 0))
1440 return 1; 1469 return 1;
1470
1441 openlog("KVP", 0, LOG_USER); 1471 openlog("KVP", 0, LOG_USER);
1442 syslog(LOG_INFO, "KVP starting; pid is:%d", getpid()); 1472 syslog(LOG_INFO, "KVP starting; pid is:%d", getpid());
1443 1473
@@ -1529,8 +1559,15 @@ int main(void)
1529 addr_p, &addr_l); 1559 addr_p, &addr_l);
1530 1560
1531 if (len < 0) { 1561 if (len < 0) {
1562 int saved_errno = errno;
1532 syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s", 1563 syslog(LOG_ERR, "recvfrom failed; pid:%u error:%d %s",
1533 addr.nl_pid, errno, strerror(errno)); 1564 addr.nl_pid, errno, strerror(errno));
1565
1566 if (saved_errno == ENOBUFS) {
1567 syslog(LOG_ERR, "receive error: ignored");
1568 continue;
1569 }
1570
1534 close(fd); 1571 close(fd);
1535 return -1; 1572 return -1;
1536 } 1573 }
@@ -1733,8 +1770,15 @@ kvp_done:
1733 1770
1734 len = netlink_send(fd, incoming_cn_msg); 1771 len = netlink_send(fd, incoming_cn_msg);
1735 if (len < 0) { 1772 if (len < 0) {
1773 int saved_errno = errno;
1736 syslog(LOG_ERR, "net_link send failed; error: %d %s", errno, 1774 syslog(LOG_ERR, "net_link send failed; error: %d %s", errno,
1737 strerror(errno)); 1775 strerror(errno));
1776
1777 if (saved_errno == ENOMEM || saved_errno == ENOBUFS) {
1778 syslog(LOG_ERR, "send error: ignored");
1779 continue;
1780 }
1781
1738 exit(EXIT_FAILURE); 1782 exit(EXIT_FAILURE);
1739 } 1783 }
1740 } 1784 }
diff --git a/tools/hv/hv_vss_daemon.c b/tools/hv/hv_vss_daemon.c
index 6a213b8cd7b9..5e63f70bd956 100644
--- a/tools/hv/hv_vss_daemon.c
+++ b/tools/hv/hv_vss_daemon.c
@@ -36,6 +36,7 @@
36#include <linux/hyperv.h> 36#include <linux/hyperv.h>
37#include <linux/netlink.h> 37#include <linux/netlink.h>
38#include <syslog.h> 38#include <syslog.h>
39#include <getopt.h>
39 40
40static struct sockaddr_nl addr; 41static struct sockaddr_nl addr;
41 42
@@ -44,35 +45,51 @@ static struct sockaddr_nl addr;
44#endif 45#endif
45 46
46 47
47static int vss_do_freeze(char *dir, unsigned int cmd, char *fs_op) 48/* Don't use syslog() in the function since that can cause write to disk */
49static int vss_do_freeze(char *dir, unsigned int cmd)
48{ 50{
49 int ret, fd = open(dir, O_RDONLY); 51 int ret, fd = open(dir, O_RDONLY);
50 52
51 if (fd < 0) 53 if (fd < 0)
52 return 1; 54 return 1;
55
53 ret = ioctl(fd, cmd, 0); 56 ret = ioctl(fd, cmd, 0);
54 syslog(LOG_INFO, "VSS: %s of %s: %s\n", fs_op, dir, strerror(errno)); 57
58 /*
59 * If a partition is mounted more than once, only the first
60 * FREEZE/THAW can succeed and the later ones will get
61 * EBUSY/EINVAL respectively: there could be 2 cases:
62 * 1) a user may mount the same partition to differnt directories
63 * by mistake or on purpose;
64 * 2) The subvolume of btrfs appears to have the same partition
65 * mounted more than once.
66 */
67 if (ret) {
68 if ((cmd == FIFREEZE && errno == EBUSY) ||
69 (cmd == FITHAW && errno == EINVAL)) {
70 close(fd);
71 return 0;
72 }
73 }
74
55 close(fd); 75 close(fd);
56 return !!ret; 76 return !!ret;
57} 77}
58 78
59static int vss_operate(int operation) 79static int vss_operate(int operation)
60{ 80{
61 char *fs_op;
62 char match[] = "/dev/"; 81 char match[] = "/dev/";
63 FILE *mounts; 82 FILE *mounts;
64 struct mntent *ent; 83 struct mntent *ent;
65 unsigned int cmd; 84 unsigned int cmd;
66 int error = 0, root_seen = 0; 85 int error = 0, root_seen = 0, save_errno = 0;
67 86
68 switch (operation) { 87 switch (operation) {
69 case VSS_OP_FREEZE: 88 case VSS_OP_FREEZE:
70 cmd = FIFREEZE; 89 cmd = FIFREEZE;
71 fs_op = "freeze";
72 break; 90 break;
73 case VSS_OP_THAW: 91 case VSS_OP_THAW:
74 cmd = FITHAW; 92 cmd = FITHAW;
75 fs_op = "thaw";
76 break; 93 break;
77 default: 94 default:
78 return -1; 95 return -1;
@@ -85,7 +102,7 @@ static int vss_operate(int operation)
85 while ((ent = getmntent(mounts))) { 102 while ((ent = getmntent(mounts))) {
86 if (strncmp(ent->mnt_fsname, match, strlen(match))) 103 if (strncmp(ent->mnt_fsname, match, strlen(match)))
87 continue; 104 continue;
88 if (strcmp(ent->mnt_type, "iso9660") == 0) 105 if (hasmntopt(ent, MNTOPT_RO) != NULL)
89 continue; 106 continue;
90 if (strcmp(ent->mnt_type, "vfat") == 0) 107 if (strcmp(ent->mnt_type, "vfat") == 0)
91 continue; 108 continue;
@@ -93,14 +110,30 @@ static int vss_operate(int operation)
93 root_seen = 1; 110 root_seen = 1;
94 continue; 111 continue;
95 } 112 }
96 error |= vss_do_freeze(ent->mnt_dir, cmd, fs_op); 113 error |= vss_do_freeze(ent->mnt_dir, cmd);
114 if (error && operation == VSS_OP_FREEZE)
115 goto err;
97 } 116 }
98 endmntent(mounts);
99 117
100 if (root_seen) { 118 if (root_seen) {
101 error |= vss_do_freeze("/", cmd, fs_op); 119 error |= vss_do_freeze("/", cmd);
120 if (error && operation == VSS_OP_FREEZE)
121 goto err;
102 } 122 }
103 123
124 goto out;
125err:
126 save_errno = errno;
127 vss_operate(VSS_OP_THAW);
128 /* Call syslog after we thaw all filesystems */
129 if (ent)
130 syslog(LOG_ERR, "FREEZE of %s failed; error:%d %s",
131 ent->mnt_dir, save_errno, strerror(save_errno));
132 else
133 syslog(LOG_ERR, "FREEZE of / failed; error:%d %s", save_errno,
134 strerror(save_errno));
135out:
136 endmntent(mounts);
104 return error; 137 return error;
105} 138}
106 139
@@ -131,7 +164,15 @@ static int netlink_send(int fd, struct cn_msg *msg)
131 return sendmsg(fd, &message, 0); 164 return sendmsg(fd, &message, 0);
132} 165}
133 166
134int main(void) 167void print_usage(char *argv[])
168{
169 fprintf(stderr, "Usage: %s [options]\n"
170 "Options are:\n"
171 " -n, --no-daemon stay in foreground, don't daemonize\n"
172 " -h, --help print this help\n", argv[0]);
173}
174
175int main(int argc, char *argv[])
135{ 176{
136 int fd, len, nl_group; 177 int fd, len, nl_group;
137 int error; 178 int error;
@@ -143,8 +184,28 @@ int main(void)
143 struct hv_vss_msg *vss_msg; 184 struct hv_vss_msg *vss_msg;
144 char *vss_recv_buffer; 185 char *vss_recv_buffer;
145 size_t vss_recv_buffer_len; 186 size_t vss_recv_buffer_len;
187 int daemonize = 1, long_index = 0, opt;
188
189 static struct option long_options[] = {
190 {"help", no_argument, 0, 'h' },
191 {"no-daemon", no_argument, 0, 'n' },
192 {0, 0, 0, 0 }
193 };
194
195 while ((opt = getopt_long(argc, argv, "hn", long_options,
196 &long_index)) != -1) {
197 switch (opt) {
198 case 'n':
199 daemonize = 0;
200 break;
201 case 'h':
202 default:
203 print_usage(argv);
204 exit(EXIT_FAILURE);
205 }
206 }
146 207
147 if (daemon(1, 0)) 208 if (daemonize && daemon(1, 0))
148 return 1; 209 return 1;
149 210
150 openlog("Hyper-V VSS", 0, LOG_USER); 211 openlog("Hyper-V VSS", 0, LOG_USER);
@@ -249,8 +310,16 @@ int main(void)
249 case VSS_OP_FREEZE: 310 case VSS_OP_FREEZE:
250 case VSS_OP_THAW: 311 case VSS_OP_THAW:
251 error = vss_operate(op); 312 error = vss_operate(op);
252 if (error) 313 syslog(LOG_INFO, "VSS: op=%s: %s\n",
314 op == VSS_OP_FREEZE ? "FREEZE" : "THAW",
315 error ? "failed" : "succeeded");
316
317 if (error) {
253 error = HV_E_FAIL; 318 error = HV_E_FAIL;
319 syslog(LOG_ERR, "op=%d failed!", op);
320 syslog(LOG_ERR, "report it with these files:");
321 syslog(LOG_ERR, "/etc/fstab and /proc/mounts");
322 }
254 break; 323 break;
255 default: 324 default:
256 syslog(LOG_ERR, "Illegal op:%d\n", op); 325 syslog(LOG_ERR, "Illegal op:%d\n", op);
diff --git a/tools/include/asm-generic/bitops.h b/tools/include/asm-generic/bitops.h
new file mode 100644
index 000000000000..6eedba1f7732
--- /dev/null
+++ b/tools/include/asm-generic/bitops.h
@@ -0,0 +1,27 @@
1#ifndef __TOOLS_ASM_GENERIC_BITOPS_H
2#define __TOOLS_ASM_GENERIC_BITOPS_H
3
4/*
5 * tools/ copied this from include/asm-generic/bitops.h, bit by bit as it needed
6 * some functions.
7 *
8 * For the benefit of those who are trying to port Linux to another
9 * architecture, here are some C-language equivalents. You should
10 * recode these in the native assembly language, if at all possible.
11 *
12 * C language equivalents written by Theodore Ts'o, 9/26/92
13 */
14
15#include <asm-generic/bitops/__ffs.h>
16#include <asm-generic/bitops/fls.h>
17#include <asm-generic/bitops/__fls.h>
18#include <asm-generic/bitops/fls64.h>
19#include <asm-generic/bitops/find.h>
20
21#ifndef _TOOLS_LINUX_BITOPS_H_
22#error only <linux/bitops.h> can be included directly
23#endif
24
25#include <asm-generic/bitops/atomic.h>
26
27#endif /* __TOOLS_ASM_GENERIC_BITOPS_H */
diff --git a/tools/include/asm-generic/bitops/__ffs.h b/tools/include/asm-generic/bitops/__ffs.h
new file mode 100644
index 000000000000..c94175015a82
--- /dev/null
+++ b/tools/include/asm-generic/bitops/__ffs.h
@@ -0,0 +1,43 @@
1#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_
2#define _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_
3
4#include <asm/types.h>
5
6/**
7 * __ffs - find first bit in word.
8 * @word: The word to search
9 *
10 * Undefined if no bit exists, so code should check against 0 first.
11 */
12static __always_inline unsigned long __ffs(unsigned long word)
13{
14 int num = 0;
15
16#if __BITS_PER_LONG == 64
17 if ((word & 0xffffffff) == 0) {
18 num += 32;
19 word >>= 32;
20 }
21#endif
22 if ((word & 0xffff) == 0) {
23 num += 16;
24 word >>= 16;
25 }
26 if ((word & 0xff) == 0) {
27 num += 8;
28 word >>= 8;
29 }
30 if ((word & 0xf) == 0) {
31 num += 4;
32 word >>= 4;
33 }
34 if ((word & 0x3) == 0) {
35 num += 2;
36 word >>= 2;
37 }
38 if ((word & 0x1) == 0)
39 num += 1;
40 return num;
41}
42
43#endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS___FFS_H_ */
diff --git a/tools/include/asm-generic/bitops/__fls.h b/tools/include/asm-generic/bitops/__fls.h
new file mode 100644
index 000000000000..2218b9add4c1
--- /dev/null
+++ b/tools/include/asm-generic/bitops/__fls.h
@@ -0,0 +1 @@
#include <../../../../include/asm-generic/bitops/__fls.h>
diff --git a/tools/include/asm-generic/bitops/atomic.h b/tools/include/asm-generic/bitops/atomic.h
new file mode 100644
index 000000000000..4bccd7c3d5d6
--- /dev/null
+++ b/tools/include/asm-generic/bitops/atomic.h
@@ -0,0 +1,22 @@
1#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_
2#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_
3
4#include <asm/types.h>
5
6static inline void set_bit(int nr, unsigned long *addr)
7{
8 addr[nr / __BITS_PER_LONG] |= 1UL << (nr % __BITS_PER_LONG);
9}
10
11static inline void clear_bit(int nr, unsigned long *addr)
12{
13 addr[nr / __BITS_PER_LONG] &= ~(1UL << (nr % __BITS_PER_LONG));
14}
15
16static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
17{
18 return ((1UL << (nr % __BITS_PER_LONG)) &
19 (((unsigned long *)addr)[nr / __BITS_PER_LONG])) != 0;
20}
21
22#endif /* _TOOLS_LINUX_ASM_GENERIC_BITOPS_ATOMIC_H_ */
diff --git a/tools/include/asm-generic/bitops/find.h b/tools/include/asm-generic/bitops/find.h
new file mode 100644
index 000000000000..31f51547fcd4
--- /dev/null
+++ b/tools/include/asm-generic/bitops/find.h
@@ -0,0 +1,33 @@
1#ifndef _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
2#define _TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_
3
4#ifndef find_next_bit
5/**
6 * find_next_bit - find the next set bit in a memory region
7 * @addr: The address to base the search on
8 * @offset: The bitnumber to start searching at
9 * @size: The bitmap size in bits
10 *
11 * Returns the bit number for the next set bit
12 * If no bits are set, returns @size.
13 */
14extern unsigned long find_next_bit(const unsigned long *addr, unsigned long
15 size, unsigned long offset);
16#endif
17
18#ifndef find_first_bit
19
20/**
21 * find_first_bit - find the first set bit in a memory region
22 * @addr: The address to start the search at
23 * @size: The maximum number of bits to search
24 *
25 * Returns the bit number of the first set bit.
26 * If no bits are set, returns @size.
27 */
28extern unsigned long find_first_bit(const unsigned long *addr,
29 unsigned long size);
30
31#endif /* find_first_bit */
32
33#endif /*_TOOLS_LINUX_ASM_GENERIC_BITOPS_FIND_H_ */
diff --git a/tools/include/asm-generic/bitops/fls.h b/tools/include/asm-generic/bitops/fls.h
new file mode 100644
index 000000000000..dbf711a28f71
--- /dev/null
+++ b/tools/include/asm-generic/bitops/fls.h
@@ -0,0 +1 @@
#include <../../../../include/asm-generic/bitops/fls.h>
diff --git a/tools/include/asm-generic/bitops/fls64.h b/tools/include/asm-generic/bitops/fls64.h
new file mode 100644
index 000000000000..980b1f63c047
--- /dev/null
+++ b/tools/include/asm-generic/bitops/fls64.h
@@ -0,0 +1 @@
#include <../../../../include/asm-generic/bitops/fls64.h>
diff --git a/tools/include/linux/bitops.h b/tools/include/linux/bitops.h
new file mode 100644
index 000000000000..26005a15e7e2
--- /dev/null
+++ b/tools/include/linux/bitops.h
@@ -0,0 +1,53 @@
1#ifndef _TOOLS_LINUX_BITOPS_H_
2#define _TOOLS_LINUX_BITOPS_H_
3
4#include <linux/kernel.h>
5#include <linux/compiler.h>
6#include <asm/hweight.h>
7
8#ifndef __WORDSIZE
9#define __WORDSIZE (__SIZEOF_LONG__ * 8)
10#endif
11
12#define BITS_PER_LONG __WORDSIZE
13
14#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
15#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
16#define BITS_PER_BYTE 8
17#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
18#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64))
19#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32))
20#define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE)
21
22/*
23 * Include this here because some architectures need generic_ffs/fls in
24 * scope
25 *
26 * XXX: this needs to be asm/bitops.h, when we get to per arch optimizations
27 */
28#include <asm-generic/bitops.h>
29
30#define for_each_set_bit(bit, addr, size) \
31 for ((bit) = find_first_bit((addr), (size)); \
32 (bit) < (size); \
33 (bit) = find_next_bit((addr), (size), (bit) + 1))
34
35/* same as for_each_set_bit() but use bit as value to start with */
36#define for_each_set_bit_from(bit, addr, size) \
37 for ((bit) = find_next_bit((addr), (size), (bit)); \
38 (bit) < (size); \
39 (bit) = find_next_bit((addr), (size), (bit) + 1))
40
41static inline unsigned long hweight_long(unsigned long w)
42{
43 return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
44}
45
46static inline unsigned fls_long(unsigned long l)
47{
48 if (sizeof(l) == 4)
49 return fls(l);
50 return fls64(l);
51}
52
53#endif
diff --git a/tools/include/linux/log2.h b/tools/include/linux/log2.h
new file mode 100644
index 000000000000..41446668ccce
--- /dev/null
+++ b/tools/include/linux/log2.h
@@ -0,0 +1,185 @@
1/* Integer base 2 logarithm calculation
2 *
3 * Copyright (C) 2006 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12#ifndef _TOOLS_LINUX_LOG2_H
13#define _TOOLS_LINUX_LOG2_H
14
15/*
16 * deal with unrepresentable constant logarithms
17 */
18extern __attribute__((const, noreturn))
19int ____ilog2_NaN(void);
20
21/*
22 * non-constant log of base 2 calculators
23 * - the arch may override these in asm/bitops.h if they can be implemented
24 * more efficiently than using fls() and fls64()
25 * - the arch is not required to handle n==0 if implementing the fallback
26 */
27static inline __attribute__((const))
28int __ilog2_u32(u32 n)
29{
30 return fls(n) - 1;
31}
32
33static inline __attribute__((const))
34int __ilog2_u64(u64 n)
35{
36 return fls64(n) - 1;
37}
38
39/*
40 * Determine whether some value is a power of two, where zero is
41 * *not* considered a power of two.
42 */
43
44static inline __attribute__((const))
45bool is_power_of_2(unsigned long n)
46{
47 return (n != 0 && ((n & (n - 1)) == 0));
48}
49
50/*
51 * round up to nearest power of two
52 */
53static inline __attribute__((const))
54unsigned long __roundup_pow_of_two(unsigned long n)
55{
56 return 1UL << fls_long(n - 1);
57}
58
59/*
60 * round down to nearest power of two
61 */
62static inline __attribute__((const))
63unsigned long __rounddown_pow_of_two(unsigned long n)
64{
65 return 1UL << (fls_long(n) - 1);
66}
67
68/**
69 * ilog2 - log of base 2 of 32-bit or a 64-bit unsigned value
70 * @n - parameter
71 *
72 * constant-capable log of base 2 calculation
73 * - this can be used to initialise global variables from constant data, hence
74 * the massive ternary operator construction
75 *
76 * selects the appropriately-sized optimised version depending on sizeof(n)
77 */
78#define ilog2(n) \
79( \
80 __builtin_constant_p(n) ? ( \
81 (n) < 1 ? ____ilog2_NaN() : \
82 (n) & (1ULL << 63) ? 63 : \
83 (n) & (1ULL << 62) ? 62 : \
84 (n) & (1ULL << 61) ? 61 : \
85 (n) & (1ULL << 60) ? 60 : \
86 (n) & (1ULL << 59) ? 59 : \
87 (n) & (1ULL << 58) ? 58 : \
88 (n) & (1ULL << 57) ? 57 : \
89 (n) & (1ULL << 56) ? 56 : \
90 (n) & (1ULL << 55) ? 55 : \
91 (n) & (1ULL << 54) ? 54 : \
92 (n) & (1ULL << 53) ? 53 : \
93 (n) & (1ULL << 52) ? 52 : \
94 (n) & (1ULL << 51) ? 51 : \
95 (n) & (1ULL << 50) ? 50 : \
96 (n) & (1ULL << 49) ? 49 : \
97 (n) & (1ULL << 48) ? 48 : \
98 (n) & (1ULL << 47) ? 47 : \
99 (n) & (1ULL << 46) ? 46 : \
100 (n) & (1ULL << 45) ? 45 : \
101 (n) & (1ULL << 44) ? 44 : \
102 (n) & (1ULL << 43) ? 43 : \
103 (n) & (1ULL << 42) ? 42 : \
104 (n) & (1ULL << 41) ? 41 : \
105 (n) & (1ULL << 40) ? 40 : \
106 (n) & (1ULL << 39) ? 39 : \
107 (n) & (1ULL << 38) ? 38 : \
108 (n) & (1ULL << 37) ? 37 : \
109 (n) & (1ULL << 36) ? 36 : \
110 (n) & (1ULL << 35) ? 35 : \
111 (n) & (1ULL << 34) ? 34 : \
112 (n) & (1ULL << 33) ? 33 : \
113 (n) & (1ULL << 32) ? 32 : \
114 (n) & (1ULL << 31) ? 31 : \
115 (n) & (1ULL << 30) ? 30 : \
116 (n) & (1ULL << 29) ? 29 : \
117 (n) & (1ULL << 28) ? 28 : \
118 (n) & (1ULL << 27) ? 27 : \
119 (n) & (1ULL << 26) ? 26 : \
120 (n) & (1ULL << 25) ? 25 : \
121 (n) & (1ULL << 24) ? 24 : \
122 (n) & (1ULL << 23) ? 23 : \
123 (n) & (1ULL << 22) ? 22 : \
124 (n) & (1ULL << 21) ? 21 : \
125 (n) & (1ULL << 20) ? 20 : \
126 (n) & (1ULL << 19) ? 19 : \
127 (n) & (1ULL << 18) ? 18 : \
128 (n) & (1ULL << 17) ? 17 : \
129 (n) & (1ULL << 16) ? 16 : \
130 (n) & (1ULL << 15) ? 15 : \
131 (n) & (1ULL << 14) ? 14 : \
132 (n) & (1ULL << 13) ? 13 : \
133 (n) & (1ULL << 12) ? 12 : \
134 (n) & (1ULL << 11) ? 11 : \
135 (n) & (1ULL << 10) ? 10 : \
136 (n) & (1ULL << 9) ? 9 : \
137 (n) & (1ULL << 8) ? 8 : \
138 (n) & (1ULL << 7) ? 7 : \
139 (n) & (1ULL << 6) ? 6 : \
140 (n) & (1ULL << 5) ? 5 : \
141 (n) & (1ULL << 4) ? 4 : \
142 (n) & (1ULL << 3) ? 3 : \
143 (n) & (1ULL << 2) ? 2 : \
144 (n) & (1ULL << 1) ? 1 : \
145 (n) & (1ULL << 0) ? 0 : \
146 ____ilog2_NaN() \
147 ) : \
148 (sizeof(n) <= 4) ? \
149 __ilog2_u32(n) : \
150 __ilog2_u64(n) \
151 )
152
153/**
154 * roundup_pow_of_two - round the given value up to nearest power of two
155 * @n - parameter
156 *
157 * round the given value up to the nearest power of two
158 * - the result is undefined when n == 0
159 * - this can be used to initialise global variables from constant data
160 */
161#define roundup_pow_of_two(n) \
162( \
163 __builtin_constant_p(n) ? ( \
164 (n == 1) ? 1 : \
165 (1UL << (ilog2((n) - 1) + 1)) \
166 ) : \
167 __roundup_pow_of_two(n) \
168 )
169
170/**
171 * rounddown_pow_of_two - round the given value down to nearest power of two
172 * @n - parameter
173 *
174 * round the given value down to the nearest power of two
175 * - the result is undefined when n == 0
176 * - this can be used to initialise global variables from constant data
177 */
178#define rounddown_pow_of_two(n) \
179( \
180 __builtin_constant_p(n) ? ( \
181 (1UL << ilog2(n))) : \
182 __rounddown_pow_of_two(n) \
183 )
184
185#endif /* _TOOLS_LINUX_LOG2_H */
diff --git a/tools/lib/api/fs/fs.c b/tools/lib/api/fs/fs.c
index c1b49c36a951..65d9be3f9887 100644
--- a/tools/lib/api/fs/fs.c
+++ b/tools/lib/api/fs/fs.c
@@ -7,6 +7,10 @@
7#include <stdlib.h> 7#include <stdlib.h>
8#include <string.h> 8#include <string.h>
9#include <sys/vfs.h> 9#include <sys/vfs.h>
10#include <sys/types.h>
11#include <sys/stat.h>
12#include <fcntl.h>
13#include <unistd.h>
10 14
11#include "debugfs.h" 15#include "debugfs.h"
12#include "fs.h" 16#include "fs.h"
@@ -163,3 +167,33 @@ const char *name##__mountpoint(void) \
163 167
164FS__MOUNTPOINT(sysfs, FS__SYSFS); 168FS__MOUNTPOINT(sysfs, FS__SYSFS);
165FS__MOUNTPOINT(procfs, FS__PROCFS); 169FS__MOUNTPOINT(procfs, FS__PROCFS);
170
171int filename__read_int(const char *filename, int *value)
172{
173 char line[64];
174 int fd = open(filename, O_RDONLY), err = -1;
175
176 if (fd < 0)
177 return -1;
178
179 if (read(fd, line, sizeof(line)) > 0) {
180 *value = atoi(line);
181 err = 0;
182 }
183
184 close(fd);
185 return err;
186}
187
188int sysctl__read_int(const char *sysctl, int *value)
189{
190 char path[PATH_MAX];
191 const char *procfs = procfs__mountpoint();
192
193 if (!procfs)
194 return -1;
195
196 snprintf(path, sizeof(path), "%s/sys/%s", procfs, sysctl);
197
198 return filename__read_int(path, value);
199}
diff --git a/tools/lib/api/fs/fs.h b/tools/lib/api/fs/fs.h
index cb7049551f33..6caa2bbc6cec 100644
--- a/tools/lib/api/fs/fs.h
+++ b/tools/lib/api/fs/fs.h
@@ -11,4 +11,7 @@
11 11
12const char *sysfs__mountpoint(void); 12const char *sysfs__mountpoint(void);
13const char *procfs__mountpoint(void); 13const char *procfs__mountpoint(void);
14
15int filename__read_int(const char *filename, int *value);
16int sysctl__read_int(const char *sysctl, int *value);
14#endif /* __API_FS__ */ 17#endif /* __API_FS__ */
diff --git a/tools/lib/util/find_next_bit.c b/tools/lib/util/find_next_bit.c
new file mode 100644
index 000000000000..41b44f65a79e
--- /dev/null
+++ b/tools/lib/util/find_next_bit.c
@@ -0,0 +1,89 @@
1/* find_next_bit.c: fallback find next bit implementation
2 *
3 * Copied from lib/find_next_bit.c to tools/lib/next_bit.c
4 *
5 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved.
6 * Written by David Howells (dhowells@redhat.com)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <linux/bitops.h>
15#include <asm/types.h>
16#include <asm/byteorder.h>
17
18#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
19
20#ifndef find_next_bit
21/*
22 * Find the next set bit in a memory region.
23 */
24unsigned long find_next_bit(const unsigned long *addr, unsigned long size,
25 unsigned long offset)
26{
27 const unsigned long *p = addr + BITOP_WORD(offset);
28 unsigned long result = offset & ~(BITS_PER_LONG-1);
29 unsigned long tmp;
30
31 if (offset >= size)
32 return size;
33 size -= result;
34 offset %= BITS_PER_LONG;
35 if (offset) {
36 tmp = *(p++);
37 tmp &= (~0UL << offset);
38 if (size < BITS_PER_LONG)
39 goto found_first;
40 if (tmp)
41 goto found_middle;
42 size -= BITS_PER_LONG;
43 result += BITS_PER_LONG;
44 }
45 while (size & ~(BITS_PER_LONG-1)) {
46 if ((tmp = *(p++)))
47 goto found_middle;
48 result += BITS_PER_LONG;
49 size -= BITS_PER_LONG;
50 }
51 if (!size)
52 return result;
53 tmp = *p;
54
55found_first:
56 tmp &= (~0UL >> (BITS_PER_LONG - size));
57 if (tmp == 0UL) /* Are any bits set? */
58 return result + size; /* Nope. */
59found_middle:
60 return result + __ffs(tmp);
61}
62#endif
63
64#ifndef find_first_bit
65/*
66 * Find the first set bit in a memory region.
67 */
68unsigned long find_first_bit(const unsigned long *addr, unsigned long size)
69{
70 const unsigned long *p = addr;
71 unsigned long result = 0;
72 unsigned long tmp;
73
74 while (size & ~(BITS_PER_LONG-1)) {
75 if ((tmp = *(p++)))
76 goto found;
77 result += BITS_PER_LONG;
78 size -= BITS_PER_LONG;
79 }
80 if (!size)
81 return result;
82
83 tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
84 if (tmp == 0UL) /* Are any bits set? */
85 return result + size; /* Nope. */
86found:
87 return result + __ffs(tmp);
88}
89#endif
diff --git a/tools/perf/Documentation/perf.txt b/tools/perf/Documentation/perf.txt
index d240bb2e5b22..1e8e400b4493 100644
--- a/tools/perf/Documentation/perf.txt
+++ b/tools/perf/Documentation/perf.txt
@@ -18,6 +18,10 @@ OPTIONS
18 --debug verbose # sets verbose = 1 18 --debug verbose # sets verbose = 1
19 --debug verbose=2 # sets verbose = 2 19 --debug verbose=2 # sets verbose = 2
20 20
21--buildid-dir::
22 Setup buildid cache directory. It has higher priority than
23 buildid.dir config file option.
24
21DESCRIPTION 25DESCRIPTION
22----------- 26-----------
23Performance counters for Linux are a new kernel-based subsystem 27Performance counters for Linux are a new kernel-based subsystem
diff --git a/tools/perf/MANIFEST b/tools/perf/MANIFEST
index 344c4d3d0a4a..83e2887f91a3 100644
--- a/tools/perf/MANIFEST
+++ b/tools/perf/MANIFEST
@@ -4,17 +4,31 @@ tools/lib/traceevent
4tools/lib/api 4tools/lib/api
5tools/lib/symbol/kallsyms.c 5tools/lib/symbol/kallsyms.c
6tools/lib/symbol/kallsyms.h 6tools/lib/symbol/kallsyms.h
7tools/lib/util/find_next_bit.c
7tools/include/asm/bug.h 8tools/include/asm/bug.h
9tools/include/asm-generic/bitops/atomic.h
10tools/include/asm-generic/bitops/__ffs.h
11tools/include/asm-generic/bitops/__fls.h
12tools/include/asm-generic/bitops/find.h
13tools/include/asm-generic/bitops/fls64.h
14tools/include/asm-generic/bitops/fls.h
15tools/include/asm-generic/bitops.h
16tools/include/linux/bitops.h
8tools/include/linux/compiler.h 17tools/include/linux/compiler.h
9tools/include/linux/hash.h
10tools/include/linux/export.h 18tools/include/linux/export.h
19tools/include/linux/hash.h
20tools/include/linux/log2.h
11tools/include/linux/types.h 21tools/include/linux/types.h
22include/asm-generic/bitops/fls64.h
23include/asm-generic/bitops/__fls.h
24include/asm-generic/bitops/fls.h
12include/linux/const.h 25include/linux/const.h
13include/linux/perf_event.h 26include/linux/perf_event.h
14include/linux/rbtree.h 27include/linux/rbtree.h
15include/linux/list.h 28include/linux/list.h
16include/linux/hash.h 29include/linux/hash.h
17include/linux/stringify.h 30include/linux/stringify.h
31lib/find_next_bit.c
18lib/rbtree.c 32lib/rbtree.c
19include/linux/swab.h 33include/linux/swab.h
20arch/*/include/asm/unistd*.h 34arch/*/include/asm/unistd*.h
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 478efa9b2364..67a03a825b3c 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -231,8 +231,16 @@ LIB_H += ../../include/uapi/linux/const.h
231LIB_H += ../include/linux/hash.h 231LIB_H += ../include/linux/hash.h
232LIB_H += ../../include/linux/stringify.h 232LIB_H += ../../include/linux/stringify.h
233LIB_H += util/include/linux/bitmap.h 233LIB_H += util/include/linux/bitmap.h
234LIB_H += util/include/linux/bitops.h 234LIB_H += ../include/linux/bitops.h
235LIB_H += ../include/asm-generic/bitops/atomic.h
236LIB_H += ../include/asm-generic/bitops/find.h
237LIB_H += ../include/asm-generic/bitops/fls64.h
238LIB_H += ../include/asm-generic/bitops/fls.h
239LIB_H += ../include/asm-generic/bitops/__ffs.h
240LIB_H += ../include/asm-generic/bitops/__fls.h
241LIB_H += ../include/asm-generic/bitops.h
235LIB_H += ../include/linux/compiler.h 242LIB_H += ../include/linux/compiler.h
243LIB_H += ../include/linux/log2.h
236LIB_H += util/include/linux/const.h 244LIB_H += util/include/linux/const.h
237LIB_H += util/include/linux/ctype.h 245LIB_H += util/include/linux/ctype.h
238LIB_H += util/include/linux/kernel.h 246LIB_H += util/include/linux/kernel.h
@@ -335,6 +343,7 @@ LIB_OBJS += $(OUTPUT)util/event.o
335LIB_OBJS += $(OUTPUT)util/evlist.o 343LIB_OBJS += $(OUTPUT)util/evlist.o
336LIB_OBJS += $(OUTPUT)util/evsel.o 344LIB_OBJS += $(OUTPUT)util/evsel.o
337LIB_OBJS += $(OUTPUT)util/exec_cmd.o 345LIB_OBJS += $(OUTPUT)util/exec_cmd.o
346LIB_OBJS += $(OUTPUT)util/find_next_bit.o
338LIB_OBJS += $(OUTPUT)util/help.o 347LIB_OBJS += $(OUTPUT)util/help.o
339LIB_OBJS += $(OUTPUT)util/kallsyms.o 348LIB_OBJS += $(OUTPUT)util/kallsyms.o
340LIB_OBJS += $(OUTPUT)util/levenshtein.o 349LIB_OBJS += $(OUTPUT)util/levenshtein.o
@@ -458,7 +467,6 @@ BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o
458BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o 467BUILTIN_OBJS += $(OUTPUT)bench/mem-memset-x86-64-asm.o
459endif 468endif
460BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o 469BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
461BUILTIN_OBJS += $(OUTPUT)bench/mem-memset.o
462BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o 470BUILTIN_OBJS += $(OUTPUT)bench/futex-hash.o
463BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o 471BUILTIN_OBJS += $(OUTPUT)bench/futex-wake.o
464BUILTIN_OBJS += $(OUTPUT)bench/futex-requeue.o 472BUILTIN_OBJS += $(OUTPUT)bench/futex-requeue.o
@@ -735,6 +743,9 @@ $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c $(OUTPUT)PERF-CFLAGS
735$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS 743$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
736 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 744 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
737 745
746$(OUTPUT)util/find_next_bit.o: ../lib/util/find_next_bit.c $(OUTPUT)PERF-CFLAGS
747 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
748
738$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS 749$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
739 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $< 750 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
740 751
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 2465141b554b..6c14afe8c1b1 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -13,6 +13,7 @@
13#include "../util/cloexec.h" 13#include "../util/cloexec.h"
14#include "bench.h" 14#include "bench.h"
15#include "mem-memcpy-arch.h" 15#include "mem-memcpy-arch.h"
16#include "mem-memset-arch.h"
16 17
17#include <stdio.h> 18#include <stdio.h>
18#include <stdlib.h> 19#include <stdlib.h>
@@ -48,20 +49,24 @@ static const struct option options[] = {
48}; 49};
49 50
50typedef void *(*memcpy_t)(void *, const void *, size_t); 51typedef void *(*memcpy_t)(void *, const void *, size_t);
52typedef void *(*memset_t)(void *, int, size_t);
51 53
52struct routine { 54struct routine {
53 const char *name; 55 const char *name;
54 const char *desc; 56 const char *desc;
55 memcpy_t fn; 57 union {
58 memcpy_t memcpy;
59 memset_t memset;
60 } fn;
56}; 61};
57 62
58struct routine routines[] = { 63struct routine memcpy_routines[] = {
59 { "default", 64 { .name = "default",
60 "Default memcpy() provided by glibc", 65 .desc = "Default memcpy() provided by glibc",
61 memcpy }, 66 .fn.memcpy = memcpy },
62#ifdef HAVE_ARCH_X86_64_SUPPORT 67#ifdef HAVE_ARCH_X86_64_SUPPORT
63 68
64#define MEMCPY_FN(fn, name, desc) { name, desc, fn }, 69#define MEMCPY_FN(_fn, _name, _desc) {.name = _name, .desc = _desc, .fn.memcpy = _fn},
65#include "mem-memcpy-x86-64-asm-def.h" 70#include "mem-memcpy-x86-64-asm-def.h"
66#undef MEMCPY_FN 71#undef MEMCPY_FN
67 72
@@ -69,7 +74,7 @@ struct routine routines[] = {
69 74
70 { NULL, 75 { NULL,
71 NULL, 76 NULL,
72 NULL } 77 {NULL} }
73}; 78};
74 79
75static const char * const bench_mem_memcpy_usage[] = { 80static const char * const bench_mem_memcpy_usage[] = {
@@ -110,63 +115,6 @@ static double timeval2double(struct timeval *ts)
110 (double)ts->tv_usec / (double)1000000; 115 (double)ts->tv_usec / (double)1000000;
111} 116}
112 117
113static void alloc_mem(void **dst, void **src, size_t length)
114{
115 *dst = zalloc(length);
116 if (!*dst)
117 die("memory allocation failed - maybe length is too large?\n");
118
119 *src = zalloc(length);
120 if (!*src)
121 die("memory allocation failed - maybe length is too large?\n");
122 /* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */
123 memset(*src, 0, length);
124}
125
126static u64 do_memcpy_cycle(memcpy_t fn, size_t len, bool prefault)
127{
128 u64 cycle_start = 0ULL, cycle_end = 0ULL;
129 void *src = NULL, *dst = NULL;
130 int i;
131
132 alloc_mem(&src, &dst, len);
133
134 if (prefault)
135 fn(dst, src, len);
136
137 cycle_start = get_cycle();
138 for (i = 0; i < iterations; ++i)
139 fn(dst, src, len);
140 cycle_end = get_cycle();
141
142 free(src);
143 free(dst);
144 return cycle_end - cycle_start;
145}
146
147static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault)
148{
149 struct timeval tv_start, tv_end, tv_diff;
150 void *src = NULL, *dst = NULL;
151 int i;
152
153 alloc_mem(&src, &dst, len);
154
155 if (prefault)
156 fn(dst, src, len);
157
158 BUG_ON(gettimeofday(&tv_start, NULL));
159 for (i = 0; i < iterations; ++i)
160 fn(dst, src, len);
161 BUG_ON(gettimeofday(&tv_end, NULL));
162
163 timersub(&tv_end, &tv_start, &tv_diff);
164
165 free(src);
166 free(dst);
167 return (double)((double)len / timeval2double(&tv_diff));
168}
169
170#define pf (no_prefault ? 0 : 1) 118#define pf (no_prefault ? 0 : 1)
171 119
172#define print_bps(x) do { \ 120#define print_bps(x) do { \
@@ -180,16 +128,25 @@ static double do_memcpy_gettimeofday(memcpy_t fn, size_t len, bool prefault)
180 printf(" %14lf GB/Sec", x / K / K / K); \ 128 printf(" %14lf GB/Sec", x / K / K / K); \
181 } while (0) 129 } while (0)
182 130
183int bench_mem_memcpy(int argc, const char **argv, 131struct bench_mem_info {
184 const char *prefix __maybe_unused) 132 const struct routine *routines;
133 u64 (*do_cycle)(const struct routine *r, size_t len, bool prefault);
134 double (*do_gettimeofday)(const struct routine *r, size_t len, bool prefault);
135 const char *const *usage;
136};
137
138static int bench_mem_common(int argc, const char **argv,
139 const char *prefix __maybe_unused,
140 struct bench_mem_info *info)
185{ 141{
186 int i; 142 int i;
187 size_t len; 143 size_t len;
144 double totallen;
188 double result_bps[2]; 145 double result_bps[2];
189 u64 result_cycle[2]; 146 u64 result_cycle[2];
190 147
191 argc = parse_options(argc, argv, options, 148 argc = parse_options(argc, argv, options,
192 bench_mem_memcpy_usage, 0); 149 info->usage, 0);
193 150
194 if (no_prefault && only_prefault) { 151 if (no_prefault && only_prefault) {
195 fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n"); 152 fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
@@ -200,6 +157,7 @@ int bench_mem_memcpy(int argc, const char **argv,
200 init_cycle(); 157 init_cycle();
201 158
202 len = (size_t)perf_atoll((char *)length_str); 159 len = (size_t)perf_atoll((char *)length_str);
160 totallen = (double)len * iterations;
203 161
204 result_cycle[0] = result_cycle[1] = 0ULL; 162 result_cycle[0] = result_cycle[1] = 0ULL;
205 result_bps[0] = result_bps[1] = 0.0; 163 result_bps[0] = result_bps[1] = 0.0;
@@ -213,16 +171,16 @@ int bench_mem_memcpy(int argc, const char **argv,
213 if (only_prefault && no_prefault) 171 if (only_prefault && no_prefault)
214 only_prefault = no_prefault = false; 172 only_prefault = no_prefault = false;
215 173
216 for (i = 0; routines[i].name; i++) { 174 for (i = 0; info->routines[i].name; i++) {
217 if (!strcmp(routines[i].name, routine)) 175 if (!strcmp(info->routines[i].name, routine))
218 break; 176 break;
219 } 177 }
220 if (!routines[i].name) { 178 if (!info->routines[i].name) {
221 printf("Unknown routine:%s\n", routine); 179 printf("Unknown routine:%s\n", routine);
222 printf("Available routines...\n"); 180 printf("Available routines...\n");
223 for (i = 0; routines[i].name; i++) { 181 for (i = 0; info->routines[i].name; i++) {
224 printf("\t%s ... %s\n", 182 printf("\t%s ... %s\n",
225 routines[i].name, routines[i].desc); 183 info->routines[i].name, info->routines[i].desc);
226 } 184 }
227 return 1; 185 return 1;
228 } 186 }
@@ -234,25 +192,25 @@ int bench_mem_memcpy(int argc, const char **argv,
234 /* show both of results */ 192 /* show both of results */
235 if (use_cycle) { 193 if (use_cycle) {
236 result_cycle[0] = 194 result_cycle[0] =
237 do_memcpy_cycle(routines[i].fn, len, false); 195 info->do_cycle(&info->routines[i], len, false);
238 result_cycle[1] = 196 result_cycle[1] =
239 do_memcpy_cycle(routines[i].fn, len, true); 197 info->do_cycle(&info->routines[i], len, true);
240 } else { 198 } else {
241 result_bps[0] = 199 result_bps[0] =
242 do_memcpy_gettimeofday(routines[i].fn, 200 info->do_gettimeofday(&info->routines[i],
243 len, false); 201 len, false);
244 result_bps[1] = 202 result_bps[1] =
245 do_memcpy_gettimeofday(routines[i].fn, 203 info->do_gettimeofday(&info->routines[i],
246 len, true); 204 len, true);
247 } 205 }
248 } else { 206 } else {
249 if (use_cycle) { 207 if (use_cycle) {
250 result_cycle[pf] = 208 result_cycle[pf] =
251 do_memcpy_cycle(routines[i].fn, 209 info->do_cycle(&info->routines[i],
252 len, only_prefault); 210 len, only_prefault);
253 } else { 211 } else {
254 result_bps[pf] = 212 result_bps[pf] =
255 do_memcpy_gettimeofday(routines[i].fn, 213 info->do_gettimeofday(&info->routines[i],
256 len, only_prefault); 214 len, only_prefault);
257 } 215 }
258 } 216 }
@@ -263,10 +221,10 @@ int bench_mem_memcpy(int argc, const char **argv,
263 if (use_cycle) { 221 if (use_cycle) {
264 printf(" %14lf Cycle/Byte\n", 222 printf(" %14lf Cycle/Byte\n",
265 (double)result_cycle[0] 223 (double)result_cycle[0]
266 / (double)len); 224 / totallen);
267 printf(" %14lf Cycle/Byte (with prefault)\n", 225 printf(" %14lf Cycle/Byte (with prefault)\n",
268 (double)result_cycle[1] 226 (double)result_cycle[1]
269 / (double)len); 227 / totallen);
270 } else { 228 } else {
271 print_bps(result_bps[0]); 229 print_bps(result_bps[0]);
272 printf("\n"); 230 printf("\n");
@@ -277,7 +235,7 @@ int bench_mem_memcpy(int argc, const char **argv,
277 if (use_cycle) { 235 if (use_cycle) {
278 printf(" %14lf Cycle/Byte", 236 printf(" %14lf Cycle/Byte",
279 (double)result_cycle[pf] 237 (double)result_cycle[pf]
280 / (double)len); 238 / totallen);
281 } else 239 } else
282 print_bps(result_bps[pf]); 240 print_bps(result_bps[pf]);
283 241
@@ -288,8 +246,8 @@ int bench_mem_memcpy(int argc, const char **argv,
288 if (!only_prefault && !no_prefault) { 246 if (!only_prefault && !no_prefault) {
289 if (use_cycle) { 247 if (use_cycle) {
290 printf("%lf %lf\n", 248 printf("%lf %lf\n",
291 (double)result_cycle[0] / (double)len, 249 (double)result_cycle[0] / totallen,
292 (double)result_cycle[1] / (double)len); 250 (double)result_cycle[1] / totallen);
293 } else { 251 } else {
294 printf("%lf %lf\n", 252 printf("%lf %lf\n",
295 result_bps[0], result_bps[1]); 253 result_bps[0], result_bps[1]);
@@ -297,7 +255,7 @@ int bench_mem_memcpy(int argc, const char **argv,
297 } else { 255 } else {
298 if (use_cycle) { 256 if (use_cycle) {
299 printf("%lf\n", (double)result_cycle[pf] 257 printf("%lf\n", (double)result_cycle[pf]
300 / (double)len); 258 / totallen);
301 } else 259 } else
302 printf("%lf\n", result_bps[pf]); 260 printf("%lf\n", result_bps[pf]);
303 } 261 }
@@ -310,3 +268,163 @@ int bench_mem_memcpy(int argc, const char **argv,
310 268
311 return 0; 269 return 0;
312} 270}
271
272static void memcpy_alloc_mem(void **dst, void **src, size_t length)
273{
274 *dst = zalloc(length);
275 if (!*dst)
276 die("memory allocation failed - maybe length is too large?\n");
277
278 *src = zalloc(length);
279 if (!*src)
280 die("memory allocation failed - maybe length is too large?\n");
281 /* Make sure to always replace the zero pages even if MMAP_THRESH is crossed */
282 memset(*src, 0, length);
283}
284
285static u64 do_memcpy_cycle(const struct routine *r, size_t len, bool prefault)
286{
287 u64 cycle_start = 0ULL, cycle_end = 0ULL;
288 void *src = NULL, *dst = NULL;
289 memcpy_t fn = r->fn.memcpy;
290 int i;
291
292 memcpy_alloc_mem(&src, &dst, len);
293
294 if (prefault)
295 fn(dst, src, len);
296
297 cycle_start = get_cycle();
298 for (i = 0; i < iterations; ++i)
299 fn(dst, src, len);
300 cycle_end = get_cycle();
301
302 free(src);
303 free(dst);
304 return cycle_end - cycle_start;
305}
306
307static double do_memcpy_gettimeofday(const struct routine *r, size_t len,
308 bool prefault)
309{
310 struct timeval tv_start, tv_end, tv_diff;
311 memcpy_t fn = r->fn.memcpy;
312 void *src = NULL, *dst = NULL;
313 int i;
314
315 memcpy_alloc_mem(&src, &dst, len);
316
317 if (prefault)
318 fn(dst, src, len);
319
320 BUG_ON(gettimeofday(&tv_start, NULL));
321 for (i = 0; i < iterations; ++i)
322 fn(dst, src, len);
323 BUG_ON(gettimeofday(&tv_end, NULL));
324
325 timersub(&tv_end, &tv_start, &tv_diff);
326
327 free(src);
328 free(dst);
329 return (double)(((double)len * iterations) / timeval2double(&tv_diff));
330}
331
332int bench_mem_memcpy(int argc, const char **argv,
333 const char *prefix __maybe_unused)
334{
335 struct bench_mem_info info = {
336 .routines = memcpy_routines,
337 .do_cycle = do_memcpy_cycle,
338 .do_gettimeofday = do_memcpy_gettimeofday,
339 .usage = bench_mem_memcpy_usage,
340 };
341
342 return bench_mem_common(argc, argv, prefix, &info);
343}
344
345static void memset_alloc_mem(void **dst, size_t length)
346{
347 *dst = zalloc(length);
348 if (!*dst)
349 die("memory allocation failed - maybe length is too large?\n");
350}
351
352static u64 do_memset_cycle(const struct routine *r, size_t len, bool prefault)
353{
354 u64 cycle_start = 0ULL, cycle_end = 0ULL;
355 memset_t fn = r->fn.memset;
356 void *dst = NULL;
357 int i;
358
359 memset_alloc_mem(&dst, len);
360
361 if (prefault)
362 fn(dst, -1, len);
363
364 cycle_start = get_cycle();
365 for (i = 0; i < iterations; ++i)
366 fn(dst, i, len);
367 cycle_end = get_cycle();
368
369 free(dst);
370 return cycle_end - cycle_start;
371}
372
373static double do_memset_gettimeofday(const struct routine *r, size_t len,
374 bool prefault)
375{
376 struct timeval tv_start, tv_end, tv_diff;
377 memset_t fn = r->fn.memset;
378 void *dst = NULL;
379 int i;
380
381 memset_alloc_mem(&dst, len);
382
383 if (prefault)
384 fn(dst, -1, len);
385
386 BUG_ON(gettimeofday(&tv_start, NULL));
387 for (i = 0; i < iterations; ++i)
388 fn(dst, i, len);
389 BUG_ON(gettimeofday(&tv_end, NULL));
390
391 timersub(&tv_end, &tv_start, &tv_diff);
392
393 free(dst);
394 return (double)(((double)len * iterations) / timeval2double(&tv_diff));
395}
396
397static const char * const bench_mem_memset_usage[] = {
398 "perf bench mem memset <options>",
399 NULL
400};
401
402static const struct routine memset_routines[] = {
403 { .name ="default",
404 .desc = "Default memset() provided by glibc",
405 .fn.memset = memset },
406#ifdef HAVE_ARCH_X86_64_SUPPORT
407
408#define MEMSET_FN(_fn, _name, _desc) { .name = _name, .desc = _desc, .fn.memset = _fn },
409#include "mem-memset-x86-64-asm-def.h"
410#undef MEMSET_FN
411
412#endif
413
414 { .name = NULL,
415 .desc = NULL,
416 .fn.memset = NULL }
417};
418
419int bench_mem_memset(int argc, const char **argv,
420 const char *prefix __maybe_unused)
421{
422 struct bench_mem_info info = {
423 .routines = memset_routines,
424 .do_cycle = do_memset_cycle,
425 .do_gettimeofday = do_memset_gettimeofday,
426 .usage = bench_mem_memset_usage,
427 };
428
429 return bench_mem_common(argc, argv, prefix, &info);
430}
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c
deleted file mode 100644
index 75fc3e65fb2a..000000000000
--- a/tools/perf/bench/mem-memset.c
+++ /dev/null
@@ -1,304 +0,0 @@
1/*
2 * mem-memset.c
3 *
4 * memset: Simple memory set in various ways
5 *
6 * Trivial clone of mem-memcpy.c.
7 */
8
9#include "../perf.h"
10#include "../util/util.h"
11#include "../util/parse-options.h"
12#include "../util/header.h"
13#include "../util/cloexec.h"
14#include "bench.h"
15#include "mem-memset-arch.h"
16
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <sys/time.h>
21#include <errno.h>
22
23#define K 1024
24
25static const char *length_str = "1MB";
26static const char *routine = "default";
27static int iterations = 1;
28static bool use_cycle;
29static int cycle_fd;
30static bool only_prefault;
31static bool no_prefault;
32
33static const struct option options[] = {
34 OPT_STRING('l', "length", &length_str, "1MB",
35 "Specify length of memory to set. "
36 "Available units: B, KB, MB, GB and TB (upper and lower)"),
37 OPT_STRING('r', "routine", &routine, "default",
38 "Specify routine to set"),
39 OPT_INTEGER('i', "iterations", &iterations,
40 "repeat memset() invocation this number of times"),
41 OPT_BOOLEAN('c', "cycle", &use_cycle,
42 "Use cycles event instead of gettimeofday() for measuring"),
43 OPT_BOOLEAN('o', "only-prefault", &only_prefault,
44 "Show only the result with page faults before memset()"),
45 OPT_BOOLEAN('n', "no-prefault", &no_prefault,
46 "Show only the result without page faults before memset()"),
47 OPT_END()
48};
49
50typedef void *(*memset_t)(void *, int, size_t);
51
52struct routine {
53 const char *name;
54 const char *desc;
55 memset_t fn;
56};
57
58static const struct routine routines[] = {
59 { "default",
60 "Default memset() provided by glibc",
61 memset },
62#ifdef HAVE_ARCH_X86_64_SUPPORT
63
64#define MEMSET_FN(fn, name, desc) { name, desc, fn },
65#include "mem-memset-x86-64-asm-def.h"
66#undef MEMSET_FN
67
68#endif
69
70 { NULL,
71 NULL,
72 NULL }
73};
74
75static const char * const bench_mem_memset_usage[] = {
76 "perf bench mem memset <options>",
77 NULL
78};
79
80static struct perf_event_attr cycle_attr = {
81 .type = PERF_TYPE_HARDWARE,
82 .config = PERF_COUNT_HW_CPU_CYCLES
83};
84
85static void init_cycle(void)
86{
87 cycle_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1,
88 perf_event_open_cloexec_flag());
89
90 if (cycle_fd < 0 && errno == ENOSYS)
91 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
92 else
93 BUG_ON(cycle_fd < 0);
94}
95
96static u64 get_cycle(void)
97{
98 int ret;
99 u64 clk;
100
101 ret = read(cycle_fd, &clk, sizeof(u64));
102 BUG_ON(ret != sizeof(u64));
103
104 return clk;
105}
106
107static double timeval2double(struct timeval *ts)
108{
109 return (double)ts->tv_sec +
110 (double)ts->tv_usec / (double)1000000;
111}
112
113static void alloc_mem(void **dst, size_t length)
114{
115 *dst = zalloc(length);
116 if (!*dst)
117 die("memory allocation failed - maybe length is too large?\n");
118}
119
120static u64 do_memset_cycle(memset_t fn, size_t len, bool prefault)
121{
122 u64 cycle_start = 0ULL, cycle_end = 0ULL;
123 void *dst = NULL;
124 int i;
125
126 alloc_mem(&dst, len);
127
128 if (prefault)
129 fn(dst, -1, len);
130
131 cycle_start = get_cycle();
132 for (i = 0; i < iterations; ++i)
133 fn(dst, i, len);
134 cycle_end = get_cycle();
135
136 free(dst);
137 return cycle_end - cycle_start;
138}
139
140static double do_memset_gettimeofday(memset_t fn, size_t len, bool prefault)
141{
142 struct timeval tv_start, tv_end, tv_diff;
143 void *dst = NULL;
144 int i;
145
146 alloc_mem(&dst, len);
147
148 if (prefault)
149 fn(dst, -1, len);
150
151 BUG_ON(gettimeofday(&tv_start, NULL));
152 for (i = 0; i < iterations; ++i)
153 fn(dst, i, len);
154 BUG_ON(gettimeofday(&tv_end, NULL));
155
156 timersub(&tv_end, &tv_start, &tv_diff);
157
158 free(dst);
159 return (double)((double)len / timeval2double(&tv_diff));
160}
161
162#define pf (no_prefault ? 0 : 1)
163
164#define print_bps(x) do { \
165 if (x < K) \
166 printf(" %14lf B/Sec", x); \
167 else if (x < K * K) \
168 printf(" %14lfd KB/Sec", x / K); \
169 else if (x < K * K * K) \
170 printf(" %14lf MB/Sec", x / K / K); \
171 else \
172 printf(" %14lf GB/Sec", x / K / K / K); \
173 } while (0)
174
175int bench_mem_memset(int argc, const char **argv,
176 const char *prefix __maybe_unused)
177{
178 int i;
179 size_t len;
180 double result_bps[2];
181 u64 result_cycle[2];
182
183 argc = parse_options(argc, argv, options,
184 bench_mem_memset_usage, 0);
185
186 if (no_prefault && only_prefault) {
187 fprintf(stderr, "Invalid options: -o and -n are mutually exclusive\n");
188 return 1;
189 }
190
191 if (use_cycle)
192 init_cycle();
193
194 len = (size_t)perf_atoll((char *)length_str);
195
196 result_cycle[0] = result_cycle[1] = 0ULL;
197 result_bps[0] = result_bps[1] = 0.0;
198
199 if ((s64)len <= 0) {
200 fprintf(stderr, "Invalid length:%s\n", length_str);
201 return 1;
202 }
203
204 /* same to without specifying either of prefault and no-prefault */
205 if (only_prefault && no_prefault)
206 only_prefault = no_prefault = false;
207
208 for (i = 0; routines[i].name; i++) {
209 if (!strcmp(routines[i].name, routine))
210 break;
211 }
212 if (!routines[i].name) {
213 printf("Unknown routine:%s\n", routine);
214 printf("Available routines...\n");
215 for (i = 0; routines[i].name; i++) {
216 printf("\t%s ... %s\n",
217 routines[i].name, routines[i].desc);
218 }
219 return 1;
220 }
221
222 if (bench_format == BENCH_FORMAT_DEFAULT)
223 printf("# Copying %s Bytes ...\n\n", length_str);
224
225 if (!only_prefault && !no_prefault) {
226 /* show both of results */
227 if (use_cycle) {
228 result_cycle[0] =
229 do_memset_cycle(routines[i].fn, len, false);
230 result_cycle[1] =
231 do_memset_cycle(routines[i].fn, len, true);
232 } else {
233 result_bps[0] =
234 do_memset_gettimeofday(routines[i].fn,
235 len, false);
236 result_bps[1] =
237 do_memset_gettimeofday(routines[i].fn,
238 len, true);
239 }
240 } else {
241 if (use_cycle) {
242 result_cycle[pf] =
243 do_memset_cycle(routines[i].fn,
244 len, only_prefault);
245 } else {
246 result_bps[pf] =
247 do_memset_gettimeofday(routines[i].fn,
248 len, only_prefault);
249 }
250 }
251
252 switch (bench_format) {
253 case BENCH_FORMAT_DEFAULT:
254 if (!only_prefault && !no_prefault) {
255 if (use_cycle) {
256 printf(" %14lf Cycle/Byte\n",
257 (double)result_cycle[0]
258 / (double)len);
259 printf(" %14lf Cycle/Byte (with prefault)\n ",
260 (double)result_cycle[1]
261 / (double)len);
262 } else {
263 print_bps(result_bps[0]);
264 printf("\n");
265 print_bps(result_bps[1]);
266 printf(" (with prefault)\n");
267 }
268 } else {
269 if (use_cycle) {
270 printf(" %14lf Cycle/Byte",
271 (double)result_cycle[pf]
272 / (double)len);
273 } else
274 print_bps(result_bps[pf]);
275
276 printf("%s\n", only_prefault ? " (with prefault)" : "");
277 }
278 break;
279 case BENCH_FORMAT_SIMPLE:
280 if (!only_prefault && !no_prefault) {
281 if (use_cycle) {
282 printf("%lf %lf\n",
283 (double)result_cycle[0] / (double)len,
284 (double)result_cycle[1] / (double)len);
285 } else {
286 printf("%lf %lf\n",
287 result_bps[0], result_bps[1]);
288 }
289 } else {
290 if (use_cycle) {
291 printf("%lf\n", (double)result_cycle[pf]
292 / (double)len);
293 } else
294 printf("%lf\n", result_bps[pf]);
295 }
296 break;
297 default:
298 /* reaching this means there's some disaster: */
299 die("unknown format: %d\n", bench_format);
300 break;
301 }
302
303 return 0;
304}
diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c
index 70385756da63..77d5cae54c6a 100644
--- a/tools/perf/builtin-buildid-cache.c
+++ b/tools/perf/builtin-buildid-cache.c
@@ -285,12 +285,11 @@ int cmd_buildid_cache(int argc, const char **argv,
285 struct str_node *pos; 285 struct str_node *pos;
286 int ret = 0; 286 int ret = 0;
287 bool force = false; 287 bool force = false;
288 char debugdir[PATH_MAX];
289 char const *add_name_list_str = NULL, 288 char const *add_name_list_str = NULL,
290 *remove_name_list_str = NULL, 289 *remove_name_list_str = NULL,
291 *missing_filename = NULL, 290 *missing_filename = NULL,
292 *update_name_list_str = NULL, 291 *update_name_list_str = NULL,
293 *kcore_filename; 292 *kcore_filename = NULL;
294 char sbuf[STRERR_BUFSIZE]; 293 char sbuf[STRERR_BUFSIZE];
295 294
296 struct perf_data_file file = { 295 struct perf_data_file file = {
@@ -335,13 +334,11 @@ int cmd_buildid_cache(int argc, const char **argv,
335 334
336 setup_pager(); 335 setup_pager();
337 336
338 snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir);
339
340 if (add_name_list_str) { 337 if (add_name_list_str) {
341 list = strlist__new(true, add_name_list_str); 338 list = strlist__new(true, add_name_list_str);
342 if (list) { 339 if (list) {
343 strlist__for_each(pos, list) 340 strlist__for_each(pos, list)
344 if (build_id_cache__add_file(pos->s, debugdir)) { 341 if (build_id_cache__add_file(pos->s, buildid_dir)) {
345 if (errno == EEXIST) { 342 if (errno == EEXIST) {
346 pr_debug("%s already in the cache\n", 343 pr_debug("%s already in the cache\n",
347 pos->s); 344 pos->s);
@@ -359,7 +356,7 @@ int cmd_buildid_cache(int argc, const char **argv,
359 list = strlist__new(true, remove_name_list_str); 356 list = strlist__new(true, remove_name_list_str);
360 if (list) { 357 if (list) {
361 strlist__for_each(pos, list) 358 strlist__for_each(pos, list)
362 if (build_id_cache__remove_file(pos->s, debugdir)) { 359 if (build_id_cache__remove_file(pos->s, buildid_dir)) {
363 if (errno == ENOENT) { 360 if (errno == ENOENT) {
364 pr_debug("%s wasn't in the cache\n", 361 pr_debug("%s wasn't in the cache\n",
365 pos->s); 362 pos->s);
@@ -380,7 +377,7 @@ int cmd_buildid_cache(int argc, const char **argv,
380 list = strlist__new(true, update_name_list_str); 377 list = strlist__new(true, update_name_list_str);
381 if (list) { 378 if (list) {
382 strlist__for_each(pos, list) 379 strlist__for_each(pos, list)
383 if (build_id_cache__update_file(pos->s, debugdir)) { 380 if (build_id_cache__update_file(pos->s, buildid_dir)) {
384 if (errno == ENOENT) { 381 if (errno == ENOENT) {
385 pr_debug("%s wasn't in the cache\n", 382 pr_debug("%s wasn't in the cache\n",
386 pos->s); 383 pos->s);
@@ -395,7 +392,7 @@ int cmd_buildid_cache(int argc, const char **argv,
395 } 392 }
396 393
397 if (kcore_filename && 394 if (kcore_filename &&
398 build_id_cache__add_kcore(kcore_filename, debugdir, force)) 395 build_id_cache__add_kcore(kcore_filename, buildid_dir, force))
399 pr_warning("Couldn't add %s\n", kcore_filename); 396 pr_warning("Couldn't add %s\n", kcore_filename);
400 397
401out: 398out:
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 3c0f3d4fb021..0894a817f67e 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -1293,7 +1293,8 @@ static int kvm_events_live(struct perf_kvm_stat *kvm,
1293 OPT_UINTEGER('d', "display", &kvm->display_time, 1293 OPT_UINTEGER('d', "display", &kvm->display_time,
1294 "time in seconds between display updates"), 1294 "time in seconds between display updates"),
1295 OPT_STRING(0, "event", &kvm->report_event, "report event", 1295 OPT_STRING(0, "event", &kvm->report_event, "report event",
1296 "event for reporting: vmexit, mmio, ioport"), 1296 "event for reporting: "
1297 "vmexit, mmio (x86 only), ioport (x86 only)"),
1297 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu, 1298 OPT_INTEGER(0, "vcpu", &kvm->trace_vcpu,
1298 "vcpu id to report"), 1299 "vcpu id to report"),
1299 OPT_STRING('k', "key", &kvm->sort_key, "sort-key", 1300 OPT_STRING('k', "key", &kvm->sort_key, "sort-key",
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c
index 83a4835c8118..badfabc6a01f 100644
--- a/tools/perf/builtin-trace.c
+++ b/tools/perf/builtin-trace.c
@@ -2045,7 +2045,6 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
2045 unsigned long before; 2045 unsigned long before;
2046 const bool forks = argc > 0; 2046 const bool forks = argc > 0;
2047 bool draining = false; 2047 bool draining = false;
2048 char sbuf[STRERR_BUFSIZE];
2049 2048
2050 trace->live = true; 2049 trace->live = true;
2051 2050
@@ -2106,11 +2105,8 @@ static int trace__run(struct trace *trace, int argc, const char **argv)
2106 goto out_error_open; 2105 goto out_error_open;
2107 2106
2108 err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false); 2107 err = perf_evlist__mmap(evlist, trace->opts.mmap_pages, false);
2109 if (err < 0) { 2108 if (err < 0)
2110 fprintf(trace->output, "Couldn't mmap the events: %s\n", 2109 goto out_error_mmap;
2111 strerror_r(errno, sbuf, sizeof(sbuf)));
2112 goto out_delete_evlist;
2113 }
2114 2110
2115 perf_evlist__enable(evlist); 2111 perf_evlist__enable(evlist);
2116 2112
@@ -2210,6 +2206,10 @@ out_error_tp:
2210 perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf)); 2206 perf_evlist__strerror_tp(evlist, errno, errbuf, sizeof(errbuf));
2211 goto out_error; 2207 goto out_error;
2212 2208
2209out_error_mmap:
2210 perf_evlist__strerror_mmap(evlist, errno, errbuf, sizeof(errbuf));
2211 goto out_error;
2212
2213out_error_open: 2213out_error_open:
2214 perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf)); 2214 perf_evlist__strerror_open(evlist, errno, errbuf, sizeof(errbuf));
2215 2215
@@ -2485,7 +2485,7 @@ int cmd_trace(int argc, const char **argv, const char *prefix __maybe_unused)
2485 .user_freq = UINT_MAX, 2485 .user_freq = UINT_MAX,
2486 .user_interval = ULLONG_MAX, 2486 .user_interval = ULLONG_MAX,
2487 .no_buffering = true, 2487 .no_buffering = true,
2488 .mmap_pages = 1024, 2488 .mmap_pages = UINT_MAX,
2489 }, 2489 },
2490 .output = stdout, 2490 .output = stdout,
2491 .show_comm = true, 2491 .show_comm = true,
diff --git a/tools/perf/perf.c b/tools/perf/perf.c
index 452a8474d29d..3700a7faca6c 100644
--- a/tools/perf/perf.c
+++ b/tools/perf/perf.c
@@ -200,6 +200,16 @@ static int handle_options(const char ***argv, int *argc, int *envchanged)
200 *envchanged = 1; 200 *envchanged = 1;
201 (*argv)++; 201 (*argv)++;
202 (*argc)--; 202 (*argc)--;
203 } else if (!strcmp(cmd, "--buildid-dir")) {
204 if (*argc < 2) {
205 fprintf(stderr, "No directory given for --buildid-dir.\n");
206 usage(perf_usage_string);
207 }
208 set_buildid_dir((*argv)[1]);
209 if (envchanged)
210 *envchanged = 1;
211 (*argv)++;
212 (*argc)--;
203 } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) { 213 } else if (!prefixcmp(cmd, CMD_DEBUGFS_DIR)) {
204 perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR)); 214 perf_debugfs_set_path(cmd + strlen(CMD_DEBUGFS_DIR));
205 fprintf(stderr, "dir: %s\n", debugfs_mountpoint); 215 fprintf(stderr, "dir: %s\n", debugfs_mountpoint);
@@ -499,7 +509,7 @@ int main(int argc, const char **argv)
499 } 509 }
500 if (!prefixcmp(cmd, "trace")) { 510 if (!prefixcmp(cmd, "trace")) {
501#ifdef HAVE_LIBAUDIT_SUPPORT 511#ifdef HAVE_LIBAUDIT_SUPPORT
502 set_buildid_dir(); 512 set_buildid_dir(NULL);
503 setup_path(); 513 setup_path();
504 argv[0] = "trace"; 514 argv[0] = "trace";
505 return cmd_trace(argc, argv, NULL); 515 return cmd_trace(argc, argv, NULL);
@@ -514,7 +524,7 @@ int main(int argc, const char **argv)
514 argc--; 524 argc--;
515 handle_options(&argv, &argc, NULL); 525 handle_options(&argv, &argc, NULL);
516 commit_pager_choice(); 526 commit_pager_choice();
517 set_buildid_dir(); 527 set_buildid_dir(NULL);
518 528
519 if (argc > 0) { 529 if (argc > 0) {
520 if (!prefixcmp(argv[0], "--")) 530 if (!prefixcmp(argv[0], "--"))
diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record
index f710b92ccff6..d3095dafed36 100644
--- a/tools/perf/tests/attr/base-record
+++ b/tools/perf/tests/attr/base-record
@@ -5,7 +5,7 @@ group_fd=-1
5flags=0|8 5flags=0|8
6cpu=* 6cpu=*
7type=0|1 7type=0|1
8size=96 8size=104
9config=0 9config=0
10sample_period=4000 10sample_period=4000
11sample_type=263 11sample_type=263
diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat
index dc3ada2470c0..872ed7e24c7c 100644
--- a/tools/perf/tests/attr/base-stat
+++ b/tools/perf/tests/attr/base-stat
@@ -5,7 +5,7 @@ group_fd=-1
5flags=0|8 5flags=0|8
6cpu=* 6cpu=*
7type=0 7type=0
8size=96 8size=104
9config=0 9config=0
10sample_period=0 10sample_period=0
11sample_type=0 11sample_type=0
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 502daff76ceb..e6bb04b5b09b 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -1252,7 +1252,7 @@ static int hists__browser_title(struct hists *hists,
1252 1252
1253 nr_samples = convert_unit(nr_samples, &unit); 1253 nr_samples = convert_unit(nr_samples, &unit);
1254 printed = scnprintf(bf, size, 1254 printed = scnprintf(bf, size,
1255 "Samples: %lu%c of event '%s', Event count (approx.): %lu", 1255 "Samples: %lu%c of event '%s', Event count (approx.): %" PRIu64,
1256 nr_samples, unit, ev_name, nr_events); 1256 nr_samples, unit, ev_name, nr_events);
1257 1257
1258 1258
diff --git a/tools/perf/ui/hist.c b/tools/perf/ui/hist.c
index 2af18376b077..dc0d095f318c 100644
--- a/tools/perf/ui/hist.c
+++ b/tools/perf/ui/hist.c
@@ -162,8 +162,8 @@ static int __hpp__sort(struct hist_entry *a, struct hist_entry *b,
162 return ret; 162 return ret;
163 163
164 nr_members = evsel->nr_members; 164 nr_members = evsel->nr_members;
165 fields_a = calloc(sizeof(*fields_a), nr_members); 165 fields_a = calloc(nr_members, sizeof(*fields_a));
166 fields_b = calloc(sizeof(*fields_b), nr_members); 166 fields_b = calloc(nr_members, sizeof(*fields_b));
167 167
168 if (!fields_a || !fields_b) 168 if (!fields_a || !fields_b)
169 goto out; 169 goto out;
diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c
index e8d79e5bfaf7..0c72680a977f 100644
--- a/tools/perf/util/build-id.c
+++ b/tools/perf/util/build-id.c
@@ -410,21 +410,18 @@ int perf_session__cache_build_ids(struct perf_session *session)
410{ 410{
411 struct rb_node *nd; 411 struct rb_node *nd;
412 int ret; 412 int ret;
413 char debugdir[PATH_MAX];
414 413
415 if (no_buildid_cache) 414 if (no_buildid_cache)
416 return 0; 415 return 0;
417 416
418 snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); 417 if (mkdir(buildid_dir, 0755) != 0 && errno != EEXIST)
419
420 if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
421 return -1; 418 return -1;
422 419
423 ret = machine__cache_build_ids(&session->machines.host, debugdir); 420 ret = machine__cache_build_ids(&session->machines.host, buildid_dir);
424 421
425 for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) { 422 for (nd = rb_first(&session->machines.guests); nd; nd = rb_next(nd)) {
426 struct machine *pos = rb_entry(nd, struct machine, rb_node); 423 struct machine *pos = rb_entry(nd, struct machine, rb_node);
427 ret |= machine__cache_build_ids(pos, debugdir); 424 ret |= machine__cache_build_ids(pos, buildid_dir);
428 } 425 }
429 return ret ? -1 : 0; 426 return ret ? -1 : 0;
430} 427}
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index cf524a35cc84..64b377e591e4 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -77,7 +77,7 @@ int parse_callchain_record_opt(const char *arg)
77 ret = 0; 77 ret = 0;
78 } else 78 } else
79 pr_err("callchain: No more arguments " 79 pr_err("callchain: No more arguments "
80 "needed for -g fp\n"); 80 "needed for --call-graph fp\n");
81 break; 81 break;
82 82
83#ifdef HAVE_DWARF_UNWIND_SUPPORT 83#ifdef HAVE_DWARF_UNWIND_SUPPORT
diff --git a/tools/perf/util/config.c b/tools/perf/util/config.c
index 57ff826f150b..e18f653cd7db 100644
--- a/tools/perf/util/config.c
+++ b/tools/perf/util/config.c
@@ -522,7 +522,7 @@ static int buildid_dir_command_config(const char *var, const char *value,
522 const char *v; 522 const char *v;
523 523
524 /* same dir for all commands */ 524 /* same dir for all commands */
525 if (!prefixcmp(var, "buildid.") && !strcmp(var + 8, "dir")) { 525 if (!strcmp(var, "buildid.dir")) {
526 v = perf_config_dirname(var, value); 526 v = perf_config_dirname(var, value);
527 if (!v) 527 if (!v)
528 return -1; 528 return -1;
@@ -539,12 +539,14 @@ static void check_buildid_dir_config(void)
539 perf_config(buildid_dir_command_config, &c); 539 perf_config(buildid_dir_command_config, &c);
540} 540}
541 541
542void set_buildid_dir(void) 542void set_buildid_dir(const char *dir)
543{ 543{
544 buildid_dir[0] = '\0'; 544 if (dir)
545 scnprintf(buildid_dir, MAXPATHLEN-1, "%s", dir);
545 546
546 /* try config file */ 547 /* try config file */
547 check_buildid_dir_config(); 548 if (buildid_dir[0] == '\0')
549 check_buildid_dir_config();
548 550
549 /* default to $HOME/.debug */ 551 /* default to $HOME/.debug */
550 if (buildid_dir[0] == '\0') { 552 if (buildid_dir[0] == '\0') {
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index cfbe2b99b9aa..cbab1fb77b1d 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -8,6 +8,7 @@
8 */ 8 */
9#include "util.h" 9#include "util.h"
10#include <api/fs/debugfs.h> 10#include <api/fs/debugfs.h>
11#include <api/fs/fs.h>
11#include <poll.h> 12#include <poll.h>
12#include "cpumap.h" 13#include "cpumap.h"
13#include "thread_map.h" 14#include "thread_map.h"
@@ -24,6 +25,7 @@
24 25
25#include <linux/bitops.h> 26#include <linux/bitops.h>
26#include <linux/hash.h> 27#include <linux/hash.h>
28#include <linux/log2.h>
27 29
28static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx); 30static void perf_evlist__mmap_put(struct perf_evlist *evlist, int idx);
29static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx); 31static void __perf_evlist__munmap(struct perf_evlist *evlist, int idx);
@@ -892,10 +894,24 @@ out_unmap:
892 894
893static size_t perf_evlist__mmap_size(unsigned long pages) 895static size_t perf_evlist__mmap_size(unsigned long pages)
894{ 896{
895 /* 512 kiB: default amount of unprivileged mlocked memory */ 897 if (pages == UINT_MAX) {
896 if (pages == UINT_MAX) 898 int max;
897 pages = (512 * 1024) / page_size; 899
898 else if (!is_power_of_2(pages)) 900 if (sysctl__read_int("kernel/perf_event_mlock_kb", &max) < 0) {
901 /*
902 * Pick a once upon a time good value, i.e. things look
903 * strange since we can't read a sysctl value, but lets not
904 * die yet...
905 */
906 max = 512;
907 } else {
908 max -= (page_size / 1024);
909 }
910
911 pages = (max * 1024) / page_size;
912 if (!is_power_of_2(pages))
913 pages = rounddown_pow_of_two(pages);
914 } else if (!is_power_of_2(pages))
899 return 0; 915 return 0;
900 916
901 return (pages + 1) * page_size; 917 return (pages + 1) * page_size;
@@ -932,7 +948,7 @@ static long parse_pages_arg(const char *str, unsigned long min,
932 /* leave number of pages at 0 */ 948 /* leave number of pages at 0 */
933 } else if (!is_power_of_2(pages)) { 949 } else if (!is_power_of_2(pages)) {
934 /* round pages up to next power of 2 */ 950 /* round pages up to next power of 2 */
935 pages = next_pow2_l(pages); 951 pages = roundup_pow_of_two(pages);
936 if (!pages) 952 if (!pages)
937 return -EINVAL; 953 return -EINVAL;
938 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n", 954 pr_info("rounding mmap pages size to %lu bytes (%lu pages)\n",
@@ -1483,6 +1499,37 @@ int perf_evlist__strerror_open(struct perf_evlist *evlist __maybe_unused,
1483 return 0; 1499 return 0;
1484} 1500}
1485 1501
1502int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size)
1503{
1504 char sbuf[STRERR_BUFSIZE], *emsg = strerror_r(err, sbuf, sizeof(sbuf));
1505 int pages_attempted = evlist->mmap_len / 1024, pages_max_per_user, printed = 0;
1506
1507 switch (err) {
1508 case EPERM:
1509 sysctl__read_int("kernel/perf_event_mlock_kb", &pages_max_per_user);
1510 printed += scnprintf(buf + printed, size - printed,
1511 "Error:\t%s.\n"
1512 "Hint:\tCheck /proc/sys/kernel/perf_event_mlock_kb (%d kB) setting.\n"
1513 "Hint:\tTried using %zd kB.\n",
1514 emsg, pages_max_per_user, pages_attempted);
1515
1516 if (pages_attempted >= pages_max_per_user) {
1517 printed += scnprintf(buf + printed, size - printed,
1518 "Hint:\tTry 'sudo sh -c \"echo %d > /proc/sys/kernel/perf_event_mlock_kb\"', or\n",
1519 pages_max_per_user + pages_attempted);
1520 }
1521
1522 printed += scnprintf(buf + printed, size - printed,
1523 "Hint:\tTry using a smaller -m/--mmap-pages value.");
1524 break;
1525 default:
1526 scnprintf(buf, size, "%s", emsg);
1527 break;
1528 }
1529
1530 return 0;
1531}
1532
1486void perf_evlist__to_front(struct perf_evlist *evlist, 1533void perf_evlist__to_front(struct perf_evlist *evlist,
1487 struct perf_evsel *move_evsel) 1534 struct perf_evsel *move_evsel)
1488{ 1535{
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h
index 649b0c597283..0ba93f67ab94 100644
--- a/tools/perf/util/evlist.h
+++ b/tools/perf/util/evlist.h
@@ -185,6 +185,7 @@ size_t perf_evlist__fprintf(struct perf_evlist *evlist, FILE *fp);
185 185
186int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size); 186int perf_evlist__strerror_tp(struct perf_evlist *evlist, int err, char *buf, size_t size);
187int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size); 187int perf_evlist__strerror_open(struct perf_evlist *evlist, int err, char *buf, size_t size);
188int perf_evlist__strerror_mmap(struct perf_evlist *evlist, int err, char *buf, size_t size);
188 189
189static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm) 190static inline unsigned int perf_mmap__read_head(struct perf_mmap *mm)
190{ 191{
diff --git a/tools/perf/util/include/asm/hash.h b/tools/perf/util/include/asm/hash.h
deleted file mode 100644
index d82b170bb216..000000000000
--- a/tools/perf/util/include/asm/hash.h
+++ /dev/null
@@ -1,6 +0,0 @@
1#ifndef __ASM_GENERIC_HASH_H
2#define __ASM_GENERIC_HASH_H
3
4/* Stub */
5
6#endif /* __ASM_GENERIC_HASH_H */
diff --git a/tools/perf/util/include/linux/bitops.h b/tools/perf/util/include/linux/bitops.h
deleted file mode 100644
index c3294163de17..000000000000
--- a/tools/perf/util/include/linux/bitops.h
+++ /dev/null
@@ -1,162 +0,0 @@
1#ifndef _PERF_LINUX_BITOPS_H_
2#define _PERF_LINUX_BITOPS_H_
3
4#include <linux/kernel.h>
5#include <linux/compiler.h>
6#include <asm/hweight.h>
7
8#ifndef __WORDSIZE
9#define __WORDSIZE (__SIZEOF_LONG__ * 8)
10#endif
11
12#define BITS_PER_LONG __WORDSIZE
13#define BITS_PER_BYTE 8
14#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
15#define BITS_TO_U64(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u64))
16#define BITS_TO_U32(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(u32))
17#define BITS_TO_BYTES(nr) DIV_ROUND_UP(nr, BITS_PER_BYTE)
18#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
19#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
20
21#define for_each_set_bit(bit, addr, size) \
22 for ((bit) = find_first_bit((addr), (size)); \
23 (bit) < (size); \
24 (bit) = find_next_bit((addr), (size), (bit) + 1))
25
26/* same as for_each_set_bit() but use bit as value to start with */
27#define for_each_set_bit_from(bit, addr, size) \
28 for ((bit) = find_next_bit((addr), (size), (bit)); \
29 (bit) < (size); \
30 (bit) = find_next_bit((addr), (size), (bit) + 1))
31
32static inline void set_bit(int nr, unsigned long *addr)
33{
34 addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
35}
36
37static inline void clear_bit(int nr, unsigned long *addr)
38{
39 addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
40}
41
42static __always_inline int test_bit(unsigned int nr, const unsigned long *addr)
43{
44 return ((1UL << (nr % BITS_PER_LONG)) &
45 (((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
46}
47
48static inline unsigned long hweight_long(unsigned long w)
49{
50 return sizeof(w) == 4 ? hweight32(w) : hweight64(w);
51}
52
53#define BITOP_WORD(nr) ((nr) / BITS_PER_LONG)
54
55/**
56 * __ffs - find first bit in word.
57 * @word: The word to search
58 *
59 * Undefined if no bit exists, so code should check against 0 first.
60 */
61static __always_inline unsigned long __ffs(unsigned long word)
62{
63 int num = 0;
64
65#if BITS_PER_LONG == 64
66 if ((word & 0xffffffff) == 0) {
67 num += 32;
68 word >>= 32;
69 }
70#endif
71 if ((word & 0xffff) == 0) {
72 num += 16;
73 word >>= 16;
74 }
75 if ((word & 0xff) == 0) {
76 num += 8;
77 word >>= 8;
78 }
79 if ((word & 0xf) == 0) {
80 num += 4;
81 word >>= 4;
82 }
83 if ((word & 0x3) == 0) {
84 num += 2;
85 word >>= 2;
86 }
87 if ((word & 0x1) == 0)
88 num += 1;
89 return num;
90}
91
92typedef const unsigned long __attribute__((__may_alias__)) long_alias_t;
93
94/*
95 * Find the first set bit in a memory region.
96 */
97static inline unsigned long
98find_first_bit(const unsigned long *addr, unsigned long size)
99{
100 long_alias_t *p = (long_alias_t *) addr;
101 unsigned long result = 0;
102 unsigned long tmp;
103
104 while (size & ~(BITS_PER_LONG-1)) {
105 if ((tmp = *(p++)))
106 goto found;
107 result += BITS_PER_LONG;
108 size -= BITS_PER_LONG;
109 }
110 if (!size)
111 return result;
112
113 tmp = (*p) & (~0UL >> (BITS_PER_LONG - size));
114 if (tmp == 0UL) /* Are any bits set? */
115 return result + size; /* Nope. */
116found:
117 return result + __ffs(tmp);
118}
119
120/*
121 * Find the next set bit in a memory region.
122 */
123static inline unsigned long
124find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset)
125{
126 const unsigned long *p = addr + BITOP_WORD(offset);
127 unsigned long result = offset & ~(BITS_PER_LONG-1);
128 unsigned long tmp;
129
130 if (offset >= size)
131 return size;
132 size -= result;
133 offset %= BITS_PER_LONG;
134 if (offset) {
135 tmp = *(p++);
136 tmp &= (~0UL << offset);
137 if (size < BITS_PER_LONG)
138 goto found_first;
139 if (tmp)
140 goto found_middle;
141 size -= BITS_PER_LONG;
142 result += BITS_PER_LONG;
143 }
144 while (size & ~(BITS_PER_LONG-1)) {
145 if ((tmp = *(p++)))
146 goto found_middle;
147 result += BITS_PER_LONG;
148 size -= BITS_PER_LONG;
149 }
150 if (!size)
151 return result;
152 tmp = *p;
153
154found_first:
155 tmp &= (~0UL >> (BITS_PER_LONG - size));
156 if (tmp == 0UL) /* Are any bits set? */
157 return result + size; /* Nope. */
158found_middle:
159 return result + __ffs(tmp);
160}
161
162#endif
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index 15dd0a9691ce..94de3e48b490 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1385,19 +1385,46 @@ struct mem_info *sample__resolve_mem(struct perf_sample *sample,
1385static int add_callchain_ip(struct thread *thread, 1385static int add_callchain_ip(struct thread *thread,
1386 struct symbol **parent, 1386 struct symbol **parent,
1387 struct addr_location *root_al, 1387 struct addr_location *root_al,
1388 int cpumode, 1388 bool branch_history,
1389 u64 ip) 1389 u64 ip)
1390{ 1390{
1391 struct addr_location al; 1391 struct addr_location al;
1392 1392
1393 al.filtered = 0; 1393 al.filtered = 0;
1394 al.sym = NULL; 1394 al.sym = NULL;
1395 if (cpumode == -1) 1395 if (branch_history)
1396 thread__find_cpumode_addr_location(thread, MAP__FUNCTION, 1396 thread__find_cpumode_addr_location(thread, MAP__FUNCTION,
1397 ip, &al); 1397 ip, &al);
1398 else 1398 else {
1399 u8 cpumode = PERF_RECORD_MISC_USER;
1400
1401 if (ip >= PERF_CONTEXT_MAX) {
1402 switch (ip) {
1403 case PERF_CONTEXT_HV:
1404 cpumode = PERF_RECORD_MISC_HYPERVISOR;
1405 break;
1406 case PERF_CONTEXT_KERNEL:
1407 cpumode = PERF_RECORD_MISC_KERNEL;
1408 break;
1409 case PERF_CONTEXT_USER:
1410 cpumode = PERF_RECORD_MISC_USER;
1411 break;
1412 default:
1413 pr_debug("invalid callchain context: "
1414 "%"PRId64"\n", (s64) ip);
1415 /*
1416 * It seems the callchain is corrupted.
1417 * Discard all.
1418 */
1419 callchain_cursor_reset(&callchain_cursor);
1420 return 1;
1421 }
1422 return 0;
1423 }
1399 thread__find_addr_location(thread, cpumode, MAP__FUNCTION, 1424 thread__find_addr_location(thread, cpumode, MAP__FUNCTION,
1400 ip, &al); 1425 ip, &al);
1426 }
1427
1401 if (al.sym != NULL) { 1428 if (al.sym != NULL) {
1402 if (sort__has_parent && !*parent && 1429 if (sort__has_parent && !*parent &&
1403 symbol__match_regex(al.sym, &parent_regex)) 1430 symbol__match_regex(al.sym, &parent_regex))
@@ -1480,11 +1507,8 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1480 struct addr_location *root_al, 1507 struct addr_location *root_al,
1481 int max_stack) 1508 int max_stack)
1482{ 1509{
1483 u8 cpumode = PERF_RECORD_MISC_USER;
1484 int chain_nr = min(max_stack, (int)chain->nr); 1510 int chain_nr = min(max_stack, (int)chain->nr);
1485 int i; 1511 int i, j, err;
1486 int j;
1487 int err;
1488 int skip_idx = -1; 1512 int skip_idx = -1;
1489 int first_call = 0; 1513 int first_call = 0;
1490 1514
@@ -1542,10 +1566,10 @@ static int thread__resolve_callchain_sample(struct thread *thread,
1542 1566
1543 for (i = 0; i < nr; i++) { 1567 for (i = 0; i < nr; i++) {
1544 err = add_callchain_ip(thread, parent, root_al, 1568 err = add_callchain_ip(thread, parent, root_al,
1545 -1, be[i].to); 1569 true, be[i].to);
1546 if (!err) 1570 if (!err)
1547 err = add_callchain_ip(thread, parent, root_al, 1571 err = add_callchain_ip(thread, parent, root_al,
1548 -1, be[i].from); 1572 true, be[i].from);
1549 if (err == -EINVAL) 1573 if (err == -EINVAL)
1550 break; 1574 break;
1551 if (err) 1575 if (err)
@@ -1574,36 +1598,10 @@ check_calls:
1574#endif 1598#endif
1575 ip = chain->ips[j]; 1599 ip = chain->ips[j];
1576 1600
1577 if (ip >= PERF_CONTEXT_MAX) { 1601 err = add_callchain_ip(thread, parent, root_al, false, ip);
1578 switch (ip) {
1579 case PERF_CONTEXT_HV:
1580 cpumode = PERF_RECORD_MISC_HYPERVISOR;
1581 break;
1582 case PERF_CONTEXT_KERNEL:
1583 cpumode = PERF_RECORD_MISC_KERNEL;
1584 break;
1585 case PERF_CONTEXT_USER:
1586 cpumode = PERF_RECORD_MISC_USER;
1587 break;
1588 default:
1589 pr_debug("invalid callchain context: "
1590 "%"PRId64"\n", (s64) ip);
1591 /*
1592 * It seems the callchain is corrupted.
1593 * Discard all.
1594 */
1595 callchain_cursor_reset(&callchain_cursor);
1596 return 0;
1597 }
1598 continue;
1599 }
1600 1602
1601 err = add_callchain_ip(thread, parent, root_al,
1602 cpumode, ip);
1603 if (err == -EINVAL)
1604 break;
1605 if (err) 1603 if (err)
1606 return err; 1604 return (err < 0) ? err : 0;
1607 } 1605 }
1608 1606
1609 return 0; 1607 return 0;
diff --git a/tools/perf/util/record.c b/tools/perf/util/record.c
index cf69325b985f..8acd0df88b5c 100644
--- a/tools/perf/util/record.c
+++ b/tools/perf/util/record.c
@@ -137,16 +137,7 @@ void perf_evlist__config(struct perf_evlist *evlist, struct record_opts *opts)
137 137
138static int get_max_rate(unsigned int *rate) 138static int get_max_rate(unsigned int *rate)
139{ 139{
140 char path[PATH_MAX]; 140 return sysctl__read_int("kernel/perf_event_max_sample_rate", (int *)rate);
141 const char *procfs = procfs__mountpoint();
142
143 if (!procfs)
144 return -1;
145
146 snprintf(path, PATH_MAX,
147 "%s/sys/kernel/perf_event_max_sample_rate", procfs);
148
149 return filename__read_int(path, (int *) rate);
150} 141}
151 142
152static int record_opts__config_freq(struct record_opts *opts) 143static int record_opts__config_freq(struct record_opts *opts)
diff --git a/tools/perf/util/srcline.c b/tools/perf/util/srcline.c
index e73b6a5c9e0f..c93fb0c5bd0b 100644
--- a/tools/perf/util/srcline.c
+++ b/tools/perf/util/srcline.c
@@ -20,7 +20,7 @@
20 20
21struct a2l_data { 21struct a2l_data {
22 const char *input; 22 const char *input;
23 unsigned long addr; 23 u64 addr;
24 24
25 bool found; 25 bool found;
26 const char *filename; 26 const char *filename;
@@ -147,7 +147,7 @@ static void addr2line_cleanup(struct a2l_data *a2l)
147 free(a2l); 147 free(a2l);
148} 148}
149 149
150static int addr2line(const char *dso_name, unsigned long addr, 150static int addr2line(const char *dso_name, u64 addr,
151 char **file, unsigned int *line, struct dso *dso) 151 char **file, unsigned int *line, struct dso *dso)
152{ 152{
153 int ret = 0; 153 int ret = 0;
@@ -193,7 +193,7 @@ void dso__free_a2l(struct dso *dso)
193 193
194#else /* HAVE_LIBBFD_SUPPORT */ 194#else /* HAVE_LIBBFD_SUPPORT */
195 195
196static int addr2line(const char *dso_name, unsigned long addr, 196static int addr2line(const char *dso_name, u64 addr,
197 char **file, unsigned int *line_nr, 197 char **file, unsigned int *line_nr,
198 struct dso *dso __maybe_unused) 198 struct dso *dso __maybe_unused)
199{ 199{
@@ -252,7 +252,7 @@ void dso__free_a2l(struct dso *dso __maybe_unused)
252 */ 252 */
253#define A2L_FAIL_LIMIT 123 253#define A2L_FAIL_LIMIT 123
254 254
255char *get_srcline(struct dso *dso, unsigned long addr, struct symbol *sym, 255char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
256 bool show_sym) 256 bool show_sym)
257{ 257{
258 char *file = NULL; 258 char *file = NULL;
@@ -293,10 +293,10 @@ out:
293 dso__free_a2l(dso); 293 dso__free_a2l(dso);
294 } 294 }
295 if (sym) { 295 if (sym) {
296 if (asprintf(&srcline, "%s+%ld", show_sym ? sym->name : "", 296 if (asprintf(&srcline, "%s+%" PRIu64, show_sym ? sym->name : "",
297 addr - sym->start) < 0) 297 addr - sym->start) < 0)
298 return SRCLINE_UNKNOWN; 298 return SRCLINE_UNKNOWN;
299 } else if (asprintf(&srcline, "%s[%lx]", dso->short_name, addr) < 0) 299 } else if (asprintf(&srcline, "%s[%" PRIx64 "]", dso->short_name, addr) < 0)
300 return SRCLINE_UNKNOWN; 300 return SRCLINE_UNKNOWN;
301 return srcline; 301 return srcline;
302} 302}
diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c
index fa585c63f56a..d7efb03b3f9a 100644
--- a/tools/perf/util/symbol-minimal.c
+++ b/tools/perf/util/symbol-minimal.c
@@ -129,6 +129,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
129 129
130 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { 130 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
131 void *tmp; 131 void *tmp;
132 long offset;
132 133
133 if (need_swap) { 134 if (need_swap) {
134 phdr->p_type = bswap_32(phdr->p_type); 135 phdr->p_type = bswap_32(phdr->p_type);
@@ -140,12 +141,13 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
140 continue; 141 continue;
141 142
142 buf_size = phdr->p_filesz; 143 buf_size = phdr->p_filesz;
144 offset = phdr->p_offset;
143 tmp = realloc(buf, buf_size); 145 tmp = realloc(buf, buf_size);
144 if (tmp == NULL) 146 if (tmp == NULL)
145 goto out_free; 147 goto out_free;
146 148
147 buf = tmp; 149 buf = tmp;
148 fseek(fp, phdr->p_offset, SEEK_SET); 150 fseek(fp, offset, SEEK_SET);
149 if (fread(buf, buf_size, 1, fp) != 1) 151 if (fread(buf, buf_size, 1, fp) != 1)
150 goto out_free; 152 goto out_free;
151 153
@@ -178,6 +180,7 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
178 180
179 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) { 181 for (i = 0, phdr = buf; i < ehdr.e_phnum; i++, phdr++) {
180 void *tmp; 182 void *tmp;
183 long offset;
181 184
182 if (need_swap) { 185 if (need_swap) {
183 phdr->p_type = bswap_32(phdr->p_type); 186 phdr->p_type = bswap_32(phdr->p_type);
@@ -189,12 +192,13 @@ int filename__read_build_id(const char *filename, void *bf, size_t size)
189 continue; 192 continue;
190 193
191 buf_size = phdr->p_filesz; 194 buf_size = phdr->p_filesz;
195 offset = phdr->p_offset;
192 tmp = realloc(buf, buf_size); 196 tmp = realloc(buf, buf_size);
193 if (tmp == NULL) 197 if (tmp == NULL)
194 goto out_free; 198 goto out_free;
195 199
196 buf = tmp; 200 buf = tmp;
197 fseek(fp, phdr->p_offset, SEEK_SET); 201 fseek(fp, offset, SEEK_SET);
198 if (fread(buf, buf_size, 1, fp) != 1) 202 if (fread(buf, buf_size, 1, fp) != 1)
199 goto out_free; 203 goto out_free;
200 204
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c
index d5eab3f3323f..b86744f29eef 100644
--- a/tools/perf/util/util.c
+++ b/tools/perf/util/util.c
@@ -442,23 +442,6 @@ unsigned long parse_tag_value(const char *str, struct parse_tag *tags)
442 return (unsigned long) -1; 442 return (unsigned long) -1;
443} 443}
444 444
445int filename__read_int(const char *filename, int *value)
446{
447 char line[64];
448 int fd = open(filename, O_RDONLY), err = -1;
449
450 if (fd < 0)
451 return -1;
452
453 if (read(fd, line, sizeof(line)) > 0) {
454 *value = atoi(line);
455 err = 0;
456 }
457
458 close(fd);
459 return err;
460}
461
462int filename__read_str(const char *filename, char **buf, size_t *sizep) 445int filename__read_str(const char *filename, char **buf, size_t *sizep)
463{ 446{
464 size_t size = 0, alloc_size = 0; 447 size_t size = 0, alloc_size = 0;
@@ -523,16 +506,9 @@ const char *get_filename_for_perf_kvm(void)
523 506
524int perf_event_paranoid(void) 507int perf_event_paranoid(void)
525{ 508{
526 char path[PATH_MAX];
527 const char *procfs = procfs__mountpoint();
528 int value; 509 int value;
529 510
530 if (!procfs) 511 if (sysctl__read_int("kernel/perf_event_paranoid", &value))
531 return INT_MAX;
532
533 scnprintf(path, PATH_MAX, "%s/sys/kernel/perf_event_paranoid", procfs);
534
535 if (filename__read_int(path, &value))
536 return INT_MAX; 512 return INT_MAX;
537 513
538 return value; 514 return value;
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index 419bee030f83..027a5153495c 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -153,7 +153,7 @@ extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2)))
153extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); 153extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN);
154 154
155extern int prefixcmp(const char *str, const char *prefix); 155extern int prefixcmp(const char *str, const char *prefix);
156extern void set_buildid_dir(void); 156extern void set_buildid_dir(const char *dir);
157 157
158static inline const char *skip_prefix(const char *str, const char *prefix) 158static inline const char *skip_prefix(const char *str, const char *prefix)
159{ 159{
@@ -269,35 +269,6 @@ void event_attr_init(struct perf_event_attr *attr);
269#define _STR(x) #x 269#define _STR(x) #x
270#define STR(x) _STR(x) 270#define STR(x) _STR(x)
271 271
272/*
273 * Determine whether some value is a power of two, where zero is
274 * *not* considered a power of two.
275 */
276
277static inline __attribute__((const))
278bool is_power_of_2(unsigned long n)
279{
280 return (n != 0 && ((n & (n - 1)) == 0));
281}
282
283static inline unsigned next_pow2(unsigned x)
284{
285 if (!x)
286 return 1;
287 return 1ULL << (32 - __builtin_clz(x - 1));
288}
289
290static inline unsigned long next_pow2_l(unsigned long x)
291{
292#if BITS_PER_LONG == 64
293 if (x <= (1UL << 31))
294 return next_pow2(x);
295 return (unsigned long)next_pow2(x >> 32) << 32;
296#else
297 return next_pow2(x);
298#endif
299}
300
301size_t hex_width(u64 v); 272size_t hex_width(u64 v);
302int hex2u64(const char *ptr, u64 *val); 273int hex2u64(const char *ptr, u64 *val);
303 274
@@ -339,11 +310,10 @@ static inline int path__join3(char *bf, size_t size,
339struct dso; 310struct dso;
340struct symbol; 311struct symbol;
341 312
342char *get_srcline(struct dso *dso, unsigned long addr, struct symbol *sym, 313char *get_srcline(struct dso *dso, u64 addr, struct symbol *sym,
343 bool show_sym); 314 bool show_sym);
344void free_srcline(char *srcline); 315void free_srcline(char *srcline);
345 316
346int filename__read_int(const char *filename, int *value);
347int filename__read_str(const char *filename, char **buf, size_t *sizep); 317int filename__read_str(const char *filename, char **buf, size_t *sizep);
348int perf_event_paranoid(void); 318int perf_event_paranoid(void);
349 319
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index bf1398180785..b9cd036f0442 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -684,11 +684,8 @@ sub set_value {
684 } 684 }
685 ${$overrides}{$lvalue} = $prvalue; 685 ${$overrides}{$lvalue} = $prvalue;
686 } 686 }
687 if ($rvalue =~ /^\s*$/) { 687
688 delete $opt{$lvalue}; 688 $opt{$lvalue} = $prvalue;
689 } else {
690 $opt{$lvalue} = $prvalue;
691 }
692} 689}
693 690
694sub set_eval { 691sub set_eval {
@@ -2005,7 +2002,7 @@ sub get_version {
2005 # get the release name 2002 # get the release name
2006 return if ($have_version); 2003 return if ($have_version);
2007 doprint "$make kernelrelease ... "; 2004 doprint "$make kernelrelease ... ";
2008 $version = `$make kernelrelease | tail -1`; 2005 $version = `$make -s kernelrelease | tail -1`;
2009 chomp($version); 2006 chomp($version);
2010 doprint "$version\n"; 2007 doprint "$version\n";
2011 $have_version = 1; 2008 $have_version = 1;
@@ -3571,7 +3568,9 @@ sub test_this_config {
3571 undef %configs; 3568 undef %configs;
3572 assign_configs \%configs, $output_config; 3569 assign_configs \%configs, $output_config;
3573 3570
3574 return $config if (!defined($configs{$config})); 3571 if (!defined($configs{$config}) || $configs{$config} =~ /^#/) {
3572 return $config;
3573 }
3575 3574
3576 doprint "disabling config $config did not change .config\n"; 3575 doprint "disabling config $config did not change .config\n";
3577 3576
@@ -3945,12 +3944,22 @@ for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) {
3945 } 3944 }
3946} 3945}
3947 3946
3947sub option_defined {
3948 my ($option) = @_;
3949
3950 if (defined($opt{$option}) && $opt{$option} !~ /^\s*$/) {
3951 return 1;
3952 }
3953
3954 return 0;
3955}
3956
3948sub __set_test_option { 3957sub __set_test_option {
3949 my ($name, $i) = @_; 3958 my ($name, $i) = @_;
3950 3959
3951 my $option = "$name\[$i\]"; 3960 my $option = "$name\[$i\]";
3952 3961
3953 if (defined($opt{$option})) { 3962 if (option_defined($option)) {
3954 return $opt{$option}; 3963 return $opt{$option};
3955 } 3964 }
3956 3965
@@ -3958,13 +3967,13 @@ sub __set_test_option {
3958 if ($i >= $test && 3967 if ($i >= $test &&
3959 $i < $test + $repeat_tests{$test}) { 3968 $i < $test + $repeat_tests{$test}) {
3960 $option = "$name\[$test\]"; 3969 $option = "$name\[$test\]";
3961 if (defined($opt{$option})) { 3970 if (option_defined($option)) {
3962 return $opt{$option}; 3971 return $opt{$option};
3963 } 3972 }
3964 } 3973 }
3965 } 3974 }
3966 3975
3967 if (defined($opt{$name})) { 3976 if (option_defined($name)) {
3968 return $opt{$name}; 3977 return $opt{$name};
3969 } 3978 }
3970 3979
@@ -4077,8 +4086,14 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) {
4077 my $installme = ""; 4086 my $installme = "";
4078 $installme = " no_install" if ($no_install); 4087 $installme = " no_install" if ($no_install);
4079 4088
4089 my $name = "";
4090
4091 if (defined($test_name)) {
4092 $name = " ($test_name)";
4093 }
4094
4080 doprint "\n\n"; 4095 doprint "\n\n";
4081 doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type$installme\n\n"; 4096 doprint "RUNNING TEST $i of $opt{NUM_TESTS}$name with option $test_type $run_type$installme\n\n";
4082 4097
4083 if (defined($pre_test)) { 4098 if (defined($pre_test)) {
4084 run_command $pre_test; 4099 run_command $pre_test;
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 45f145c6f843..4e511221a0c1 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -1,20 +1,23 @@
1TARGETS = breakpoints 1TARGETS = breakpoints
2TARGETS += cpu-hotplug 2TARGETS += cpu-hotplug
3TARGETS += efivarfs 3TARGETS += efivarfs
4TARGETS += exec
5TARGETS += firmware
6TARGETS += ftrace
4TARGETS += kcmp 7TARGETS += kcmp
5TARGETS += memfd 8TARGETS += memfd
6TARGETS += memory-hotplug 9TARGETS += memory-hotplug
7TARGETS += mqueue
8TARGETS += mount 10TARGETS += mount
11TARGETS += mqueue
9TARGETS += net 12TARGETS += net
13TARGETS += powerpc
10TARGETS += ptrace 14TARGETS += ptrace
15TARGETS += size
16TARGETS += sysctl
11TARGETS += timers 17TARGETS += timers
12TARGETS += vm
13TARGETS += powerpc
14TARGETS += user 18TARGETS += user
15TARGETS += sysctl 19TARGETS += vm
16TARGETS += firmware 20#Please keep the TARGETS list alphabetically sorted
17TARGETS += ftrace
18 21
19TARGETS_HOTPLUG = cpu-hotplug 22TARGETS_HOTPLUG = cpu-hotplug
20TARGETS_HOTPLUG += memory-hotplug 23TARGETS_HOTPLUG += memory-hotplug
diff --git a/tools/testing/selftests/README.txt b/tools/testing/selftests/README.txt
deleted file mode 100644
index 2660d5ff9179..000000000000
--- a/tools/testing/selftests/README.txt
+++ /dev/null
@@ -1,61 +0,0 @@
1Linux Kernel Selftests
2
3The kernel contains a set of "self tests" under the tools/testing/selftests/
4directory. These are intended to be small unit tests to exercise individual
5code paths in the kernel.
6
7On some systems, hot-plug tests could hang forever waiting for cpu and
8memory to be ready to be offlined. A special hot-plug target is created
9to run full range of hot-plug tests. In default mode, hot-plug tests run
10in safe mode with a limited scope. In limited mode, cpu-hotplug test is
11run on a single cpu as opposed to all hotplug capable cpus, and memory
12hotplug test is run on 2% of hotplug capable memory instead of 10%.
13
14Running the selftests (hotplug tests are run in limited mode)
15=============================================================
16
17To build the tests:
18
19 $ make -C tools/testing/selftests
20
21
22To run the tests:
23
24 $ make -C tools/testing/selftests run_tests
25
26- note that some tests will require root privileges.
27
28To run only tests targeted for a single subsystem: (including
29hotplug targets in limited mode)
30
31 $ make -C tools/testing/selftests TARGETS=cpu-hotplug run_tests
32
33See the top-level tools/testing/selftests/Makefile for the list of all possible
34targets.
35
36Running the full range hotplug selftests
37========================================
38
39To build the tests:
40
41 $ make -C tools/testing/selftests hotplug
42
43To run the tests:
44
45 $ make -C tools/testing/selftests run_hotplug
46
47- note that some tests will require root privileges.
48
49Contributing new tests
50======================
51
52In general, the rules for for selftests are
53
54 * Do as much as you can if you're not root;
55
56 * Don't take too long;
57
58 * Don't break the build on any architecture, and
59
60 * Don't cause the top-level "make run_tests" to fail if your feature is
61 unconfigured.
diff --git a/tools/testing/selftests/breakpoints/breakpoint_test.c b/tools/testing/selftests/breakpoints/breakpoint_test.c
index a0743f3b2b57..120895ab5505 100644
--- a/tools/testing/selftests/breakpoints/breakpoint_test.c
+++ b/tools/testing/selftests/breakpoints/breakpoint_test.c
@@ -17,6 +17,8 @@
17#include <sys/types.h> 17#include <sys/types.h>
18#include <sys/wait.h> 18#include <sys/wait.h>
19 19
20#include "../kselftest.h"
21
20 22
21/* Breakpoint access modes */ 23/* Breakpoint access modes */
22enum { 24enum {
@@ -42,7 +44,7 @@ static void set_breakpoint_addr(void *addr, int n)
42 offsetof(struct user, u_debugreg[n]), addr); 44 offsetof(struct user, u_debugreg[n]), addr);
43 if (ret) { 45 if (ret) {
44 perror("Can't set breakpoint addr\n"); 46 perror("Can't set breakpoint addr\n");
45 exit(-1); 47 ksft_exit_fail();
46 } 48 }
47} 49}
48 50
@@ -105,7 +107,7 @@ static void toggle_breakpoint(int n, int type, int len,
105 offsetof(struct user, u_debugreg[7]), dr7); 107 offsetof(struct user, u_debugreg[7]), dr7);
106 if (ret) { 108 if (ret) {
107 perror("Can't set dr7"); 109 perror("Can't set dr7");
108 exit(-1); 110 ksft_exit_fail();
109 } 111 }
110} 112}
111 113
@@ -275,7 +277,7 @@ static void check_success(const char *msg)
275 msg2 = "Ok"; 277 msg2 = "Ok";
276 if (ptrace(PTRACE_POKEDATA, child_pid, &trapped, 1)) { 278 if (ptrace(PTRACE_POKEDATA, child_pid, &trapped, 1)) {
277 perror("Can't poke\n"); 279 perror("Can't poke\n");
278 exit(-1); 280 ksft_exit_fail();
279 } 281 }
280 } 282 }
281 283
@@ -390,5 +392,5 @@ int main(int argc, char **argv)
390 392
391 wait(NULL); 393 wait(NULL);
392 394
393 return 0; 395 return ksft_exit_pass();
394} 396}
diff --git a/tools/testing/selftests/exec/.gitignore b/tools/testing/selftests/exec/.gitignore
new file mode 100644
index 000000000000..64073e050c6a
--- /dev/null
+++ b/tools/testing/selftests/exec/.gitignore
@@ -0,0 +1,9 @@
1subdir*
2script*
3execveat
4execveat.symlink
5execveat.moved
6execveat.path.ephemeral
7execveat.ephemeral
8execveat.denatured
9xxxxxxxx* \ No newline at end of file
diff --git a/tools/testing/selftests/exec/Makefile b/tools/testing/selftests/exec/Makefile
new file mode 100644
index 000000000000..66dfc2ce1788
--- /dev/null
+++ b/tools/testing/selftests/exec/Makefile
@@ -0,0 +1,25 @@
1CC = $(CROSS_COMPILE)gcc
2CFLAGS = -Wall
3BINARIES = execveat
4DEPS = execveat.symlink execveat.denatured script subdir
5all: $(BINARIES) $(DEPS)
6
7subdir:
8 mkdir -p $@
9script:
10 echo '#!/bin/sh' > $@
11 echo 'exit $$*' >> $@
12 chmod +x $@
13execveat.symlink: execveat
14 ln -s -f $< $@
15execveat.denatured: execveat
16 cp $< $@
17 chmod -x $@
18%: %.c
19 $(CC) $(CFLAGS) -o $@ $^
20
21run_tests: all
22 ./execveat
23
24clean:
25 rm -rf $(BINARIES) $(DEPS) subdir.moved execveat.moved xxxxx*
diff --git a/tools/testing/selftests/exec/execveat.c b/tools/testing/selftests/exec/execveat.c
new file mode 100644
index 000000000000..33a5c06d95ca
--- /dev/null
+++ b/tools/testing/selftests/exec/execveat.c
@@ -0,0 +1,397 @@
1/*
2 * Copyright (c) 2014 Google, Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2
5 *
6 * Selftests for execveat(2).
7 */
8
9#define _GNU_SOURCE /* to get O_PATH, AT_EMPTY_PATH */
10#include <sys/sendfile.h>
11#include <sys/stat.h>
12#include <sys/syscall.h>
13#include <sys/types.h>
14#include <sys/wait.h>
15#include <errno.h>
16#include <fcntl.h>
17#include <limits.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include <unistd.h>
22
23static char longpath[2 * PATH_MAX] = "";
24static char *envp[] = { "IN_TEST=yes", NULL, NULL };
25static char *argv[] = { "execveat", "99", NULL };
26
27static int execveat_(int fd, const char *path, char **argv, char **envp,
28 int flags)
29{
30#ifdef __NR_execveat
31 return syscall(__NR_execveat, fd, path, argv, envp, flags);
32#else
33 errno = -ENOSYS;
34 return -1;
35#endif
36}
37
38#define check_execveat_fail(fd, path, flags, errno) \
39 _check_execveat_fail(fd, path, flags, errno, #errno)
40static int _check_execveat_fail(int fd, const char *path, int flags,
41 int expected_errno, const char *errno_str)
42{
43 int rc;
44
45 errno = 0;
46 printf("Check failure of execveat(%d, '%s', %d) with %s... ",
47 fd, path?:"(null)", flags, errno_str);
48 rc = execveat_(fd, path, argv, envp, flags);
49
50 if (rc > 0) {
51 printf("[FAIL] (unexpected success from execveat(2))\n");
52 return 1;
53 }
54 if (errno != expected_errno) {
55 printf("[FAIL] (expected errno %d (%s) not %d (%s)\n",
56 expected_errno, strerror(expected_errno),
57 errno, strerror(errno));
58 return 1;
59 }
60 printf("[OK]\n");
61 return 0;
62}
63
64static int check_execveat_invoked_rc(int fd, const char *path, int flags,
65 int expected_rc)
66{
67 int status;
68 int rc;
69 pid_t child;
70 int pathlen = path ? strlen(path) : 0;
71
72 if (pathlen > 40)
73 printf("Check success of execveat(%d, '%.20s...%s', %d)... ",
74 fd, path, (path + pathlen - 20), flags);
75 else
76 printf("Check success of execveat(%d, '%s', %d)... ",
77 fd, path?:"(null)", flags);
78 child = fork();
79 if (child < 0) {
80 printf("[FAIL] (fork() failed)\n");
81 return 1;
82 }
83 if (child == 0) {
84 /* Child: do execveat(). */
85 rc = execveat_(fd, path, argv, envp, flags);
86 printf("[FAIL]: execveat() failed, rc=%d errno=%d (%s)\n",
87 rc, errno, strerror(errno));
88 exit(1); /* should not reach here */
89 }
90 /* Parent: wait for & check child's exit status. */
91 rc = waitpid(child, &status, 0);
92 if (rc != child) {
93 printf("[FAIL] (waitpid(%d,...) returned %d)\n", child, rc);
94 return 1;
95 }
96 if (!WIFEXITED(status)) {
97 printf("[FAIL] (child %d did not exit cleanly, status=%08x)\n",
98 child, status);
99 return 1;
100 }
101 if (WEXITSTATUS(status) != expected_rc) {
102 printf("[FAIL] (child %d exited with %d not %d)\n",
103 child, WEXITSTATUS(status), expected_rc);
104 return 1;
105 }
106 printf("[OK]\n");
107 return 0;
108}
109
110static int check_execveat(int fd, const char *path, int flags)
111{
112 return check_execveat_invoked_rc(fd, path, flags, 99);
113}
114
115static char *concat(const char *left, const char *right)
116{
117 char *result = malloc(strlen(left) + strlen(right) + 1);
118
119 strcpy(result, left);
120 strcat(result, right);
121 return result;
122}
123
124static int open_or_die(const char *filename, int flags)
125{
126 int fd = open(filename, flags);
127
128 if (fd < 0) {
129 printf("Failed to open '%s'; "
130 "check prerequisites are available\n", filename);
131 exit(1);
132 }
133 return fd;
134}
135
136static void exe_cp(const char *src, const char *dest)
137{
138 int in_fd = open_or_die(src, O_RDONLY);
139 int out_fd = open(dest, O_RDWR|O_CREAT|O_TRUNC, 0755);
140 struct stat info;
141
142 fstat(in_fd, &info);
143 sendfile(out_fd, in_fd, NULL, info.st_size);
144 close(in_fd);
145 close(out_fd);
146}
147
148#define XX_DIR_LEN 200
149static int check_execveat_pathmax(int dot_dfd, const char *src, int is_script)
150{
151 int fail = 0;
152 int ii, count, len;
153 char longname[XX_DIR_LEN + 1];
154 int fd;
155
156 if (*longpath == '\0') {
157 /* Create a filename close to PATH_MAX in length */
158 memset(longname, 'x', XX_DIR_LEN - 1);
159 longname[XX_DIR_LEN - 1] = '/';
160 longname[XX_DIR_LEN] = '\0';
161 count = (PATH_MAX - 3) / XX_DIR_LEN;
162 for (ii = 0; ii < count; ii++) {
163 strcat(longpath, longname);
164 mkdir(longpath, 0755);
165 }
166 len = (PATH_MAX - 3) - (count * XX_DIR_LEN);
167 if (len <= 0)
168 len = 1;
169 memset(longname, 'y', len);
170 longname[len] = '\0';
171 strcat(longpath, longname);
172 }
173 exe_cp(src, longpath);
174
175 /*
176 * Execute as a pre-opened file descriptor, which works whether this is
177 * a script or not (because the interpreter sees a filename like
178 * "/dev/fd/20").
179 */
180 fd = open(longpath, O_RDONLY);
181 if (fd > 0) {
182 printf("Invoke copy of '%s' via filename of length %lu:\n",
183 src, strlen(longpath));
184 fail += check_execveat(fd, "", AT_EMPTY_PATH);
185 } else {
186 printf("Failed to open length %lu filename, errno=%d (%s)\n",
187 strlen(longpath), errno, strerror(errno));
188 fail++;
189 }
190
191 /*
192 * Execute as a long pathname relative to ".". If this is a script,
193 * the interpreter will launch but fail to open the script because its
194 * name ("/dev/fd/5/xxx....") is bigger than PATH_MAX.
195 */
196 if (is_script)
197 fail += check_execveat_invoked_rc(dot_dfd, longpath, 0, 127);
198 else
199 fail += check_execveat(dot_dfd, longpath, 0);
200
201 return fail;
202}
203
204static int run_tests(void)
205{
206 int fail = 0;
207 char *fullname = realpath("execveat", NULL);
208 char *fullname_script = realpath("script", NULL);
209 char *fullname_symlink = concat(fullname, ".symlink");
210 int subdir_dfd = open_or_die("subdir", O_DIRECTORY|O_RDONLY);
211 int subdir_dfd_ephemeral = open_or_die("subdir.ephemeral",
212 O_DIRECTORY|O_RDONLY);
213 int dot_dfd = open_or_die(".", O_DIRECTORY|O_RDONLY);
214 int dot_dfd_path = open_or_die(".", O_DIRECTORY|O_RDONLY|O_PATH);
215 int dot_dfd_cloexec = open_or_die(".", O_DIRECTORY|O_RDONLY|O_CLOEXEC);
216 int fd = open_or_die("execveat", O_RDONLY);
217 int fd_path = open_or_die("execveat", O_RDONLY|O_PATH);
218 int fd_symlink = open_or_die("execveat.symlink", O_RDONLY);
219 int fd_denatured = open_or_die("execveat.denatured", O_RDONLY);
220 int fd_denatured_path = open_or_die("execveat.denatured",
221 O_RDONLY|O_PATH);
222 int fd_script = open_or_die("script", O_RDONLY);
223 int fd_ephemeral = open_or_die("execveat.ephemeral", O_RDONLY);
224 int fd_ephemeral_path = open_or_die("execveat.path.ephemeral",
225 O_RDONLY|O_PATH);
226 int fd_script_ephemeral = open_or_die("script.ephemeral", O_RDONLY);
227 int fd_cloexec = open_or_die("execveat", O_RDONLY|O_CLOEXEC);
228 int fd_script_cloexec = open_or_die("script", O_RDONLY|O_CLOEXEC);
229
230 /* Change file position to confirm it doesn't affect anything */
231 lseek(fd, 10, SEEK_SET);
232
233 /* Normal executable file: */
234 /* dfd + path */
235 fail += check_execveat(subdir_dfd, "../execveat", 0);
236 fail += check_execveat(dot_dfd, "execveat", 0);
237 fail += check_execveat(dot_dfd_path, "execveat", 0);
238 /* absolute path */
239 fail += check_execveat(AT_FDCWD, fullname, 0);
240 /* absolute path with nonsense dfd */
241 fail += check_execveat(99, fullname, 0);
242 /* fd + no path */
243 fail += check_execveat(fd, "", AT_EMPTY_PATH);
244 /* O_CLOEXEC fd + no path */
245 fail += check_execveat(fd_cloexec, "", AT_EMPTY_PATH);
246 /* O_PATH fd */
247 fail += check_execveat(fd_path, "", AT_EMPTY_PATH);
248
249 /* Mess with executable file that's already open: */
250 /* fd + no path to a file that's been renamed */
251 rename("execveat.ephemeral", "execveat.moved");
252 fail += check_execveat(fd_ephemeral, "", AT_EMPTY_PATH);
253 /* fd + no path to a file that's been deleted */
254 unlink("execveat.moved"); /* remove the file now fd open */
255 fail += check_execveat(fd_ephemeral, "", AT_EMPTY_PATH);
256
257 /* Mess with executable file that's already open with O_PATH */
258 /* fd + no path to a file that's been deleted */
259 unlink("execveat.path.ephemeral");
260 fail += check_execveat(fd_ephemeral_path, "", AT_EMPTY_PATH);
261
262 /* Invalid argument failures */
263 fail += check_execveat_fail(fd, "", 0, ENOENT);
264 fail += check_execveat_fail(fd, NULL, AT_EMPTY_PATH, EFAULT);
265
266 /* Symlink to executable file: */
267 /* dfd + path */
268 fail += check_execveat(dot_dfd, "execveat.symlink", 0);
269 fail += check_execveat(dot_dfd_path, "execveat.symlink", 0);
270 /* absolute path */
271 fail += check_execveat(AT_FDCWD, fullname_symlink, 0);
272 /* fd + no path, even with AT_SYMLINK_NOFOLLOW (already followed) */
273 fail += check_execveat(fd_symlink, "", AT_EMPTY_PATH);
274 fail += check_execveat(fd_symlink, "",
275 AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW);
276
277 /* Symlink fails when AT_SYMLINK_NOFOLLOW set: */
278 /* dfd + path */
279 fail += check_execveat_fail(dot_dfd, "execveat.symlink",
280 AT_SYMLINK_NOFOLLOW, ELOOP);
281 fail += check_execveat_fail(dot_dfd_path, "execveat.symlink",
282 AT_SYMLINK_NOFOLLOW, ELOOP);
283 /* absolute path */
284 fail += check_execveat_fail(AT_FDCWD, fullname_symlink,
285 AT_SYMLINK_NOFOLLOW, ELOOP);
286
287 /* Shell script wrapping executable file: */
288 /* dfd + path */
289 fail += check_execveat(subdir_dfd, "../script", 0);
290 fail += check_execveat(dot_dfd, "script", 0);
291 fail += check_execveat(dot_dfd_path, "script", 0);
292 /* absolute path */
293 fail += check_execveat(AT_FDCWD, fullname_script, 0);
294 /* fd + no path */
295 fail += check_execveat(fd_script, "", AT_EMPTY_PATH);
296 fail += check_execveat(fd_script, "",
297 AT_EMPTY_PATH|AT_SYMLINK_NOFOLLOW);
298 /* O_CLOEXEC fd fails for a script (as script file inaccessible) */
299 fail += check_execveat_fail(fd_script_cloexec, "", AT_EMPTY_PATH,
300 ENOENT);
301 fail += check_execveat_fail(dot_dfd_cloexec, "script", 0, ENOENT);
302
303 /* Mess with script file that's already open: */
304 /* fd + no path to a file that's been renamed */
305 rename("script.ephemeral", "script.moved");
306 fail += check_execveat(fd_script_ephemeral, "", AT_EMPTY_PATH);
307 /* fd + no path to a file that's been deleted */
308 unlink("script.moved"); /* remove the file while fd open */
309 fail += check_execveat(fd_script_ephemeral, "", AT_EMPTY_PATH);
310
311 /* Rename a subdirectory in the path: */
312 rename("subdir.ephemeral", "subdir.moved");
313 fail += check_execveat(subdir_dfd_ephemeral, "../script", 0);
314 fail += check_execveat(subdir_dfd_ephemeral, "script", 0);
315 /* Remove the subdir and its contents */
316 unlink("subdir.moved/script");
317 unlink("subdir.moved");
318 /* Shell loads via deleted subdir OK because name starts with .. */
319 fail += check_execveat(subdir_dfd_ephemeral, "../script", 0);
320 fail += check_execveat_fail(subdir_dfd_ephemeral, "script", 0, ENOENT);
321
322 /* Flag values other than AT_SYMLINK_NOFOLLOW => EINVAL */
323 fail += check_execveat_fail(dot_dfd, "execveat", 0xFFFF, EINVAL);
324 /* Invalid path => ENOENT */
325 fail += check_execveat_fail(dot_dfd, "no-such-file", 0, ENOENT);
326 fail += check_execveat_fail(dot_dfd_path, "no-such-file", 0, ENOENT);
327 fail += check_execveat_fail(AT_FDCWD, "no-such-file", 0, ENOENT);
328 /* Attempt to execute directory => EACCES */
329 fail += check_execveat_fail(dot_dfd, "", AT_EMPTY_PATH, EACCES);
330 /* Attempt to execute non-executable => EACCES */
331 fail += check_execveat_fail(dot_dfd, "Makefile", 0, EACCES);
332 fail += check_execveat_fail(fd_denatured, "", AT_EMPTY_PATH, EACCES);
333 fail += check_execveat_fail(fd_denatured_path, "", AT_EMPTY_PATH,
334 EACCES);
335 /* Attempt to execute nonsense FD => EBADF */
336 fail += check_execveat_fail(99, "", AT_EMPTY_PATH, EBADF);
337 fail += check_execveat_fail(99, "execveat", 0, EBADF);
338 /* Attempt to execute relative to non-directory => ENOTDIR */
339 fail += check_execveat_fail(fd, "execveat", 0, ENOTDIR);
340
341 fail += check_execveat_pathmax(dot_dfd, "execveat", 0);
342 fail += check_execveat_pathmax(dot_dfd, "script", 1);
343 return fail;
344}
345
346static void prerequisites(void)
347{
348 int fd;
349 const char *script = "#!/bin/sh\nexit $*\n";
350
351 /* Create ephemeral copies of files */
352 exe_cp("execveat", "execveat.ephemeral");
353 exe_cp("execveat", "execveat.path.ephemeral");
354 exe_cp("script", "script.ephemeral");
355 mkdir("subdir.ephemeral", 0755);
356
357 fd = open("subdir.ephemeral/script", O_RDWR|O_CREAT|O_TRUNC, 0755);
358 write(fd, script, strlen(script));
359 close(fd);
360}
361
362int main(int argc, char **argv)
363{
364 int ii;
365 int rc;
366 const char *verbose = getenv("VERBOSE");
367
368 if (argc >= 2) {
369 /* If we are invoked with an argument, don't run tests. */
370 const char *in_test = getenv("IN_TEST");
371
372 if (verbose) {
373 printf(" invoked with:");
374 for (ii = 0; ii < argc; ii++)
375 printf(" [%d]='%s'", ii, argv[ii]);
376 printf("\n");
377 }
378
379 /* Check expected environment transferred. */
380 if (!in_test || strcmp(in_test, "yes") != 0) {
381 printf("[FAIL] (no IN_TEST=yes in env)\n");
382 return 1;
383 }
384
385 /* Use the final argument as an exit code. */
386 rc = atoi(argv[argc - 1]);
387 fflush(stdout);
388 } else {
389 prerequisites();
390 if (verbose)
391 envp[1] = "VERBOSE=1";
392 rc = run_tests();
393 if (rc > 0)
394 printf("%d tests failed\n", rc);
395 }
396 return rc;
397}
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest
index 515247601df4..da48812ab95e 100755
--- a/tools/testing/selftests/ftrace/ftracetest
+++ b/tools/testing/selftests/ftrace/ftracetest
@@ -13,6 +13,7 @@ echo "Usage: ftracetest [options] [testcase(s)] [testcase-directory(s)]"
13echo " Options:" 13echo " Options:"
14echo " -h|--help Show help message" 14echo " -h|--help Show help message"
15echo " -k|--keep Keep passed test logs" 15echo " -k|--keep Keep passed test logs"
16echo " -v|--verbose Show all stdout messages in testcases"
16echo " -d|--debug Debug mode (trace all shell commands)" 17echo " -d|--debug Debug mode (trace all shell commands)"
17exit $1 18exit $1
18} 19}
@@ -37,7 +38,7 @@ abspath() {
37} 38}
38 39
39find_testcases() { #directory 40find_testcases() { #directory
40 echo `find $1 -name \*.tc` 41 echo `find $1 -name \*.tc | sort`
41} 42}
42 43
43parse_opts() { # opts 44parse_opts() { # opts
@@ -53,6 +54,10 @@ parse_opts() { # opts
53 KEEP_LOG=1 54 KEEP_LOG=1
54 shift 1 55 shift 1
55 ;; 56 ;;
57 --verbose|-v)
58 VERBOSE=1
59 shift 1
60 ;;
56 --debug|-d) 61 --debug|-d)
57 DEBUG=1 62 DEBUG=1
58 shift 1 63 shift 1
@@ -90,6 +95,7 @@ TEST_CASES=`find_testcases $TEST_DIR`
90LOG_DIR=$TOP_DIR/logs/`date +%Y%m%d-%H%M%S`/ 95LOG_DIR=$TOP_DIR/logs/`date +%Y%m%d-%H%M%S`/
91KEEP_LOG=0 96KEEP_LOG=0
92DEBUG=0 97DEBUG=0
98VERBOSE=0
93# Parse command-line options 99# Parse command-line options
94parse_opts $* 100parse_opts $*
95 101
@@ -135,15 +141,12 @@ TOTAL_RESULT=0
135CASENO=0 141CASENO=0
136testcase() { # testfile 142testcase() { # testfile
137 CASENO=$((CASENO+1)) 143 CASENO=$((CASENO+1))
138 prlog -n "[$CASENO]"`grep "^#[ \t]*description:" $1 | cut -f2 -d:` 144 desc=`grep "^#[ \t]*description:" $1 | cut -f2 -d:`
145 prlog -n "[$CASENO]$desc"
139} 146}
140 147
141eval_result() { # retval sigval 148eval_result() { # sigval
142 local retval=$2 149 case $1 in
143 if [ $2 -eq 0 ]; then
144 test $1 -ne 0 && retval=$FAIL
145 fi
146 case $retval in
147 $PASS) 150 $PASS)
148 prlog " [PASS]" 151 prlog " [PASS]"
149 PASSED_CASES="$PASSED_CASES $CASENO" 152 PASSED_CASES="$PASSED_CASES $CASENO"
@@ -187,6 +190,9 @@ SIG_RESULT=
187SIG_BASE=36 # Use realtime signals 190SIG_BASE=36 # Use realtime signals
188SIG_PID=$$ 191SIG_PID=$$
189 192
193SIG_FAIL=$((SIG_BASE + FAIL))
194trap 'SIG_RESULT=$FAIL' $SIG_FAIL
195
190SIG_UNRESOLVED=$((SIG_BASE + UNRESOLVED)) 196SIG_UNRESOLVED=$((SIG_BASE + UNRESOLVED))
191exit_unresolved () { 197exit_unresolved () {
192 kill -s $SIG_UNRESOLVED $SIG_PID 198 kill -s $SIG_UNRESOLVED $SIG_PID
@@ -215,17 +221,25 @@ exit_xfail () {
215} 221}
216trap 'SIG_RESULT=$XFAIL' $SIG_XFAIL 222trap 'SIG_RESULT=$XFAIL' $SIG_XFAIL
217 223
224__run_test() { # testfile
225 # setup PID and PPID, $$ is not updated.
226 (cd $TRACING_DIR; read PID _ < /proc/self/stat ; set -e; set -x; . $1)
227 [ $? -ne 0 ] && kill -s $SIG_FAIL $SIG_PID
228}
229
218# Run one test case 230# Run one test case
219run_test() { # testfile 231run_test() { # testfile
220 local testname=`basename $1` 232 local testname=`basename $1`
221 local testlog=`mktemp --tmpdir=$LOG_DIR ${testname}-XXXXXX.log` 233 local testlog=`mktemp $LOG_DIR/${testname}-log.XXXXXX`
222 testcase $1 234 testcase $1
223 echo "execute: "$1 > $testlog 235 echo "execute: "$1 > $testlog
224 SIG_RESULT=0 236 SIG_RESULT=0
225 # setup PID and PPID, $$ is not updated. 237 if [ $VERBOSE -ne 0 ]; then
226 (cd $TRACING_DIR; read PID _ < /proc/self/stat ; 238 __run_test $1 2>> $testlog | tee -a $testlog
227 set -e; set -x; . $1) >> $testlog 2>&1 239 else
228 eval_result $? $SIG_RESULT 240 __run_test $1 >> $testlog 2>&1
241 fi
242 eval_result $SIG_RESULT
229 if [ $? -eq 0 ]; then 243 if [ $? -eq 0 ]; then
230 # Remove test log if the test was done as it was expected. 244 # Remove test log if the test was done as it was expected.
231 [ $KEEP_LOG -eq 0 ] && rm $testlog 245 [ $KEEP_LOG -eq 0 ] && rm $testlog
@@ -235,6 +249,9 @@ run_test() { # testfile
235 fi 249 fi
236} 250}
237 251
252# load in the helper functions
253. $TEST_DIR/functions
254
238# Main loop 255# Main loop
239for t in $TEST_CASES; do 256for t in $TEST_CASES; do
240 run_test $t 257 run_test $t
diff --git a/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc b/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc
new file mode 100644
index 000000000000..fd9c49a13612
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/00basic/basic4.tc
@@ -0,0 +1,5 @@
1#!/bin/sh
2# description: Basic event tracing check
3test -f available_events -a -f set_event -a -d events
4# check scheduler events are available
5grep -q sched available_events && exit 0 || exit -1 \ No newline at end of file
diff --git a/tools/testing/selftests/ftrace/test.d/event/event-enable.tc b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc
new file mode 100644
index 000000000000..668616d9bb03
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/event/event-enable.tc
@@ -0,0 +1,53 @@
1#!/bin/sh
2# description: event tracing - enable/disable with event level files
3
4do_reset() {
5 echo > set_event
6 clear_trace
7}
8
9fail() { #msg
10 do_reset
11 echo $1
12 exit -1
13}
14
15if [ ! -f set_event -o ! -d events/sched ]; then
16 echo "event tracing is not supported"
17 exit_unsupported
18fi
19
20reset_tracer
21do_reset
22
23echo 'sched:sched_switch' > set_event
24usleep 1
25
26count=`cat trace | grep sched_switch | wc -l`
27if [ $count -eq 0 ]; then
28 fail "sched_switch events are not recorded"
29fi
30
31do_reset
32
33echo 1 > events/sched/sched_switch/enable
34usleep 1
35
36count=`cat trace | grep sched_switch | wc -l`
37if [ $count -eq 0 ]; then
38 fail "sched_switch events are not recorded"
39fi
40
41do_reset
42
43echo 0 > events/sched/sched_switch/enable
44usleep 1
45
46count=`cat trace | grep sched_switch | wc -l`
47if [ $count -ne 0 ]; then
48 fail "sched_switch events should not be recorded"
49fi
50
51do_reset
52
53exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc
new file mode 100644
index 000000000000..655c415b6e7f
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/event/subsystem-enable.tc
@@ -0,0 +1,53 @@
1#!/bin/sh
2# description: event tracing - enable/disable with subsystem level files
3
4do_reset() {
5 echo > set_event
6 clear_trace
7}
8
9fail() { #msg
10 do_reset
11 echo $1
12 exit -1
13}
14
15if [ ! -f set_event -o ! -d events/sched ]; then
16 echo "event tracing is not supported"
17 exit_unsupported
18fi
19
20reset_tracer
21do_reset
22
23echo 'sched:*' > set_event
24usleep 1
25
26count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l`
27if [ $count -lt 3 ]; then
28 fail "at least fork, exec and exit events should be recorded"
29fi
30
31do_reset
32
33echo 1 > events/sched/enable
34usleep 1
35
36count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l`
37if [ $count -lt 3 ]; then
38 fail "at least fork, exec and exit events should be recorded"
39fi
40
41do_reset
42
43echo 0 > events/sched/enable
44usleep 1
45
46count=`cat trace | grep -v ^# | awk '{ print $5 }' | sort -u | wc -l`
47if [ $count -ne 0 ]; then
48 fail "any of scheduler events should not be recorded"
49fi
50
51do_reset
52
53exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc
new file mode 100644
index 000000000000..480845774007
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/event/toplevel-enable.tc
@@ -0,0 +1,47 @@
1#!/bin/sh
2# description: event tracing - enable/disable with top level files
3
4do_reset() {
5 echo > set_event
6 clear_trace
7}
8
9fail() { #msg
10 do_reset
11 echo $1
12 exit -1
13}
14
15if [ ! -f available_events -o ! -f set_event -o ! -d events ]; then
16 echo "event tracing is not supported"
17 exit_unsupported
18fi
19
20reset_tracer
21do_reset
22
23echo '*:*' > set_event
24count=`cat trace | grep -v ^# | wc -l`
25if [ $count -eq 0 ]; then
26 fail "none of events are recorded"
27fi
28
29do_reset
30
31echo 1 > events/enable
32count=`cat trace | grep -v ^# | wc -l`
33if [ $count -eq 0 ]; then
34 fail "none of events are recorded"
35fi
36
37do_reset
38
39echo 0 > events/enable
40count=`cat trace | grep -v ^# | wc -l`
41if [ $count -ne 0 ]; then
42 fail "any of events should not be recorded"
43fi
44
45do_reset
46
47exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc
new file mode 100644
index 000000000000..c15e018e0220
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter-stack.tc
@@ -0,0 +1,89 @@
1#!/bin/sh
2# description: ftrace - function graph filters with stack tracer
3
4# Make sure that function graph filtering works, and is not
5# affected by other tracers enabled (like stack tracer)
6
7if ! grep -q function_graph available_tracers; then
8 echo "no function graph tracer configured"
9 exit_unsupported
10fi
11
12if [ ! -f set_ftrace_filter ]; then
13 echo "set_ftrace_filter not found? Is dynamic ftrace not set?"
14 exit_unsupported
15fi
16
17do_reset() {
18 reset_tracer
19 echo 0 > /proc/sys/kernel/stack_tracer_enabled
20 enable_tracing
21 clear_trace
22 echo > set_ftrace_filter
23}
24
25fail() { # msg
26 do_reset
27 echo $1
28 exit -1
29}
30
31disable_tracing
32clear_trace;
33
34# filter something, schedule is always good
35if ! echo "schedule" > set_ftrace_filter; then
36 # test for powerpc 64
37 if ! echo ".schedule" > set_ftrace_filter; then
38 fail "can not enable schedule filter"
39 fi
40fi
41
42echo function_graph > current_tracer
43
44if [ ! -f stack_trace ]; then
45 echo "Stack tracer not configured"
46 do_reset
47 exit_unsupported;
48fi
49
50echo "Now testing with stack tracer"
51
52echo 1 > /proc/sys/kernel/stack_tracer_enabled
53
54disable_tracing
55clear_trace
56enable_tracing
57sleep 1
58
59count=`cat trace | grep '()' | grep -v schedule | wc -l`
60
61if [ $count -ne 0 ]; then
62 fail "Graph filtering not working with stack tracer?"
63fi
64
65# Make sure we did find something
66count=`cat trace | grep 'schedule()' | wc -l`
67if [ $count -eq 0 ]; then
68 fail "No schedule traces found?"
69fi
70
71echo 0 > /proc/sys/kernel/stack_tracer_enabled
72clear_trace
73sleep 1
74
75
76count=`cat trace | grep '()' | grep -v schedule | wc -l`
77
78if [ $count -ne 0 ]; then
79 fail "Graph filtering not working after stack tracer disabled?"
80fi
81
82count=`cat trace | grep 'schedule()' | wc -l`
83if [ $count -eq 0 ]; then
84 fail "No schedule traces found?"
85fi
86
87do_reset
88
89exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc
new file mode 100644
index 000000000000..6af5f6360b18
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/fgraph-filter.tc
@@ -0,0 +1,52 @@
1#!/bin/sh
2# description: ftrace - function graph filters
3
4# Make sure that function graph filtering works
5
6if ! grep -q function_graph available_tracers; then
7 echo "no function graph tracer configured"
8 exit_unsupported
9fi
10
11do_reset() {
12 reset_tracer
13 enable_tracing
14 clear_trace
15}
16
17fail() { # msg
18 do_reset
19 echo $1
20 exit -1
21}
22
23disable_tracing
24clear_trace
25
26# filter something, schedule is always good
27if ! echo "schedule" > set_ftrace_filter; then
28 # test for powerpc 64
29 if ! echo ".schedule" > set_ftrace_filter; then
30 fail "can not enable schedule filter"
31 fi
32fi
33
34echo function_graph > current_tracer
35enable_tracing
36sleep 1
37# search for functions (has "()" on the line), and make sure
38# that only the schedule function was found
39count=`cat trace | grep '()' | grep -v schedule | wc -l`
40if [ $count -ne 0 ]; then
41 fail "Graph filtering not working by itself?"
42fi
43
44# Make sure we did find something
45count=`cat trace | grep 'schedule()' | wc -l`
46if [ $count -eq 0 ]; then
47 fail "No schedule traces found?"
48fi
49
50do_reset
51
52exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc b/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc
new file mode 100644
index 000000000000..2e719cb1fc4d
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/ftrace/func_profiler.tc
@@ -0,0 +1,80 @@
1#!/bin/sh
2# description: ftrace - function profiler with function tracing
3
4# There was a bug after a rewrite of the ftrace infrastructure that
5# caused the function_profiler not to be able to run with the function
6# tracer, because the function_profiler used the function_graph tracer
7# and it was assumed the two could not run simultaneously.
8#
9# There was another related bug where the solution to the first bug
10# broke the way filtering of the function tracer worked.
11#
12# This test triggers those bugs on those kernels.
13#
14# We need function_graph and profiling to to run this test
15if ! grep -q function_graph available_tracers; then
16 echo "no function graph tracer configured"
17 exit_unsupported;
18fi
19
20if [ ! -f set_ftrace_filter ]; then
21 echo "set_ftrace_filter not found? Is dynamic ftrace not set?"
22 exit_unsupported
23fi
24
25if [ ! -f function_profile_enabled ]; then
26 echo "function_profile_enabled not found, function profiling enabled?"
27 exit_unsupported
28fi
29
30fail() { # mesg
31 reset_tracer
32 echo > set_ftrace_filter
33 echo $1
34 exit -1
35}
36
37echo "Testing function tracer with profiler:"
38echo "enable function tracer"
39echo function > current_tracer
40echo "enable profiler"
41echo 1 > function_profile_enabled
42
43sleep 1
44
45echo "Now filter on just schedule"
46echo '*schedule' > set_ftrace_filter
47clear_trace
48
49echo "Now disable function profiler"
50echo 0 > function_profile_enabled
51
52sleep 1
53
54# make sure only schedule functions exist
55
56echo "testing if only schedule is being traced"
57if grep -v -e '^#' -e 'schedule' trace; then
58 fail "more than schedule was found"
59fi
60
61echo "Make sure schedule was traced"
62if ! grep -e 'schedule' trace > /dev/null; then
63 cat trace
64 fail "can not find schedule in trace"
65fi
66
67echo > set_ftrace_filter
68clear_trace
69
70sleep 1
71
72echo "make sure something other than scheduler is being traced"
73if ! grep -v -e '^#' -e 'schedule' trace > /dev/null; then
74 cat trace
75 fail "no other functions besides schedule was found"
76fi
77
78reset_tracer
79
80exit 0
diff --git a/tools/testing/selftests/ftrace/test.d/functions b/tools/testing/selftests/ftrace/test.d/functions
new file mode 100644
index 000000000000..5d8cd06d920f
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/functions
@@ -0,0 +1,16 @@
1
2clear_trace() { # reset trace output
3 echo > trace
4}
5
6disable_tracing() { # stop trace recording
7 echo 0 > tracing_on
8}
9
10enable_tracing() { # start trace recording
11 echo 1 > tracing_on
12}
13
14reset_tracer() { # reset the current tracer
15 echo nop > current_tracer
16}
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc b/tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc
index 1b8b665ab2b3..a5a426211129 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/add_and_remove.tc
@@ -9,3 +9,4 @@ echo p:myevent do_fork > kprobe_events
9grep myevent kprobe_events 9grep myevent kprobe_events
10test -d events/kprobes/myevent 10test -d events/kprobes/myevent
11echo > kprobe_events 11echo > kprobe_events
12clear_trace
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc b/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc
index b55c84003587..d8c7bb6581fe 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/busy_check.tc
@@ -11,3 +11,4 @@ echo 1 > events/kprobes/myevent/enable
11echo > kprobe_events && exit 1 # this must fail 11echo > kprobe_events && exit 1 # this must fail
12echo 0 > events/kprobes/myevent/enable 12echo 0 > events/kprobes/myevent/enable
13echo > kprobe_events # this must succeed 13echo > kprobe_events # this must succeed
14clear_trace
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc
index a603d3f8db7b..c45ee2761354 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_args.tc
@@ -12,5 +12,6 @@ echo 1 > events/kprobes/testprobe/enable
12( echo "forked") 12( echo "forked")
13echo 0 > events/kprobes/testprobe/enable 13echo 0 > events/kprobes/testprobe/enable
14echo "-:testprobe" >> kprobe_events 14echo "-:testprobe" >> kprobe_events
15clear_trace
15test -d events/kprobes/testprobe && exit 1 || exit 0 16test -d events/kprobes/testprobe && exit 1 || exit 0
16 17
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc
new file mode 100644
index 000000000000..ab41d2b29841
--- /dev/null
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_ftrace.tc
@@ -0,0 +1,55 @@
1#!/bin/sh
2# description: Kprobe dynamic event with function tracer
3
4[ -f kprobe_events ] || exit_unsupported # this is configurable
5grep function available_tracers || exit_unsupported # this is configurable
6
7# prepare
8echo nop > current_tracer
9echo do_fork > set_ftrace_filter
10echo 0 > events/enable
11echo > kprobe_events
12echo 'p:testprobe do_fork' > kprobe_events
13
14# kprobe on / ftrace off
15echo 1 > events/kprobes/testprobe/enable
16echo > trace
17( echo "forked")
18grep testprobe trace
19! grep 'do_fork <-' trace
20
21# kprobe on / ftrace on
22echo function > current_tracer
23echo > trace
24( echo "forked")
25grep testprobe trace
26grep 'do_fork <-' trace
27
28# kprobe off / ftrace on
29echo 0 > events/kprobes/testprobe/enable
30echo > trace
31( echo "forked")
32! grep testprobe trace
33grep 'do_fork <-' trace
34
35# kprobe on / ftrace on
36echo 1 > events/kprobes/testprobe/enable
37echo function > current_tracer
38echo > trace
39( echo "forked")
40grep testprobe trace
41grep 'do_fork <-' trace
42
43# kprobe on / ftrace off
44echo nop > current_tracer
45echo > trace
46( echo "forked")
47grep testprobe trace
48! grep 'do_fork <-' trace
49
50# cleanup
51echo nop > current_tracer
52echo > set_ftrace_filter
53echo 0 > events/kprobes/testprobe/enable
54echo > kprobe_events
55echo > trace
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc
index 283c29e7f7c4..31717985acc7 100644
--- a/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc
+++ b/tools/testing/selftests/ftrace/test.d/kprobe/kretprobe_args.tc
@@ -12,4 +12,5 @@ echo 1 > events/kprobes/testprobe2/enable
12( echo "forked") 12( echo "forked")
13echo 0 > events/kprobes/testprobe2/enable 13echo 0 > events/kprobes/testprobe2/enable
14echo '-:testprobe2' >> kprobe_events 14echo '-:testprobe2' >> kprobe_events
15clear_trace
15test -d events/kprobes/testprobe2 && exit 1 || exit 0 16test -d events/kprobes/testprobe2 && exit 1 || exit 0
diff --git a/tools/testing/selftests/ipc/msgque.c b/tools/testing/selftests/ipc/msgque.c
index 552f0810bffb..1b2ce334bb3f 100644
--- a/tools/testing/selftests/ipc/msgque.c
+++ b/tools/testing/selftests/ipc/msgque.c
@@ -5,6 +5,8 @@
5#include <linux/msg.h> 5#include <linux/msg.h>
6#include <fcntl.h> 6#include <fcntl.h>
7 7
8#include "../kselftest.h"
9
8#define MAX_MSG_SIZE 32 10#define MAX_MSG_SIZE 32
9 11
10struct msg1 { 12struct msg1 {
@@ -195,58 +197,58 @@ int main(int argc, char **argv)
195 197
196 if (getuid() != 0) { 198 if (getuid() != 0) {
197 printf("Please run the test as root - Exiting.\n"); 199 printf("Please run the test as root - Exiting.\n");
198 exit(1); 200 return ksft_exit_fail();
199 } 201 }
200 202
201 msgque.key = ftok(argv[0], 822155650); 203 msgque.key = ftok(argv[0], 822155650);
202 if (msgque.key == -1) { 204 if (msgque.key == -1) {
203 printf("Can't make key\n"); 205 printf("Can't make key: %d\n", -errno);
204 return -errno; 206 return ksft_exit_fail();
205 } 207 }
206 208
207 msgque.msq_id = msgget(msgque.key, IPC_CREAT | IPC_EXCL | 0666); 209 msgque.msq_id = msgget(msgque.key, IPC_CREAT | IPC_EXCL | 0666);
208 if (msgque.msq_id == -1) { 210 if (msgque.msq_id == -1) {
209 err = -errno; 211 err = -errno;
210 printf("Can't create queue\n"); 212 printf("Can't create queue: %d\n", err);
211 goto err_out; 213 goto err_out;
212 } 214 }
213 215
214 err = fill_msgque(&msgque); 216 err = fill_msgque(&msgque);
215 if (err) { 217 if (err) {
216 printf("Failed to fill queue\n"); 218 printf("Failed to fill queue: %d\n", err);
217 goto err_destroy; 219 goto err_destroy;
218 } 220 }
219 221
220 err = dump_queue(&msgque); 222 err = dump_queue(&msgque);
221 if (err) { 223 if (err) {
222 printf("Failed to dump queue\n"); 224 printf("Failed to dump queue: %d\n", err);
223 goto err_destroy; 225 goto err_destroy;
224 } 226 }
225 227
226 err = check_and_destroy_queue(&msgque); 228 err = check_and_destroy_queue(&msgque);
227 if (err) { 229 if (err) {
228 printf("Failed to check and destroy queue\n"); 230 printf("Failed to check and destroy queue: %d\n", err);
229 goto err_out; 231 goto err_out;
230 } 232 }
231 233
232 err = restore_queue(&msgque); 234 err = restore_queue(&msgque);
233 if (err) { 235 if (err) {
234 printf("Failed to restore queue\n"); 236 printf("Failed to restore queue: %d\n", err);
235 goto err_destroy; 237 goto err_destroy;
236 } 238 }
237 239
238 err = check_and_destroy_queue(&msgque); 240 err = check_and_destroy_queue(&msgque);
239 if (err) { 241 if (err) {
240 printf("Failed to test queue\n"); 242 printf("Failed to test queue: %d\n", err);
241 goto err_out; 243 goto err_out;
242 } 244 }
243 return 0; 245 return ksft_exit_pass();
244 246
245err_destroy: 247err_destroy:
246 if (msgctl(msgque.msq_id, IPC_RMID, 0)) { 248 if (msgctl(msgque.msq_id, IPC_RMID, 0)) {
247 printf("Failed to destroy queue: %d\n", -errno); 249 printf("Failed to destroy queue: %d\n", -errno);
248 return -errno; 250 return ksft_exit_fail();
249 } 251 }
250err_out: 252err_out:
251 return err; 253 return ksft_exit_fail();
252} 254}
diff --git a/tools/testing/selftests/kcmp/Makefile b/tools/testing/selftests/kcmp/Makefile
index 8aabd82db9e4..ff0eefdc6ceb 100644
--- a/tools/testing/selftests/kcmp/Makefile
+++ b/tools/testing/selftests/kcmp/Makefile
@@ -1,25 +1,7 @@
1uname_M := $(shell uname -m 2>/dev/null || echo not) 1CC := $(CROSS_COMPILE)$(CC)
2ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/)
3ifeq ($(ARCH),i386)
4 ARCH := x86
5 CFLAGS := -DCONFIG_X86_32 -D__i386__
6endif
7ifeq ($(ARCH),x86_64)
8 ARCH := x86
9 CFLAGS := -DCONFIG_X86_64 -D__x86_64__
10endif
11
12CFLAGS += -I../../../../arch/x86/include/generated/
13CFLAGS += -I../../../../include/
14CFLAGS += -I../../../../usr/include/ 2CFLAGS += -I../../../../usr/include/
15CFLAGS += -I../../../../arch/x86/include/
16 3
17all: 4all: kcmp_test
18ifeq ($(ARCH),x86)
19 gcc $(CFLAGS) kcmp_test.c -o kcmp_test
20else
21 echo "Not an x86 target, can't build kcmp selftest"
22endif
23 5
24run_tests: all 6run_tests: all
25 @./kcmp_test || echo "kcmp_test: [FAIL]" 7 @./kcmp_test || echo "kcmp_test: [FAIL]"
diff --git a/tools/testing/selftests/kcmp/kcmp_test.c b/tools/testing/selftests/kcmp/kcmp_test.c
index dbba4084869c..a5a4da856dfe 100644
--- a/tools/testing/selftests/kcmp/kcmp_test.c
+++ b/tools/testing/selftests/kcmp/kcmp_test.c
@@ -17,6 +17,8 @@
17#include <sys/stat.h> 17#include <sys/stat.h>
18#include <sys/wait.h> 18#include <sys/wait.h>
19 19
20#include "../kselftest.h"
21
20static long sys_kcmp(int pid1, int pid2, int type, int fd1, int fd2) 22static long sys_kcmp(int pid1, int pid2, int type, int fd1, int fd2)
21{ 23{
22 return syscall(__NR_kcmp, pid1, pid2, type, fd1, fd2); 24 return syscall(__NR_kcmp, pid1, pid2, type, fd1, fd2);
@@ -34,13 +36,13 @@ int main(int argc, char **argv)
34 36
35 if (fd1 < 0) { 37 if (fd1 < 0) {
36 perror("Can't create file"); 38 perror("Can't create file");
37 exit(1); 39 ksft_exit_fail();
38 } 40 }
39 41
40 pid2 = fork(); 42 pid2 = fork();
41 if (pid2 < 0) { 43 if (pid2 < 0) {
42 perror("fork failed"); 44 perror("fork failed");
43 exit(1); 45 ksft_exit_fail();
44 } 46 }
45 47
46 if (!pid2) { 48 if (!pid2) {
@@ -50,7 +52,7 @@ int main(int argc, char **argv)
50 fd2 = open(kpath, O_RDWR, 0644); 52 fd2 = open(kpath, O_RDWR, 0644);
51 if (fd2 < 0) { 53 if (fd2 < 0) {
52 perror("Can't open file"); 54 perror("Can't open file");
53 exit(1); 55 ksft_exit_fail();
54 } 56 }
55 57
56 /* An example of output and arguments */ 58 /* An example of output and arguments */
@@ -74,23 +76,34 @@ int main(int argc, char **argv)
74 if (ret) { 76 if (ret) {
75 printf("FAIL: 0 expected but %d returned (%s)\n", 77 printf("FAIL: 0 expected but %d returned (%s)\n",
76 ret, strerror(errno)); 78 ret, strerror(errno));
79 ksft_inc_fail_cnt();
77 ret = -1; 80 ret = -1;
78 } else 81 } else {
79 printf("PASS: 0 returned as expected\n"); 82 printf("PASS: 0 returned as expected\n");
83 ksft_inc_pass_cnt();
84 }
80 85
81 /* Compare with self */ 86 /* Compare with self */
82 ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0); 87 ret = sys_kcmp(pid1, pid1, KCMP_VM, 0, 0);
83 if (ret) { 88 if (ret) {
84 printf("FAIL: 0 expected but %d returned (%s)\n", 89 printf("FAIL: 0 expected but %d returned (%s)\n",
85 ret, strerror(errno)); 90 ret, strerror(errno));
91 ksft_inc_fail_cnt();
86 ret = -1; 92 ret = -1;
87 } else 93 } else {
88 printf("PASS: 0 returned as expected\n"); 94 printf("PASS: 0 returned as expected\n");
95 ksft_inc_pass_cnt();
96 }
97
98 ksft_print_cnts();
89 99
90 exit(ret); 100 if (ret)
101 ksft_exit_fail();
102 else
103 ksft_exit_pass();
91 } 104 }
92 105
93 waitpid(pid2, &status, P_ALL); 106 waitpid(pid2, &status, P_ALL);
94 107
95 return 0; 108 return ksft_exit_pass();
96} 109}
diff --git a/tools/testing/selftests/kselftest.h b/tools/testing/selftests/kselftest.h
new file mode 100644
index 000000000000..572c8888167a
--- /dev/null
+++ b/tools/testing/selftests/kselftest.h
@@ -0,0 +1,62 @@
1/*
2 * kselftest.h: kselftest framework return codes to include from
3 * selftests.
4 *
5 * Copyright (c) 2014 Shuah Khan <shuahkh@osg.samsung.com>
6 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
7 *
8 * This file is released under the GPLv2.
9 */
10#ifndef __KSELFTEST_H
11#define __KSELFTEST_H
12
13#include <stdlib.h>
14#include <unistd.h>
15
16/* counters */
17struct ksft_count {
18 unsigned int ksft_pass;
19 unsigned int ksft_fail;
20 unsigned int ksft_xfail;
21 unsigned int ksft_xpass;
22 unsigned int ksft_xskip;
23};
24
25static struct ksft_count ksft_cnt;
26
27static inline void ksft_inc_pass_cnt(void) { ksft_cnt.ksft_pass++; }
28static inline void ksft_inc_fail_cnt(void) { ksft_cnt.ksft_fail++; }
29static inline void ksft_inc_xfail_cnt(void) { ksft_cnt.ksft_xfail++; }
30static inline void ksft_inc_xpass_cnt(void) { ksft_cnt.ksft_xpass++; }
31static inline void ksft_inc_xskip_cnt(void) { ksft_cnt.ksft_xskip++; }
32
33static inline void ksft_print_cnts(void)
34{
35 printf("Pass: %d Fail: %d Xfail: %d Xpass: %d, Xskip: %d\n",
36 ksft_cnt.ksft_pass, ksft_cnt.ksft_fail,
37 ksft_cnt.ksft_xfail, ksft_cnt.ksft_xpass,
38 ksft_cnt.ksft_xskip);
39}
40
41static inline int ksft_exit_pass(void)
42{
43 exit(0);
44}
45static inline int ksft_exit_fail(void)
46{
47 exit(1);
48}
49static inline int ksft_exit_xfail(void)
50{
51 exit(2);
52}
53static inline int ksft_exit_xpass(void)
54{
55 exit(3);
56}
57static inline int ksft_exit_skip(void)
58{
59 exit(4);
60}
61
62#endif /* __KSELFTEST_H */
diff --git a/tools/testing/selftests/mount/unprivileged-remount-test.c b/tools/testing/selftests/mount/unprivileged-remount-test.c
index 1b3ff2fda4d0..517785052f1c 100644
--- a/tools/testing/selftests/mount/unprivileged-remount-test.c
+++ b/tools/testing/selftests/mount/unprivileged-remount-test.c
@@ -6,6 +6,8 @@
6#include <sys/types.h> 6#include <sys/types.h>
7#include <sys/mount.h> 7#include <sys/mount.h>
8#include <sys/wait.h> 8#include <sys/wait.h>
9#include <sys/vfs.h>
10#include <sys/statvfs.h>
9#include <stdlib.h> 11#include <stdlib.h>
10#include <unistd.h> 12#include <unistd.h>
11#include <fcntl.h> 13#include <fcntl.h>
@@ -32,11 +34,14 @@
32# define CLONE_NEWPID 0x20000000 34# define CLONE_NEWPID 0x20000000
33#endif 35#endif
34 36
37#ifndef MS_REC
38# define MS_REC 16384
39#endif
35#ifndef MS_RELATIME 40#ifndef MS_RELATIME
36#define MS_RELATIME (1 << 21) 41# define MS_RELATIME (1 << 21)
37#endif 42#endif
38#ifndef MS_STRICTATIME 43#ifndef MS_STRICTATIME
39#define MS_STRICTATIME (1 << 24) 44# define MS_STRICTATIME (1 << 24)
40#endif 45#endif
41 46
42static void die(char *fmt, ...) 47static void die(char *fmt, ...)
@@ -48,17 +53,14 @@ static void die(char *fmt, ...)
48 exit(EXIT_FAILURE); 53 exit(EXIT_FAILURE);
49} 54}
50 55
51static void write_file(char *filename, char *fmt, ...) 56static void vmaybe_write_file(bool enoent_ok, char *filename, char *fmt, va_list ap)
52{ 57{
53 char buf[4096]; 58 char buf[4096];
54 int fd; 59 int fd;
55 ssize_t written; 60 ssize_t written;
56 int buf_len; 61 int buf_len;
57 va_list ap;
58 62
59 va_start(ap, fmt);
60 buf_len = vsnprintf(buf, sizeof(buf), fmt, ap); 63 buf_len = vsnprintf(buf, sizeof(buf), fmt, ap);
61 va_end(ap);
62 if (buf_len < 0) { 64 if (buf_len < 0) {
63 die("vsnprintf failed: %s\n", 65 die("vsnprintf failed: %s\n",
64 strerror(errno)); 66 strerror(errno));
@@ -69,6 +71,8 @@ static void write_file(char *filename, char *fmt, ...)
69 71
70 fd = open(filename, O_WRONLY); 72 fd = open(filename, O_WRONLY);
71 if (fd < 0) { 73 if (fd < 0) {
74 if ((errno == ENOENT) && enoent_ok)
75 return;
72 die("open of %s failed: %s\n", 76 die("open of %s failed: %s\n",
73 filename, strerror(errno)); 77 filename, strerror(errno));
74 } 78 }
@@ -87,6 +91,65 @@ static void write_file(char *filename, char *fmt, ...)
87 } 91 }
88} 92}
89 93
94static void maybe_write_file(char *filename, char *fmt, ...)
95{
96 va_list ap;
97
98 va_start(ap, fmt);
99 vmaybe_write_file(true, filename, fmt, ap);
100 va_end(ap);
101
102}
103
104static void write_file(char *filename, char *fmt, ...)
105{
106 va_list ap;
107
108 va_start(ap, fmt);
109 vmaybe_write_file(false, filename, fmt, ap);
110 va_end(ap);
111
112}
113
114static int read_mnt_flags(const char *path)
115{
116 int ret;
117 struct statvfs stat;
118 int mnt_flags;
119
120 ret = statvfs(path, &stat);
121 if (ret != 0) {
122 die("statvfs of %s failed: %s\n",
123 path, strerror(errno));
124 }
125 if (stat.f_flag & ~(ST_RDONLY | ST_NOSUID | ST_NODEV | \
126 ST_NOEXEC | ST_NOATIME | ST_NODIRATIME | ST_RELATIME | \
127 ST_SYNCHRONOUS | ST_MANDLOCK)) {
128 die("Unrecognized mount flags\n");
129 }
130 mnt_flags = 0;
131 if (stat.f_flag & ST_RDONLY)
132 mnt_flags |= MS_RDONLY;
133 if (stat.f_flag & ST_NOSUID)
134 mnt_flags |= MS_NOSUID;
135 if (stat.f_flag & ST_NODEV)
136 mnt_flags |= MS_NODEV;
137 if (stat.f_flag & ST_NOEXEC)
138 mnt_flags |= MS_NOEXEC;
139 if (stat.f_flag & ST_NOATIME)
140 mnt_flags |= MS_NOATIME;
141 if (stat.f_flag & ST_NODIRATIME)
142 mnt_flags |= MS_NODIRATIME;
143 if (stat.f_flag & ST_RELATIME)
144 mnt_flags |= MS_RELATIME;
145 if (stat.f_flag & ST_SYNCHRONOUS)
146 mnt_flags |= MS_SYNCHRONOUS;
147 if (stat.f_flag & ST_MANDLOCK)
148 mnt_flags |= ST_MANDLOCK;
149
150 return mnt_flags;
151}
152
90static void create_and_enter_userns(void) 153static void create_and_enter_userns(void)
91{ 154{
92 uid_t uid; 155 uid_t uid;
@@ -100,13 +163,10 @@ static void create_and_enter_userns(void)
100 strerror(errno)); 163 strerror(errno));
101 } 164 }
102 165
166 maybe_write_file("/proc/self/setgroups", "deny");
103 write_file("/proc/self/uid_map", "0 %d 1", uid); 167 write_file("/proc/self/uid_map", "0 %d 1", uid);
104 write_file("/proc/self/gid_map", "0 %d 1", gid); 168 write_file("/proc/self/gid_map", "0 %d 1", gid);
105 169
106 if (setgroups(0, NULL) != 0) {
107 die("setgroups failed: %s\n",
108 strerror(errno));
109 }
110 if (setgid(0) != 0) { 170 if (setgid(0) != 0) {
111 die ("setgid(0) failed %s\n", 171 die ("setgid(0) failed %s\n",
112 strerror(errno)); 172 strerror(errno));
@@ -118,7 +178,8 @@ static void create_and_enter_userns(void)
118} 178}
119 179
120static 180static
121bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags) 181bool test_unpriv_remount(const char *fstype, const char *mount_options,
182 int mount_flags, int remount_flags, int invalid_flags)
122{ 183{
123 pid_t child; 184 pid_t child;
124 185
@@ -151,9 +212,11 @@ bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags)
151 strerror(errno)); 212 strerror(errno));
152 } 213 }
153 214
154 if (mount("testing", "/tmp", "ramfs", mount_flags, NULL) != 0) { 215 if (mount("testing", "/tmp", fstype, mount_flags, mount_options) != 0) {
155 die("mount of /tmp failed: %s\n", 216 die("mount of %s with options '%s' on /tmp failed: %s\n",
156 strerror(errno)); 217 fstype,
218 mount_options? mount_options : "",
219 strerror(errno));
157 } 220 }
158 221
159 create_and_enter_userns(); 222 create_and_enter_userns();
@@ -181,62 +244,127 @@ bool test_unpriv_remount(int mount_flags, int remount_flags, int invalid_flags)
181 244
182static bool test_unpriv_remount_simple(int mount_flags) 245static bool test_unpriv_remount_simple(int mount_flags)
183{ 246{
184 return test_unpriv_remount(mount_flags, mount_flags, 0); 247 return test_unpriv_remount("ramfs", NULL, mount_flags, mount_flags, 0);
185} 248}
186 249
187static bool test_unpriv_remount_atime(int mount_flags, int invalid_flags) 250static bool test_unpriv_remount_atime(int mount_flags, int invalid_flags)
188{ 251{
189 return test_unpriv_remount(mount_flags, mount_flags, invalid_flags); 252 return test_unpriv_remount("ramfs", NULL, mount_flags, mount_flags,
253 invalid_flags);
254}
255
256static bool test_priv_mount_unpriv_remount(void)
257{
258 pid_t child;
259 int ret;
260 const char *orig_path = "/dev";
261 const char *dest_path = "/tmp";
262 int orig_mnt_flags, remount_mnt_flags;
263
264 child = fork();
265 if (child == -1) {
266 die("fork failed: %s\n",
267 strerror(errno));
268 }
269 if (child != 0) { /* parent */
270 pid_t pid;
271 int status;
272 pid = waitpid(child, &status, 0);
273 if (pid == -1) {
274 die("waitpid failed: %s\n",
275 strerror(errno));
276 }
277 if (pid != child) {
278 die("waited for %d got %d\n",
279 child, pid);
280 }
281 if (!WIFEXITED(status)) {
282 die("child did not terminate cleanly\n");
283 }
284 return WEXITSTATUS(status) == EXIT_SUCCESS ? true : false;
285 }
286
287 orig_mnt_flags = read_mnt_flags(orig_path);
288
289 create_and_enter_userns();
290 ret = unshare(CLONE_NEWNS);
291 if (ret != 0) {
292 die("unshare(CLONE_NEWNS) failed: %s\n",
293 strerror(errno));
294 }
295
296 ret = mount(orig_path, dest_path, "bind", MS_BIND | MS_REC, NULL);
297 if (ret != 0) {
298 die("recursive bind mount of %s onto %s failed: %s\n",
299 orig_path, dest_path, strerror(errno));
300 }
301
302 ret = mount(dest_path, dest_path, "none",
303 MS_REMOUNT | MS_BIND | orig_mnt_flags , NULL);
304 if (ret != 0) {
305 /* system("cat /proc/self/mounts"); */
306 die("remount of /tmp failed: %s\n",
307 strerror(errno));
308 }
309
310 remount_mnt_flags = read_mnt_flags(dest_path);
311 if (orig_mnt_flags != remount_mnt_flags) {
312 die("Mount flags unexpectedly changed during remount of %s originally mounted on %s\n",
313 dest_path, orig_path);
314 }
315 exit(EXIT_SUCCESS);
190} 316}
191 317
192int main(int argc, char **argv) 318int main(int argc, char **argv)
193{ 319{
194 if (!test_unpriv_remount_simple(MS_RDONLY|MS_NODEV)) { 320 if (!test_unpriv_remount_simple(MS_RDONLY)) {
195 die("MS_RDONLY malfunctions\n"); 321 die("MS_RDONLY malfunctions\n");
196 } 322 }
197 if (!test_unpriv_remount_simple(MS_NODEV)) { 323 if (!test_unpriv_remount("devpts", "newinstance", MS_NODEV, MS_NODEV, 0)) {
198 die("MS_NODEV malfunctions\n"); 324 die("MS_NODEV malfunctions\n");
199 } 325 }
200 if (!test_unpriv_remount_simple(MS_NOSUID|MS_NODEV)) { 326 if (!test_unpriv_remount_simple(MS_NOSUID)) {
201 die("MS_NOSUID malfunctions\n"); 327 die("MS_NOSUID malfunctions\n");
202 } 328 }
203 if (!test_unpriv_remount_simple(MS_NOEXEC|MS_NODEV)) { 329 if (!test_unpriv_remount_simple(MS_NOEXEC)) {
204 die("MS_NOEXEC malfunctions\n"); 330 die("MS_NOEXEC malfunctions\n");
205 } 331 }
206 if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODEV, 332 if (!test_unpriv_remount_atime(MS_RELATIME,
207 MS_NOATIME|MS_NODEV)) 333 MS_NOATIME))
208 { 334 {
209 die("MS_RELATIME malfunctions\n"); 335 die("MS_RELATIME malfunctions\n");
210 } 336 }
211 if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODEV, 337 if (!test_unpriv_remount_atime(MS_STRICTATIME,
212 MS_NOATIME|MS_NODEV)) 338 MS_NOATIME))
213 { 339 {
214 die("MS_STRICTATIME malfunctions\n"); 340 die("MS_STRICTATIME malfunctions\n");
215 } 341 }
216 if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODEV, 342 if (!test_unpriv_remount_atime(MS_NOATIME,
217 MS_STRICTATIME|MS_NODEV)) 343 MS_STRICTATIME))
218 { 344 {
219 die("MS_RELATIME malfunctions\n"); 345 die("MS_NOATIME malfunctions\n");
220 } 346 }
221 if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODIRATIME|MS_NODEV, 347 if (!test_unpriv_remount_atime(MS_RELATIME|MS_NODIRATIME,
222 MS_NOATIME|MS_NODEV)) 348 MS_NOATIME))
223 { 349 {
224 die("MS_RELATIME malfunctions\n"); 350 die("MS_RELATIME|MS_NODIRATIME malfunctions\n");
225 } 351 }
226 if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODIRATIME|MS_NODEV, 352 if (!test_unpriv_remount_atime(MS_STRICTATIME|MS_NODIRATIME,
227 MS_NOATIME|MS_NODEV)) 353 MS_NOATIME))
228 { 354 {
229 die("MS_RELATIME malfunctions\n"); 355 die("MS_STRICTATIME|MS_NODIRATIME malfunctions\n");
230 } 356 }
231 if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODIRATIME|MS_NODEV, 357 if (!test_unpriv_remount_atime(MS_NOATIME|MS_NODIRATIME,
232 MS_STRICTATIME|MS_NODEV)) 358 MS_STRICTATIME))
233 { 359 {
234 die("MS_RELATIME malfunctions\n"); 360 die("MS_NOATIME|MS_DIRATIME malfunctions\n");
235 } 361 }
236 if (!test_unpriv_remount(MS_STRICTATIME|MS_NODEV, MS_NODEV, 362 if (!test_unpriv_remount("ramfs", NULL, MS_STRICTATIME, 0, MS_NOATIME))
237 MS_NOATIME|MS_NODEV))
238 { 363 {
239 die("Default atime malfunctions\n"); 364 die("Default atime malfunctions\n");
240 } 365 }
366 if (!test_priv_mount_unpriv_remount()) {
367 die("Mount flags unexpectedly changed after remount\n");
368 }
241 return EXIT_SUCCESS; 369 return EXIT_SUCCESS;
242} 370}
diff --git a/tools/testing/selftests/net/Makefile b/tools/testing/selftests/net/Makefile
index c7493b8f9b0e..62f22cc9941c 100644
--- a/tools/testing/selftests/net/Makefile
+++ b/tools/testing/selftests/net/Makefile
@@ -14,12 +14,6 @@ all: $(NET_PROGS)
14run_tests: all 14run_tests: all
15 @/bin/sh ./run_netsocktests || echo "sockettests: [FAIL]" 15 @/bin/sh ./run_netsocktests || echo "sockettests: [FAIL]"
16 @/bin/sh ./run_afpackettests || echo "afpackettests: [FAIL]" 16 @/bin/sh ./run_afpackettests || echo "afpackettests: [FAIL]"
17 @if /sbin/modprobe test_bpf ; then \ 17 ./test_bpf.sh
18 /sbin/rmmod test_bpf; \
19 echo "test_bpf: ok"; \
20 else \
21 echo "test_bpf: [FAIL]"; \
22 exit 1; \
23 fi
24clean: 18clean:
25 $(RM) $(NET_PROGS) 19 $(RM) $(NET_PROGS)
diff --git a/tools/testing/selftests/net/test_bpf.sh b/tools/testing/selftests/net/test_bpf.sh
new file mode 100755
index 000000000000..8b29796d46aa
--- /dev/null
+++ b/tools/testing/selftests/net/test_bpf.sh
@@ -0,0 +1,10 @@
1#!/bin/sh
2# Runs bpf test using test_bpf kernel module
3
4if /sbin/modprobe -q test_bpf ; then
5 /sbin/modprobe -q -r test_bpf;
6 echo "test_bpf: ok";
7else
8 echo "test_bpf: [FAIL]";
9 exit 1;
10fi
diff --git a/tools/testing/selftests/size/.gitignore b/tools/testing/selftests/size/.gitignore
new file mode 100644
index 000000000000..189b7818de34
--- /dev/null
+++ b/tools/testing/selftests/size/.gitignore
@@ -0,0 +1 @@
get_size
diff --git a/tools/testing/selftests/size/Makefile b/tools/testing/selftests/size/Makefile
new file mode 100644
index 000000000000..04dc25e4fa92
--- /dev/null
+++ b/tools/testing/selftests/size/Makefile
@@ -0,0 +1,12 @@
1CC = $(CROSS_COMPILE)gcc
2
3all: get_size
4
5get_size: get_size.c
6 $(CC) -static -ffreestanding -nostartfiles -s $< -o $@
7
8run_tests: all
9 ./get_size
10
11clean:
12 $(RM) get_size
diff --git a/tools/testing/selftests/size/get_size.c b/tools/testing/selftests/size/get_size.c
new file mode 100644
index 000000000000..2d1af7cca463
--- /dev/null
+++ b/tools/testing/selftests/size/get_size.c
@@ -0,0 +1,100 @@
1/*
2 * Copyright 2014 Sony Mobile Communications Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2
5 *
6 * Selftest for runtime system size
7 *
8 * Prints the amount of RAM that the currently running system is using.
9 *
10 * This program tries to be as small as possible itself, to
11 * avoid perturbing the system memory utilization with its
12 * own execution. It also attempts to have as few dependencies
13 * on kernel features as possible.
14 *
15 * It should be statically linked, with startup libs avoided.
16 * It uses no library calls, and only the following 3 syscalls:
17 * sysinfo(), write(), and _exit()
18 *
19 * For output, it avoids printf (which in some C libraries
20 * has large external dependencies) by implementing it's own
21 * number output and print routines, and using __builtin_strlen()
22 */
23
24#include <sys/sysinfo.h>
25#include <unistd.h>
26
27#define STDOUT_FILENO 1
28
29static int print(const char *s)
30{
31 return write(STDOUT_FILENO, s, __builtin_strlen(s));
32}
33
34static inline char *num_to_str(unsigned long num, char *buf, int len)
35{
36 unsigned int digit;
37
38 /* put digits in buffer from back to front */
39 buf += len - 1;
40 *buf = 0;
41 do {
42 digit = num % 10;
43 *(--buf) = digit + '0';
44 num /= 10;
45 } while (num > 0);
46
47 return buf;
48}
49
50static int print_num(unsigned long num)
51{
52 char num_buf[30];
53
54 return print(num_to_str(num, num_buf, sizeof(num_buf)));
55}
56
57static int print_k_value(const char *s, unsigned long num, unsigned long units)
58{
59 unsigned long long temp;
60 int ccode;
61
62 print(s);
63
64 temp = num;
65 temp = (temp * units)/1024;
66 num = temp;
67 ccode = print_num(num);
68 print("\n");
69 return ccode;
70}
71
72/* this program has no main(), as startup libraries are not used */
73void _start(void)
74{
75 int ccode;
76 struct sysinfo info;
77 unsigned long used;
78
79 print("Testing system size.\n");
80 print("1..1\n");
81
82 ccode = sysinfo(&info);
83 if (ccode < 0) {
84 print("not ok 1 get runtime memory use\n");
85 print("# could not get sysinfo\n");
86 _exit(ccode);
87 }
88 /* ignore cache complexities for now */
89 used = info.totalram - info.freeram - info.bufferram;
90 print_k_value("ok 1 get runtime memory use # size = ", used,
91 info.mem_unit);
92
93 print("# System runtime memory report (units in Kilobytes):\n");
94 print_k_value("# Total: ", info.totalram, info.mem_unit);
95 print_k_value("# Free: ", info.freeram, info.mem_unit);
96 print_k_value("# Buffer: ", info.bufferram, info.mem_unit);
97 print_k_value("# In use: ", used, info.mem_unit);
98
99 _exit(0);
100}
diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c
index 41bd85559d4b..f87d970a485c 100644
--- a/tools/testing/selftests/timers/posix_timers.c
+++ b/tools/testing/selftests/timers/posix_timers.c
@@ -15,6 +15,8 @@
15#include <time.h> 15#include <time.h>
16#include <pthread.h> 16#include <pthread.h>
17 17
18#include "../kselftest.h"
19
18#define DELAY 2 20#define DELAY 2
19#define USECS_PER_SEC 1000000 21#define USECS_PER_SEC 1000000
20 22
@@ -194,16 +196,16 @@ int main(int argc, char **argv)
194 printf("based timers if other threads run on the CPU...\n"); 196 printf("based timers if other threads run on the CPU...\n");
195 197
196 if (check_itimer(ITIMER_VIRTUAL) < 0) 198 if (check_itimer(ITIMER_VIRTUAL) < 0)
197 return -1; 199 return ksft_exit_fail();
198 200
199 if (check_itimer(ITIMER_PROF) < 0) 201 if (check_itimer(ITIMER_PROF) < 0)
200 return -1; 202 return ksft_exit_fail();
201 203
202 if (check_itimer(ITIMER_REAL) < 0) 204 if (check_itimer(ITIMER_REAL) < 0)
203 return -1; 205 return ksft_exit_fail();
204 206
205 if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0) 207 if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0)
206 return -1; 208 return ksft_exit_fail();
207 209
208 /* 210 /*
209 * It's unfortunately hard to reliably test a timer expiration 211 * It's unfortunately hard to reliably test a timer expiration
@@ -215,7 +217,7 @@ int main(int argc, char **argv)
215 * find a better solution. 217 * find a better solution.
216 */ 218 */
217 if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0) 219 if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0)
218 return -1; 220 return ksft_exit_fail();
219 221
220 return 0; 222 return ksft_exit_pass();
221} 223}
diff --git a/tools/testing/selftests/user/Makefile b/tools/testing/selftests/user/Makefile
index 396255bd720e..12c9d15bab07 100644
--- a/tools/testing/selftests/user/Makefile
+++ b/tools/testing/selftests/user/Makefile
@@ -4,10 +4,4 @@
4all: 4all:
5 5
6run_tests: all 6run_tests: all
7 @if /sbin/modprobe test_user_copy ; then \ 7 ./test_user_copy.sh
8 rmmod test_user_copy; \
9 echo "user_copy: ok"; \
10 else \
11 echo "user_copy: [FAIL]"; \
12 exit 1; \
13 fi
diff --git a/tools/testing/selftests/user/test_user_copy.sh b/tools/testing/selftests/user/test_user_copy.sh
new file mode 100755
index 000000000000..350107f40c1d
--- /dev/null
+++ b/tools/testing/selftests/user/test_user_copy.sh
@@ -0,0 +1,10 @@
1#!/bin/sh
2# Runs copy_to/from_user infrastructure using test_user_copy kernel module
3
4if /sbin/modprobe -q test_user_copy; then
5 /sbin/modprobe -q -r test_user_copy
6 echo "user_copy: ok"
7else
8 echo "user_copy: [FAIL]"
9 exit 1
10fi
diff --git a/tools/thermal/tmon/sysfs.c b/tools/thermal/tmon/sysfs.c
index dfe454855cd2..1c12536f2081 100644
--- a/tools/thermal/tmon/sysfs.c
+++ b/tools/thermal/tmon/sysfs.c
@@ -446,7 +446,7 @@ int probe_thermal_sysfs(void)
446 return -1; 446 return -1;
447 } 447 }
448 448
449 ptdata.tzi = calloc(sizeof(struct tz_info), ptdata.max_tz_instance+1); 449 ptdata.tzi = calloc(ptdata.max_tz_instance+1, sizeof(struct tz_info));
450 if (!ptdata.tzi) { 450 if (!ptdata.tzi) {
451 fprintf(stderr, "Err: allocate tz_info\n"); 451 fprintf(stderr, "Err: allocate tz_info\n");
452 return -1; 452 return -1;
@@ -454,8 +454,8 @@ int probe_thermal_sysfs(void)
454 454
455 /* we still show thermal zone information if there is no cdev */ 455 /* we still show thermal zone information if there is no cdev */
456 if (ptdata.nr_cooling_dev) { 456 if (ptdata.nr_cooling_dev) {
457 ptdata.cdi = calloc(sizeof(struct cdev_info), 457 ptdata.cdi = calloc(ptdata.max_cdev_instance + 1,
458 ptdata.max_cdev_instance + 1); 458 sizeof(struct cdev_info));
459 if (!ptdata.cdi) { 459 if (!ptdata.cdi) {
460 free(ptdata.tzi); 460 free(ptdata.tzi);
461 fprintf(stderr, "Err: allocate cdev_info\n"); 461 fprintf(stderr, "Err: allocate cdev_info\n");
diff --git a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
index af4b0508be77..aaca1f44e788 100644
--- a/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
+++ b/tools/usb/ffs-aio-example/multibuff/device_app/aio_multibuff.c
@@ -342,7 +342,7 @@ int main(int argc, char *argv[])
342 iobuf[i].requested = ret; 342 iobuf[i].requested = ret;
343 printf("submit: %d requests buf: %d\n", ret, i); 343 printf("submit: %d requests buf: %d\n", ret, i);
344 } else 344 } else
345 perror("unable to submit reqests"); 345 perror("unable to submit requests");
346 } 346 }
347 347
348 /* if event is ready to read */ 348 /* if event is ready to read */
diff --git a/tools/usb/usbip/libsrc/list.h b/tools/usb/usbip/libsrc/list.h
index 8d0c936e184f..5eaaa78e2c6a 100644
--- a/tools/usb/usbip/libsrc/list.h
+++ b/tools/usb/usbip/libsrc/list.h
@@ -98,7 +98,7 @@ static inline void list_del(struct list_head *entry)
98 * list_entry - get the struct for this entry 98 * list_entry - get the struct for this entry
99 * @ptr: the &struct list_head pointer. 99 * @ptr: the &struct list_head pointer.
100 * @type: the type of the struct this is embedded in. 100 * @type: the type of the struct this is embedded in.
101 * @member: the name of the list_struct within the struct. 101 * @member: the name of the list_head within the struct.
102 */ 102 */
103#define list_entry(ptr, type, member) \ 103#define list_entry(ptr, type, member) \
104 container_of(ptr, type, member) 104 container_of(ptr, type, member)
diff --git a/tools/usb/usbip/src/usbipd.c b/tools/usb/usbip/src/usbipd.c
index 2f87f2d348ba..2a7cd2b8d966 100644
--- a/tools/usb/usbip/src/usbipd.c
+++ b/tools/usb/usbip/src/usbipd.c
@@ -91,7 +91,6 @@ static void usbipd_help(void)
91static int recv_request_import(int sockfd) 91static int recv_request_import(int sockfd)
92{ 92{
93 struct op_import_request req; 93 struct op_import_request req;
94 struct op_common reply;
95 struct usbip_exported_device *edev; 94 struct usbip_exported_device *edev;
96 struct usbip_usb_device pdu_udev; 95 struct usbip_usb_device pdu_udev;
97 struct list_head *i; 96 struct list_head *i;
@@ -100,7 +99,6 @@ static int recv_request_import(int sockfd)
100 int rc; 99 int rc;
101 100
102 memset(&req, 0, sizeof(req)); 101 memset(&req, 0, sizeof(req));
103 memset(&reply, 0, sizeof(reply));
104 102
105 rc = usbip_net_recv(sockfd, &req, sizeof(req)); 103 rc = usbip_net_recv(sockfd, &req, sizeof(req));
106 if (rc < 0) { 104 if (rc < 0) {
diff --git a/tools/virtio/Makefile b/tools/virtio/Makefile
index 9325f4693821..505ad51b3b51 100644
--- a/tools/virtio/Makefile
+++ b/tools/virtio/Makefile
@@ -3,7 +3,7 @@ test: virtio_test vringh_test
3virtio_test: virtio_ring.o virtio_test.o 3virtio_test: virtio_ring.o virtio_test.o
4vringh_test: vringh_test.o vringh.o virtio_ring.o 4vringh_test: vringh_test.o vringh.o virtio_ring.o
5 5
6CFLAGS += -g -O2 -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE 6CFLAGS += -g -O2 -Werror -Wall -I. -I../include/ -I ../../usr/include/ -Wno-pointer-sign -fno-strict-overflow -fno-strict-aliasing -fno-common -MMD -U_FORTIFY_SOURCE
7vpath %.c ../../drivers/virtio ../../drivers/vhost 7vpath %.c ../../drivers/virtio ../../drivers/vhost
8mod: 8mod:
9 ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test 9 ${MAKE} -C `pwd`/../.. M=`pwd`/vhost_test
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
index 5a2d1f0f6bc7..a3e07016a440 100644
--- a/tools/virtio/linux/virtio.h
+++ b/tools/virtio/linux/virtio.h
@@ -6,31 +6,12 @@
6/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */ 6/* TODO: empty stubs for now. Broken but enough for virtio_ring.c */
7#define list_add_tail(a, b) do {} while (0) 7#define list_add_tail(a, b) do {} while (0)
8#define list_del(a) do {} while (0) 8#define list_del(a) do {} while (0)
9 9#define list_for_each_entry(a, b, c) while (0)
10#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)
11#define BITS_PER_BYTE 8
12#define BITS_PER_LONG (sizeof(long) * BITS_PER_BYTE)
13#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))
14
15/* TODO: Not atomic as it should be:
16 * we don't use this for anything important. */
17static inline void clear_bit(int nr, volatile unsigned long *addr)
18{
19 unsigned long mask = BIT_MASK(nr);
20 unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);
21
22 *p &= ~mask;
23}
24
25static inline int test_bit(int nr, const volatile unsigned long *addr)
26{
27 return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
28}
29/* end of stubs */ 10/* end of stubs */
30 11
31struct virtio_device { 12struct virtio_device {
32 void *dev; 13 void *dev;
33 unsigned long features[1]; 14 u64 features;
34}; 15};
35 16
36struct virtqueue { 17struct virtqueue {
diff --git a/tools/virtio/linux/virtio_byteorder.h b/tools/virtio/linux/virtio_byteorder.h
new file mode 100644
index 000000000000..9de9e6ac1d10
--- /dev/null
+++ b/tools/virtio/linux/virtio_byteorder.h
@@ -0,0 +1,8 @@
1#ifndef _LINUX_VIRTIO_BYTEORDER_STUB_H
2#define _LINUX_VIRTIO_BYTEORDER_STUB_H
3
4#include <asm/byteorder.h>
5#include "../../include/linux/byteorder/generic.h"
6#include "../../include/linux/virtio_byteorder.h"
7
8#endif
diff --git a/tools/virtio/linux/virtio_config.h b/tools/virtio/linux/virtio_config.h
index 5049967f99f7..806d683ab107 100644
--- a/tools/virtio/linux/virtio_config.h
+++ b/tools/virtio/linux/virtio_config.h
@@ -1,6 +1,72 @@
1#define VIRTIO_TRANSPORT_F_START 28 1#include <linux/virtio_byteorder.h>
2#define VIRTIO_TRANSPORT_F_END 32 2#include <linux/virtio.h>
3#include <uapi/linux/virtio_config.h>
4
5/*
6 * __virtio_test_bit - helper to test feature bits. For use by transports.
7 * Devices should normally use virtio_has_feature,
8 * which includes more checks.
9 * @vdev: the device
10 * @fbit: the feature bit
11 */
12static inline bool __virtio_test_bit(const struct virtio_device *vdev,
13 unsigned int fbit)
14{
15 return vdev->features & (1ULL << fbit);
16}
17
18/**
19 * __virtio_set_bit - helper to set feature bits. For use by transports.
20 * @vdev: the device
21 * @fbit: the feature bit
22 */
23static inline void __virtio_set_bit(struct virtio_device *vdev,
24 unsigned int fbit)
25{
26 vdev->features |= (1ULL << fbit);
27}
28
29/**
30 * __virtio_clear_bit - helper to clear feature bits. For use by transports.
31 * @vdev: the device
32 * @fbit: the feature bit
33 */
34static inline void __virtio_clear_bit(struct virtio_device *vdev,
35 unsigned int fbit)
36{
37 vdev->features &= ~(1ULL << fbit);
38}
3 39
4#define virtio_has_feature(dev, feature) \ 40#define virtio_has_feature(dev, feature) \
5 test_bit((feature), (dev)->features) 41 (__virtio_test_bit((dev), feature))
42
43static inline u16 virtio16_to_cpu(struct virtio_device *vdev, __virtio16 val)
44{
45 return __virtio16_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
46}
47
48static inline __virtio16 cpu_to_virtio16(struct virtio_device *vdev, u16 val)
49{
50 return __cpu_to_virtio16(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
51}
52
53static inline u32 virtio32_to_cpu(struct virtio_device *vdev, __virtio32 val)
54{
55 return __virtio32_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
56}
57
58static inline __virtio32 cpu_to_virtio32(struct virtio_device *vdev, u32 val)
59{
60 return __cpu_to_virtio32(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
61}
62
63static inline u64 virtio64_to_cpu(struct virtio_device *vdev, __virtio64 val)
64{
65 return __virtio64_to_cpu(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
66}
67
68static inline __virtio64 cpu_to_virtio64(struct virtio_device *vdev, u64 val)
69{
70 return __cpu_to_virtio64(virtio_has_feature(vdev, VIRTIO_F_VERSION_1), val);
71}
6 72
diff --git a/tools/virtio/uapi/linux/virtio_types.h b/tools/virtio/uapi/linux/virtio_types.h
new file mode 100644
index 000000000000..e7a1096e7c97
--- /dev/null
+++ b/tools/virtio/uapi/linux/virtio_types.h
@@ -0,0 +1 @@
#include "../../include/uapi/linux/virtio_types.h"
diff --git a/tools/virtio/virtio_test.c b/tools/virtio/virtio_test.c
index 00ea679b3826..e0445898f08f 100644
--- a/tools/virtio/virtio_test.c
+++ b/tools/virtio/virtio_test.c
@@ -11,6 +11,7 @@
11#include <sys/types.h> 11#include <sys/types.h>
12#include <fcntl.h> 12#include <fcntl.h>
13#include <stdbool.h> 13#include <stdbool.h>
14#include <linux/virtio_types.h>
14#include <linux/vhost.h> 15#include <linux/vhost.h>
15#include <linux/virtio.h> 16#include <linux/virtio.h>
16#include <linux/virtio_ring.h> 17#include <linux/virtio_ring.h>
@@ -60,7 +61,7 @@ void vhost_vq_setup(struct vdev_info *dev, struct vq_info *info)
60{ 61{
61 struct vhost_vring_state state = { .index = info->idx }; 62 struct vhost_vring_state state = { .index = info->idx };
62 struct vhost_vring_file file = { .index = info->idx }; 63 struct vhost_vring_file file = { .index = info->idx };
63 unsigned long long features = dev->vdev.features[0]; 64 unsigned long long features = dev->vdev.features;
64 struct vhost_vring_addr addr = { 65 struct vhost_vring_addr addr = {
65 .index = info->idx, 66 .index = info->idx,
66 .desc_user_addr = (uint64_t)(unsigned long)info->vring.desc, 67 .desc_user_addr = (uint64_t)(unsigned long)info->vring.desc,
@@ -113,8 +114,7 @@ static void vdev_info_init(struct vdev_info* dev, unsigned long long features)
113{ 114{
114 int r; 115 int r;
115 memset(dev, 0, sizeof *dev); 116 memset(dev, 0, sizeof *dev);
116 dev->vdev.features[0] = features; 117 dev->vdev.features = features;
117 dev->vdev.features[1] = features >> 32;
118 dev->buf_size = 1024; 118 dev->buf_size = 1024;
119 dev->buf = malloc(dev->buf_size); 119 dev->buf = malloc(dev->buf_size);
120 assert(dev->buf); 120 assert(dev->buf);
@@ -228,6 +228,14 @@ const struct option longopts[] = {
228 .val = 'i', 228 .val = 'i',
229 }, 229 },
230 { 230 {
231 .name = "virtio-1",
232 .val = '1',
233 },
234 {
235 .name = "no-virtio-1",
236 .val = '0',
237 },
238 {
231 .name = "delayed-interrupt", 239 .name = "delayed-interrupt",
232 .val = 'D', 240 .val = 'D',
233 }, 241 },
@@ -244,6 +252,7 @@ static void help(void)
244 fprintf(stderr, "Usage: virtio_test [--help]" 252 fprintf(stderr, "Usage: virtio_test [--help]"
245 " [--no-indirect]" 253 " [--no-indirect]"
246 " [--no-event-idx]" 254 " [--no-event-idx]"
255 " [--no-virtio-1]"
247 " [--delayed-interrupt]" 256 " [--delayed-interrupt]"
248 "\n"); 257 "\n");
249} 258}
@@ -252,7 +261,7 @@ int main(int argc, char **argv)
252{ 261{
253 struct vdev_info dev; 262 struct vdev_info dev;
254 unsigned long long features = (1ULL << VIRTIO_RING_F_INDIRECT_DESC) | 263 unsigned long long features = (1ULL << VIRTIO_RING_F_INDIRECT_DESC) |
255 (1ULL << VIRTIO_RING_F_EVENT_IDX); 264 (1ULL << VIRTIO_RING_F_EVENT_IDX) | (1ULL << VIRTIO_F_VERSION_1);
256 int o; 265 int o;
257 bool delayed = false; 266 bool delayed = false;
258 267
@@ -273,6 +282,9 @@ int main(int argc, char **argv)
273 case 'i': 282 case 'i':
274 features &= ~(1ULL << VIRTIO_RING_F_INDIRECT_DESC); 283 features &= ~(1ULL << VIRTIO_RING_F_INDIRECT_DESC);
275 break; 284 break;
285 case '0':
286 features &= ~(1ULL << VIRTIO_F_VERSION_1);
287 break;
276 case 'D': 288 case 'D':
277 delayed = true; 289 delayed = true;
278 break; 290 break;
diff --git a/tools/virtio/vringh_test.c b/tools/virtio/vringh_test.c
index 14a4f4cab5b9..5f94f5105678 100644
--- a/tools/virtio/vringh_test.c
+++ b/tools/virtio/vringh_test.c
@@ -7,6 +7,7 @@
7#include <linux/virtio.h> 7#include <linux/virtio.h>
8#include <linux/vringh.h> 8#include <linux/vringh.h>
9#include <linux/virtio_ring.h> 9#include <linux/virtio_ring.h>
10#include <linux/virtio_config.h>
10#include <linux/uaccess.h> 11#include <linux/uaccess.h>
11#include <sys/types.h> 12#include <sys/types.h>
12#include <sys/stat.h> 13#include <sys/stat.h>
@@ -131,7 +132,7 @@ static inline int vringh_get_head(struct vringh *vrh, u16 *head)
131 return 1; 132 return 1;
132} 133}
133 134
134static int parallel_test(unsigned long features, 135static int parallel_test(u64 features,
135 bool (*getrange)(struct vringh *vrh, 136 bool (*getrange)(struct vringh *vrh,
136 u64 addr, struct vringh_range *r), 137 u64 addr, struct vringh_range *r),
137 bool fast_vringh) 138 bool fast_vringh)
@@ -304,7 +305,7 @@ static int parallel_test(unsigned long features,
304 close(to_guest[1]); 305 close(to_guest[1]);
305 close(to_host[0]); 306 close(to_host[0]);
306 307
307 gvdev.vdev.features[0] = features; 308 gvdev.vdev.features = features;
308 gvdev.to_host_fd = to_host[1]; 309 gvdev.to_host_fd = to_host[1];
309 gvdev.notifies = 0; 310 gvdev.notifies = 0;
310 311
@@ -449,13 +450,15 @@ int main(int argc, char *argv[])
449 bool fast_vringh = false, parallel = false; 450 bool fast_vringh = false, parallel = false;
450 451
451 getrange = getrange_iov; 452 getrange = getrange_iov;
452 vdev.features[0] = 0; 453 vdev.features = 0;
453 454
454 while (argv[1]) { 455 while (argv[1]) {
455 if (strcmp(argv[1], "--indirect") == 0) 456 if (strcmp(argv[1], "--indirect") == 0)
456 vdev.features[0] |= (1 << VIRTIO_RING_F_INDIRECT_DESC); 457 __virtio_set_bit(&vdev, VIRTIO_RING_F_INDIRECT_DESC);
457 else if (strcmp(argv[1], "--eventidx") == 0) 458 else if (strcmp(argv[1], "--eventidx") == 0)
458 vdev.features[0] |= (1 << VIRTIO_RING_F_EVENT_IDX); 459 __virtio_set_bit(&vdev, VIRTIO_RING_F_EVENT_IDX);
460 else if (strcmp(argv[1], "--virtio-1") == 0)
461 __virtio_set_bit(&vdev, VIRTIO_F_VERSION_1);
459 else if (strcmp(argv[1], "--slow-range") == 0) 462 else if (strcmp(argv[1], "--slow-range") == 0)
460 getrange = getrange_slow; 463 getrange = getrange_slow;
461 else if (strcmp(argv[1], "--fast-vringh") == 0) 464 else if (strcmp(argv[1], "--fast-vringh") == 0)
@@ -468,7 +471,7 @@ int main(int argc, char *argv[])
468 } 471 }
469 472
470 if (parallel) 473 if (parallel)
471 return parallel_test(vdev.features[0], getrange, fast_vringh); 474 return parallel_test(vdev.features, getrange, fast_vringh);
472 475
473 if (posix_memalign(&__user_addr_min, PAGE_SIZE, USER_MEM) != 0) 476 if (posix_memalign(&__user_addr_min, PAGE_SIZE, USER_MEM) != 0)
474 abort(); 477 abort();
@@ -483,7 +486,7 @@ int main(int argc, char *argv[])
483 486
484 /* Set up host side. */ 487 /* Set up host side. */
485 vring_init(&vrh.vring, RINGSIZE, __user_addr_min, ALIGN); 488 vring_init(&vrh.vring, RINGSIZE, __user_addr_min, ALIGN);
486 vringh_init_user(&vrh, vdev.features[0], RINGSIZE, true, 489 vringh_init_user(&vrh, vdev.features, RINGSIZE, true,
487 vrh.vring.desc, vrh.vring.avail, vrh.vring.used); 490 vrh.vring.desc, vrh.vring.avail, vrh.vring.used);
488 491
489 /* No descriptor to get yet... */ 492 /* No descriptor to get yet... */
@@ -652,13 +655,13 @@ int main(int argc, char *argv[])
652 } 655 }
653 656
654 /* Test weird (but legal!) indirect. */ 657 /* Test weird (but legal!) indirect. */
655 if (vdev.features[0] & (1 << VIRTIO_RING_F_INDIRECT_DESC)) { 658 if (__virtio_test_bit(&vdev, VIRTIO_RING_F_INDIRECT_DESC)) {
656 char *data = __user_addr_max - USER_MEM/4; 659 char *data = __user_addr_max - USER_MEM/4;
657 struct vring_desc *d = __user_addr_max - USER_MEM/2; 660 struct vring_desc *d = __user_addr_max - USER_MEM/2;
658 struct vring vring; 661 struct vring vring;
659 662
660 /* Force creation of direct, which we modify. */ 663 /* Force creation of direct, which we modify. */
661 vdev.features[0] &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC); 664 __virtio_clear_bit(&vdev, VIRTIO_RING_F_INDIRECT_DESC);
662 vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &vdev, true, 665 vq = vring_new_virtqueue(0, RINGSIZE, ALIGN, &vdev, true,
663 __user_addr_min, 666 __user_addr_min,
664 never_notify_host, 667 never_notify_host,
diff --git a/tools/vm/Makefile b/tools/vm/Makefile
index 3d907dacf2ac..ac884b65a072 100644
--- a/tools/vm/Makefile
+++ b/tools/vm/Makefile
@@ -1,6 +1,6 @@
1# Makefile for vm tools 1# Makefile for vm tools
2# 2#
3TARGETS=page-types slabinfo 3TARGETS=page-types slabinfo page_owner_sort
4 4
5LIB_DIR = ../lib/api 5LIB_DIR = ../lib/api
6LIBS = $(LIB_DIR)/libapikfs.a 6LIBS = $(LIB_DIR)/libapikfs.a
@@ -18,5 +18,5 @@ $(LIBS):
18 $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS) 18 $(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
19 19
20clean: 20clean:
21 $(RM) page-types slabinfo 21 $(RM) page-types slabinfo page_owner_sort
22 make -C $(LIB_DIR) clean 22 make -C $(LIB_DIR) clean
diff --git a/tools/vm/page_owner_sort.c b/tools/vm/page_owner_sort.c
new file mode 100644
index 000000000000..77147b42d598
--- /dev/null
+++ b/tools/vm/page_owner_sort.c
@@ -0,0 +1,144 @@
1/*
2 * User-space helper to sort the output of /sys/kernel/debug/page_owner
3 *
4 * Example use:
5 * cat /sys/kernel/debug/page_owner > page_owner_full.txt
6 * grep -v ^PFN page_owner_full.txt > page_owner.txt
7 * ./sort page_owner.txt sorted_page_owner.txt
8*/
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <sys/types.h>
13#include <sys/stat.h>
14#include <fcntl.h>
15#include <unistd.h>
16#include <string.h>
17
18struct block_list {
19 char *txt;
20 int len;
21 int num;
22};
23
24
25static struct block_list *list;
26static int list_size;
27static int max_size;
28
29struct block_list *block_head;
30
31int read_block(char *buf, int buf_size, FILE *fin)
32{
33 char *curr = buf, *const buf_end = buf + buf_size;
34
35 while (buf_end - curr > 1 && fgets(curr, buf_end - curr, fin)) {
36 if (*curr == '\n') /* empty line */
37 return curr - buf;
38 curr += strlen(curr);
39 }
40
41 return -1; /* EOF or no space left in buf. */
42}
43
44static int compare_txt(const void *p1, const void *p2)
45{
46 const struct block_list *l1 = p1, *l2 = p2;
47
48 return strcmp(l1->txt, l2->txt);
49}
50
51static int compare_num(const void *p1, const void *p2)
52{
53 const struct block_list *l1 = p1, *l2 = p2;
54
55 return l2->num - l1->num;
56}
57
58static void add_list(char *buf, int len)
59{
60 if (list_size != 0 &&
61 len == list[list_size-1].len &&
62 memcmp(buf, list[list_size-1].txt, len) == 0) {
63 list[list_size-1].num++;
64 return;
65 }
66 if (list_size == max_size) {
67 printf("max_size too small??\n");
68 exit(1);
69 }
70 list[list_size].txt = malloc(len+1);
71 list[list_size].len = len;
72 list[list_size].num = 1;
73 memcpy(list[list_size].txt, buf, len);
74 list[list_size].txt[len] = 0;
75 list_size++;
76 if (list_size % 1000 == 0) {
77 printf("loaded %d\r", list_size);
78 fflush(stdout);
79 }
80}
81
82#define BUF_SIZE 1024
83
84int main(int argc, char **argv)
85{
86 FILE *fin, *fout;
87 char buf[BUF_SIZE];
88 int ret, i, count;
89 struct block_list *list2;
90 struct stat st;
91
92 if (argc < 3) {
93 printf("Usage: ./program <input> <output>\n");
94 perror("open: ");
95 exit(1);
96 }
97
98 fin = fopen(argv[1], "r");
99 fout = fopen(argv[2], "w");
100 if (!fin || !fout) {
101 printf("Usage: ./program <input> <output>\n");
102 perror("open: ");
103 exit(1);
104 }
105
106 fstat(fileno(fin), &st);
107 max_size = st.st_size / 100; /* hack ... */
108
109 list = malloc(max_size * sizeof(*list));
110
111 for ( ; ; ) {
112 ret = read_block(buf, BUF_SIZE, fin);
113 if (ret < 0)
114 break;
115
116 add_list(buf, ret);
117 }
118
119 printf("loaded %d\n", list_size);
120
121 printf("sorting ....\n");
122
123 qsort(list, list_size, sizeof(list[0]), compare_txt);
124
125 list2 = malloc(sizeof(*list) * list_size);
126
127 printf("culling\n");
128
129 for (i = count = 0; i < list_size; i++) {
130 if (count == 0 ||
131 strcmp(list2[count-1].txt, list[i].txt) != 0) {
132 list2[count++] = list[i];
133 } else {
134 list2[count-1].num += list[i].num;
135 }
136 }
137
138 qsort(list2, count, sizeof(list[0]), compare_num);
139
140 for (i = 0; i < count; i++)
141 fprintf(fout, "%d times:\n%s\n", list2[i].num, list2[i].txt);
142
143 return 0;
144}