aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/hv/hv_kvp_daemon.c63
-rw-r--r--tools/include/tools/be_byteshift.h34
-rw-r--r--tools/include/tools/le_byteshift.h34
-rw-r--r--tools/lguest/Makefile1
-rw-r--r--tools/lguest/lguest.c32
-rw-r--r--tools/lib/lk/Makefile20
-rw-r--r--tools/perf/Documentation/Makefile12
-rw-r--r--tools/perf/Documentation/examples.txt4
-rw-r--r--tools/perf/Documentation/perf-archive.txt2
-rw-r--r--tools/perf/Documentation/perf-record.txt8
-rw-r--r--tools/perf/Documentation/perf-report.txt4
-rw-r--r--tools/perf/Documentation/perf-top.txt4
-rw-r--r--tools/perf/Makefile633
-rw-r--r--tools/perf/bench/mem-memcpy.c4
-rw-r--r--tools/perf/bench/mem-memset.c2
-rw-r--r--tools/perf/builtin-diff.c20
-rw-r--r--tools/perf/builtin-kmem.c2
-rw-r--r--tools/perf/builtin-kvm.c3
-rw-r--r--tools/perf/builtin-lock.c2
-rw-r--r--tools/perf/builtin-record.c87
-rw-r--r--tools/perf/builtin-report.c105
-rw-r--r--tools/perf/builtin-sched.c1
-rw-r--r--tools/perf/builtin-stat.c30
-rw-r--r--tools/perf/builtin-timechart.c4
-rw-r--r--tools/perf/builtin-top.c76
-rw-r--r--tools/perf/config/Makefile477
-rw-r--r--tools/perf/config/utilities.mak4
-rw-r--r--tools/perf/scripts/perl/Perf-Trace-Util/Context.xs2
-rw-r--r--tools/perf/tests/attr/base-record4
-rw-r--r--tools/perf/tests/attr/base-stat4
-rw-r--r--tools/perf/tests/attr/test-record-data5
-rw-r--r--tools/perf/tests/bp_signal.c6
-rw-r--r--tools/perf/tests/bp_signal_overflow.c6
-rw-r--r--tools/perf/tests/builtin-test.c2
-rw-r--r--tools/perf/tests/make138
-rw-r--r--tools/perf/ui/browsers/hists.c106
-rw-r--r--tools/perf/ui/gtk/hists.c13
-rw-r--r--tools/perf/ui/stdio/hist.c7
-rwxr-xr-xtools/perf/util/PERF-VERSION-GEN21
-rw-r--r--tools/perf/util/dso.c10
-rw-r--r--tools/perf/util/dso.h3
-rw-r--r--tools/perf/util/evlist.c12
-rw-r--r--tools/perf/util/evsel.c6
-rw-r--r--tools/perf/util/header.c17
-rw-r--r--tools/perf/util/header.h1
-rw-r--r--tools/perf/util/hist.c96
-rw-r--r--tools/perf/util/hist.h16
-rw-r--r--tools/perf/util/map.c1
-rw-r--r--tools/perf/util/parse-events.c4
-rw-r--r--tools/perf/util/session.h1
-rw-r--r--tools/perf/util/setup.py5
-rw-r--r--tools/perf/util/sort.c128
-rw-r--r--tools/perf/util/sort.h36
-rw-r--r--tools/perf/util/stat.c2
-rw-r--r--tools/perf/util/symbol.c1
-rw-r--r--tools/perf/util/thread.c4
-rw-r--r--tools/perf/util/thread.h1
-rw-r--r--tools/perf/util/top.c23
-rw-r--r--tools/perf/util/top.h2
-rw-r--r--tools/perf/util/util.h6
-rw-r--r--tools/perf/util/vdso.c2
-rw-r--r--tools/power/cpupower/Makefile4
-rw-r--r--tools/power/cpupower/man/cpupower-monitor.110
-rw-r--r--tools/power/cpupower/utils/builtin.h1
-rw-r--r--tools/power/cpupower/utils/cpuidle-info.c24
-rw-r--r--tools/power/cpupower/utils/cpuidle-set.c118
-rw-r--r--tools/power/cpupower/utils/cpupower.c13
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.c118
-rw-r--r--tools/power/cpupower/utils/helpers/sysfs.h10
-rw-r--r--tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c196
-rw-r--r--tools/power/cpupower/utils/idle_monitor/idle_monitors.def1
-rw-r--r--tools/power/cpupower/utils/idle_monitor/snb_idle.c4
-rw-r--r--tools/scripts/Makefile.include2
-rwxr-xr-xtools/testing/ktest/ktest.pl2
-rw-r--r--tools/testing/selftests/Makefile1
-rw-r--r--tools/testing/selftests/cpu-hotplug/Makefile2
-rw-r--r--tools/testing/selftests/kcmp/.gitignore2
-rw-r--r--tools/testing/selftests/kcmp/Makefile3
-rw-r--r--tools/testing/selftests/memory-hotplug/Makefile2
-rw-r--r--tools/testing/selftests/net/psock_tpacket.c59
-rw-r--r--tools/testing/selftests/timers/Makefile8
-rw-r--r--tools/testing/selftests/timers/posix_timers.c221
-rw-r--r--tools/testing/selftests/vm/.gitignore4
-rw-r--r--tools/testing/selftests/vm/Makefile7
-rw-r--r--tools/testing/selftests/vm/hugetlbfstest.c84
-rw-r--r--tools/testing/selftests/vm/run_vmtests16
-rw-r--r--tools/virtio/linux/module.h5
-rw-r--r--tools/virtio/linux/virtio.h3
88 files changed, 2223 insertions, 1056 deletions
diff --git a/tools/hv/hv_kvp_daemon.c b/tools/hv/hv_kvp_daemon.c
index 5a1f6489d185..07819bfa7dba 100644
--- a/tools/hv/hv_kvp_daemon.c
+++ b/tools/hv/hv_kvp_daemon.c
@@ -127,7 +127,8 @@ static void kvp_acquire_lock(int pool)
127 fl.l_pid = getpid(); 127 fl.l_pid = getpid();
128 128
129 if (fcntl(kvp_file_info[pool].fd, F_SETLKW, &fl) == -1) { 129 if (fcntl(kvp_file_info[pool].fd, F_SETLKW, &fl) == -1) {
130 syslog(LOG_ERR, "Failed to acquire the lock pool: %d", pool); 130 syslog(LOG_ERR, "Failed to acquire the lock pool: %d; error: %d %s", pool,
131 errno, strerror(errno));
131 exit(EXIT_FAILURE); 132 exit(EXIT_FAILURE);
132 } 133 }
133} 134}
@@ -138,8 +139,8 @@ static void kvp_release_lock(int pool)
138 fl.l_pid = getpid(); 139 fl.l_pid = getpid();
139 140
140 if (fcntl(kvp_file_info[pool].fd, F_SETLK, &fl) == -1) { 141 if (fcntl(kvp_file_info[pool].fd, F_SETLK, &fl) == -1) {
141 perror("fcntl"); 142 syslog(LOG_ERR, "Failed to release the lock pool: %d; error: %d %s", pool,
142 syslog(LOG_ERR, "Failed to release the lock pool: %d", pool); 143 errno, strerror(errno));
143 exit(EXIT_FAILURE); 144 exit(EXIT_FAILURE);
144 } 145 }
145} 146}
@@ -157,8 +158,9 @@ static void kvp_update_file(int pool)
157 158
158 filep = fopen(kvp_file_info[pool].fname, "we"); 159 filep = fopen(kvp_file_info[pool].fname, "we");
159 if (!filep) { 160 if (!filep) {
161 syslog(LOG_ERR, "Failed to open file, pool: %d; error: %d %s", pool,
162 errno, strerror(errno));
160 kvp_release_lock(pool); 163 kvp_release_lock(pool);
161 syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
162 exit(EXIT_FAILURE); 164 exit(EXIT_FAILURE);
163 } 165 }
164 166
@@ -188,8 +190,9 @@ static void kvp_update_mem_state(int pool)
188 190
189 filep = fopen(kvp_file_info[pool].fname, "re"); 191 filep = fopen(kvp_file_info[pool].fname, "re");
190 if (!filep) { 192 if (!filep) {
193 syslog(LOG_ERR, "Failed to open file, pool: %d; error: %d %s", pool,
194 errno, strerror(errno));
191 kvp_release_lock(pool); 195 kvp_release_lock(pool);
192 syslog(LOG_ERR, "Failed to open file, pool: %d", pool);
193 exit(EXIT_FAILURE); 196 exit(EXIT_FAILURE);
194 } 197 }
195 for (;;) { 198 for (;;) {
@@ -240,7 +243,8 @@ static int kvp_file_init(void)
240 243
241 if (access(KVP_CONFIG_LOC, F_OK)) { 244 if (access(KVP_CONFIG_LOC, F_OK)) {
242 if (mkdir(KVP_CONFIG_LOC, 0755 /* rwxr-xr-x */)) { 245 if (mkdir(KVP_CONFIG_LOC, 0755 /* rwxr-xr-x */)) {
243 syslog(LOG_ERR, " Failed to create %s", KVP_CONFIG_LOC); 246 syslog(LOG_ERR, "Failed to create '%s'; error: %d %s", KVP_CONFIG_LOC,
247 errno, strerror(errno));
244 exit(EXIT_FAILURE); 248 exit(EXIT_FAILURE);
245 } 249 }
246 } 250 }
@@ -257,12 +261,15 @@ static int kvp_file_init(void)
257 261
258 262
259 filep = fopen(fname, "re"); 263 filep = fopen(fname, "re");
260 if (!filep) 264 if (!filep) {
265 close(fd);
261 return 1; 266 return 1;
267 }
262 268
263 record = malloc(alloc_unit * num_blocks); 269 record = malloc(alloc_unit * num_blocks);
264 if (record == NULL) { 270 if (record == NULL) {
265 fclose(filep); 271 fclose(filep);
272 close(fd);
266 return 1; 273 return 1;
267 } 274 }
268 for (;;) { 275 for (;;) {
@@ -286,6 +293,7 @@ static int kvp_file_init(void)
286 num_blocks); 293 num_blocks);
287 if (record == NULL) { 294 if (record == NULL) {
288 fclose(filep); 295 fclose(filep);
296 close(fd);
289 return 1; 297 return 1;
290 } 298 }
291 continue; 299 continue;
@@ -765,7 +773,9 @@ static void kvp_process_ipconfig_file(char *cmd,
765 break; 773 break;
766 774
767 x = strchr(p, '\n'); 775 x = strchr(p, '\n');
768 *x = '\0'; 776 if (x)
777 *x = '\0';
778
769 strcat(config_buf, p); 779 strcat(config_buf, p);
770 strcat(config_buf, ";"); 780 strcat(config_buf, ";");
771 } 781 }
@@ -1016,9 +1026,10 @@ kvp_get_ip_info(int family, char *if_name, int op,
1016 1026
1017 if (sn_offset == 0) 1027 if (sn_offset == 0)
1018 strcpy(sn_str, cidr_mask); 1028 strcpy(sn_str, cidr_mask);
1019 else 1029 else {
1030 strcat((char *)ip_buffer->sub_net, ";");
1020 strcat(sn_str, cidr_mask); 1031 strcat(sn_str, cidr_mask);
1021 strcat((char *)ip_buffer->sub_net, ";"); 1032 }
1022 sn_offset += strlen(sn_str) + 1; 1033 sn_offset += strlen(sn_str) + 1;
1023 } 1034 }
1024 1035
@@ -1274,7 +1285,8 @@ static int kvp_set_ip_info(char *if_name, struct hv_kvp_ipaddr_value *new_val)
1274 file = fopen(if_file, "w"); 1285 file = fopen(if_file, "w");
1275 1286
1276 if (file == NULL) { 1287 if (file == NULL) {
1277 syslog(LOG_ERR, "Failed to open config file"); 1288 syslog(LOG_ERR, "Failed to open config file; error: %d %s",
1289 errno, strerror(errno));
1278 return HV_E_FAIL; 1290 return HV_E_FAIL;
1279 } 1291 }
1280 1292
@@ -1441,7 +1453,8 @@ int main(void)
1441 1453
1442 fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR); 1454 fd = socket(AF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);
1443 if (fd < 0) { 1455 if (fd < 0) {
1444 syslog(LOG_ERR, "netlink socket creation failed; error:%d", fd); 1456 syslog(LOG_ERR, "netlink socket creation failed; error: %d %s", errno,
1457 strerror(errno));
1445 exit(EXIT_FAILURE); 1458 exit(EXIT_FAILURE);
1446 } 1459 }
1447 addr.nl_family = AF_NETLINK; 1460 addr.nl_family = AF_NETLINK;
@@ -1452,12 +1465,18 @@ int main(void)
1452 1465
1453 error = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); 1466 error = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
1454 if (error < 0) { 1467 if (error < 0) {
1455 syslog(LOG_ERR, "bind failed; error:%d", error); 1468 syslog(LOG_ERR, "bind failed; error: %d %s", errno, strerror(errno));
1456 close(fd); 1469 close(fd);
1457 exit(EXIT_FAILURE); 1470 exit(EXIT_FAILURE);
1458 } 1471 }
1459 nl_group = CN_KVP_IDX; 1472 nl_group = CN_KVP_IDX;
1460 setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &nl_group, sizeof(nl_group)); 1473
1474 if (setsockopt(fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, &nl_group, sizeof(nl_group)) < 0) {
1475 syslog(LOG_ERR, "setsockopt failed; error: %d %s", errno, strerror(errno));
1476 close(fd);
1477 exit(EXIT_FAILURE);
1478 }
1479
1461 /* 1480 /*
1462 * Register ourselves with the kernel. 1481 * Register ourselves with the kernel.
1463 */ 1482 */
@@ -1472,7 +1491,7 @@ int main(void)
1472 1491
1473 len = netlink_send(fd, message); 1492 len = netlink_send(fd, message);
1474 if (len < 0) { 1493 if (len < 0) {
1475 syslog(LOG_ERR, "netlink_send failed; error:%d", len); 1494 syslog(LOG_ERR, "netlink_send failed; error: %d %s", errno, strerror(errno));
1476 close(fd); 1495 close(fd);
1477 exit(EXIT_FAILURE); 1496 exit(EXIT_FAILURE);
1478 } 1497 }
@@ -1484,7 +1503,16 @@ int main(void)
1484 socklen_t addr_l = sizeof(addr); 1503 socklen_t addr_l = sizeof(addr);
1485 pfd.events = POLLIN; 1504 pfd.events = POLLIN;
1486 pfd.revents = 0; 1505 pfd.revents = 0;
1487 poll(&pfd, 1, -1); 1506
1507 if (poll(&pfd, 1, -1) < 0) {
1508 syslog(LOG_ERR, "poll failed; error: %d %s", errno, strerror(errno));
1509 if (errno == EINVAL) {
1510 close(fd);
1511 exit(EXIT_FAILURE);
1512 }
1513 else
1514 continue;
1515 }
1488 1516
1489 len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0, 1517 len = recvfrom(fd, kvp_recv_buffer, sizeof(kvp_recv_buffer), 0,
1490 addr_p, &addr_l); 1518 addr_p, &addr_l);
@@ -1695,7 +1723,8 @@ kvp_done:
1695 1723
1696 len = netlink_send(fd, incoming_cn_msg); 1724 len = netlink_send(fd, incoming_cn_msg);
1697 if (len < 0) { 1725 if (len < 0) {
1698 syslog(LOG_ERR, "net_link send failed; error:%d", len); 1726 syslog(LOG_ERR, "net_link send failed; error: %d %s", errno,
1727 strerror(errno));
1699 exit(EXIT_FAILURE); 1728 exit(EXIT_FAILURE);
1700 } 1729 }
1701 } 1730 }
diff --git a/tools/include/tools/be_byteshift.h b/tools/include/tools/be_byteshift.h
index f4912e2668ba..84c17d836578 100644
--- a/tools/include/tools/be_byteshift.h
+++ b/tools/include/tools/be_byteshift.h
@@ -1,68 +1,68 @@
1#ifndef _TOOLS_BE_BYTESHIFT_H 1#ifndef _TOOLS_BE_BYTESHIFT_H
2#define _TOOLS_BE_BYTESHIFT_H 2#define _TOOLS_BE_BYTESHIFT_H
3 3
4#include <linux/types.h> 4#include <stdint.h>
5 5
6static inline __u16 __get_unaligned_be16(const __u8 *p) 6static inline uint16_t __get_unaligned_be16(const uint8_t *p)
7{ 7{
8 return p[0] << 8 | p[1]; 8 return p[0] << 8 | p[1];
9} 9}
10 10
11static inline __u32 __get_unaligned_be32(const __u8 *p) 11static inline uint32_t __get_unaligned_be32(const uint8_t *p)
12{ 12{
13 return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3]; 13 return p[0] << 24 | p[1] << 16 | p[2] << 8 | p[3];
14} 14}
15 15
16static inline __u64 __get_unaligned_be64(const __u8 *p) 16static inline uint64_t __get_unaligned_be64(const uint8_t *p)
17{ 17{
18 return (__u64)__get_unaligned_be32(p) << 32 | 18 return (uint64_t)__get_unaligned_be32(p) << 32 |
19 __get_unaligned_be32(p + 4); 19 __get_unaligned_be32(p + 4);
20} 20}
21 21
22static inline void __put_unaligned_be16(__u16 val, __u8 *p) 22static inline void __put_unaligned_be16(uint16_t val, uint8_t *p)
23{ 23{
24 *p++ = val >> 8; 24 *p++ = val >> 8;
25 *p++ = val; 25 *p++ = val;
26} 26}
27 27
28static inline void __put_unaligned_be32(__u32 val, __u8 *p) 28static inline void __put_unaligned_be32(uint32_t val, uint8_t *p)
29{ 29{
30 __put_unaligned_be16(val >> 16, p); 30 __put_unaligned_be16(val >> 16, p);
31 __put_unaligned_be16(val, p + 2); 31 __put_unaligned_be16(val, p + 2);
32} 32}
33 33
34static inline void __put_unaligned_be64(__u64 val, __u8 *p) 34static inline void __put_unaligned_be64(uint64_t val, uint8_t *p)
35{ 35{
36 __put_unaligned_be32(val >> 32, p); 36 __put_unaligned_be32(val >> 32, p);
37 __put_unaligned_be32(val, p + 4); 37 __put_unaligned_be32(val, p + 4);
38} 38}
39 39
40static inline __u16 get_unaligned_be16(const void *p) 40static inline uint16_t get_unaligned_be16(const void *p)
41{ 41{
42 return __get_unaligned_be16((const __u8 *)p); 42 return __get_unaligned_be16((const uint8_t *)p);
43} 43}
44 44
45static inline __u32 get_unaligned_be32(const void *p) 45static inline uint32_t get_unaligned_be32(const void *p)
46{ 46{
47 return __get_unaligned_be32((const __u8 *)p); 47 return __get_unaligned_be32((const uint8_t *)p);
48} 48}
49 49
50static inline __u64 get_unaligned_be64(const void *p) 50static inline uint64_t get_unaligned_be64(const void *p)
51{ 51{
52 return __get_unaligned_be64((const __u8 *)p); 52 return __get_unaligned_be64((const uint8_t *)p);
53} 53}
54 54
55static inline void put_unaligned_be16(__u16 val, void *p) 55static inline void put_unaligned_be16(uint16_t val, void *p)
56{ 56{
57 __put_unaligned_be16(val, p); 57 __put_unaligned_be16(val, p);
58} 58}
59 59
60static inline void put_unaligned_be32(__u32 val, void *p) 60static inline void put_unaligned_be32(uint32_t val, void *p)
61{ 61{
62 __put_unaligned_be32(val, p); 62 __put_unaligned_be32(val, p);
63} 63}
64 64
65static inline void put_unaligned_be64(__u64 val, void *p) 65static inline void put_unaligned_be64(uint64_t val, void *p)
66{ 66{
67 __put_unaligned_be64(val, p); 67 __put_unaligned_be64(val, p);
68} 68}
diff --git a/tools/include/tools/le_byteshift.h b/tools/include/tools/le_byteshift.h
index c99d45a68bda..8fe9f2488ec7 100644
--- a/tools/include/tools/le_byteshift.h
+++ b/tools/include/tools/le_byteshift.h
@@ -1,68 +1,68 @@
1#ifndef _TOOLS_LE_BYTESHIFT_H 1#ifndef _TOOLS_LE_BYTESHIFT_H
2#define _TOOLS_LE_BYTESHIFT_H 2#define _TOOLS_LE_BYTESHIFT_H
3 3
4#include <linux/types.h> 4#include <stdint.h>
5 5
6static inline __u16 __get_unaligned_le16(const __u8 *p) 6static inline uint16_t __get_unaligned_le16(const uint8_t *p)
7{ 7{
8 return p[0] | p[1] << 8; 8 return p[0] | p[1] << 8;
9} 9}
10 10
11static inline __u32 __get_unaligned_le32(const __u8 *p) 11static inline uint32_t __get_unaligned_le32(const uint8_t *p)
12{ 12{
13 return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24; 13 return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
14} 14}
15 15
16static inline __u64 __get_unaligned_le64(const __u8 *p) 16static inline uint64_t __get_unaligned_le64(const uint8_t *p)
17{ 17{
18 return (__u64)__get_unaligned_le32(p + 4) << 32 | 18 return (uint64_t)__get_unaligned_le32(p + 4) << 32 |
19 __get_unaligned_le32(p); 19 __get_unaligned_le32(p);
20} 20}
21 21
22static inline void __put_unaligned_le16(__u16 val, __u8 *p) 22static inline void __put_unaligned_le16(uint16_t val, uint8_t *p)
23{ 23{
24 *p++ = val; 24 *p++ = val;
25 *p++ = val >> 8; 25 *p++ = val >> 8;
26} 26}
27 27
28static inline void __put_unaligned_le32(__u32 val, __u8 *p) 28static inline void __put_unaligned_le32(uint32_t val, uint8_t *p)
29{ 29{
30 __put_unaligned_le16(val >> 16, p + 2); 30 __put_unaligned_le16(val >> 16, p + 2);
31 __put_unaligned_le16(val, p); 31 __put_unaligned_le16(val, p);
32} 32}
33 33
34static inline void __put_unaligned_le64(__u64 val, __u8 *p) 34static inline void __put_unaligned_le64(uint64_t val, uint8_t *p)
35{ 35{
36 __put_unaligned_le32(val >> 32, p + 4); 36 __put_unaligned_le32(val >> 32, p + 4);
37 __put_unaligned_le32(val, p); 37 __put_unaligned_le32(val, p);
38} 38}
39 39
40static inline __u16 get_unaligned_le16(const void *p) 40static inline uint16_t get_unaligned_le16(const void *p)
41{ 41{
42 return __get_unaligned_le16((const __u8 *)p); 42 return __get_unaligned_le16((const uint8_t *)p);
43} 43}
44 44
45static inline __u32 get_unaligned_le32(const void *p) 45static inline uint32_t get_unaligned_le32(const void *p)
46{ 46{
47 return __get_unaligned_le32((const __u8 *)p); 47 return __get_unaligned_le32((const uint8_t *)p);
48} 48}
49 49
50static inline __u64 get_unaligned_le64(const void *p) 50static inline uint64_t get_unaligned_le64(const void *p)
51{ 51{
52 return __get_unaligned_le64((const __u8 *)p); 52 return __get_unaligned_le64((const uint8_t *)p);
53} 53}
54 54
55static inline void put_unaligned_le16(__u16 val, void *p) 55static inline void put_unaligned_le16(uint16_t val, void *p)
56{ 56{
57 __put_unaligned_le16(val, p); 57 __put_unaligned_le16(val, p);
58} 58}
59 59
60static inline void put_unaligned_le32(__u32 val, void *p) 60static inline void put_unaligned_le32(uint32_t val, void *p)
61{ 61{
62 __put_unaligned_le32(val, p); 62 __put_unaligned_le32(val, p);
63} 63}
64 64
65static inline void put_unaligned_le64(__u64 val, void *p) 65static inline void put_unaligned_le64(uint64_t val, void *p)
66{ 66{
67 __put_unaligned_le64(val, p); 67 __put_unaligned_le64(val, p);
68} 68}
diff --git a/tools/lguest/Makefile b/tools/lguest/Makefile
index 0ac34206f7a7..97bca4871ea3 100644
--- a/tools/lguest/Makefile
+++ b/tools/lguest/Makefile
@@ -1,5 +1,4 @@
1# This creates the demonstration utility "lguest" which runs a Linux guest. 1# This creates the demonstration utility "lguest" which runs a Linux guest.
2# Missing headers? Add "-I../../../include -I../../../arch/x86/include"
3CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE 2CFLAGS:=-m32 -Wall -Wmissing-declarations -Wmissing-prototypes -O3 -U_FORTIFY_SOURCE
4 3
5all: lguest 4all: lguest
diff --git a/tools/lguest/lguest.c b/tools/lguest/lguest.c
index 07a03452c227..68f67cf3d318 100644
--- a/tools/lguest/lguest.c
+++ b/tools/lguest/lguest.c
@@ -42,14 +42,6 @@
42#include <pwd.h> 42#include <pwd.h>
43#include <grp.h> 43#include <grp.h>
44 44
45#include <linux/virtio_config.h>
46#include <linux/virtio_net.h>
47#include <linux/virtio_blk.h>
48#include <linux/virtio_console.h>
49#include <linux/virtio_rng.h>
50#include <linux/virtio_ring.h>
51#include <asm/bootparam.h>
52#include "../../include/linux/lguest_launcher.h"
53/*L:110 45/*L:110
54 * We can ignore the 43 include files we need for this program, but I do want 46 * We can ignore the 43 include files we need for this program, but I do want
55 * to draw attention to the use of kernel-style types. 47 * to draw attention to the use of kernel-style types.
@@ -65,6 +57,15 @@ typedef uint16_t u16;
65typedef uint8_t u8; 57typedef uint8_t u8;
66/*:*/ 58/*:*/
67 59
60#include <linux/virtio_config.h>
61#include <linux/virtio_net.h>
62#include <linux/virtio_blk.h>
63#include <linux/virtio_console.h>
64#include <linux/virtio_rng.h>
65#include <linux/virtio_ring.h>
66#include <asm/bootparam.h>
67#include "../../include/linux/lguest_launcher.h"
68
68#define BRIDGE_PFX "bridge:" 69#define BRIDGE_PFX "bridge:"
69#ifndef SIOCBRADDIF 70#ifndef SIOCBRADDIF
70#define SIOCBRADDIF 0x89a2 /* add interface to bridge */ 71#define SIOCBRADDIF 0x89a2 /* add interface to bridge */
@@ -177,7 +178,8 @@ static struct termios orig_term;
177 * in precise order. 178 * in precise order.
178 */ 179 */
179#define wmb() __asm__ __volatile__("" : : : "memory") 180#define wmb() __asm__ __volatile__("" : : : "memory")
180#define mb() __asm__ __volatile__("" : : : "memory") 181#define rmb() __asm__ __volatile__("lock; addl $0,0(%%esp)" : : : "memory")
182#define mb() __asm__ __volatile__("lock; addl $0,0(%%esp)" : : : "memory")
181 183
182/* Wrapper for the last available index. Makes it easier to change. */ 184/* Wrapper for the last available index. Makes it easier to change. */
183#define lg_last_avail(vq) ((vq)->last_avail_idx) 185#define lg_last_avail(vq) ((vq)->last_avail_idx)
@@ -676,6 +678,12 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
676 errx(1, "Guest moved used index from %u to %u", 678 errx(1, "Guest moved used index from %u to %u",
677 last_avail, vq->vring.avail->idx); 679 last_avail, vq->vring.avail->idx);
678 680
681 /*
682 * Make sure we read the descriptor number *after* we read the ring
683 * update; don't let the cpu or compiler change the order.
684 */
685 rmb();
686
679 /* 687 /*
680 * Grab the next descriptor number they're advertising, and increment 688 * Grab the next descriptor number they're advertising, and increment
681 * the index we've seen. 689 * the index we've seen.
@@ -695,6 +703,12 @@ static unsigned wait_for_vq_desc(struct virtqueue *vq,
695 i = head; 703 i = head;
696 704
697 /* 705 /*
706 * We have to read the descriptor after we read the descriptor number,
707 * but there's a data dependency there so the CPU shouldn't reorder
708 * that: no rmb() required.
709 */
710
711 /*
698 * If this is an indirect entry, then this buffer contains a descriptor 712 * If this is an indirect entry, then this buffer contains a descriptor
699 * table which we handle as if it's any normal descriptor chain. 713 * table which we handle as if it's any normal descriptor chain.
700 */ 714 */
diff --git a/tools/lib/lk/Makefile b/tools/lib/lk/Makefile
index 926cbf3efc7f..280dd8205430 100644
--- a/tools/lib/lk/Makefile
+++ b/tools/lib/lk/Makefile
@@ -1,5 +1,23 @@
1include ../../scripts/Makefile.include 1include ../../scripts/Makefile.include
2 2
3CC = $(CROSS_COMPILE)gcc
4AR = $(CROSS_COMPILE)ar
5
6# Makefiles suck: This macro sets a default value of $(2) for the
7# variable named by $(1), unless the variable has been set by
8# environment or command line. This is necessary for CC and AR
9# because make sets default values, so the simpler ?= approach
10# won't work as expected.
11define allow-override
12 $(if $(or $(findstring environment,$(origin $(1))),\
13 $(findstring command line,$(origin $(1)))),,\
14 $(eval $(1) = $(2)))
15endef
16
17# Allow setting CC and AR, or setting CROSS_COMPILE as a prefix.
18$(call allow-override,CC,$(CROSS_COMPILE)gcc)
19$(call allow-override,AR,$(CROSS_COMPILE)ar)
20
3# guard against environment variables 21# guard against environment variables
4LIB_H= 22LIB_H=
5LIB_OBJS= 23LIB_OBJS=
@@ -11,7 +29,7 @@ LIB_OBJS += $(OUTPUT)debugfs.o
11LIBFILE = liblk.a 29LIBFILE = liblk.a
12 30
13CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC 31CFLAGS = -ggdb3 -Wall -Wextra -std=gnu99 -Werror -O6 -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) -fPIC
14EXTLIBS = -lpthread -lrt -lelf -lm 32EXTLIBS = -lelf -lpthread -lrt -lm
15ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 33ALL_CFLAGS = $(CFLAGS) $(BASIC_CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
16ALL_LDFLAGS = $(LDFLAGS) 34ALL_LDFLAGS = $(LDFLAGS)
17 35
diff --git a/tools/perf/Documentation/Makefile b/tools/perf/Documentation/Makefile
index eb30044a922a..5a37a7c84e69 100644
--- a/tools/perf/Documentation/Makefile
+++ b/tools/perf/Documentation/Makefile
@@ -1,12 +1,6 @@
1include ../../scripts/Makefile.include
1include ../config/utilities.mak 2include ../config/utilities.mak
2 3
3OUTPUT := ./
4ifeq ("$(origin O)", "command line")
5 ifneq ($(O),)
6 OUTPUT := $(O)/
7 endif
8endif
9
10MAN1_TXT= \ 4MAN1_TXT= \
11 $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \ 5 $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
12 $(wildcard perf-*.txt)) \ 6 $(wildcard perf-*.txt)) \
@@ -150,7 +144,7 @@ NO_SUBDIR = :
150endif 144endif
151 145
152ifneq ($(findstring $(MAKEFLAGS),s),s) 146ifneq ($(findstring $(MAKEFLAGS),s),s)
153ifndef V 147ifneq ($(V),1)
154 QUIET_ASCIIDOC = @echo ' ' ASCIIDOC $@; 148 QUIET_ASCIIDOC = @echo ' ' ASCIIDOC $@;
155 QUIET_XMLTO = @echo ' ' XMLTO $@; 149 QUIET_XMLTO = @echo ' ' XMLTO $@;
156 QUIET_DB2TEXI = @echo ' ' DB2TEXI $@; 150 QUIET_DB2TEXI = @echo ' ' DB2TEXI $@;
@@ -277,7 +271,7 @@ $(MAN_HTML): $(OUTPUT)%.html : %.txt
277 271
278$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml 272$(OUTPUT)%.1 $(OUTPUT)%.5 $(OUTPUT)%.7 : $(OUTPUT)%.xml
279 $(QUIET_XMLTO)$(RM) $@ && \ 273 $(QUIET_XMLTO)$(RM) $@ && \
280 $(XMLTO) -o $(OUTPUT) -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $< 274 $(XMLTO) -o $(OUTPUT). -m $(MANPAGE_XSL) $(XMLTO_EXTRA) man $<
281 275
282$(OUTPUT)%.xml : %.txt 276$(OUTPUT)%.xml : %.txt
283 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \ 277 $(QUIET_ASCIIDOC)$(RM) $@+ $@ && \
diff --git a/tools/perf/Documentation/examples.txt b/tools/perf/Documentation/examples.txt
index 77f952762426..a4e392156488 100644
--- a/tools/perf/Documentation/examples.txt
+++ b/tools/perf/Documentation/examples.txt
@@ -66,7 +66,7 @@ Furthermore, these tracepoints can be used to sample the workload as
66well. For example the page allocations done by a 'git gc' can be 66well. For example the page allocations done by a 'git gc' can be
67captured the following way: 67captured the following way:
68 68
69 titan:~/git> perf record -f -e kmem:mm_page_alloc -c 1 ./git gc 69 titan:~/git> perf record -e kmem:mm_page_alloc -c 1 ./git gc
70 Counting objects: 1148, done. 70 Counting objects: 1148, done.
71 Delta compression using up to 2 threads. 71 Delta compression using up to 2 threads.
72 Compressing objects: 100% (450/450), done. 72 Compressing objects: 100% (450/450), done.
@@ -120,7 +120,7 @@ Furthermore, call-graph sampling can be done too, of page
120allocations - to see precisely what kind of page allocations there 120allocations - to see precisely what kind of page allocations there
121are: 121are:
122 122
123 titan:~/git> perf record -f -g -e kmem:mm_page_alloc -c 1 ./git gc 123 titan:~/git> perf record -g -e kmem:mm_page_alloc -c 1 ./git gc
124 Counting objects: 1148, done. 124 Counting objects: 1148, done.
125 Delta compression using up to 2 threads. 125 Delta compression using up to 2 threads.
126 Compressing objects: 100% (450/450), done. 126 Compressing objects: 100% (450/450), done.
diff --git a/tools/perf/Documentation/perf-archive.txt b/tools/perf/Documentation/perf-archive.txt
index fae174dc7d01..5032a142853e 100644
--- a/tools/perf/Documentation/perf-archive.txt
+++ b/tools/perf/Documentation/perf-archive.txt
@@ -13,7 +13,7 @@ SYNOPSIS
13DESCRIPTION 13DESCRIPTION
14----------- 14-----------
15This command runs runs perf-buildid-list --with-hits, and collects the files 15This command runs runs perf-buildid-list --with-hits, and collects the files
16with the buildids found so that analisys of perf.data contents can be possible 16with the buildids found so that analysis of perf.data contents can be possible
17on another machine. 17on another machine.
18 18
19 19
diff --git a/tools/perf/Documentation/perf-record.txt b/tools/perf/Documentation/perf-record.txt
index d4da111ef53d..e297b74471b8 100644
--- a/tools/perf/Documentation/perf-record.txt
+++ b/tools/perf/Documentation/perf-record.txt
@@ -65,16 +65,10 @@ OPTIONS
65-r:: 65-r::
66--realtime=:: 66--realtime=::
67 Collect data with this RT SCHED_FIFO priority. 67 Collect data with this RT SCHED_FIFO priority.
68
68-D:: 69-D::
69--no-delay:: 70--no-delay::
70 Collect data without buffering. 71 Collect data without buffering.
71-A::
72--append::
73 Append to the output file to do incremental profiling.
74
75-f::
76--force::
77 Overwrite existing data file. (deprecated)
78 72
79-c:: 73-c::
80--count=:: 74--count=::
diff --git a/tools/perf/Documentation/perf-report.txt b/tools/perf/Documentation/perf-report.txt
index 7d5f4f38aa52..66dab7410c1d 100644
--- a/tools/perf/Documentation/perf-report.txt
+++ b/tools/perf/Documentation/perf-report.txt
@@ -210,6 +210,10 @@ OPTIONS
210 Demangle symbol names to human readable form. It's enabled by default, 210 Demangle symbol names to human readable form. It's enabled by default,
211 disable with --no-demangle. 211 disable with --no-demangle.
212 212
213--percent-limit::
214 Do not show entries which have an overhead under that percent.
215 (Default: 0).
216
213SEE ALSO 217SEE ALSO
214-------- 218--------
215linkperf:perf-stat[1], linkperf:perf-annotate[1] 219linkperf:perf-stat[1], linkperf:perf-annotate[1]
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index 9f1a2fe54757..7fdd1909e376 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -155,6 +155,10 @@ Default is to monitor all CPUS.
155 155
156 Default: fractal,0.5,callee. 156 Default: fractal,0.5,callee.
157 157
158--percent-limit::
159 Do not show entries which have an overhead under that percent.
160 (Default: 0).
161
158INTERACTIVE PROMPTING KEYS 162INTERACTIVE PROMPTING KEYS
159-------------------------- 163--------------------------
160 164
diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index b0f164b133d9..641fccddb249 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -51,189 +51,63 @@ include config/utilities.mak
51# Define NO_BACKTRACE if you do not want stack backtrace debug feature 51# Define NO_BACKTRACE if you do not want stack backtrace debug feature
52# 52#
53# Define NO_LIBNUMA if you do not want numa perf benchmark 53# Define NO_LIBNUMA if you do not want numa perf benchmark
54#
55# Define NO_LIBAUDIT if you do not want libaudit support
56#
57# Define NO_LIBBIONIC if you do not want bionic support
54 58
55$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE 59ifeq ($(srctree),)
56 @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT) 60srctree := $(patsubst %/,%,$(dir $(shell pwd)))
57 61srctree := $(patsubst %/,%,$(dir $(srctree)))
58uname_M := $(shell uname -m 2>/dev/null || echo not) 62#$(info Determined 'srctree' to be $(srctree))
59
60ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
61 -e s/arm.*/arm/ -e s/sa110/arm/ \
62 -e s/s390x/s390/ -e s/parisc64/parisc/ \
63 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
64 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
65NO_PERF_REGS := 1
66
67CC = $(CROSS_COMPILE)gcc
68AR = $(CROSS_COMPILE)ar
69
70# Additional ARCH settings for x86
71ifeq ($(ARCH),i386)
72 override ARCH := x86
73 NO_PERF_REGS := 0
74 LIBUNWIND_LIBS = -lunwind -lunwind-x86
75endif
76ifeq ($(ARCH),x86_64)
77 override ARCH := x86
78 IS_X86_64 := 0
79 ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
80 IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
81 endif
82 ifeq (${IS_X86_64}, 1)
83 RAW_ARCH := x86_64
84 ARCH_CFLAGS := -DARCH_X86_64
85 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
86 endif
87 NO_PERF_REGS := 0
88 LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
89endif
90
91# Treat warnings as errors unless directed not to
92ifneq ($(WERROR),0)
93 CFLAGS_WERROR := -Werror
94endif
95
96ifeq ("$(origin DEBUG)", "command line")
97 PERF_DEBUG = $(DEBUG)
98endif
99ifndef PERF_DEBUG
100 CFLAGS_OPTIMIZE = -O6
101endif 63endif
102 64
103ifdef PARSER_DEBUG 65ifneq ($(objtree),)
104 PARSER_DEBUG_BISON := -t 66#$(info Determined 'objtree' to be $(objtree))
105 PARSER_DEBUG_FLEX := -d
106 PARSER_DEBUG_CFLAGS := -DPARSER_DEBUG
107endif 67endif
108 68
109ifdef NO_NEWT 69ifneq ($(OUTPUT),)
110 NO_SLANG=1 70#$(info Determined 'OUTPUT' to be $(OUTPUT))
111endif 71endif
112 72
113CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS) 73$(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
114EXTLIBS = -lpthread -lrt -lelf -lm 74 @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
115ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
116ALL_LDFLAGS = $(LDFLAGS)
117STRIP ?= strip
118
119# Among the variables below, these:
120# perfexecdir
121# template_dir
122# mandir
123# infodir
124# htmldir
125# ETC_PERFCONFIG (but not sysconfdir)
126# can be specified as a relative path some/where/else;
127# this is interpreted as relative to $(prefix) and "perf" at
128# runtime figures out where they are based on the path to the executable.
129# This can help installing the suite in a relocatable way.
130
131# Make the path relative to DESTDIR, not to prefix
132ifndef DESTDIR
133prefix = $(HOME)
134endif
135bindir_relative = bin
136bindir = $(prefix)/$(bindir_relative)
137mandir = share/man
138infodir = share/info
139perfexecdir = libexec/perf-core
140sharedir = $(prefix)/share
141template_dir = share/perf-core/templates
142htmldir = share/doc/perf-doc
143ifeq ($(prefix),/usr)
144sysconfdir = /etc
145ETC_PERFCONFIG = $(sysconfdir)/perfconfig
146else
147sysconfdir = $(prefix)/etc
148ETC_PERFCONFIG = etc/perfconfig
149endif
150lib = lib
151 75
152export prefix bindir sharedir sysconfdir 76CC = $(CROSS_COMPILE)gcc
77AR = $(CROSS_COMPILE)ar
153 78
154RM = rm -f 79RM = rm -f
155MKDIR = mkdir 80MKDIR = mkdir
156FIND = find 81FIND = find
157INSTALL = install 82INSTALL = install
158FLEX = flex 83FLEX = flex
159BISON= bison 84BISON = bison
160 85STRIP = strip
161# sparse is architecture-neutral, which means that we need to tell it
162# explicitly what architecture to check for. Fix this up for yours..
163SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
164 86
165ifneq ($(MAKECMDGOALS),clean) 87LK_DIR = $(srctree)/tools/lib/lk/
166ifneq ($(MAKECMDGOALS),tags) 88TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
167-include config/feature-tests.mak
168 89
169ifeq ($(call get-executable,$(FLEX)),) 90# include config/Makefile by default and rule out
170 dummy := $(error Error: $(FLEX) is missing on this system, please install it) 91# non-config cases
171endif 92config := 1
172 93
173ifeq ($(call get-executable,$(BISON)),) 94NON_CONFIG_TARGETS := clean TAGS tags cscope help
174 dummy := $(error Error: $(BISON) is missing on this system, please install it)
175endif
176 95
177ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y) 96ifdef MAKECMDGOALS
178 CFLAGS := $(CFLAGS) -fstack-protector-all 97ifeq ($(filter-out $(NON_CONFIG_TARGETS),$(MAKECMDGOALS)),)
98 config := 0
179endif 99endif
180
181ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
182 CFLAGS := $(CFLAGS) -Wstack-protector
183endif
184
185ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
186 CFLAGS := $(CFLAGS) -Wvolatile-register-var
187endif 100endif
188 101
189ifndef PERF_DEBUG 102ifeq ($(config),1)
190 ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y) 103include config/Makefile
191 CFLAGS := $(CFLAGS) -D_FORTIFY_SOURCE=2
192 endif
193endif 104endif
194 105
195### --- END CONFIGURATION SECTION --- 106export prefix bindir sharedir sysconfdir
196
197ifeq ($(srctree),)
198srctree := $(patsubst %/,%,$(dir $(shell pwd)))
199srctree := $(patsubst %/,%,$(dir $(srctree)))
200#$(info Determined 'srctree' to be $(srctree))
201endif
202
203ifneq ($(objtree),)
204#$(info Determined 'objtree' to be $(objtree))
205endif
206
207ifneq ($(OUTPUT),)
208#$(info Determined 'OUTPUT' to be $(OUTPUT))
209endif
210 107
211BASIC_CFLAGS = \ 108# sparse is architecture-neutral, which means that we need to tell it
212 -Iutil/include \ 109# explicitly what architecture to check for. Fix this up for yours..
213 -Iarch/$(ARCH)/include \ 110SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
214 $(if $(objtree),-I$(objtree)/arch/$(ARCH)/include/generated/uapi) \
215 -I$(srctree)/arch/$(ARCH)/include/uapi \
216 -I$(srctree)/arch/$(ARCH)/include \
217 $(if $(objtree),-I$(objtree)/include/generated/uapi) \
218 -I$(srctree)/include/uapi \
219 -I$(srctree)/include \
220 -I$(OUTPUT)util \
221 -Iutil \
222 -I. \
223 -I$(TRACE_EVENT_DIR) \
224 -I../lib/ \
225 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
226
227BASIC_LDFLAGS =
228
229ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
230 BIONIC := 1
231 EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
232 EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
233 BASIC_CFLAGS += -I.
234endif
235endif # MAKECMDGOALS != tags
236endif # MAKECMDGOALS != clean
237 111
238# Guard against environment variables 112# Guard against environment variables
239BUILTIN_OBJS = 113BUILTIN_OBJS =
@@ -247,20 +121,16 @@ SCRIPT_SH += perf-archive.sh
247grep-libs = $(filter -l%,$(1)) 121grep-libs = $(filter -l%,$(1))
248strip-libs = $(filter-out -l%,$(1)) 122strip-libs = $(filter-out -l%,$(1))
249 123
250LK_DIR = ../lib/lk/
251TRACE_EVENT_DIR = ../lib/traceevent/
252
253LK_PATH=$(LK_DIR)
254
255ifneq ($(OUTPUT),) 124ifneq ($(OUTPUT),)
256 TE_PATH=$(OUTPUT) 125 TE_PATH=$(OUTPUT)
257ifneq ($(subdir),) 126ifneq ($(subdir),)
258 LK_PATH=$(OUTPUT)$(LK_DIR) 127 LK_PATH=$(objtree)/lib/lk/
259else 128else
260 LK_PATH=$(OUTPUT) 129 LK_PATH=$(OUTPUT)
261endif 130endif
262else 131else
263 TE_PATH=$(TRACE_EVENT_DIR) 132 TE_PATH=$(TRACE_EVENT_DIR)
133 LK_PATH=$(LK_DIR)
264endif 134endif
265 135
266LIBTRACEEVENT = $(TE_PATH)libtraceevent.a 136LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
@@ -278,10 +148,10 @@ export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
278python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so 148python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
279 149
280PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources) 150PYTHON_EXT_SRCS := $(shell grep -v ^\# util/python-ext-sources)
281PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) 151PYTHON_EXT_DEPS := util/python-ext-sources util/setup.py $(LIBTRACEEVENT) $(LIBLK)
282 152
283$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS) 153$(OUTPUT)python/perf.so: $(PYTHON_EXT_SRCS) $(PYTHON_EXT_DEPS)
284 $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \ 154 $(QUIET_GEN)CFLAGS='$(CFLAGS)' $(PYTHON_WORD) util/setup.py \
285 --quiet build_ext; \ 155 --quiet build_ext; \
286 mkdir -p $(OUTPUT)python && \ 156 mkdir -p $(OUTPUT)python && \
287 cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/ 157 cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
@@ -296,8 +166,6 @@ SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
296# 166#
297PROGRAMS += $(OUTPUT)perf 167PROGRAMS += $(OUTPUT)perf
298 168
299LANG_BINDINGS =
300
301# what 'all' will build and 'install' will install, in perfexecdir 169# what 'all' will build and 'install' will install, in perfexecdir
302ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) 170ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
303 171
@@ -306,10 +174,10 @@ OTHER_PROGRAMS = $(OUTPUT)perf
306 174
307# Set paths to tools early so that they can be used for version tests. 175# Set paths to tools early so that they can be used for version tests.
308ifndef SHELL_PATH 176ifndef SHELL_PATH
309 SHELL_PATH = /bin/sh 177 SHELL_PATH = /bin/sh
310endif 178endif
311ifndef PERL_PATH 179ifndef PERL_PATH
312 PERL_PATH = /usr/bin/perl 180 PERL_PATH = /usr/bin/perl
313endif 181endif
314 182
315export PERL_PATH 183export PERL_PATH
@@ -557,79 +425,14 @@ BUILTIN_OBJS += $(OUTPUT)builtin-mem.o
557 425
558PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT) 426PERFLIBS = $(LIB_FILE) $(LIBLK) $(LIBTRACEEVENT)
559 427
560#
561# Platform specific tweaks
562#
563ifneq ($(MAKECMDGOALS),clean)
564ifneq ($(MAKECMDGOALS),tags)
565
566# We choose to avoid "if .. else if .. else .. endif endif" 428# We choose to avoid "if .. else if .. else .. endif endif"
567# because maintaining the nesting to match is a pain. If 429# because maintaining the nesting to match is a pain. If
568# we had "elif" things would have been much nicer... 430# we had "elif" things would have been much nicer...
569 431
570ifdef NO_LIBELF
571 NO_DWARF := 1
572 NO_DEMANGLE := 1
573 NO_LIBUNWIND := 1
574else
575FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
576ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
577 FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
578 ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
579 LIBC_SUPPORT := 1
580 endif
581 ifeq ($(BIONIC),1)
582 LIBC_SUPPORT := 1
583 endif
584 ifeq ($(LIBC_SUPPORT),1)
585 msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
586
587 NO_LIBELF := 1
588 NO_DWARF := 1
589 NO_DEMANGLE := 1
590 else
591 msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
592 endif
593else
594 # for linking with debug library, run like:
595 # make DEBUG=1 LIBDW_DIR=/opt/libdw/
596 ifdef LIBDW_DIR
597 LIBDW_CFLAGS := -I$(LIBDW_DIR)/include
598 LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
599 endif
600
601 FLAGS_DWARF=$(ALL_CFLAGS) $(LIBDW_CFLAGS) -ldw -lelf $(LIBDW_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
602 ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
603 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
604 NO_DWARF := 1
605 endif # Dwarf support
606endif # SOURCE_LIBELF
607endif # NO_LIBELF
608
609# There's only x86 (both 32 and 64) support for CFI unwind so far
610ifneq ($(ARCH),x86)
611 NO_LIBUNWIND := 1
612endif
613
614ifndef NO_LIBUNWIND
615# for linking with debug library, run like:
616# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
617ifdef LIBUNWIND_DIR
618 LIBUNWIND_CFLAGS := -I$(LIBUNWIND_DIR)/include
619 LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
620endif
621
622FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(ALL_CFLAGS) $(LIBUNWIND_LDFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
623ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
624 msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
625 NO_LIBUNWIND := 1
626endif # Libunwind support
627endif # NO_LIBUNWIND
628
629-include arch/$(ARCH)/Makefile 432-include arch/$(ARCH)/Makefile
630 433
631ifneq ($(OUTPUT),) 434ifneq ($(OUTPUT),)
632 BASIC_CFLAGS += -I$(OUTPUT) 435 CFLAGS += -I$(OUTPUT)
633endif 436endif
634 437
635ifdef NO_LIBELF 438ifdef NO_LIBELF
@@ -647,281 +450,74 @@ BUILTIN_OBJS := $(filter-out $(OUTPUT)builtin-probe.o,$(BUILTIN_OBJS))
647LIB_OBJS += $(OUTPUT)util/symbol-minimal.o 450LIB_OBJS += $(OUTPUT)util/symbol-minimal.o
648 451
649else # NO_LIBELF 452else # NO_LIBELF
650BASIC_CFLAGS += -DLIBELF_SUPPORT
651
652FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
653ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
654 BASIC_CFLAGS += -DLIBELF_MMAP
655endif
656
657ifndef NO_DWARF 453ifndef NO_DWARF
658ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) 454 LIB_OBJS += $(OUTPUT)util/probe-finder.o
659 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); 455 LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
660else
661 BASIC_CFLAGS := -DDWARF_SUPPORT $(LIBDW_CFLAGS) $(BASIC_CFLAGS)
662 BASIC_LDFLAGS := $(LIBDW_LDFLAGS) $(BASIC_LDFLAGS)
663 EXTLIBS += -lelf -ldw
664 LIB_OBJS += $(OUTPUT)util/probe-finder.o
665 LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
666endif # PERF_HAVE_DWARF_REGS
667endif # NO_DWARF 456endif # NO_DWARF
668endif # NO_LIBELF 457endif # NO_LIBELF
669 458
670ifndef NO_LIBUNWIND 459ifndef NO_LIBUNWIND
671 BASIC_CFLAGS += -DLIBUNWIND_SUPPORT 460 LIB_OBJS += $(OUTPUT)util/unwind.o
672 EXTLIBS += $(LIBUNWIND_LIBS)
673 BASIC_CFLAGS := $(LIBUNWIND_CFLAGS) $(BASIC_CFLAGS)
674 BASIC_LDFLAGS := $(LIBUNWIND_LDFLAGS) $(BASIC_LDFLAGS)
675 LIB_OBJS += $(OUTPUT)util/unwind.o
676endif 461endif
677 462
678ifndef NO_LIBAUDIT 463ifndef NO_LIBAUDIT
679 FLAGS_LIBAUDIT = $(ALL_CFLAGS) $(ALL_LDFLAGS) -laudit 464 BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
680 ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
681 msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
682 else
683 BASIC_CFLAGS += -DLIBAUDIT_SUPPORT
684 BUILTIN_OBJS += $(OUTPUT)builtin-trace.o
685 EXTLIBS += -laudit
686 endif
687endif 465endif
688 466
689ifndef NO_SLANG 467ifndef NO_SLANG
690 FLAGS_SLANG=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang 468 LIB_OBJS += $(OUTPUT)ui/browser.o
691 ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y) 469 LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o
692 msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev); 470 LIB_OBJS += $(OUTPUT)ui/browsers/hists.o
693 else 471 LIB_OBJS += $(OUTPUT)ui/browsers/map.o
694 # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h 472 LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o
695 BASIC_CFLAGS += -I/usr/include/slang 473 LIB_OBJS += $(OUTPUT)ui/tui/setup.o
696 BASIC_CFLAGS += -DSLANG_SUPPORT 474 LIB_OBJS += $(OUTPUT)ui/tui/util.o
697 EXTLIBS += -lslang 475 LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
698 LIB_OBJS += $(OUTPUT)ui/browser.o 476 LIB_OBJS += $(OUTPUT)ui/tui/progress.o
699 LIB_OBJS += $(OUTPUT)ui/browsers/annotate.o 477 LIB_H += ui/browser.h
700 LIB_OBJS += $(OUTPUT)ui/browsers/hists.o 478 LIB_H += ui/browsers/map.h
701 LIB_OBJS += $(OUTPUT)ui/browsers/map.o 479 LIB_H += ui/keysyms.h
702 LIB_OBJS += $(OUTPUT)ui/browsers/scripts.o 480 LIB_H += ui/libslang.h
703 LIB_OBJS += $(OUTPUT)ui/tui/setup.o
704 LIB_OBJS += $(OUTPUT)ui/tui/util.o
705 LIB_OBJS += $(OUTPUT)ui/tui/helpline.o
706 LIB_OBJS += $(OUTPUT)ui/tui/progress.o
707 LIB_H += ui/browser.h
708 LIB_H += ui/browsers/map.h
709 LIB_H += ui/keysyms.h
710 LIB_H += ui/libslang.h
711 endif
712endif 481endif
713 482
714ifndef NO_GTK2 483ifndef NO_GTK2
715 FLAGS_GTK2=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null) 484 LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
716 ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y) 485 LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
717 msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev); 486 LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
718 else 487 LIB_OBJS += $(OUTPUT)ui/gtk/util.o
719 ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y) 488 LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
720 BASIC_CFLAGS += -DHAVE_GTK_INFO_BAR 489 LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
721 endif 490 LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
722 BASIC_CFLAGS += -DGTK2_SUPPORT
723 BASIC_CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
724 EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
725 LIB_OBJS += $(OUTPUT)ui/gtk/browser.o
726 LIB_OBJS += $(OUTPUT)ui/gtk/hists.o
727 LIB_OBJS += $(OUTPUT)ui/gtk/setup.o
728 LIB_OBJS += $(OUTPUT)ui/gtk/util.o
729 LIB_OBJS += $(OUTPUT)ui/gtk/helpline.o
730 LIB_OBJS += $(OUTPUT)ui/gtk/progress.o
731 LIB_OBJS += $(OUTPUT)ui/gtk/annotate.o
732 endif
733endif 491endif
734 492
735ifdef NO_LIBPERL 493ifndef NO_LIBPERL
736 BASIC_CFLAGS += -DNO_LIBPERL 494 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
737else 495 LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
738 PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
739 PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
740 PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
741 PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
742 FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
743
744 ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
745 BASIC_CFLAGS += -DNO_LIBPERL
746 else
747 ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
748 EXTLIBS += $(PERL_EMBED_LIBADD)
749 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
750 LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
751 endif
752endif 496endif
753 497
754disable-python = $(eval $(disable-python_code)) 498ifndef NO_LIBPYTHON
755define disable-python_code 499 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
756 BASIC_CFLAGS += -DNO_LIBPYTHON 500 LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
757 $(if $(1),$(warning No $(1) was found))
758 $(warning Python support will not be built)
759endef
760
761override PYTHON := \
762 $(call get-executable-or-default,PYTHON,python)
763
764ifndef PYTHON
765 $(call disable-python,python interpreter)
766else
767
768 PYTHON_WORD := $(call shell-wordify,$(PYTHON))
769
770 ifdef NO_LIBPYTHON
771 $(call disable-python)
772 else
773
774 override PYTHON_CONFIG := \
775 $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
776
777 ifndef PYTHON_CONFIG
778 $(call disable-python,python-config tool)
779 else
780
781 PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
782
783 PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
784 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
785 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
786 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
787 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
788
789 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
790 $(call disable-python,Python.h (for Python 2.x))
791 else
792
793 ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
794 $(warning Python 3 is not yet supported; please set)
795 $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
796 $(warning If you also have Python 2 installed, then)
797 $(warning try something like:)
798 $(warning $(and ,))
799 $(warning $(and ,) make PYTHON=python2)
800 $(warning $(and ,))
801 $(warning Otherwise, disable Python support entirely:)
802 $(warning $(and ,))
803 $(warning $(and ,) make NO_LIBPYTHON=1)
804 $(warning $(and ,))
805 $(error $(and ,))
806 else
807 ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
808 EXTLIBS += $(PYTHON_EMBED_LIBADD)
809 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
810 LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
811 LANG_BINDINGS += $(OUTPUT)python/perf.so
812 endif
813
814 endif
815 endif
816 endif
817endif
818
819ifdef NO_DEMANGLE
820 BASIC_CFLAGS += -DNO_DEMANGLE
821else
822 ifdef HAVE_CPLUS_DEMANGLE
823 EXTLIBS += -liberty
824 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
825 else
826 FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
827 has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
828 ifeq ($(has_bfd),y)
829 EXTLIBS += -lbfd
830 else
831 FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
832 has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
833 ifeq ($(has_bfd_iberty),y)
834 EXTLIBS += -lbfd -liberty
835 else
836 FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
837 has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
838 ifeq ($(has_bfd_iberty_z),y)
839 EXTLIBS += -lbfd -liberty -lz
840 else
841 FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
842 has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
843 ifeq ($(has_cplus_demangle),y)
844 EXTLIBS += -liberty
845 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
846 else
847 msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
848 BASIC_CFLAGS += -DNO_DEMANGLE
849 endif
850 endif
851 endif
852 endif
853 endif
854endif 501endif
855 502
856ifeq ($(NO_PERF_REGS),0) 503ifeq ($(NO_PERF_REGS),0)
857 ifeq ($(ARCH),x86) 504 ifeq ($(ARCH),x86)
858 LIB_H += arch/x86/include/perf_regs.h 505 LIB_H += arch/x86/include/perf_regs.h
859 endif 506 endif
860 BASIC_CFLAGS += -DHAVE_PERF_REGS
861endif
862
863ifndef NO_STRLCPY
864 ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
865 BASIC_CFLAGS += -DHAVE_STRLCPY
866 endif
867endif
868
869ifndef NO_ON_EXIT
870 ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
871 BASIC_CFLAGS += -DHAVE_ON_EXIT
872 endif
873endif
874
875ifndef NO_BACKTRACE
876 ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
877 BASIC_CFLAGS += -DBACKTRACE_SUPPORT
878 endif
879endif 507endif
880 508
881ifndef NO_LIBNUMA 509ifndef NO_LIBNUMA
882 FLAGS_LIBNUMA = $(ALL_CFLAGS) $(ALL_LDFLAGS) -lnuma 510 BUILTIN_OBJS += $(OUTPUT)bench/numa.o
883 ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
884 msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
885 else
886 BASIC_CFLAGS += -DLIBNUMA_SUPPORT
887 BUILTIN_OBJS += $(OUTPUT)bench/numa.o
888 EXTLIBS += -lnuma
889 endif
890endif 511endif
891 512
892ifdef ASCIIDOC8 513ifdef ASCIIDOC8
893 export ASCIIDOC8 514 export ASCIIDOC8
894endif 515endif
895 516
896endif # MAKECMDGOALS != tags
897endif # MAKECMDGOALS != clean
898
899# Shell quote (do not use $(call) to accommodate ancient setups);
900
901ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
902
903DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
904bindir_SQ = $(subst ','\'',$(bindir))
905bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
906mandir_SQ = $(subst ','\'',$(mandir))
907infodir_SQ = $(subst ','\'',$(infodir))
908perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
909template_dir_SQ = $(subst ','\'',$(template_dir))
910htmldir_SQ = $(subst ','\'',$(htmldir))
911prefix_SQ = $(subst ','\'',$(prefix))
912sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
913
914SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
915
916LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group 517LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
917 518
918ALL_CFLAGS += $(BASIC_CFLAGS)
919ALL_CFLAGS += $(ARCH_CFLAGS)
920ALL_LDFLAGS += $(BASIC_LDFLAGS)
921
922export INSTALL SHELL_PATH 519export INSTALL SHELL_PATH
923 520
924
925### Build rules 521### Build rules
926 522
927SHELL = $(SHELL_PATH) 523SHELL = $(SHELL_PATH)
@@ -939,20 +535,20 @@ strip: $(PROGRAMS) $(OUTPUT)perf
939$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS 535$(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
940 $(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \ 536 $(QUIET_CC)$(CC) -include $(OUTPUT)PERF-VERSION-FILE \
941 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 537 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
942 $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@ 538 $(CFLAGS) -c $(filter %.c,$^) -o $@
943 539
944$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) 540$(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
945 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(OUTPUT)perf.o \ 541 $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(OUTPUT)perf.o \
946 $(BUILTIN_OBJS) $(LIBS) -o $@ 542 $(BUILTIN_OBJS) $(LIBS) -o $@
947 543
948$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS 544$(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
949 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ 545 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
950 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 546 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
951 '-DPERF_MAN_PATH="$(mandir_SQ)"' \ 547 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
952 '-DPERF_INFO_PATH="$(infodir_SQ)"' $< 548 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
953 549
954$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS 550$(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
955 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ 551 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
956 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 552 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
957 '-DPERF_MAN_PATH="$(mandir_SQ)"' \ 553 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
958 '-DPERF_INFO_PATH="$(infodir_SQ)"' $< 554 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
@@ -977,77 +573,77 @@ $(OUTPUT)perf.o perf.spec \
977# over the general rule for .o 573# over the general rule for .o
978 574
979$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS 575$(OUTPUT)util/%-flex.o: $(OUTPUT)util/%-flex.c $(OUTPUT)PERF-CFLAGS
980 $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(ALL_CFLAGS) -w $< 576 $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -w $<
981 577
982$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS 578$(OUTPUT)util/%-bison.o: $(OUTPUT)util/%-bison.c $(OUTPUT)PERF-CFLAGS
983 $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(ALL_CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $< 579 $(QUIET_CC)$(CC) -o $@ -c -Iutil/ $(CFLAGS) -DYYENABLE_NLS=0 -DYYLTYPE_IS_TRIVIAL=0 -w $<
984 580
985$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS 581$(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
986 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< 582 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
987$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS 583$(OUTPUT)%.i: %.c $(OUTPUT)PERF-CFLAGS
988 $(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $< 584 $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
989$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS 585$(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
990 $(QUIET_CC)$(CC) -o $@ -S $(ALL_CFLAGS) $< 586 $(QUIET_CC)$(CC) -o $@ -S $(CFLAGS) $<
991$(OUTPUT)%.o: %.S 587$(OUTPUT)%.o: %.S
992 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< 588 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $<
993$(OUTPUT)%.s: %.S 589$(OUTPUT)%.s: %.S
994 $(QUIET_CC)$(CC) -o $@ -E $(ALL_CFLAGS) $< 590 $(QUIET_CC)$(CC) -o $@ -E $(CFLAGS) $<
995 591
996$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS 592$(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
997 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ 593 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
998 '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \ 594 '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
999 '-DPREFIX="$(prefix_SQ)"' \ 595 '-DPREFIX="$(prefix_SQ)"' \
1000 $< 596 $<
1001 597
1002$(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS 598$(OUTPUT)tests/attr.o: tests/attr.c $(OUTPUT)PERF-CFLAGS
1003 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ 599 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
1004 '-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \ 600 '-DBINDIR="$(bindir_SQ)"' -DPYTHON='"$(PYTHON_WORD)"' \
1005 $< 601 $<
1006 602
1007$(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS 603$(OUTPUT)tests/python-use.o: tests/python-use.c $(OUTPUT)PERF-CFLAGS
1008 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ 604 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) \
1009 -DPYTHONPATH='"$(OUTPUT)python"' \ 605 -DPYTHONPATH='"$(OUTPUT)python"' \
1010 -DPYTHON='"$(PYTHON_WORD)"' \ 606 -DPYTHON='"$(PYTHON_WORD)"' \
1011 $< 607 $<
1012 608
1013$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS 609$(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
1014 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 610 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
1015 611
1016$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS 612$(OUTPUT)ui/browser.o: ui/browser.c $(OUTPUT)PERF-CFLAGS
1017 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 613 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1018 614
1019$(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS 615$(OUTPUT)ui/browsers/annotate.o: ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
1020 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 616 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1021 617
1022$(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS 618$(OUTPUT)ui/browsers/hists.o: ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
1023 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 619 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1024 620
1025$(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS 621$(OUTPUT)ui/browsers/map.o: ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
1026 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 622 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1027 623
1028$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS 624$(OUTPUT)ui/browsers/scripts.o: ui/browsers/scripts.c $(OUTPUT)PERF-CFLAGS
1029 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 625 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -DENABLE_SLFUTURE_CONST $<
1030 626
1031$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS 627$(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
1032 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 628 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-unused-parameter -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
1033 629
1034$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS 630$(OUTPUT)util/parse-events.o: util/parse-events.c $(OUTPUT)PERF-CFLAGS
1035 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -Wno-redundant-decls $< 631 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) -Wno-redundant-decls $<
1036 632
1037$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS 633$(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
1038 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< 634 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
1039 635
1040$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS 636$(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
1041 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $< 637 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
1042 638
1043$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS 639$(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
1044 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< 640 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
1045 641
1046$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS 642$(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
1047 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $< 643 $(QUIET_CC)$(CC) -o $@ -c $(CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
1048 644
1049$(OUTPUT)perf-%: %.o $(PERFLIBS) 645$(OUTPUT)perf-%: %.o $(PERFLIBS)
1050 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) 646 $(QUIET_LINK)$(CC) $(CFLAGS) -o $@ $(LDFLAGS) $(filter %.o,$^) $(LIBS)
1051 647
1052$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) 648$(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
1053$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) 649$(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
@@ -1134,7 +730,7 @@ cscope:
1134 $(FIND) . -name '*.[hcS]' -print | xargs cscope -b 730 $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
1135 731
1136### Detect prefix changes 732### Detect prefix changes
1137TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\ 733TRACK_CFLAGS = $(subst ','\'',$(CFLAGS)):\
1138 $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ) 734 $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
1139 735
1140$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS 736$(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
@@ -1155,7 +751,7 @@ check: $(OUTPUT)common-cmds.h
1155 then \ 751 then \
1156 for i in *.c */*.c; \ 752 for i in *.c */*.c; \
1157 do \ 753 do \
1158 sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \ 754 sparse $(CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
1159 done; \ 755 done; \
1160 else \ 756 else \
1161 exit 1; \ 757 exit 1; \
@@ -1163,13 +759,6 @@ check: $(OUTPUT)common-cmds.h
1163 759
1164### Installation rules 760### Installation rules
1165 761
1166ifneq ($(filter /%,$(firstword $(perfexecdir))),)
1167perfexec_instdir = $(perfexecdir)
1168else
1169perfexec_instdir = $(prefix)/$(perfexecdir)
1170endif
1171perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
1172
1173install-bin: all 762install-bin: all
1174 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' 763 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
1175 $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' 764 $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
diff --git a/tools/perf/bench/mem-memcpy.c b/tools/perf/bench/mem-memcpy.c
index 93c83e3cb4a7..25fd3f1966f1 100644
--- a/tools/perf/bench/mem-memcpy.c
+++ b/tools/perf/bench/mem-memcpy.c
@@ -111,11 +111,11 @@ static double timeval2double(struct timeval *ts)
111static void alloc_mem(void **dst, void **src, size_t length) 111static void alloc_mem(void **dst, void **src, size_t length)
112{ 112{
113 *dst = zalloc(length); 113 *dst = zalloc(length);
114 if (!dst) 114 if (!*dst)
115 die("memory allocation failed - maybe length is too large?\n"); 115 die("memory allocation failed - maybe length is too large?\n");
116 116
117 *src = zalloc(length); 117 *src = zalloc(length);
118 if (!src) 118 if (!*src)
119 die("memory allocation failed - maybe length is too large?\n"); 119 die("memory allocation failed - maybe length is too large?\n");
120} 120}
121 121
diff --git a/tools/perf/bench/mem-memset.c b/tools/perf/bench/mem-memset.c
index c6e4bc523492..4a2f12081964 100644
--- a/tools/perf/bench/mem-memset.c
+++ b/tools/perf/bench/mem-memset.c
@@ -111,7 +111,7 @@ static double timeval2double(struct timeval *ts)
111static void alloc_mem(void **dst, size_t length) 111static void alloc_mem(void **dst, size_t length)
112{ 112{
113 *dst = zalloc(length); 113 *dst = zalloc(length);
114 if (!dst) 114 if (!*dst)
115 die("memory allocation failed - maybe length is too large?\n"); 115 die("memory allocation failed - maybe length is too large?\n");
116} 116}
117 117
diff --git a/tools/perf/builtin-diff.c b/tools/perf/builtin-diff.c
index 2d0462d89a97..0aac5f3e594d 100644
--- a/tools/perf/builtin-diff.c
+++ b/tools/perf/builtin-diff.c
@@ -323,13 +323,20 @@ static void hists__baseline_only(struct hists *hists)
323 323
324static void hists__precompute(struct hists *hists) 324static void hists__precompute(struct hists *hists)
325{ 325{
326 struct rb_node *next = rb_first(&hists->entries); 326 struct rb_root *root;
327 struct rb_node *next;
328
329 if (sort__need_collapse)
330 root = &hists->entries_collapsed;
331 else
332 root = hists->entries_in;
327 333
334 next = rb_first(root);
328 while (next != NULL) { 335 while (next != NULL) {
329 struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node); 336 struct hist_entry *he = rb_entry(next, struct hist_entry, rb_node_in);
330 struct hist_entry *pair = hist_entry__next_pair(he); 337 struct hist_entry *pair = hist_entry__next_pair(he);
331 338
332 next = rb_next(&he->rb_node); 339 next = rb_next(&he->rb_node_in);
333 if (!pair) 340 if (!pair)
334 continue; 341 continue;
335 342
@@ -457,7 +464,7 @@ static void hists__process(struct hists *old, struct hists *new)
457 hists__output_resort(new); 464 hists__output_resort(new);
458 } 465 }
459 466
460 hists__fprintf(new, true, 0, 0, stdout); 467 hists__fprintf(new, true, 0, 0, 0, stdout);
461} 468}
462 469
463static int __cmd_diff(void) 470static int __cmd_diff(void)
@@ -600,7 +607,6 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
600 input_new = "perf.data.guest"; 607 input_new = "perf.data.guest";
601 } 608 }
602 609
603 symbol_conf.exclude_other = false;
604 if (symbol__init() < 0) 610 if (symbol__init() < 0)
605 return -1; 611 return -1;
606 612
@@ -611,9 +617,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix __maybe_unused)
611 617
612 setup_pager(); 618 setup_pager();
613 619
614 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", NULL); 620 sort__setup_elide(NULL);
615 sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", NULL);
616 sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", NULL);
617 621
618 return __cmd_diff(); 622 return __cmd_diff();
619} 623}
diff --git a/tools/perf/builtin-kmem.c b/tools/perf/builtin-kmem.c
index 46878daca5cc..0259502638b4 100644
--- a/tools/perf/builtin-kmem.c
+++ b/tools/perf/builtin-kmem.c
@@ -708,7 +708,7 @@ static int parse_line_opt(const struct option *opt __maybe_unused,
708static int __cmd_record(int argc, const char **argv) 708static int __cmd_record(int argc, const char **argv)
709{ 709{
710 const char * const record_args[] = { 710 const char * const record_args[] = {
711 "record", "-a", "-R", "-f", "-c", "1", 711 "record", "-a", "-R", "-c", "1",
712 "-e", "kmem:kmalloc", 712 "-e", "kmem:kmalloc",
713 "-e", "kmem:kmalloc_node", 713 "-e", "kmem:kmalloc_node",
714 "-e", "kmem:kfree", 714 "-e", "kmem:kfree",
diff --git a/tools/perf/builtin-kvm.c b/tools/perf/builtin-kvm.c
index 533501e2b07c..24b78aecc928 100644
--- a/tools/perf/builtin-kvm.c
+++ b/tools/perf/builtin-kvm.c
@@ -328,6 +328,7 @@ static int kvm_events_hash_fn(u64 key)
328static bool kvm_event_expand(struct kvm_event *event, int vcpu_id) 328static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
329{ 329{
330 int old_max_vcpu = event->max_vcpu; 330 int old_max_vcpu = event->max_vcpu;
331 void *prev;
331 332
332 if (vcpu_id < event->max_vcpu) 333 if (vcpu_id < event->max_vcpu)
333 return true; 334 return true;
@@ -335,9 +336,11 @@ static bool kvm_event_expand(struct kvm_event *event, int vcpu_id)
335 while (event->max_vcpu <= vcpu_id) 336 while (event->max_vcpu <= vcpu_id)
336 event->max_vcpu += DEFAULT_VCPU_NUM; 337 event->max_vcpu += DEFAULT_VCPU_NUM;
337 338
339 prev = event->vcpu;
338 event->vcpu = realloc(event->vcpu, 340 event->vcpu = realloc(event->vcpu,
339 event->max_vcpu * sizeof(*event->vcpu)); 341 event->max_vcpu * sizeof(*event->vcpu));
340 if (!event->vcpu) { 342 if (!event->vcpu) {
343 free(prev);
341 pr_err("Not enough memory\n"); 344 pr_err("Not enough memory\n");
342 return false; 345 return false;
343 } 346 }
diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c
index 425830069749..76543a4a7a30 100644
--- a/tools/perf/builtin-lock.c
+++ b/tools/perf/builtin-lock.c
@@ -878,7 +878,7 @@ static int __cmd_report(void)
878static int __cmd_record(int argc, const char **argv) 878static int __cmd_record(int argc, const char **argv)
879{ 879{
880 const char *record_args[] = { 880 const char *record_args[] = {
881 "record", "-R", "-f", "-m", "1024", "-c", "1", 881 "record", "-R", "-m", "1024", "-c", "1",
882 }; 882 };
883 unsigned int rec_argc, i, j; 883 unsigned int rec_argc, i, j;
884 const char **rec_argv; 884 const char **rec_argv;
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c
index cdf58ecc04b1..ecca62e27b28 100644
--- a/tools/perf/builtin-record.c
+++ b/tools/perf/builtin-record.c
@@ -61,11 +61,6 @@ static void __handle_on_exit_funcs(void)
61} 61}
62#endif 62#endif
63 63
64enum write_mode_t {
65 WRITE_FORCE,
66 WRITE_APPEND
67};
68
69struct perf_record { 64struct perf_record {
70 struct perf_tool tool; 65 struct perf_tool tool;
71 struct perf_record_opts opts; 66 struct perf_record_opts opts;
@@ -77,12 +72,8 @@ struct perf_record {
77 int output; 72 int output;
78 unsigned int page_size; 73 unsigned int page_size;
79 int realtime_prio; 74 int realtime_prio;
80 enum write_mode_t write_mode;
81 bool no_buildid; 75 bool no_buildid;
82 bool no_buildid_cache; 76 bool no_buildid_cache;
83 bool force;
84 bool file_new;
85 bool append_file;
86 long samples; 77 long samples;
87 off_t post_processing_offset; 78 off_t post_processing_offset;
88}; 79};
@@ -198,26 +189,6 @@ static void perf_record__sig_exit(int exit_status __maybe_unused, void *arg)
198 return; 189 return;
199 190
200 signal(signr, SIG_DFL); 191 signal(signr, SIG_DFL);
201 kill(getpid(), signr);
202}
203
204static bool perf_evlist__equal(struct perf_evlist *evlist,
205 struct perf_evlist *other)
206{
207 struct perf_evsel *pos, *pair;
208
209 if (evlist->nr_entries != other->nr_entries)
210 return false;
211
212 pair = perf_evlist__first(other);
213
214 list_for_each_entry(pos, &evlist->entries, node) {
215 if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0))
216 return false;
217 pair = perf_evsel__next(pair);
218 }
219
220 return true;
221} 192}
222 193
223static int perf_record__open(struct perf_record *rec) 194static int perf_record__open(struct perf_record *rec)
@@ -274,16 +245,7 @@ try_again:
274 goto out; 245 goto out;
275 } 246 }
276 247
277 if (rec->file_new) 248 session->evlist = evlist;
278 session->evlist = evlist;
279 else {
280 if (!perf_evlist__equal(session->evlist, evlist)) {
281 fprintf(stderr, "incompatible append\n");
282 rc = -1;
283 goto out;
284 }
285 }
286
287 perf_session__set_id_hdr_size(session); 249 perf_session__set_id_hdr_size(session);
288out: 250out:
289 return rc; 251 return rc;
@@ -404,6 +366,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
404 signal(SIGCHLD, sig_handler); 366 signal(SIGCHLD, sig_handler);
405 signal(SIGINT, sig_handler); 367 signal(SIGINT, sig_handler);
406 signal(SIGUSR1, sig_handler); 368 signal(SIGUSR1, sig_handler);
369 signal(SIGTERM, sig_handler);
407 370
408 if (!output_name) { 371 if (!output_name) {
409 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode)) 372 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
@@ -415,23 +378,15 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
415 if (!strcmp(output_name, "-")) 378 if (!strcmp(output_name, "-"))
416 opts->pipe_output = true; 379 opts->pipe_output = true;
417 else if (!stat(output_name, &st) && st.st_size) { 380 else if (!stat(output_name, &st) && st.st_size) {
418 if (rec->write_mode == WRITE_FORCE) { 381 char oldname[PATH_MAX];
419 char oldname[PATH_MAX]; 382 snprintf(oldname, sizeof(oldname), "%s.old",
420 snprintf(oldname, sizeof(oldname), "%s.old", 383 output_name);
421 output_name); 384 unlink(oldname);
422 unlink(oldname); 385 rename(output_name, oldname);
423 rename(output_name, oldname);
424 }
425 } else if (rec->write_mode == WRITE_APPEND) {
426 rec->write_mode = WRITE_FORCE;
427 } 386 }
428 } 387 }
429 388
430 flags = O_CREAT|O_RDWR; 389 flags = O_CREAT|O_RDWR|O_TRUNC;
431 if (rec->write_mode == WRITE_APPEND)
432 rec->file_new = 0;
433 else
434 flags |= O_TRUNC;
435 390
436 if (opts->pipe_output) 391 if (opts->pipe_output)
437 output = STDOUT_FILENO; 392 output = STDOUT_FILENO;
@@ -445,7 +400,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
445 rec->output = output; 400 rec->output = output;
446 401
447 session = perf_session__new(output_name, O_WRONLY, 402 session = perf_session__new(output_name, O_WRONLY,
448 rec->write_mode == WRITE_FORCE, false, NULL); 403 true, false, NULL);
449 if (session == NULL) { 404 if (session == NULL) {
450 pr_err("Not enough memory for reading perf file header\n"); 405 pr_err("Not enough memory for reading perf file header\n");
451 return -1; 406 return -1;
@@ -465,12 +420,6 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
465 if (!rec->opts.branch_stack) 420 if (!rec->opts.branch_stack)
466 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK); 421 perf_header__clear_feat(&session->header, HEADER_BRANCH_STACK);
467 422
468 if (!rec->file_new) {
469 err = perf_session__read_header(session, output);
470 if (err < 0)
471 goto out_delete_session;
472 }
473
474 if (forks) { 423 if (forks) {
475 err = perf_evlist__prepare_workload(evsel_list, &opts->target, 424 err = perf_evlist__prepare_workload(evsel_list, &opts->target,
476 argv, opts->pipe_output, 425 argv, opts->pipe_output,
@@ -498,7 +447,7 @@ static int __cmd_record(struct perf_record *rec, int argc, const char **argv)
498 err = perf_header__write_pipe(output); 447 err = perf_header__write_pipe(output);
499 if (err < 0) 448 if (err < 0)
500 goto out_delete_session; 449 goto out_delete_session;
501 } else if (rec->file_new) { 450 } else {
502 err = perf_session__write_header(session, evsel_list, 451 err = perf_session__write_header(session, evsel_list,
503 output, false); 452 output, false);
504 if (err < 0) 453 if (err < 0)
@@ -869,8 +818,6 @@ static struct perf_record record = {
869 .uses_mmap = true, 818 .uses_mmap = true,
870 }, 819 },
871 }, 820 },
872 .write_mode = WRITE_FORCE,
873 .file_new = true,
874}; 821};
875 822
876#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: " 823#define CALLCHAIN_HELP "do call-graph (stack chain/backtrace) recording: "
@@ -906,12 +853,8 @@ const struct option record_options[] = {
906 "collect raw sample records from all opened counters"), 853 "collect raw sample records from all opened counters"),
907 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide, 854 OPT_BOOLEAN('a', "all-cpus", &record.opts.target.system_wide,
908 "system-wide collection from all CPUs"), 855 "system-wide collection from all CPUs"),
909 OPT_BOOLEAN('A', "append", &record.append_file,
910 "append to the output file to do incremental profiling"),
911 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu", 856 OPT_STRING('C', "cpu", &record.opts.target.cpu_list, "cpu",
912 "list of cpus to monitor"), 857 "list of cpus to monitor"),
913 OPT_BOOLEAN('f', "force", &record.force,
914 "overwrite existing data file (deprecated)"),
915 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"), 858 OPT_U64('c', "count", &record.opts.user_interval, "event period to sample"),
916 OPT_STRING('o', "output", &record.output_name, "file", 859 OPT_STRING('o', "output", &record.output_name, "file",
917 "output file name"), 860 "output file name"),
@@ -977,16 +920,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __maybe_unused)
977 if (!argc && perf_target__none(&rec->opts.target)) 920 if (!argc && perf_target__none(&rec->opts.target))
978 usage_with_options(record_usage, record_options); 921 usage_with_options(record_usage, record_options);
979 922
980 if (rec->force && rec->append_file) {
981 ui__error("Can't overwrite and append at the same time."
982 " You need to choose between -f and -A");
983 usage_with_options(record_usage, record_options);
984 } else if (rec->append_file) {
985 rec->write_mode = WRITE_APPEND;
986 } else {
987 rec->write_mode = WRITE_FORCE;
988 }
989
990 if (nr_cgroups && !rec->opts.target.system_wide) { 923 if (nr_cgroups && !rec->opts.target.system_wide) {
991 ui__error("cgroup monitoring only available in" 924 ui__error("cgroup monitoring only available in"
992 " system-wide mode\n"); 925 " system-wide mode\n");
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c
index bd0ca81eeaca..3662047cc6b1 100644
--- a/tools/perf/builtin-report.c
+++ b/tools/perf/builtin-report.c
@@ -52,6 +52,7 @@ struct perf_report {
52 symbol_filter_t annotate_init; 52 symbol_filter_t annotate_init;
53 const char *cpu_list; 53 const char *cpu_list;
54 const char *symbol_filter_str; 54 const char *symbol_filter_str;
55 float min_percent;
55 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 56 DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
56}; 57};
57 58
@@ -61,6 +62,11 @@ static int perf_report_config(const char *var, const char *value, void *cb)
61 symbol_conf.event_group = perf_config_bool(var, value); 62 symbol_conf.event_group = perf_config_bool(var, value);
62 return 0; 63 return 0;
63 } 64 }
65 if (!strcmp(var, "report.percent-limit")) {
66 struct perf_report *rep = cb;
67 rep->min_percent = strtof(value, NULL);
68 return 0;
69 }
64 70
65 return perf_default_config(var, value, cb); 71 return perf_default_config(var, value, cb);
66} 72}
@@ -187,6 +193,9 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
187 for (i = 0; i < sample->branch_stack->nr; i++) { 193 for (i = 0; i < sample->branch_stack->nr; i++) {
188 if (rep->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym)) 194 if (rep->hide_unresolved && !(bi[i].from.sym && bi[i].to.sym))
189 continue; 195 continue;
196
197 err = -ENOMEM;
198
190 /* 199 /*
191 * The report shows the percentage of total branches captured 200 * The report shows the percentage of total branches captured
192 * and not events sampled. Thus we use a pseudo period of 1. 201 * and not events sampled. Thus we use a pseudo period of 1.
@@ -195,7 +204,6 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
195 &bi[i], 1, 1); 204 &bi[i], 1, 1);
196 if (he) { 205 if (he) {
197 struct annotation *notes; 206 struct annotation *notes;
198 err = -ENOMEM;
199 bx = he->branch_info; 207 bx = he->branch_info;
200 if (bx->from.sym && use_browser == 1 && sort__has_sym) { 208 if (bx->from.sym && use_browser == 1 && sort__has_sym) {
201 notes = symbol__annotation(bx->from.sym); 209 notes = symbol__annotation(bx->from.sym);
@@ -226,11 +234,12 @@ static int perf_report__add_branch_hist_entry(struct perf_tool *tool,
226 } 234 }
227 evsel->hists.stats.total_period += 1; 235 evsel->hists.stats.total_period += 1;
228 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); 236 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
229 err = 0;
230 } else 237 } else
231 return -ENOMEM; 238 goto out;
232 } 239 }
240 err = 0;
233out: 241out:
242 free(bi);
234 return err; 243 return err;
235} 244}
236 245
@@ -294,6 +303,7 @@ static int process_sample_event(struct perf_tool *tool,
294{ 303{
295 struct perf_report *rep = container_of(tool, struct perf_report, tool); 304 struct perf_report *rep = container_of(tool, struct perf_report, tool);
296 struct addr_location al; 305 struct addr_location al;
306 int ret;
297 307
298 if (perf_event__preprocess_sample(event, machine, &al, sample, 308 if (perf_event__preprocess_sample(event, machine, &al, sample,
299 rep->annotate_init) < 0) { 309 rep->annotate_init) < 0) {
@@ -308,28 +318,25 @@ static int process_sample_event(struct perf_tool *tool,
308 if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap)) 318 if (rep->cpu_list && !test_bit(sample->cpu, rep->cpu_bitmap))
309 return 0; 319 return 0;
310 320
311 if (sort__branch_mode == 1) { 321 if (sort__mode == SORT_MODE__BRANCH) {
312 if (perf_report__add_branch_hist_entry(tool, &al, sample, 322 ret = perf_report__add_branch_hist_entry(tool, &al, sample,
313 evsel, machine)) { 323 evsel, machine);
324 if (ret < 0)
314 pr_debug("problem adding lbr entry, skipping event\n"); 325 pr_debug("problem adding lbr entry, skipping event\n");
315 return -1;
316 }
317 } else if (rep->mem_mode == 1) { 326 } else if (rep->mem_mode == 1) {
318 if (perf_report__add_mem_hist_entry(tool, &al, sample, 327 ret = perf_report__add_mem_hist_entry(tool, &al, sample,
319 evsel, machine, event)) { 328 evsel, machine, event);
329 if (ret < 0)
320 pr_debug("problem adding mem entry, skipping event\n"); 330 pr_debug("problem adding mem entry, skipping event\n");
321 return -1;
322 }
323 } else { 331 } else {
324 if (al.map != NULL) 332 if (al.map != NULL)
325 al.map->dso->hit = 1; 333 al.map->dso->hit = 1;
326 334
327 if (perf_evsel__add_hist_entry(evsel, &al, sample, machine)) { 335 ret = perf_evsel__add_hist_entry(evsel, &al, sample, machine);
336 if (ret < 0)
328 pr_debug("problem incrementing symbol period, skipping event\n"); 337 pr_debug("problem incrementing symbol period, skipping event\n");
329 return -1;
330 }
331 } 338 }
332 return 0; 339 return ret;
333} 340}
334 341
335static int process_read_event(struct perf_tool *tool, 342static int process_read_event(struct perf_tool *tool,
@@ -384,7 +391,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep)
384 } 391 }
385 } 392 }
386 393
387 if (sort__branch_mode == 1) { 394 if (sort__mode == SORT_MODE__BRANCH) {
388 if (!self->fd_pipe && 395 if (!self->fd_pipe &&
389 !(sample_type & PERF_SAMPLE_BRANCH_STACK)) { 396 !(sample_type & PERF_SAMPLE_BRANCH_STACK)) {
390 ui__error("Selected -b but no branch data. " 397 ui__error("Selected -b but no branch data. "
@@ -455,7 +462,7 @@ static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
455 continue; 462 continue;
456 463
457 hists__fprintf_nr_sample_events(rep, hists, evname, stdout); 464 hists__fprintf_nr_sample_events(rep, hists, evname, stdout);
458 hists__fprintf(hists, true, 0, 0, stdout); 465 hists__fprintf(hists, true, 0, 0, rep->min_percent, stdout);
459 fprintf(stdout, "\n\n"); 466 fprintf(stdout, "\n\n");
460 } 467 }
461 468
@@ -574,8 +581,8 @@ static int __cmd_report(struct perf_report *rep)
574 if (use_browser > 0) { 581 if (use_browser > 0) {
575 if (use_browser == 1) { 582 if (use_browser == 1) {
576 ret = perf_evlist__tui_browse_hists(session->evlist, 583 ret = perf_evlist__tui_browse_hists(session->evlist,
577 help, 584 help, NULL,
578 NULL, 585 rep->min_percent,
579 &session->header.env); 586 &session->header.env);
580 /* 587 /*
581 * Usually "ret" is the last pressed key, and we only 588 * Usually "ret" is the last pressed key, and we only
@@ -586,7 +593,7 @@ static int __cmd_report(struct perf_report *rep)
586 593
587 } else if (use_browser == 2) { 594 } else if (use_browser == 2) {
588 perf_evlist__gtk_browse_hists(session->evlist, help, 595 perf_evlist__gtk_browse_hists(session->evlist, help,
589 NULL); 596 NULL, rep->min_percent);
590 } 597 }
591 } else 598 } else
592 perf_evlist__tty_browse_hists(session->evlist, rep, help); 599 perf_evlist__tty_browse_hists(session->evlist, rep, help);
@@ -691,7 +698,19 @@ static int
691parse_branch_mode(const struct option *opt __maybe_unused, 698parse_branch_mode(const struct option *opt __maybe_unused,
692 const char *str __maybe_unused, int unset) 699 const char *str __maybe_unused, int unset)
693{ 700{
694 sort__branch_mode = !unset; 701 int *branch_mode = opt->value;
702
703 *branch_mode = !unset;
704 return 0;
705}
706
707static int
708parse_percent_limit(const struct option *opt, const char *str,
709 int unset __maybe_unused)
710{
711 struct perf_report *rep = opt->value;
712
713 rep->min_percent = strtof(str, NULL);
695 return 0; 714 return 0;
696} 715}
697 716
@@ -700,6 +719,7 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
700 struct perf_session *session; 719 struct perf_session *session;
701 struct stat st; 720 struct stat st;
702 bool has_br_stack = false; 721 bool has_br_stack = false;
722 int branch_mode = -1;
703 int ret = -1; 723 int ret = -1;
704 char callchain_default_opt[] = "fractal,0.5,callee"; 724 char callchain_default_opt[] = "fractal,0.5,callee";
705 const char * const report_usage[] = { 725 const char * const report_usage[] = {
@@ -796,17 +816,19 @@ int cmd_report(int argc, const char **argv, const char *prefix __maybe_unused)
796 "Show a column with the sum of periods"), 816 "Show a column with the sum of periods"),
797 OPT_BOOLEAN(0, "group", &symbol_conf.event_group, 817 OPT_BOOLEAN(0, "group", &symbol_conf.event_group,
798 "Show event group information together"), 818 "Show event group information together"),
799 OPT_CALLBACK_NOOPT('b', "branch-stack", &sort__branch_mode, "", 819 OPT_CALLBACK_NOOPT('b', "branch-stack", &branch_mode, "",
800 "use branch records for histogram filling", parse_branch_mode), 820 "use branch records for histogram filling", parse_branch_mode),
801 OPT_STRING(0, "objdump", &objdump_path, "path", 821 OPT_STRING(0, "objdump", &objdump_path, "path",
802 "objdump binary to use for disassembly and annotations"), 822 "objdump binary to use for disassembly and annotations"),
803 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle, 823 OPT_BOOLEAN(0, "demangle", &symbol_conf.demangle,
804 "Disable symbol demangling"), 824 "Disable symbol demangling"),
805 OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"), 825 OPT_BOOLEAN(0, "mem-mode", &report.mem_mode, "mem access profile"),
826 OPT_CALLBACK(0, "percent-limit", &report, "percent",
827 "Don't show entries under that percent", parse_percent_limit),
806 OPT_END() 828 OPT_END()
807 }; 829 };
808 830
809 perf_config(perf_report_config, NULL); 831 perf_config(perf_report_config, &report);
810 832
811 argc = parse_options(argc, argv, options, report_usage, 0); 833 argc = parse_options(argc, argv, options, report_usage, 0);
812 834
@@ -846,11 +868,11 @@ repeat:
846 has_br_stack = perf_header__has_feat(&session->header, 868 has_br_stack = perf_header__has_feat(&session->header,
847 HEADER_BRANCH_STACK); 869 HEADER_BRANCH_STACK);
848 870
849 if (sort__branch_mode == -1 && has_br_stack) 871 if (branch_mode == -1 && has_br_stack)
850 sort__branch_mode = 1; 872 sort__mode = SORT_MODE__BRANCH;
851 873
852 /* sort__branch_mode could be 0 if --no-branch-stack */ 874 /* sort__mode could be NORMAL if --no-branch-stack */
853 if (sort__branch_mode == 1) { 875 if (sort__mode == SORT_MODE__BRANCH) {
854 /* 876 /*
855 * if no sort_order is provided, then specify 877 * if no sort_order is provided, then specify
856 * branch-mode specific order 878 * branch-mode specific order
@@ -861,10 +883,12 @@ repeat:
861 883
862 } 884 }
863 if (report.mem_mode) { 885 if (report.mem_mode) {
864 if (sort__branch_mode == 1) { 886 if (sort__mode == SORT_MODE__BRANCH) {
865 fprintf(stderr, "branch and mem mode incompatible\n"); 887 fprintf(stderr, "branch and mem mode incompatible\n");
866 goto error; 888 goto error;
867 } 889 }
890 sort__mode = SORT_MODE__MEMORY;
891
868 /* 892 /*
869 * if no sort_order is provided, then specify 893 * if no sort_order is provided, then specify
870 * branch-mode specific order 894 * branch-mode specific order
@@ -915,8 +939,7 @@ repeat:
915 */ 939 */
916 if (!strstr(sort_order, "parent")) 940 if (!strstr(sort_order, "parent"))
917 sort_parent.elide = 1; 941 sort_parent.elide = 1;
918 } else 942 }
919 symbol_conf.exclude_other = false;
920 943
921 if (argc) { 944 if (argc) {
922 /* 945 /*
@@ -929,25 +952,7 @@ repeat:
929 report.symbol_filter_str = argv[0]; 952 report.symbol_filter_str = argv[0];
930 } 953 }
931 954
932 sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout); 955 sort__setup_elide(stdout);
933
934 if (sort__branch_mode == 1) {
935 sort_entry__setup_elide(&sort_dso_from, symbol_conf.dso_from_list, "dso_from", stdout);
936 sort_entry__setup_elide(&sort_dso_to, symbol_conf.dso_to_list, "dso_to", stdout);
937 sort_entry__setup_elide(&sort_sym_from, symbol_conf.sym_from_list, "sym_from", stdout);
938 sort_entry__setup_elide(&sort_sym_to, symbol_conf.sym_to_list, "sym_to", stdout);
939 } else {
940 if (report.mem_mode) {
941 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "symbol_daddr", stdout);
942 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso_daddr", stdout);
943 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "mem", stdout);
944 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "local_weight", stdout);
945 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "tlb", stdout);
946 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "snoop", stdout);
947 }
948 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
949 sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
950 }
951 956
952 ret = __cmd_report(&report); 957 ret = __cmd_report(&report);
953 if (ret == K_SWITCH_INPUT_DATA) { 958 if (ret == K_SWITCH_INPUT_DATA) {
diff --git a/tools/perf/builtin-sched.c b/tools/perf/builtin-sched.c
index 2da2a6ca22bf..fed9ae432c16 100644
--- a/tools/perf/builtin-sched.c
+++ b/tools/perf/builtin-sched.c
@@ -1632,7 +1632,6 @@ static int __cmd_record(int argc, const char **argv)
1632 "record", 1632 "record",
1633 "-a", 1633 "-a",
1634 "-R", 1634 "-R",
1635 "-f",
1636 "-m", "1024", 1635 "-m", "1024",
1637 "-c", "1", 1636 "-c", "1",
1638 "-e", "sched:sched_switch", 1637 "-e", "sched:sched_switch",
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 7e910bab1097..352fbd7ff4a1 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -87,7 +87,7 @@ static int run_count = 1;
87static bool no_inherit = false; 87static bool no_inherit = false;
88static bool scale = true; 88static bool scale = true;
89static enum aggr_mode aggr_mode = AGGR_GLOBAL; 89static enum aggr_mode aggr_mode = AGGR_GLOBAL;
90static pid_t child_pid = -1; 90static volatile pid_t child_pid = -1;
91static bool null_run = false; 91static bool null_run = false;
92static int detailed_run = 0; 92static int detailed_run = 0;
93static bool big_num = true; 93static bool big_num = true;
@@ -924,7 +924,7 @@ static void abs_printout(int cpu, int nr, struct perf_evsel *evsel, double avg)
924static void print_aggr(char *prefix) 924static void print_aggr(char *prefix)
925{ 925{
926 struct perf_evsel *counter; 926 struct perf_evsel *counter;
927 int cpu, s, s2, id, nr; 927 int cpu, cpu2, s, s2, id, nr;
928 u64 ena, run, val; 928 u64 ena, run, val;
929 929
930 if (!(aggr_map || aggr_get_id)) 930 if (!(aggr_map || aggr_get_id))
@@ -936,7 +936,8 @@ static void print_aggr(char *prefix)
936 val = ena = run = 0; 936 val = ena = run = 0;
937 nr = 0; 937 nr = 0;
938 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) { 938 for (cpu = 0; cpu < perf_evsel__nr_cpus(counter); cpu++) {
939 s2 = aggr_get_id(evsel_list->cpus, cpu); 939 cpu2 = perf_evsel__cpus(counter)->map[cpu];
940 s2 = aggr_get_id(evsel_list->cpus, cpu2);
940 if (s2 != id) 941 if (s2 != id)
941 continue; 942 continue;
942 val += counter->counts->cpu[cpu].val; 943 val += counter->counts->cpu[cpu].val;
@@ -948,7 +949,7 @@ static void print_aggr(char *prefix)
948 fprintf(output, "%s", prefix); 949 fprintf(output, "%s", prefix);
949 950
950 if (run == 0 || ena == 0) { 951 if (run == 0 || ena == 0) {
951 aggr_printout(counter, cpu, nr); 952 aggr_printout(counter, id, nr);
952 953
953 fprintf(output, "%*s%s%*s", 954 fprintf(output, "%*s%s%*s",
954 csv_output ? 0 : 18, 955 csv_output ? 0 : 18,
@@ -1148,13 +1149,34 @@ static void skip_signal(int signo)
1148 done = 1; 1149 done = 1;
1149 1150
1150 signr = signo; 1151 signr = signo;
1152 /*
1153 * render child_pid harmless
1154 * won't send SIGTERM to a random
1155 * process in case of race condition
1156 * and fast PID recycling
1157 */
1158 child_pid = -1;
1151} 1159}
1152 1160
1153static void sig_atexit(void) 1161static void sig_atexit(void)
1154{ 1162{
1163 sigset_t set, oset;
1164
1165 /*
1166 * avoid race condition with SIGCHLD handler
1167 * in skip_signal() which is modifying child_pid
1168 * goal is to avoid send SIGTERM to a random
1169 * process
1170 */
1171 sigemptyset(&set);
1172 sigaddset(&set, SIGCHLD);
1173 sigprocmask(SIG_BLOCK, &set, &oset);
1174
1155 if (child_pid != -1) 1175 if (child_pid != -1)
1156 kill(child_pid, SIGTERM); 1176 kill(child_pid, SIGTERM);
1157 1177
1178 sigprocmask(SIG_SETMASK, &oset, NULL);
1179
1158 if (signr == -1) 1180 if (signr == -1)
1159 return; 1181 return;
1160 1182
diff --git a/tools/perf/builtin-timechart.c b/tools/perf/builtin-timechart.c
index ab4cf232b852..4536a92b18f3 100644
--- a/tools/perf/builtin-timechart.c
+++ b/tools/perf/builtin-timechart.c
@@ -1005,7 +1005,7 @@ static int __cmd_record(int argc, const char **argv)
1005{ 1005{
1006#ifdef SUPPORT_OLD_POWER_EVENTS 1006#ifdef SUPPORT_OLD_POWER_EVENTS
1007 const char * const record_old_args[] = { 1007 const char * const record_old_args[] = {
1008 "record", "-a", "-R", "-f", "-c", "1", 1008 "record", "-a", "-R", "-c", "1",
1009 "-e", "power:power_start", 1009 "-e", "power:power_start",
1010 "-e", "power:power_end", 1010 "-e", "power:power_end",
1011 "-e", "power:power_frequency", 1011 "-e", "power:power_frequency",
@@ -1014,7 +1014,7 @@ static int __cmd_record(int argc, const char **argv)
1014 }; 1014 };
1015#endif 1015#endif
1016 const char * const record_new_args[] = { 1016 const char * const record_new_args[] = {
1017 "record", "-a", "-R", "-f", "-c", "1", 1017 "record", "-a", "-R", "-c", "1",
1018 "-e", "power:cpu_frequency", 1018 "-e", "power:cpu_frequency",
1019 "-e", "power:cpu_idle", 1019 "-e", "power:cpu_idle",
1020 "-e", "sched:sched_wakeup", 1020 "-e", "sched:sched_wakeup",
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c
index 67bdb9f14ad6..e06c4f869330 100644
--- a/tools/perf/builtin-top.c
+++ b/tools/perf/builtin-top.c
@@ -70,10 +70,11 @@
70 70
71static volatile int done; 71static volatile int done;
72 72
73#define HEADER_LINE_NR 5
74
73static void perf_top__update_print_entries(struct perf_top *top) 75static void perf_top__update_print_entries(struct perf_top *top)
74{ 76{
75 if (top->print_entries > 9) 77 top->print_entries = top->winsize.ws_row - HEADER_LINE_NR;
76 top->print_entries -= 9;
77} 78}
78 79
79static void perf_top__sig_winch(int sig __maybe_unused, 80static void perf_top__sig_winch(int sig __maybe_unused,
@@ -82,13 +83,6 @@ static void perf_top__sig_winch(int sig __maybe_unused,
82 struct perf_top *top = arg; 83 struct perf_top *top = arg;
83 84
84 get_term_dimensions(&top->winsize); 85 get_term_dimensions(&top->winsize);
85 if (!top->print_entries
86 || (top->print_entries+4) > top->winsize.ws_row) {
87 top->print_entries = top->winsize.ws_row;
88 } else {
89 top->print_entries += 4;
90 top->winsize.ws_row = top->print_entries;
91 }
92 perf_top__update_print_entries(top); 86 perf_top__update_print_entries(top);
93} 87}
94 88
@@ -251,8 +245,11 @@ static struct hist_entry *perf_evsel__add_hist_entry(struct perf_evsel *evsel,
251{ 245{
252 struct hist_entry *he; 246 struct hist_entry *he;
253 247
248 pthread_mutex_lock(&evsel->hists.lock);
254 he = __hists__add_entry(&evsel->hists, al, NULL, sample->period, 249 he = __hists__add_entry(&evsel->hists, al, NULL, sample->period,
255 sample->weight); 250 sample->weight);
251 pthread_mutex_unlock(&evsel->hists.lock);
252
256 if (he == NULL) 253 if (he == NULL)
257 return NULL; 254 return NULL;
258 255
@@ -290,16 +287,17 @@ static void perf_top__print_sym_table(struct perf_top *top)
290 return; 287 return;
291 } 288 }
292 289
293 hists__collapse_resort_threaded(&top->sym_evsel->hists); 290 hists__collapse_resort(&top->sym_evsel->hists);
294 hists__output_resort_threaded(&top->sym_evsel->hists); 291 hists__output_resort(&top->sym_evsel->hists);
295 hists__decay_entries_threaded(&top->sym_evsel->hists, 292 hists__decay_entries(&top->sym_evsel->hists,
296 top->hide_user_symbols, 293 top->hide_user_symbols,
297 top->hide_kernel_symbols); 294 top->hide_kernel_symbols);
298 hists__output_recalc_col_len(&top->sym_evsel->hists, 295 hists__output_recalc_col_len(&top->sym_evsel->hists,
299 top->winsize.ws_row - 3); 296 top->print_entries - printed);
300 putchar('\n'); 297 putchar('\n');
301 hists__fprintf(&top->sym_evsel->hists, false, 298 hists__fprintf(&top->sym_evsel->hists, false,
302 top->winsize.ws_row - 4 - printed, win_width, stdout); 299 top->print_entries - printed, win_width,
300 top->min_percent, stdout);
303} 301}
304 302
305static void prompt_integer(int *target, const char *msg) 303static void prompt_integer(int *target, const char *msg)
@@ -477,7 +475,6 @@ static bool perf_top__handle_keypress(struct perf_top *top, int c)
477 perf_top__sig_winch(SIGWINCH, NULL, top); 475 perf_top__sig_winch(SIGWINCH, NULL, top);
478 sigaction(SIGWINCH, &act, NULL); 476 sigaction(SIGWINCH, &act, NULL);
479 } else { 477 } else {
480 perf_top__sig_winch(SIGWINCH, NULL, top);
481 signal(SIGWINCH, SIG_DFL); 478 signal(SIGWINCH, SIG_DFL);
482 } 479 }
483 break; 480 break;
@@ -556,11 +553,11 @@ static void perf_top__sort_new_samples(void *arg)
556 if (t->evlist->selected != NULL) 553 if (t->evlist->selected != NULL)
557 t->sym_evsel = t->evlist->selected; 554 t->sym_evsel = t->evlist->selected;
558 555
559 hists__collapse_resort_threaded(&t->sym_evsel->hists); 556 hists__collapse_resort(&t->sym_evsel->hists);
560 hists__output_resort_threaded(&t->sym_evsel->hists); 557 hists__output_resort(&t->sym_evsel->hists);
561 hists__decay_entries_threaded(&t->sym_evsel->hists, 558 hists__decay_entries(&t->sym_evsel->hists,
562 t->hide_user_symbols, 559 t->hide_user_symbols,
563 t->hide_kernel_symbols); 560 t->hide_kernel_symbols);
564} 561}
565 562
566static void *display_thread_tui(void *arg) 563static void *display_thread_tui(void *arg)
@@ -584,7 +581,7 @@ static void *display_thread_tui(void *arg)
584 list_for_each_entry(pos, &top->evlist->entries, node) 581 list_for_each_entry(pos, &top->evlist->entries, node)
585 pos->hists.uid_filter_str = top->record_opts.target.uid_str; 582 pos->hists.uid_filter_str = top->record_opts.target.uid_str;
586 583
587 perf_evlist__tui_browse_hists(top->evlist, help, &hbt, 584 perf_evlist__tui_browse_hists(top->evlist, help, &hbt, top->min_percent,
588 &top->session->header.env); 585 &top->session->header.env);
589 586
590 done = 1; 587 done = 1;
@@ -794,7 +791,7 @@ static void perf_event__process_sample(struct perf_tool *tool,
794 return; 791 return;
795 } 792 }
796 793
797 if (top->sort_has_symbols) 794 if (sort__has_sym)
798 perf_top__record_precise_ip(top, he, evsel->idx, ip); 795 perf_top__record_precise_ip(top, he, evsel->idx, ip);
799 } 796 }
800 797
@@ -912,9 +909,9 @@ out_err:
912 return -1; 909 return -1;
913} 910}
914 911
915static int perf_top__setup_sample_type(struct perf_top *top) 912static int perf_top__setup_sample_type(struct perf_top *top __maybe_unused)
916{ 913{
917 if (!top->sort_has_symbols) { 914 if (!sort__has_sym) {
918 if (symbol_conf.use_callchain) { 915 if (symbol_conf.use_callchain) {
919 ui__error("Selected -g but \"sym\" not present in --sort/-s."); 916 ui__error("Selected -g but \"sym\" not present in --sort/-s.");
920 return -EINVAL; 917 return -EINVAL;
@@ -1025,6 +1022,16 @@ parse_callchain_opt(const struct option *opt, const char *arg, int unset)
1025 return record_parse_callchain_opt(opt, arg, unset); 1022 return record_parse_callchain_opt(opt, arg, unset);
1026} 1023}
1027 1024
1025static int
1026parse_percent_limit(const struct option *opt, const char *arg,
1027 int unset __maybe_unused)
1028{
1029 struct perf_top *top = opt->value;
1030
1031 top->min_percent = strtof(arg, NULL);
1032 return 0;
1033}
1034
1028int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused) 1035int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1029{ 1036{
1030 int status; 1037 int status;
@@ -1110,6 +1117,8 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1110 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style", 1117 OPT_STRING('M', "disassembler-style", &disassembler_style, "disassembler style",
1111 "Specify disassembler style (e.g. -M intel for intel syntax)"), 1118 "Specify disassembler style (e.g. -M intel for intel syntax)"),
1112 OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"), 1119 OPT_STRING('u', "uid", &target->uid_str, "user", "user to profile"),
1120 OPT_CALLBACK(0, "percent-limit", &top, "percent",
1121 "Don't show entries under that percent", parse_percent_limit),
1113 OPT_END() 1122 OPT_END()
1114 }; 1123 };
1115 const char * const top_usage[] = { 1124 const char * const top_usage[] = {
@@ -1121,8 +1130,6 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1121 if (top.evlist == NULL) 1130 if (top.evlist == NULL)
1122 return -ENOMEM; 1131 return -ENOMEM;
1123 1132
1124 symbol_conf.exclude_other = false;
1125
1126 argc = parse_options(argc, argv, options, top_usage, 0); 1133 argc = parse_options(argc, argv, options, top_usage, 0);
1127 if (argc) 1134 if (argc)
1128 usage_with_options(top_usage, options); 1135 usage_with_options(top_usage, options);
@@ -1133,6 +1140,9 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1133 if (setup_sorting() < 0) 1140 if (setup_sorting() < 0)
1134 usage_with_options(top_usage, options); 1141 usage_with_options(top_usage, options);
1135 1142
1143 /* display thread wants entries to be collapsed in a different tree */
1144 sort__need_collapse = 1;
1145
1136 if (top.use_stdio) 1146 if (top.use_stdio)
1137 use_browser = 0; 1147 use_browser = 0;
1138 else if (top.use_tui) 1148 else if (top.use_tui)
@@ -1200,15 +1210,7 @@ int cmd_top(int argc, const char **argv, const char *prefix __maybe_unused)
1200 if (symbol__init() < 0) 1210 if (symbol__init() < 0)
1201 return -1; 1211 return -1;
1202 1212
1203 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout); 1213 sort__setup_elide(stdout);
1204 sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
1205 sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
1206
1207 /*
1208 * Avoid annotation data structures overhead when symbols aren't on the
1209 * sort list.
1210 */
1211 top.sort_has_symbols = sort_sym.list.next != NULL;
1212 1214
1213 get_term_dimensions(&top.winsize); 1215 get_term_dimensions(&top.winsize);
1214 if (top.print_entries == 0) { 1216 if (top.print_entries == 0) {
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
new file mode 100644
index 000000000000..b5d9238cb181
--- /dev/null
+++ b/tools/perf/config/Makefile
@@ -0,0 +1,477 @@
1uname_M := $(shell uname -m 2>/dev/null || echo not)
2
3ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
4 -e s/arm.*/arm/ -e s/sa110/arm/ \
5 -e s/s390x/s390/ -e s/parisc64/parisc/ \
6 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
7 -e s/sh[234].*/sh/ -e s/aarch64.*/arm64/ )
8NO_PERF_REGS := 1
9CFLAGS := $(EXTRA_CFLAGS) $(EXTRA_WARNINGS)
10
11# Additional ARCH settings for x86
12ifeq ($(ARCH),i386)
13 override ARCH := x86
14 NO_PERF_REGS := 0
15 LIBUNWIND_LIBS = -lunwind -lunwind-x86
16endif
17
18ifeq ($(ARCH),x86_64)
19 override ARCH := x86
20 IS_X86_64 := 0
21 ifeq (, $(findstring m32,$(CFLAGS)))
22 IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -x c - | tail -n 1)
23 endif
24 ifeq (${IS_X86_64}, 1)
25 RAW_ARCH := x86_64
26 CFLAGS += -DARCH_X86_64
27 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S ../../arch/x86/lib/memset_64.S
28 endif
29 NO_PERF_REGS := 0
30 LIBUNWIND_LIBS = -lunwind -lunwind-x86_64
31endif
32
33ifeq ($(NO_PERF_REGS),0)
34 CFLAGS += -DHAVE_PERF_REGS
35endif
36
37ifeq ($(src-perf),)
38src-perf := $(srctree)/tools/perf
39endif
40
41ifeq ($(obj-perf),)
42obj-perf := $(OUTPUT)
43endif
44
45ifneq ($(obj-perf),)
46obj-perf := $(abspath $(obj-perf))/
47endif
48
49# include ARCH specific config
50-include $(src-perf)/arch/$(ARCH)/Makefile
51
52include $(src-perf)/config/feature-tests.mak
53include $(src-perf)/config/utilities.mak
54
55ifeq ($(call get-executable,$(FLEX)),)
56 dummy := $(error Error: $(FLEX) is missing on this system, please install it)
57endif
58
59ifeq ($(call get-executable,$(BISON)),)
60 dummy := $(error Error: $(BISON) is missing on this system, please install it)
61endif
62
63# Treat warnings as errors unless directed not to
64ifneq ($(WERROR),0)
65 CFLAGS += -Werror
66endif
67
68ifeq ("$(origin DEBUG)", "command line")
69 PERF_DEBUG = $(DEBUG)
70endif
71ifndef PERF_DEBUG
72 CFLAGS += -O6
73endif
74
75ifdef PARSER_DEBUG
76 PARSER_DEBUG_BISON := -t
77 PARSER_DEBUG_FLEX := -d
78 CFLAGS += -DPARSER_DEBUG
79endif
80
81CFLAGS += -fno-omit-frame-pointer
82CFLAGS += -ggdb3
83CFLAGS += -funwind-tables
84CFLAGS += -Wall
85CFLAGS += -Wextra
86CFLAGS += -std=gnu99
87
88EXTLIBS = -lelf -lpthread -lrt -lm
89
90ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -fstack-protector-all,-fstack-protector-all),y)
91 CFLAGS += -fstack-protector-all
92endif
93
94ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wstack-protector,-Wstack-protector),y)
95 CFLAGS += -Wstack-protector
96endif
97
98ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -Werror -Wvolatile-register-var,-Wvolatile-register-var),y)
99 CFLAGS += -Wvolatile-register-var
100endif
101
102ifndef PERF_DEBUG
103 ifeq ($(call try-cc,$(SOURCE_HELLO),$(CFLAGS) -D_FORTIFY_SOURCE=2,-D_FORTIFY_SOURCE=2),y)
104 CFLAGS += -D_FORTIFY_SOURCE=2
105 endif
106endif
107
108CFLAGS += -I$(src-perf)/util/include
109CFLAGS += -I$(src-perf)/arch/$(ARCH)/include
110CFLAGS += -I$(srctree)/arch/$(ARCH)/include/uapi
111CFLAGS += -I$(srctree)/arch/$(ARCH)/include
112CFLAGS += -I$(srctree)/include/uapi
113CFLAGS += -I$(srctree)/include
114
115# $(obj-perf) for generated common-cmds.h
116# $(obj-perf)/util for generated bison/flex headers
117ifneq ($(OUTPUT),)
118CFLAGS += -I$(obj-perf)/util
119CFLAGS += -I$(obj-perf)
120endif
121
122CFLAGS += -I$(src-perf)/util
123CFLAGS += -I$(src-perf)
124CFLAGS += -I$(TRACE_EVENT_DIR)
125CFLAGS += -I$(srctree)/tools/lib/
126
127CFLAGS += -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
128
129ifndef NO_BIONIC
130ifeq ($(call try-cc,$(SOURCE_BIONIC),$(CFLAGS),bionic),y)
131 BIONIC := 1
132 EXTLIBS := $(filter-out -lrt,$(EXTLIBS))
133 EXTLIBS := $(filter-out -lpthread,$(EXTLIBS))
134endif
135endif # NO_BIONIC
136
137ifdef NO_LIBELF
138 NO_DWARF := 1
139 NO_DEMANGLE := 1
140 NO_LIBUNWIND := 1
141else
142FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
143ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF),libelf),y)
144 FLAGS_GLIBC=$(CFLAGS) $(LDFLAGS)
145 ifeq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC),glibc),y)
146 LIBC_SUPPORT := 1
147 endif
148 ifeq ($(BIONIC),1)
149 LIBC_SUPPORT := 1
150 endif
151 ifeq ($(LIBC_SUPPORT),1)
152 msg := $(warning No libelf found, disables 'probe' tool, please install elfutils-libelf-devel/libelf-dev);
153
154 NO_LIBELF := 1
155 NO_DWARF := 1
156 NO_DEMANGLE := 1
157 else
158 msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
159 endif
160else
161 # for linking with debug library, run like:
162 # make DEBUG=1 LIBDW_DIR=/opt/libdw/
163 ifdef LIBDW_DIR
164 LIBDW_CFLAGS := -I$(LIBDW_DIR)/include
165 LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
166 endif
167
168 FLAGS_DWARF=$(CFLAGS) $(LIBDW_CFLAGS) -ldw -lz -lelf $(LIBDW_LDFLAGS) $(LDFLAGS) $(EXTLIBS)
169 ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF),libdw),y)
170 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
171 NO_DWARF := 1
172 endif # Dwarf support
173endif # SOURCE_LIBELF
174endif # NO_LIBELF
175
176ifndef NO_LIBELF
177CFLAGS += -DLIBELF_SUPPORT
178FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
179ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
180 CFLAGS += -DLIBELF_MMAP
181endif
182
183# include ARCH specific config
184-include $(src-perf)/arch/$(ARCH)/Makefile
185
186ifndef NO_DWARF
187ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
188 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
189 NO_DWARF := 1
190else
191 CFLAGS += -DDWARF_SUPPORT $(LIBDW_CFLAGS)
192 LDFLAGS += $(LIBDW_LDFLAGS)
193 EXTLIBS += -lelf -ldw
194endif # PERF_HAVE_DWARF_REGS
195endif # NO_DWARF
196
197endif # NO_LIBELF
198
199ifndef NO_LIBELF
200CFLAGS += -DLIBELF_SUPPORT
201FLAGS_LIBELF=$(CFLAGS) $(LDFLAGS) $(EXTLIBS)
202ifeq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_LIBELF),-DLIBELF_MMAP),y)
203 CFLAGS += -DLIBELF_MMAP
204endif # try-cc
205endif # NO_LIBELF
206
207# There's only x86 (both 32 and 64) support for CFI unwind so far
208ifneq ($(ARCH),x86)
209 NO_LIBUNWIND := 1
210endif
211
212ifndef NO_LIBUNWIND
213# for linking with debug library, run like:
214# make DEBUG=1 LIBUNWIND_DIR=/opt/libunwind/
215ifdef LIBUNWIND_DIR
216 LIBUNWIND_CFLAGS := -I$(LIBUNWIND_DIR)/include
217 LIBUNWIND_LDFLAGS := -L$(LIBUNWIND_DIR)/lib
218endif
219
220FLAGS_UNWIND=$(LIBUNWIND_CFLAGS) $(CFLAGS) $(LIBUNWIND_LDFLAGS) $(LDFLAGS) $(EXTLIBS) $(LIBUNWIND_LIBS)
221ifneq ($(call try-cc,$(SOURCE_LIBUNWIND),$(FLAGS_UNWIND),libunwind),y)
222 msg := $(warning No libunwind found, disabling post unwind support. Please install libunwind-dev[el] >= 0.99);
223 NO_LIBUNWIND := 1
224endif # Libunwind support
225endif # NO_LIBUNWIND
226
227ifndef NO_LIBUNWIND
228 CFLAGS += -DLIBUNWIND_SUPPORT
229 EXTLIBS += $(LIBUNWIND_LIBS)
230 CFLAGS += $(LIBUNWIND_CFLAGS)
231 LDFLAGS += $(LIBUNWIND_LDFLAGS)
232endif # NO_LIBUNWIND
233
234ifndef NO_LIBAUDIT
235 FLAGS_LIBAUDIT = $(CFLAGS) $(LDFLAGS) -laudit
236 ifneq ($(call try-cc,$(SOURCE_LIBAUDIT),$(FLAGS_LIBAUDIT),libaudit),y)
237 msg := $(warning No libaudit.h found, disables 'trace' tool, please install audit-libs-devel or libaudit-dev);
238 NO_LIBAUDIT := 1
239 else
240 CFLAGS += -DLIBAUDIT_SUPPORT
241 EXTLIBS += -laudit
242 endif
243endif
244
245ifdef NO_NEWT
246 NO_SLANG=1
247endif
248
249ifndef NO_SLANG
250 FLAGS_SLANG=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -I/usr/include/slang -lslang
251 ifneq ($(call try-cc,$(SOURCE_SLANG),$(FLAGS_SLANG),libslang),y)
252 msg := $(warning slang not found, disables TUI support. Please install slang-devel or libslang-dev);
253 NO_SLANG := 1
254 else
255 # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
256 CFLAGS += -I/usr/include/slang
257 CFLAGS += -DSLANG_SUPPORT
258 EXTLIBS += -lslang
259 endif
260endif
261
262ifndef NO_GTK2
263 FLAGS_GTK2=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) $(shell pkg-config --libs --cflags gtk+-2.0 2>/dev/null)
264 ifneq ($(call try-cc,$(SOURCE_GTK2),$(FLAGS_GTK2),gtk2),y)
265 msg := $(warning GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev);
266 NO_GTK2 := 1
267 else
268 ifeq ($(call try-cc,$(SOURCE_GTK2_INFOBAR),$(FLAGS_GTK2),-DHAVE_GTK_INFO_BAR),y)
269 CFLAGS += -DHAVE_GTK_INFO_BAR
270 endif
271 CFLAGS += -DGTK2_SUPPORT
272 CFLAGS += $(shell pkg-config --cflags gtk+-2.0 2>/dev/null)
273 EXTLIBS += $(shell pkg-config --libs gtk+-2.0 2>/dev/null)
274 endif
275endif
276
277grep-libs = $(filter -l%,$(1))
278strip-libs = $(filter-out -l%,$(1))
279
280ifdef NO_LIBPERL
281 CFLAGS += -DNO_LIBPERL
282else
283 PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
284 PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
285 PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
286 PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
287 FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
288
289 ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED),perl),y)
290 CFLAGS += -DNO_LIBPERL
291 NO_LIBPERL := 1
292 else
293 LDFLAGS += $(PERL_EMBED_LDFLAGS)
294 EXTLIBS += $(PERL_EMBED_LIBADD)
295 endif
296endif
297
298disable-python = $(eval $(disable-python_code))
299define disable-python_code
300 CFLAGS += -DNO_LIBPYTHON
301 $(if $(1),$(warning No $(1) was found))
302 $(warning Python support will not be built)
303 NO_LIBPYTHON := 1
304endef
305
306override PYTHON := \
307 $(call get-executable-or-default,PYTHON,python)
308
309ifndef PYTHON
310 $(call disable-python,python interpreter)
311else
312
313 PYTHON_WORD := $(call shell-wordify,$(PYTHON))
314
315 ifdef NO_LIBPYTHON
316 $(call disable-python)
317 else
318
319 override PYTHON_CONFIG := \
320 $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
321
322 ifndef PYTHON_CONFIG
323 $(call disable-python,python-config tool)
324 else
325
326 PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
327
328 PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
329 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
330 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
331 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
332 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
333
334 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED),python),y)
335 $(call disable-python,Python.h (for Python 2.x))
336 else
337
338 ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED),python version),y)
339 $(warning Python 3 is not yet supported; please set)
340 $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
341 $(warning If you also have Python 2 installed, then)
342 $(warning try something like:)
343 $(warning $(and ,))
344 $(warning $(and ,) make PYTHON=python2)
345 $(warning $(and ,))
346 $(warning Otherwise, disable Python support entirely:)
347 $(warning $(and ,))
348 $(warning $(and ,) make NO_LIBPYTHON=1)
349 $(warning $(and ,))
350 $(error $(and ,))
351 else
352 LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
353 EXTLIBS += $(PYTHON_EMBED_LIBADD)
354 LANG_BINDINGS += $(obj-perf)python/perf.so
355 endif
356 endif
357 endif
358 endif
359endif
360
361ifdef NO_DEMANGLE
362 CFLAGS += -DNO_DEMANGLE
363else
364 ifdef HAVE_CPLUS_DEMANGLE
365 EXTLIBS += -liberty
366 CFLAGS += -DHAVE_CPLUS_DEMANGLE
367 else
368 FLAGS_BFD=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -DPACKAGE='perf' -lbfd
369 has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD),libbfd)
370 ifeq ($(has_bfd),y)
371 EXTLIBS += -lbfd
372 else
373 FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
374 has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY),liberty)
375 ifeq ($(has_bfd_iberty),y)
376 EXTLIBS += -lbfd -liberty
377 else
378 FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
379 has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z),libz)
380 ifeq ($(has_bfd_iberty_z),y)
381 EXTLIBS += -lbfd -liberty -lz
382 else
383 FLAGS_CPLUS_DEMANGLE=$(CFLAGS) $(LDFLAGS) $(EXTLIBS) -liberty
384 has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE),demangle)
385 ifeq ($(has_cplus_demangle),y)
386 EXTLIBS += -liberty
387 CFLAGS += -DHAVE_CPLUS_DEMANGLE
388 else
389 msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
390 CFLAGS += -DNO_DEMANGLE
391 endif
392 endif
393 endif
394 endif
395 endif
396endif
397
398ifndef NO_STRLCPY
399 ifeq ($(call try-cc,$(SOURCE_STRLCPY),,-DHAVE_STRLCPY),y)
400 CFLAGS += -DHAVE_STRLCPY
401 endif
402endif
403
404ifndef NO_ON_EXIT
405 ifeq ($(call try-cc,$(SOURCE_ON_EXIT),,-DHAVE_ON_EXIT),y)
406 CFLAGS += -DHAVE_ON_EXIT
407 endif
408endif
409
410ifndef NO_BACKTRACE
411 ifeq ($(call try-cc,$(SOURCE_BACKTRACE),,-DBACKTRACE_SUPPORT),y)
412 CFLAGS += -DBACKTRACE_SUPPORT
413 endif
414endif
415
416ifndef NO_LIBNUMA
417 FLAGS_LIBNUMA = $(CFLAGS) $(LDFLAGS) -lnuma
418 ifneq ($(call try-cc,$(SOURCE_LIBNUMA),$(FLAGS_LIBNUMA),libnuma),y)
419 msg := $(warning No numa.h found, disables 'perf bench numa mem' benchmark, please install numa-libs-devel or libnuma-dev);
420 NO_LIBNUMA := 1
421 else
422 CFLAGS += -DLIBNUMA_SUPPORT
423 EXTLIBS += -lnuma
424 endif
425endif
426
427# Among the variables below, these:
428# perfexecdir
429# template_dir
430# mandir
431# infodir
432# htmldir
433# ETC_PERFCONFIG (but not sysconfdir)
434# can be specified as a relative path some/where/else;
435# this is interpreted as relative to $(prefix) and "perf" at
436# runtime figures out where they are based on the path to the executable.
437# This can help installing the suite in a relocatable way.
438
439# Make the path relative to DESTDIR, not to prefix
440ifndef DESTDIR
441prefix = $(HOME)
442endif
443bindir_relative = bin
444bindir = $(prefix)/$(bindir_relative)
445mandir = share/man
446infodir = share/info
447perfexecdir = libexec/perf-core
448sharedir = $(prefix)/share
449template_dir = share/perf-core/templates
450htmldir = share/doc/perf-doc
451ifeq ($(prefix),/usr)
452sysconfdir = /etc
453ETC_PERFCONFIG = $(sysconfdir)/perfconfig
454else
455sysconfdir = $(prefix)/etc
456ETC_PERFCONFIG = etc/perfconfig
457endif
458lib = lib
459
460# Shell quote (do not use $(call) to accommodate ancient setups);
461ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
462DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
463bindir_SQ = $(subst ','\'',$(bindir))
464mandir_SQ = $(subst ','\'',$(mandir))
465infodir_SQ = $(subst ','\'',$(infodir))
466perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
467template_dir_SQ = $(subst ','\'',$(template_dir))
468htmldir_SQ = $(subst ','\'',$(htmldir))
469prefix_SQ = $(subst ','\'',$(prefix))
470sysconfdir_SQ = $(subst ','\'',$(sysconfdir))
471
472ifneq ($(filter /%,$(firstword $(perfexecdir))),)
473perfexec_instdir = $(perfexecdir)
474else
475perfexec_instdir = $(prefix)/$(perfexecdir)
476endif
477perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
diff --git a/tools/perf/config/utilities.mak b/tools/perf/config/utilities.mak
index 8ef3bd30a549..94d2d4f9c35d 100644
--- a/tools/perf/config/utilities.mak
+++ b/tools/perf/config/utilities.mak
@@ -173,7 +173,7 @@ _ge-abspath = $(if $(is-executable),$(1))
173# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default) 173# Usage: absolute-executable-path-or-empty = $(call get-executable-or-default,variable,default)
174# 174#
175define get-executable-or-default 175define get-executable-or-default
176$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2),$(1))) 176$(if $($(1)),$(call _ge_attempt,$($(1)),$(1)),$(call _ge_attempt,$(2)))
177endef 177endef
178_ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2))) 178_ge_attempt = $(if $(get-executable),$(get-executable),$(_gea_warn)$(call _gea_err,$(2)))
179_gea_warn = $(warning The path '$(1)' is not executable.) 179_gea_warn = $(warning The path '$(1)' is not executable.)
@@ -181,7 +181,7 @@ _gea_err = $(if $(1),$(error Please set '$(1)' appropriately))
181 181
182# try-cc 182# try-cc
183# Usage: option = $(call try-cc, source-to-build, cc-options, msg) 183# Usage: option = $(call try-cc, source-to-build, cc-options, msg)
184ifndef V 184ifneq ($(V),1)
185TRY_CC_OUTPUT= > /dev/null 2>&1 185TRY_CC_OUTPUT= > /dev/null 2>&1
186endif 186endif
187TRY_CC_MSG=echo " CHK $(3)" 1>&2; 187TRY_CC_MSG=echo " CHK $(3)" 1>&2;
diff --git a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
index c1e2ed1ed34e..8c7ea42444d1 100644
--- a/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
+++ b/tools/perf/scripts/perl/Perf-Trace-Util/Context.xs
@@ -23,7 +23,7 @@
23#include "perl.h" 23#include "perl.h"
24#include "XSUB.h" 24#include "XSUB.h"
25#include "../../../perf.h" 25#include "../../../perf.h"
26#include "../../../util/script-event.h" 26#include "../../../util/trace-event.h"
27 27
28MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context 28MODULE = Perf::Trace::Context PACKAGE = Perf::Trace::Context
29PROTOTYPES: ENABLE 29PROTOTYPES: ENABLE
diff --git a/tools/perf/tests/attr/base-record b/tools/perf/tests/attr/base-record
index b4fc835de607..e9bd6391f2ae 100644
--- a/tools/perf/tests/attr/base-record
+++ b/tools/perf/tests/attr/base-record
@@ -27,8 +27,8 @@ watermark=0
27precise_ip=0 27precise_ip=0
28mmap_data=0 28mmap_data=0
29sample_id_all=1 29sample_id_all=1
30exclude_host=0 30exclude_host=0|1
31exclude_guest=1 31exclude_guest=0|1
32exclude_callchain_kernel=0 32exclude_callchain_kernel=0
33exclude_callchain_user=0 33exclude_callchain_user=0
34wakeup_events=0 34wakeup_events=0
diff --git a/tools/perf/tests/attr/base-stat b/tools/perf/tests/attr/base-stat
index 748ee949a204..91cd48b399f3 100644
--- a/tools/perf/tests/attr/base-stat
+++ b/tools/perf/tests/attr/base-stat
@@ -27,8 +27,8 @@ watermark=0
27precise_ip=0 27precise_ip=0
28mmap_data=0 28mmap_data=0
29sample_id_all=0 29sample_id_all=0
30exclude_host=0 30exclude_host=0|1
31exclude_guest=1 31exclude_guest=0|1
32exclude_callchain_kernel=0 32exclude_callchain_kernel=0
33exclude_callchain_user=0 33exclude_callchain_user=0
34wakeup_events=0 34wakeup_events=0
diff --git a/tools/perf/tests/attr/test-record-data b/tools/perf/tests/attr/test-record-data
index 6627c3e7534a..716e143b5291 100644
--- a/tools/perf/tests/attr/test-record-data
+++ b/tools/perf/tests/attr/test-record-data
@@ -4,5 +4,8 @@ args = -d kill >/dev/null 2>&1
4 4
5[event:base-record] 5[event:base-record]
6sample_period=4000 6sample_period=4000
7sample_type=271 7
8# sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_TIME |
9# PERF_SAMPLE_ADDR | PERF_SAMPLE_PERIOD | PERF_SAMPLE_DATA_SRC
10sample_type=33039
8mmap_data=1 11mmap_data=1
diff --git a/tools/perf/tests/bp_signal.c b/tools/perf/tests/bp_signal.c
index 68daa289e94c..aba095489193 100644
--- a/tools/perf/tests/bp_signal.c
+++ b/tools/perf/tests/bp_signal.c
@@ -4,6 +4,12 @@
4 * (git://github.com/deater/perf_event_tests) 4 * (git://github.com/deater/perf_event_tests)
5 */ 5 */
6 6
7/*
8 * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
9 * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
10 */
11#define __SANE_USERSPACE_TYPES__
12
7#include <stdlib.h> 13#include <stdlib.h>
8#include <stdio.h> 14#include <stdio.h>
9#include <unistd.h> 15#include <unistd.h>
diff --git a/tools/perf/tests/bp_signal_overflow.c b/tools/perf/tests/bp_signal_overflow.c
index fe7ed28815f8..44ac82179708 100644
--- a/tools/perf/tests/bp_signal_overflow.c
+++ b/tools/perf/tests/bp_signal_overflow.c
@@ -3,6 +3,12 @@
3 * perf_event_tests (git://github.com/deater/perf_event_tests) 3 * perf_event_tests (git://github.com/deater/perf_event_tests)
4 */ 4 */
5 5
6/*
7 * Powerpc needs __SANE_USERSPACE_TYPES__ before <linux/types.h> to select
8 * 'int-ll64.h' and avoid compile warnings when printing __u64 with %llu.
9 */
10#define __SANE_USERSPACE_TYPES__
11
6#include <stdlib.h> 12#include <stdlib.h>
7#include <stdio.h> 13#include <stdio.h>
8#include <unistd.h> 14#include <unistd.h>
diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 0918ada4cc41..35b45f1466b5 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -70,7 +70,7 @@ static struct test {
70 .func = test__attr, 70 .func = test__attr,
71 }, 71 },
72 { 72 {
73 .desc = "Test matching and linking mutliple hists", 73 .desc = "Test matching and linking multiple hists",
74 .func = test__hists_link, 74 .func = test__hists_link,
75 }, 75 },
76 { 76 {
diff --git a/tools/perf/tests/make b/tools/perf/tests/make
new file mode 100644
index 000000000000..c441a2875128
--- /dev/null
+++ b/tools/perf/tests/make
@@ -0,0 +1,138 @@
1PERF := .
2MK := Makefile
3
4# standard single make variable specified
5make_clean_all := clean all
6make_python_perf_so := python/perf.so
7make_debug := DEBUG=1
8make_no_libperl := NO_LIBPERL=1
9make_no_libpython := NO_LIBPYTHON=1
10make_no_scripts := NO_LIBPYTHON=1 NO_LIBPERL=1
11make_no_newt := NO_NEWT=1
12make_no_slang := NO_SLANG=1
13make_no_gtk2 := NO_GTK2=1
14make_no_ui := NO_NEWT=1 NO_SLANG=1 NO_GTK2=1
15make_no_demangle := NO_DEMANGLE=1
16make_no_libelf := NO_LIBELF=1
17make_no_libunwind := NO_LIBUNWIND=1
18make_no_backtrace := NO_BACKTRACE=1
19make_no_libnuma := NO_LIBNUMA=1
20make_no_libaudit := NO_LIBAUDIT=1
21make_no_libbionic := NO_LIBBIONIC=1
22make_tags := tags
23make_cscope := cscope
24make_help := help
25make_doc := doc
26make_perf_o := perf.o
27make_util_map_o := util/map.o
28
29# all the NO_* variable combined
30make_minimal := NO_LIBPERL=1 NO_LIBPYTHON=1 NO_NEWT=1 NO_GTK2=1
31make_minimal += NO_DEMANGLE=1 NO_LIBELF=1 NO_LIBUNWIND=1 NO_BACKTRACE=1
32make_minimal += NO_LIBNUMA=1 NO_LIBAUDIT=1 NO_LIBBIONIC=1
33
34# $(run) contains all available tests
35run := make_pure
36run += make_clean_all
37run += make_python_perf_so
38run += make_debug
39run += make_no_libperl
40run += make_no_libpython
41run += make_no_scripts
42run += make_no_newt
43run += make_no_slang
44run += make_no_gtk2
45run += make_no_ui
46run += make_no_demangle
47run += make_no_libelf
48run += make_no_libunwind
49run += make_no_backtrace
50run += make_no_libnuma
51run += make_no_libaudit
52run += make_no_libbionic
53run += make_tags
54run += make_cscope
55run += make_help
56run += make_doc
57run += make_perf_o
58run += make_util_map_o
59run += make_minimal
60
61# $(run_O) contains same portion of $(run) tests with '_O' attached
62# to distinguish O=... tests
63run_O := $(addsuffix _O,$(run))
64
65# disable some tests for O=...
66run_O := $(filter-out make_python_perf_so_O,$(run_O))
67
68# define test for each compile as 'test_NAME' variable
69# with the test itself as a value
70test_make_tags = test -f tags
71test_make_cscope = test -f cscope.out
72
73test_make_tags_O := $(test_make_tags)
74test_make_cscope_O := $(test_make_cscope)
75
76test_ok := true
77test_make_help := $(test_ok)
78test_make_doc := $(test_ok)
79test_make_help_O := $(test_ok)
80test_make_doc_O := $(test_ok)
81
82test_make_python_perf_so := test -f $(PERF)/python/perf.so
83
84test_make_perf_o := test -f $(PERF)/perf.o
85test_make_util_map_o := test -f $(PERF)/util/map.o
86
87# Kbuild tests only
88#test_make_python_perf_so_O := test -f $$TMP/tools/perf/python/perf.so
89#test_make_perf_o_O := test -f $$TMP/tools/perf/perf.o
90#test_make_util_map_o_O := test -f $$TMP/tools/perf/util/map.o
91
92test_make_perf_o_O := true
93test_make_util_map_o_O := true
94
95test_default = test -x $(PERF)/perf
96test = $(if $(test_$1),$(test_$1),$(test_default))
97
98test_default_O = test -x $$TMP/perf
99test_O = $(if $(test_$1),$(test_$1),$(test_default_O))
100
101all:
102
103ifdef DEBUG
104d := $(info run $(run))
105d := $(info run_O $(run_O))
106endif
107
108MAKEFLAGS := --no-print-directory
109
110clean := @(cd $(PERF); make -s -f $(MK) clean >/dev/null)
111
112$(run):
113 $(call clean)
114 @cmd="cd $(PERF) && make -f $(MK) $($@)"; \
115 echo "- $@: $$cmd" && echo $$cmd > $@ && \
116 ( eval $$cmd ) >> $@ 2>&1; \
117 echo " test: $(call test,$@)"; \
118 $(call test,$@) && \
119 rm -f $@
120
121$(run_O):
122 $(call clean)
123 @TMP=$$(mktemp -d); \
124 cmd="cd $(PERF) && make -f $(MK) $($(patsubst %_O,%,$@)) O=$$TMP"; \
125 echo "- $@: $$cmd" && echo $$cmd > $@ && \
126 ( eval $$cmd ) >> $@ 2>&1 && \
127 echo " test: $(call test_O,$@)"; \
128 $(call test_O,$@) && \
129 rm -f $@ && \
130 rm -rf $$TMP
131
132all: $(run) $(run_O)
133 @echo OK
134
135out: $(run_O)
136 @echo OK
137
138.PHONY: all $(run) $(run_O) clean
diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index d88a2d0acb6d..fc0bd3843d34 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -25,7 +25,8 @@ struct hist_browser {
25 struct map_symbol *selection; 25 struct map_symbol *selection;
26 int print_seq; 26 int print_seq;
27 bool show_dso; 27 bool show_dso;
28 bool has_symbols; 28 float min_pcnt;
29 u64 nr_pcnt_entries;
29}; 30};
30 31
31extern void hist_browser__init_hpp(void); 32extern void hist_browser__init_hpp(void);
@@ -309,6 +310,8 @@ static void ui_browser__warn_lost_events(struct ui_browser *browser)
309 "Or reduce the sampling frequency."); 310 "Or reduce the sampling frequency.");
310} 311}
311 312
313static void hist_browser__update_pcnt_entries(struct hist_browser *hb);
314
312static int hist_browser__run(struct hist_browser *browser, const char *ev_name, 315static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
313 struct hist_browser_timer *hbt) 316 struct hist_browser_timer *hbt)
314{ 317{
@@ -318,6 +321,8 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
318 321
319 browser->b.entries = &browser->hists->entries; 322 browser->b.entries = &browser->hists->entries;
320 browser->b.nr_entries = browser->hists->nr_entries; 323 browser->b.nr_entries = browser->hists->nr_entries;
324 if (browser->min_pcnt)
325 browser->b.nr_entries = browser->nr_pcnt_entries;
321 326
322 hist_browser__refresh_dimensions(browser); 327 hist_browser__refresh_dimensions(browser);
323 hists__browser_title(browser->hists, title, sizeof(title), ev_name); 328 hists__browser_title(browser->hists, title, sizeof(title), ev_name);
@@ -330,9 +335,18 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
330 key = ui_browser__run(&browser->b, delay_secs); 335 key = ui_browser__run(&browser->b, delay_secs);
331 336
332 switch (key) { 337 switch (key) {
333 case K_TIMER: 338 case K_TIMER: {
339 u64 nr_entries;
334 hbt->timer(hbt->arg); 340 hbt->timer(hbt->arg);
335 ui_browser__update_nr_entries(&browser->b, browser->hists->nr_entries); 341
342 if (browser->min_pcnt) {
343 hist_browser__update_pcnt_entries(browser);
344 nr_entries = browser->nr_pcnt_entries;
345 } else {
346 nr_entries = browser->hists->nr_entries;
347 }
348
349 ui_browser__update_nr_entries(&browser->b, nr_entries);
336 350
337 if (browser->hists->stats.nr_lost_warned != 351 if (browser->hists->stats.nr_lost_warned !=
338 browser->hists->stats.nr_events[PERF_RECORD_LOST]) { 352 browser->hists->stats.nr_events[PERF_RECORD_LOST]) {
@@ -344,6 +358,7 @@ static int hist_browser__run(struct hist_browser *browser, const char *ev_name,
344 hists__browser_title(browser->hists, title, sizeof(title), ev_name); 358 hists__browser_title(browser->hists, title, sizeof(title), ev_name);
345 ui_browser__show_title(&browser->b, title); 359 ui_browser__show_title(&browser->b, title);
346 continue; 360 continue;
361 }
347 case 'D': { /* Debug */ 362 case 'D': { /* Debug */
348 static int seq; 363 static int seq;
349 struct hist_entry *h = rb_entry(browser->b.top, 364 struct hist_entry *h = rb_entry(browser->b.top,
@@ -796,10 +811,15 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
796 811
797 for (nd = browser->top; nd; nd = rb_next(nd)) { 812 for (nd = browser->top; nd; nd = rb_next(nd)) {
798 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 813 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
814 float percent = h->stat.period * 100.0 /
815 hb->hists->stats.total_period;
799 816
800 if (h->filtered) 817 if (h->filtered)
801 continue; 818 continue;
802 819
820 if (percent < hb->min_pcnt)
821 continue;
822
803 row += hist_browser__show_entry(hb, h, row); 823 row += hist_browser__show_entry(hb, h, row);
804 if (row == browser->height) 824 if (row == browser->height)
805 break; 825 break;
@@ -808,10 +828,18 @@ static unsigned int hist_browser__refresh(struct ui_browser *browser)
808 return row; 828 return row;
809} 829}
810 830
811static struct rb_node *hists__filter_entries(struct rb_node *nd) 831static struct rb_node *hists__filter_entries(struct rb_node *nd,
832 struct hists *hists,
833 float min_pcnt)
812{ 834{
813 while (nd != NULL) { 835 while (nd != NULL) {
814 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 836 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
837 float percent = h->stat.period * 100.0 /
838 hists->stats.total_period;
839
840 if (percent < min_pcnt)
841 return NULL;
842
815 if (!h->filtered) 843 if (!h->filtered)
816 return nd; 844 return nd;
817 845
@@ -821,11 +849,16 @@ static struct rb_node *hists__filter_entries(struct rb_node *nd)
821 return NULL; 849 return NULL;
822} 850}
823 851
824static struct rb_node *hists__filter_prev_entries(struct rb_node *nd) 852static struct rb_node *hists__filter_prev_entries(struct rb_node *nd,
853 struct hists *hists,
854 float min_pcnt)
825{ 855{
826 while (nd != NULL) { 856 while (nd != NULL) {
827 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 857 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
828 if (!h->filtered) 858 float percent = h->stat.period * 100.0 /
859 hists->stats.total_period;
860
861 if (!h->filtered && percent >= min_pcnt)
829 return nd; 862 return nd;
830 863
831 nd = rb_prev(nd); 864 nd = rb_prev(nd);
@@ -840,6 +873,9 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
840 struct hist_entry *h; 873 struct hist_entry *h;
841 struct rb_node *nd; 874 struct rb_node *nd;
842 bool first = true; 875 bool first = true;
876 struct hist_browser *hb;
877
878 hb = container_of(browser, struct hist_browser, b);
843 879
844 if (browser->nr_entries == 0) 880 if (browser->nr_entries == 0)
845 return; 881 return;
@@ -848,13 +884,15 @@ static void ui_browser__hists_seek(struct ui_browser *browser,
848 884
849 switch (whence) { 885 switch (whence) {
850 case SEEK_SET: 886 case SEEK_SET:
851 nd = hists__filter_entries(rb_first(browser->entries)); 887 nd = hists__filter_entries(rb_first(browser->entries),
888 hb->hists, hb->min_pcnt);
852 break; 889 break;
853 case SEEK_CUR: 890 case SEEK_CUR:
854 nd = browser->top; 891 nd = browser->top;
855 goto do_offset; 892 goto do_offset;
856 case SEEK_END: 893 case SEEK_END:
857 nd = hists__filter_prev_entries(rb_last(browser->entries)); 894 nd = hists__filter_prev_entries(rb_last(browser->entries),
895 hb->hists, hb->min_pcnt);
858 first = false; 896 first = false;
859 break; 897 break;
860 default: 898 default:
@@ -897,7 +935,8 @@ do_offset:
897 break; 935 break;
898 } 936 }
899 } 937 }
900 nd = hists__filter_entries(rb_next(nd)); 938 nd = hists__filter_entries(rb_next(nd), hb->hists,
939 hb->min_pcnt);
901 if (nd == NULL) 940 if (nd == NULL)
902 break; 941 break;
903 --offset; 942 --offset;
@@ -930,7 +969,8 @@ do_offset:
930 } 969 }
931 } 970 }
932 971
933 nd = hists__filter_prev_entries(rb_prev(nd)); 972 nd = hists__filter_prev_entries(rb_prev(nd), hb->hists,
973 hb->min_pcnt);
934 if (nd == NULL) 974 if (nd == NULL)
935 break; 975 break;
936 ++offset; 976 ++offset;
@@ -1099,14 +1139,17 @@ static int hist_browser__fprintf_entry(struct hist_browser *browser,
1099 1139
1100static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp) 1140static int hist_browser__fprintf(struct hist_browser *browser, FILE *fp)
1101{ 1141{
1102 struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries)); 1142 struct rb_node *nd = hists__filter_entries(rb_first(browser->b.entries),
1143 browser->hists,
1144 browser->min_pcnt);
1103 int printed = 0; 1145 int printed = 0;
1104 1146
1105 while (nd) { 1147 while (nd) {
1106 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 1148 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
1107 1149
1108 printed += hist_browser__fprintf_entry(browser, h, fp); 1150 printed += hist_browser__fprintf_entry(browser, h, fp);
1109 nd = hists__filter_entries(rb_next(nd)); 1151 nd = hists__filter_entries(rb_next(nd), browser->hists,
1152 browser->min_pcnt);
1110 } 1153 }
1111 1154
1112 return printed; 1155 return printed;
@@ -1155,10 +1198,6 @@ static struct hist_browser *hist_browser__new(struct hists *hists)
1155 browser->b.refresh = hist_browser__refresh; 1198 browser->b.refresh = hist_browser__refresh;
1156 browser->b.seek = ui_browser__hists_seek; 1199 browser->b.seek = ui_browser__hists_seek;
1157 browser->b.use_navkeypressed = true; 1200 browser->b.use_navkeypressed = true;
1158 if (sort__branch_mode == 1)
1159 browser->has_symbols = sort_sym_from.list.next != NULL;
1160 else
1161 browser->has_symbols = sort_sym.list.next != NULL;
1162 } 1201 }
1163 1202
1164 return browser; 1203 return browser;
@@ -1329,11 +1368,25 @@ close_file_and_continue:
1329 return ret; 1368 return ret;
1330} 1369}
1331 1370
1371static void hist_browser__update_pcnt_entries(struct hist_browser *hb)
1372{
1373 u64 nr_entries = 0;
1374 struct rb_node *nd = rb_first(&hb->hists->entries);
1375
1376 while (nd) {
1377 nr_entries++;
1378 nd = hists__filter_entries(rb_next(nd), hb->hists,
1379 hb->min_pcnt);
1380 }
1381
1382 hb->nr_pcnt_entries = nr_entries;
1383}
1332 1384
1333static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events, 1385static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1334 const char *helpline, const char *ev_name, 1386 const char *helpline, const char *ev_name,
1335 bool left_exits, 1387 bool left_exits,
1336 struct hist_browser_timer *hbt, 1388 struct hist_browser_timer *hbt,
1389 float min_pcnt,
1337 struct perf_session_env *env) 1390 struct perf_session_env *env)
1338{ 1391{
1339 struct hists *hists = &evsel->hists; 1392 struct hists *hists = &evsel->hists;
@@ -1350,6 +1403,11 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1350 if (browser == NULL) 1403 if (browser == NULL)
1351 return -1; 1404 return -1;
1352 1405
1406 if (min_pcnt) {
1407 browser->min_pcnt = min_pcnt;
1408 hist_browser__update_pcnt_entries(browser);
1409 }
1410
1353 fstack = pstack__new(2); 1411 fstack = pstack__new(2);
1354 if (fstack == NULL) 1412 if (fstack == NULL)
1355 goto out; 1413 goto out;
@@ -1386,7 +1444,7 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1386 */ 1444 */
1387 goto out_free_stack; 1445 goto out_free_stack;
1388 case 'a': 1446 case 'a':
1389 if (!browser->has_symbols) { 1447 if (!sort__has_sym) {
1390 ui_browser__warning(&browser->b, delay_secs * 2, 1448 ui_browser__warning(&browser->b, delay_secs * 2,
1391 "Annotation is only available for symbolic views, " 1449 "Annotation is only available for symbolic views, "
1392 "include \"sym*\" in --sort to use it."); 1450 "include \"sym*\" in --sort to use it.");
@@ -1485,10 +1543,10 @@ static int perf_evsel__hists_browse(struct perf_evsel *evsel, int nr_events,
1485 continue; 1543 continue;
1486 } 1544 }
1487 1545
1488 if (!browser->has_symbols) 1546 if (!sort__has_sym)
1489 goto add_exit_option; 1547 goto add_exit_option;
1490 1548
1491 if (sort__branch_mode == 1) { 1549 if (sort__mode == SORT_MODE__BRANCH) {
1492 bi = browser->he_selection->branch_info; 1550 bi = browser->he_selection->branch_info;
1493 if (browser->selection != NULL && 1551 if (browser->selection != NULL &&
1494 bi && 1552 bi &&
@@ -1689,6 +1747,7 @@ struct perf_evsel_menu {
1689 struct ui_browser b; 1747 struct ui_browser b;
1690 struct perf_evsel *selection; 1748 struct perf_evsel *selection;
1691 bool lost_events, lost_events_warned; 1749 bool lost_events, lost_events_warned;
1750 float min_pcnt;
1692 struct perf_session_env *env; 1751 struct perf_session_env *env;
1693}; 1752};
1694 1753
@@ -1782,6 +1841,7 @@ browse_hists:
1782 ev_name = perf_evsel__name(pos); 1841 ev_name = perf_evsel__name(pos);
1783 key = perf_evsel__hists_browse(pos, nr_events, help, 1842 key = perf_evsel__hists_browse(pos, nr_events, help,
1784 ev_name, true, hbt, 1843 ev_name, true, hbt,
1844 menu->min_pcnt,
1785 menu->env); 1845 menu->env);
1786 ui_browser__show_title(&menu->b, title); 1846 ui_browser__show_title(&menu->b, title);
1787 switch (key) { 1847 switch (key) {
@@ -1843,6 +1903,7 @@ static bool filter_group_entries(struct ui_browser *self __maybe_unused,
1843static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist, 1903static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1844 int nr_entries, const char *help, 1904 int nr_entries, const char *help,
1845 struct hist_browser_timer *hbt, 1905 struct hist_browser_timer *hbt,
1906 float min_pcnt,
1846 struct perf_session_env *env) 1907 struct perf_session_env *env)
1847{ 1908{
1848 struct perf_evsel *pos; 1909 struct perf_evsel *pos;
@@ -1856,6 +1917,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1856 .nr_entries = nr_entries, 1917 .nr_entries = nr_entries,
1857 .priv = evlist, 1918 .priv = evlist,
1858 }, 1919 },
1920 .min_pcnt = min_pcnt,
1859 .env = env, 1921 .env = env,
1860 }; 1922 };
1861 1923
@@ -1874,6 +1936,7 @@ static int __perf_evlist__tui_browse_hists(struct perf_evlist *evlist,
1874 1936
1875int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, 1937int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
1876 struct hist_browser_timer *hbt, 1938 struct hist_browser_timer *hbt,
1939 float min_pcnt,
1877 struct perf_session_env *env) 1940 struct perf_session_env *env)
1878{ 1941{
1879 int nr_entries = evlist->nr_entries; 1942 int nr_entries = evlist->nr_entries;
@@ -1885,7 +1948,8 @@ single_entry:
1885 const char *ev_name = perf_evsel__name(first); 1948 const char *ev_name = perf_evsel__name(first);
1886 1949
1887 return perf_evsel__hists_browse(first, nr_entries, help, 1950 return perf_evsel__hists_browse(first, nr_entries, help,
1888 ev_name, false, hbt, env); 1951 ev_name, false, hbt, min_pcnt,
1952 env);
1889 } 1953 }
1890 1954
1891 if (symbol_conf.event_group) { 1955 if (symbol_conf.event_group) {
@@ -1901,5 +1965,5 @@ single_entry:
1901 } 1965 }
1902 1966
1903 return __perf_evlist__tui_browse_hists(evlist, nr_entries, help, 1967 return __perf_evlist__tui_browse_hists(evlist, nr_entries, help,
1904 hbt, env); 1968 hbt, min_pcnt, env);
1905} 1969}
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 6f259b3d14e2..9708dd5fb8f3 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -124,7 +124,8 @@ void perf_gtk__init_hpp(void)
124 perf_gtk__hpp_color_overhead_guest_us; 124 perf_gtk__hpp_color_overhead_guest_us;
125} 125}
126 126
127static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists) 127static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists,
128 float min_pcnt)
128{ 129{
129 struct perf_hpp_fmt *fmt; 130 struct perf_hpp_fmt *fmt;
130 GType col_types[MAX_COLUMNS]; 131 GType col_types[MAX_COLUMNS];
@@ -189,10 +190,15 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
189 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { 190 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
190 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 191 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
191 GtkTreeIter iter; 192 GtkTreeIter iter;
193 float percent = h->stat.period * 100.0 /
194 hists->stats.total_period;
192 195
193 if (h->filtered) 196 if (h->filtered)
194 continue; 197 continue;
195 198
199 if (percent < min_pcnt)
200 continue;
201
196 gtk_list_store_append(store, &iter); 202 gtk_list_store_append(store, &iter);
197 203
198 col_idx = 0; 204 col_idx = 0;
@@ -222,7 +228,8 @@ static void perf_gtk__show_hists(GtkWidget *window, struct hists *hists)
222 228
223int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, 229int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
224 const char *help, 230 const char *help,
225 struct hist_browser_timer *hbt __maybe_unused) 231 struct hist_browser_timer *hbt __maybe_unused,
232 float min_pcnt)
226{ 233{
227 struct perf_evsel *pos; 234 struct perf_evsel *pos;
228 GtkWidget *vbox; 235 GtkWidget *vbox;
@@ -286,7 +293,7 @@ int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist,
286 GTK_POLICY_AUTOMATIC, 293 GTK_POLICY_AUTOMATIC,
287 GTK_POLICY_AUTOMATIC); 294 GTK_POLICY_AUTOMATIC);
288 295
289 perf_gtk__show_hists(scrolled_window, hists); 296 perf_gtk__show_hists(scrolled_window, hists, min_pcnt);
290 297
291 tab_label = gtk_label_new(evname); 298 tab_label = gtk_label_new(evname);
292 299
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index ff1f60cf442e..ae7a75432249 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -334,7 +334,7 @@ static int hist_entry__fprintf(struct hist_entry *he, size_t size,
334} 334}
335 335
336size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows, 336size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
337 int max_cols, FILE *fp) 337 int max_cols, float min_pcnt, FILE *fp)
338{ 338{
339 struct perf_hpp_fmt *fmt; 339 struct perf_hpp_fmt *fmt;
340 struct sort_entry *se; 340 struct sort_entry *se;
@@ -440,10 +440,15 @@ size_t hists__fprintf(struct hists *hists, bool show_header, int max_rows,
440print_entries: 440print_entries:
441 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) { 441 for (nd = rb_first(&hists->entries); nd; nd = rb_next(nd)) {
442 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node); 442 struct hist_entry *h = rb_entry(nd, struct hist_entry, rb_node);
443 float percent = h->stat.period * 100.0 /
444 hists->stats.total_period;
443 445
444 if (h->filtered) 446 if (h->filtered)
445 continue; 447 continue;
446 448
449 if (percent < min_pcnt)
450 continue;
451
447 ret += hist_entry__fprintf(h, max_cols, hists, fp); 452 ret += hist_entry__fprintf(h, max_cols, hists, fp);
448 453
449 if (max_rows && ++nr_rows >= max_rows) 454 if (max_rows && ++nr_rows >= max_rows)
diff --git a/tools/perf/util/PERF-VERSION-GEN b/tools/perf/util/PERF-VERSION-GEN
index 055fef34b6f6..15a77b7c0e36 100755
--- a/tools/perf/util/PERF-VERSION-GEN
+++ b/tools/perf/util/PERF-VERSION-GEN
@@ -13,13 +13,22 @@ LF='
13# First check if there is a .git to get the version from git describe 13# First check if there is a .git to get the version from git describe
14# otherwise try to get the version from the kernel Makefile 14# otherwise try to get the version from the kernel Makefile
15# 15#
16if test -d ../../.git -o -f ../../.git && 16CID=
17 VN=$(git tag 2>/dev/null | tail -1 | grep -E "v[0-9].[0-9]*") 17TAG=
18if test -d ../../.git -o -f ../../.git
18then 19then
19 VN=$(echo $VN"-g"$(git log -1 --abbrev=4 --pretty=format:"%h" HEAD)) 20 TAG=$(git describe --abbrev=0 --match "v[0-9].[0-9]*" 2>/dev/null )
20 VN=$(echo "$VN" | sed -e 's/-/./g'); 21 CID=$(git log -1 --abbrev=4 --pretty=format:"%h" 2>/dev/null) && CID="-g$CID"
21else 22fi
22 VN=$(MAKEFLAGS= make -sC ../.. kernelversion) 23if test -z "$TAG"
24then
25 TAG=$(MAKEFLAGS= make -sC ../.. kernelversion)
26fi
27VN="$TAG$CID"
28if test -n "$CID"
29then
30 # format version string, strip trailing zero of sublevel:
31 VN=$(echo "$VN" | sed -e 's/-/./g;s/\([0-9]*[.][0-9]*\)[.]0/\1/')
23fi 32fi
24 33
25VN=$(expr "$VN" : v*'\(.*\)') 34VN=$(expr "$VN" : v*'\(.*\)')
diff --git a/tools/perf/util/dso.c b/tools/perf/util/dso.c
index 6f7d5a9d6b05..c4374f07603c 100644
--- a/tools/perf/util/dso.c
+++ b/tools/perf/util/dso.c
@@ -513,10 +513,16 @@ void dsos__add(struct list_head *head, struct dso *dso)
513 list_add_tail(&dso->node, head); 513 list_add_tail(&dso->node, head);
514} 514}
515 515
516struct dso *dsos__find(struct list_head *head, const char *name) 516struct dso *dsos__find(struct list_head *head, const char *name, bool cmp_short)
517{ 517{
518 struct dso *pos; 518 struct dso *pos;
519 519
520 if (cmp_short) {
521 list_for_each_entry(pos, head, node)
522 if (strcmp(pos->short_name, name) == 0)
523 return pos;
524 return NULL;
525 }
520 list_for_each_entry(pos, head, node) 526 list_for_each_entry(pos, head, node)
521 if (strcmp(pos->long_name, name) == 0) 527 if (strcmp(pos->long_name, name) == 0)
522 return pos; 528 return pos;
@@ -525,7 +531,7 @@ struct dso *dsos__find(struct list_head *head, const char *name)
525 531
526struct dso *__dsos__findnew(struct list_head *head, const char *name) 532struct dso *__dsos__findnew(struct list_head *head, const char *name)
527{ 533{
528 struct dso *dso = dsos__find(head, name); 534 struct dso *dso = dsos__find(head, name, false);
529 535
530 if (!dso) { 536 if (!dso) {
531 dso = dso__new(name); 537 dso = dso__new(name);
diff --git a/tools/perf/util/dso.h b/tools/perf/util/dso.h
index 450199ab51b5..d51aaf272c68 100644
--- a/tools/perf/util/dso.h
+++ b/tools/perf/util/dso.h
@@ -133,7 +133,8 @@ struct dso *dso__kernel_findnew(struct machine *machine, const char *name,
133 const char *short_name, int dso_type); 133 const char *short_name, int dso_type);
134 134
135void dsos__add(struct list_head *head, struct dso *dso); 135void dsos__add(struct list_head *head, struct dso *dso);
136struct dso *dsos__find(struct list_head *head, const char *name); 136struct dso *dsos__find(struct list_head *head, const char *name,
137 bool cmp_short);
137struct dso *__dsos__findnew(struct list_head *head, const char *name); 138struct dso *__dsos__findnew(struct list_head *head, const char *name);
138bool __dsos__read_build_ids(struct list_head *head, bool with_hits); 139bool __dsos__read_build_ids(struct list_head *head, bool with_hits);
139 140
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c
index f7c727801aab..8065ce8fa9a5 100644
--- a/tools/perf/util/evlist.c
+++ b/tools/perf/util/evlist.c
@@ -776,6 +776,8 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
776 if (pipe_output) 776 if (pipe_output)
777 dup2(2, 1); 777 dup2(2, 1);
778 778
779 signal(SIGTERM, SIG_DFL);
780
779 close(child_ready_pipe[0]); 781 close(child_ready_pipe[0]);
780 close(go_pipe[1]); 782 close(go_pipe[1]);
781 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 783 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
@@ -819,6 +821,7 @@ int perf_evlist__prepare_workload(struct perf_evlist *evlist,
819 goto out_close_pipes; 821 goto out_close_pipes;
820 } 822 }
821 823
824 fcntl(go_pipe[1], F_SETFD, FD_CLOEXEC);
822 evlist->workload.cork_fd = go_pipe[1]; 825 evlist->workload.cork_fd = go_pipe[1];
823 close(child_ready_pipe[0]); 826 close(child_ready_pipe[0]);
824 return 0; 827 return 0;
@@ -835,10 +838,17 @@ out_close_ready_pipe:
835int perf_evlist__start_workload(struct perf_evlist *evlist) 838int perf_evlist__start_workload(struct perf_evlist *evlist)
836{ 839{
837 if (evlist->workload.cork_fd > 0) { 840 if (evlist->workload.cork_fd > 0) {
841 char bf;
842 int ret;
838 /* 843 /*
839 * Remove the cork, let it rip! 844 * Remove the cork, let it rip!
840 */ 845 */
841 return close(evlist->workload.cork_fd); 846 ret = write(evlist->workload.cork_fd, &bf, 1);
847 if (ret < 0)
848 perror("enable to write to pipe");
849
850 close(evlist->workload.cork_fd);
851 return ret;
842 } 852 }
843 853
844 return 0; 854 return 0;
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c
index 07b1a3ad3e24..c9c7494506a1 100644
--- a/tools/perf/util/evsel.c
+++ b/tools/perf/util/evsel.c
@@ -124,7 +124,7 @@ struct event_format *event_format__new(const char *sys, const char *name)
124 bf = nbf; 124 bf = nbf;
125 } 125 }
126 126
127 n = read(fd, bf + size, BUFSIZ); 127 n = read(fd, bf + size, alloc_size - size);
128 if (n < 0) 128 if (n < 0)
129 goto out_free_bf; 129 goto out_free_bf;
130 size += n; 130 size += n;
@@ -1170,7 +1170,7 @@ int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event,
1170 } else { 1170 } else {
1171 data->user_stack.data = (char *)array; 1171 data->user_stack.data = (char *)array;
1172 array += size / sizeof(*array); 1172 array += size / sizeof(*array);
1173 data->user_stack.size = *array; 1173 data->user_stack.size = *array++;
1174 } 1174 }
1175 } 1175 }
1176 1176
@@ -1514,7 +1514,7 @@ int perf_evsel__open_strerror(struct perf_evsel *evsel,
1514 switch (err) { 1514 switch (err) {
1515 case EPERM: 1515 case EPERM:
1516 case EACCES: 1516 case EACCES:
1517 return scnprintf(msg, size, "%s", 1517 return scnprintf(msg, size,
1518 "You may not have permission to collect %sstats.\n" 1518 "You may not have permission to collect %sstats.\n"
1519 "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n" 1519 "Consider tweaking /proc/sys/kernel/perf_event_paranoid:\n"
1520 " -1 - Not paranoid at all\n" 1520 " -1 - Not paranoid at all\n"
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c
index 326068a593a5..a4dafbee2511 100644
--- a/tools/perf/util/header.c
+++ b/tools/perf/util/header.c
@@ -2303,29 +2303,18 @@ int perf_session__write_header(struct perf_session *session,
2303 struct perf_file_header f_header; 2303 struct perf_file_header f_header;
2304 struct perf_file_attr f_attr; 2304 struct perf_file_attr f_attr;
2305 struct perf_header *header = &session->header; 2305 struct perf_header *header = &session->header;
2306 struct perf_evsel *evsel, *pair = NULL; 2306 struct perf_evsel *evsel;
2307 int err; 2307 int err;
2308 2308
2309 lseek(fd, sizeof(f_header), SEEK_SET); 2309 lseek(fd, sizeof(f_header), SEEK_SET);
2310 2310
2311 if (session->evlist != evlist)
2312 pair = perf_evlist__first(session->evlist);
2313
2314 list_for_each_entry(evsel, &evlist->entries, node) { 2311 list_for_each_entry(evsel, &evlist->entries, node) {
2315 evsel->id_offset = lseek(fd, 0, SEEK_CUR); 2312 evsel->id_offset = lseek(fd, 0, SEEK_CUR);
2316 err = do_write(fd, evsel->id, evsel->ids * sizeof(u64)); 2313 err = do_write(fd, evsel->id, evsel->ids * sizeof(u64));
2317 if (err < 0) { 2314 if (err < 0) {
2318out_err_write:
2319 pr_debug("failed to write perf header\n"); 2315 pr_debug("failed to write perf header\n");
2320 return err; 2316 return err;
2321 } 2317 }
2322 if (session->evlist != evlist) {
2323 err = do_write(fd, pair->id, pair->ids * sizeof(u64));
2324 if (err < 0)
2325 goto out_err_write;
2326 evsel->ids += pair->ids;
2327 pair = perf_evsel__next(pair);
2328 }
2329 } 2318 }
2330 2319
2331 header->attr_offset = lseek(fd, 0, SEEK_CUR); 2320 header->attr_offset = lseek(fd, 0, SEEK_CUR);
@@ -2391,7 +2380,6 @@ out_err_write:
2391 } 2380 }
2392 lseek(fd, header->data_offset + header->data_size, SEEK_SET); 2381 lseek(fd, header->data_offset + header->data_size, SEEK_SET);
2393 2382
2394 header->frozen = 1;
2395 return 0; 2383 return 0;
2396} 2384}
2397 2385
@@ -2871,7 +2859,6 @@ int perf_session__read_header(struct perf_session *session, int fd)
2871 session->pevent)) 2859 session->pevent))
2872 goto out_delete_evlist; 2860 goto out_delete_evlist;
2873 2861
2874 header->frozen = 1;
2875 return 0; 2862 return 0;
2876out_errno: 2863out_errno:
2877 return -errno; 2864 return -errno;
@@ -2969,6 +2956,8 @@ int perf_event__process_attr(union perf_event *event,
2969 perf_evlist__id_add(evlist, evsel, 0, i, event->attr.id[i]); 2956 perf_evlist__id_add(evlist, evsel, 0, i, event->attr.id[i]);
2970 } 2957 }
2971 2958
2959 symbol_conf.nr_events = evlist->nr_entries;
2960
2972 return 0; 2961 return 0;
2973} 2962}
2974 2963
diff --git a/tools/perf/util/header.h b/tools/perf/util/header.h
index c9fc55cada6d..16a3e83c584e 100644
--- a/tools/perf/util/header.h
+++ b/tools/perf/util/header.h
@@ -84,7 +84,6 @@ struct perf_session_env {
84}; 84};
85 85
86struct perf_header { 86struct perf_header {
87 int frozen;
88 bool needs_swap; 87 bool needs_swap;
89 s64 attr_offset; 88 s64 attr_offset;
90 u64 data_offset; 89 u64 data_offset;
diff --git a/tools/perf/util/hist.c b/tools/perf/util/hist.c
index 6b32721f829a..b11a6cfdb414 100644
--- a/tools/perf/util/hist.c
+++ b/tools/perf/util/hist.c
@@ -70,9 +70,17 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
70 int symlen; 70 int symlen;
71 u16 len; 71 u16 len;
72 72
73 if (h->ms.sym) 73 /*
74 hists__new_col_len(hists, HISTC_SYMBOL, h->ms.sym->namelen + 4); 74 * +4 accounts for '[x] ' priv level info
75 else { 75 * +2 accounts for 0x prefix on raw addresses
76 * +3 accounts for ' y ' symtab origin info
77 */
78 if (h->ms.sym) {
79 symlen = h->ms.sym->namelen + 4;
80 if (verbose)
81 symlen += BITS_PER_LONG / 4 + 2 + 3;
82 hists__new_col_len(hists, HISTC_SYMBOL, symlen);
83 } else {
76 symlen = unresolved_col_width + 4 + 2; 84 symlen = unresolved_col_width + 4 + 2;
77 hists__new_col_len(hists, HISTC_SYMBOL, symlen); 85 hists__new_col_len(hists, HISTC_SYMBOL, symlen);
78 hists__set_unres_dso_col_len(hists, HISTC_DSO); 86 hists__set_unres_dso_col_len(hists, HISTC_DSO);
@@ -91,12 +99,10 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
91 hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen); 99 hists__new_col_len(hists, HISTC_PARENT, h->parent->namelen);
92 100
93 if (h->branch_info) { 101 if (h->branch_info) {
94 /*
95 * +4 accounts for '[x] ' priv level info
96 * +2 account of 0x prefix on raw addresses
97 */
98 if (h->branch_info->from.sym) { 102 if (h->branch_info->from.sym) {
99 symlen = (int)h->branch_info->from.sym->namelen + 4; 103 symlen = (int)h->branch_info->from.sym->namelen + 4;
104 if (verbose)
105 symlen += BITS_PER_LONG / 4 + 2 + 3;
100 hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen); 106 hists__new_col_len(hists, HISTC_SYMBOL_FROM, symlen);
101 107
102 symlen = dso__name_len(h->branch_info->from.map->dso); 108 symlen = dso__name_len(h->branch_info->from.map->dso);
@@ -109,6 +115,8 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
109 115
110 if (h->branch_info->to.sym) { 116 if (h->branch_info->to.sym) {
111 symlen = (int)h->branch_info->to.sym->namelen + 4; 117 symlen = (int)h->branch_info->to.sym->namelen + 4;
118 if (verbose)
119 symlen += BITS_PER_LONG / 4 + 2 + 3;
112 hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen); 120 hists__new_col_len(hists, HISTC_SYMBOL_TO, symlen);
113 121
114 symlen = dso__name_len(h->branch_info->to.map->dso); 122 symlen = dso__name_len(h->branch_info->to.map->dso);
@@ -121,10 +129,6 @@ void hists__calc_col_len(struct hists *hists, struct hist_entry *h)
121 } 129 }
122 130
123 if (h->mem_info) { 131 if (h->mem_info) {
124 /*
125 * +4 accounts for '[x] ' priv level info
126 * +2 account of 0x prefix on raw addresses
127 */
128 if (h->mem_info->daddr.sym) { 132 if (h->mem_info->daddr.sym) {
129 symlen = (int)h->mem_info->daddr.sym->namelen + 4 133 symlen = (int)h->mem_info->daddr.sym->namelen + 4
130 + unresolved_col_width + 2; 134 + unresolved_col_width + 2;
@@ -236,8 +240,7 @@ static bool hists__decay_entry(struct hists *hists, struct hist_entry *he)
236 return he->stat.period == 0; 240 return he->stat.period == 0;
237} 241}
238 242
239static void __hists__decay_entries(struct hists *hists, bool zap_user, 243void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
240 bool zap_kernel, bool threaded)
241{ 244{
242 struct rb_node *next = rb_first(&hists->entries); 245 struct rb_node *next = rb_first(&hists->entries);
243 struct hist_entry *n; 246 struct hist_entry *n;
@@ -256,7 +259,7 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user,
256 !n->used) { 259 !n->used) {
257 rb_erase(&n->rb_node, &hists->entries); 260 rb_erase(&n->rb_node, &hists->entries);
258 261
259 if (sort__need_collapse || threaded) 262 if (sort__need_collapse)
260 rb_erase(&n->rb_node_in, &hists->entries_collapsed); 263 rb_erase(&n->rb_node_in, &hists->entries_collapsed);
261 264
262 hist_entry__free(n); 265 hist_entry__free(n);
@@ -265,17 +268,6 @@ static void __hists__decay_entries(struct hists *hists, bool zap_user,
265 } 268 }
266} 269}
267 270
268void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel)
269{
270 return __hists__decay_entries(hists, zap_user, zap_kernel, false);
271}
272
273void hists__decay_entries_threaded(struct hists *hists,
274 bool zap_user, bool zap_kernel)
275{
276 return __hists__decay_entries(hists, zap_user, zap_kernel, true);
277}
278
279/* 271/*
280 * histogram, sorted on item, collects periods 272 * histogram, sorted on item, collects periods
281 */ 273 */
@@ -292,6 +284,20 @@ static struct hist_entry *hist_entry__new(struct hist_entry *template)
292 he->ms.map->referenced = true; 284 he->ms.map->referenced = true;
293 285
294 if (he->branch_info) { 286 if (he->branch_info) {
287 /*
288 * This branch info is (a part of) allocated from
289 * machine__resolve_bstack() and will be freed after
290 * adding new entries. So we need to save a copy.
291 */
292 he->branch_info = malloc(sizeof(*he->branch_info));
293 if (he->branch_info == NULL) {
294 free(he);
295 return NULL;
296 }
297
298 memcpy(he->branch_info, template->branch_info,
299 sizeof(*he->branch_info));
300
295 if (he->branch_info->from.map) 301 if (he->branch_info->from.map)
296 he->branch_info->from.map->referenced = true; 302 he->branch_info->from.map->referenced = true;
297 if (he->branch_info->to.map) 303 if (he->branch_info->to.map)
@@ -341,8 +347,6 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
341 struct hist_entry *he; 347 struct hist_entry *he;
342 int cmp; 348 int cmp;
343 349
344 pthread_mutex_lock(&hists->lock);
345
346 p = &hists->entries_in->rb_node; 350 p = &hists->entries_in->rb_node;
347 351
348 while (*p != NULL) { 352 while (*p != NULL) {
@@ -360,6 +364,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
360 if (!cmp) { 364 if (!cmp) {
361 he_stat__add_period(&he->stat, period, weight); 365 he_stat__add_period(&he->stat, period, weight);
362 366
367 /*
368 * This mem info was allocated from machine__resolve_mem
369 * and will not be used anymore.
370 */
371 free(entry->mem_info);
372
363 /* If the map of an existing hist_entry has 373 /* If the map of an existing hist_entry has
364 * become out-of-date due to an exec() or 374 * become out-of-date due to an exec() or
365 * similar, update it. Otherwise we will 375 * similar, update it. Otherwise we will
@@ -382,14 +392,12 @@ static struct hist_entry *add_hist_entry(struct hists *hists,
382 392
383 he = hist_entry__new(entry); 393 he = hist_entry__new(entry);
384 if (!he) 394 if (!he)
385 goto out_unlock; 395 return NULL;
386 396
387 rb_link_node(&he->rb_node_in, parent, p); 397 rb_link_node(&he->rb_node_in, parent, p);
388 rb_insert_color(&he->rb_node_in, hists->entries_in); 398 rb_insert_color(&he->rb_node_in, hists->entries_in);
389out: 399out:
390 hist_entry__add_cpumode_period(he, al->cpumode, period); 400 hist_entry__add_cpumode_period(he, al->cpumode, period);
391out_unlock:
392 pthread_mutex_unlock(&hists->lock);
393 return he; 401 return he;
394} 402}
395 403
@@ -589,13 +597,13 @@ static void hists__apply_filters(struct hists *hists, struct hist_entry *he)
589 hists__filter_entry_by_symbol(hists, he); 597 hists__filter_entry_by_symbol(hists, he);
590} 598}
591 599
592static void __hists__collapse_resort(struct hists *hists, bool threaded) 600void hists__collapse_resort(struct hists *hists)
593{ 601{
594 struct rb_root *root; 602 struct rb_root *root;
595 struct rb_node *next; 603 struct rb_node *next;
596 struct hist_entry *n; 604 struct hist_entry *n;
597 605
598 if (!sort__need_collapse && !threaded) 606 if (!sort__need_collapse)
599 return; 607 return;
600 608
601 root = hists__get_rotate_entries_in(hists); 609 root = hists__get_rotate_entries_in(hists);
@@ -617,16 +625,6 @@ static void __hists__collapse_resort(struct hists *hists, bool threaded)
617 } 625 }
618} 626}
619 627
620void hists__collapse_resort(struct hists *hists)
621{
622 return __hists__collapse_resort(hists, false);
623}
624
625void hists__collapse_resort_threaded(struct hists *hists)
626{
627 return __hists__collapse_resort(hists, true);
628}
629
630/* 628/*
631 * reverse the map, sort on period. 629 * reverse the map, sort on period.
632 */ 630 */
@@ -713,7 +711,7 @@ static void __hists__insert_output_entry(struct rb_root *entries,
713 rb_insert_color(&he->rb_node, entries); 711 rb_insert_color(&he->rb_node, entries);
714} 712}
715 713
716static void __hists__output_resort(struct hists *hists, bool threaded) 714void hists__output_resort(struct hists *hists)
717{ 715{
718 struct rb_root *root; 716 struct rb_root *root;
719 struct rb_node *next; 717 struct rb_node *next;
@@ -722,7 +720,7 @@ static void __hists__output_resort(struct hists *hists, bool threaded)
722 720
723 min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100); 721 min_callchain_hits = hists->stats.total_period * (callchain_param.min_percent / 100);
724 722
725 if (sort__need_collapse || threaded) 723 if (sort__need_collapse)
726 root = &hists->entries_collapsed; 724 root = &hists->entries_collapsed;
727 else 725 else
728 root = hists->entries_in; 726 root = hists->entries_in;
@@ -743,16 +741,6 @@ static void __hists__output_resort(struct hists *hists, bool threaded)
743 } 741 }
744} 742}
745 743
746void hists__output_resort(struct hists *hists)
747{
748 return __hists__output_resort(hists, false);
749}
750
751void hists__output_resort_threaded(struct hists *hists)
752{
753 return __hists__output_resort(hists, true);
754}
755
756static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h, 744static void hists__remove_entry_filter(struct hists *hists, struct hist_entry *h,
757 enum hist_filter filter) 745 enum hist_filter filter)
758{ 746{
diff --git a/tools/perf/util/hist.h b/tools/perf/util/hist.h
index 14c2fe20aa62..2d3790fd99bb 100644
--- a/tools/perf/util/hist.h
+++ b/tools/perf/util/hist.h
@@ -43,12 +43,12 @@ enum hist_column {
43 HISTC_COMM, 43 HISTC_COMM,
44 HISTC_PARENT, 44 HISTC_PARENT,
45 HISTC_CPU, 45 HISTC_CPU,
46 HISTC_SRCLINE,
46 HISTC_MISPREDICT, 47 HISTC_MISPREDICT,
47 HISTC_SYMBOL_FROM, 48 HISTC_SYMBOL_FROM,
48 HISTC_SYMBOL_TO, 49 HISTC_SYMBOL_TO,
49 HISTC_DSO_FROM, 50 HISTC_DSO_FROM,
50 HISTC_DSO_TO, 51 HISTC_DSO_TO,
51 HISTC_SRCLINE,
52 HISTC_LOCAL_WEIGHT, 52 HISTC_LOCAL_WEIGHT,
53 HISTC_GLOBAL_WEIGHT, 53 HISTC_GLOBAL_WEIGHT,
54 HISTC_MEM_DADDR_SYMBOL, 54 HISTC_MEM_DADDR_SYMBOL,
@@ -104,13 +104,9 @@ struct hist_entry *__hists__add_mem_entry(struct hists *self,
104 u64 weight); 104 u64 weight);
105 105
106void hists__output_resort(struct hists *self); 106void hists__output_resort(struct hists *self);
107void hists__output_resort_threaded(struct hists *hists);
108void hists__collapse_resort(struct hists *self); 107void hists__collapse_resort(struct hists *self);
109void hists__collapse_resort_threaded(struct hists *hists);
110 108
111void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel); 109void hists__decay_entries(struct hists *hists, bool zap_user, bool zap_kernel);
112void hists__decay_entries_threaded(struct hists *hists, bool zap_user,
113 bool zap_kernel);
114void hists__output_recalc_col_len(struct hists *hists, int max_rows); 110void hists__output_recalc_col_len(struct hists *hists, int max_rows);
115 111
116void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h); 112void hists__inc_nr_entries(struct hists *hists, struct hist_entry *h);
@@ -119,7 +115,7 @@ void events_stats__inc(struct events_stats *stats, u32 type);
119size_t events_stats__fprintf(struct events_stats *stats, FILE *fp); 115size_t events_stats__fprintf(struct events_stats *stats, FILE *fp);
120 116
121size_t hists__fprintf(struct hists *self, bool show_header, int max_rows, 117size_t hists__fprintf(struct hists *self, bool show_header, int max_rows,
122 int max_cols, FILE *fp); 118 int max_cols, float min_pcnt, FILE *fp);
123 119
124int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr); 120int hist_entry__inc_addr_samples(struct hist_entry *self, int evidx, u64 addr);
125int hist_entry__annotate(struct hist_entry *self, size_t privsize); 121int hist_entry__annotate(struct hist_entry *self, size_t privsize);
@@ -199,6 +195,7 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
199 195
200int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help, 196int perf_evlist__tui_browse_hists(struct perf_evlist *evlist, const char *help,
201 struct hist_browser_timer *hbt, 197 struct hist_browser_timer *hbt,
198 float min_pcnt,
202 struct perf_session_env *env); 199 struct perf_session_env *env);
203int script_browse(const char *script_opt); 200int script_browse(const char *script_opt);
204#else 201#else
@@ -206,6 +203,7 @@ static inline
206int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused, 203int perf_evlist__tui_browse_hists(struct perf_evlist *evlist __maybe_unused,
207 const char *help __maybe_unused, 204 const char *help __maybe_unused,
208 struct hist_browser_timer *hbt __maybe_unused, 205 struct hist_browser_timer *hbt __maybe_unused,
206 float min_pcnt __maybe_unused,
209 struct perf_session_env *env __maybe_unused) 207 struct perf_session_env *env __maybe_unused)
210{ 208{
211 return 0; 209 return 0;
@@ -233,12 +231,14 @@ static inline int script_browse(const char *script_opt __maybe_unused)
233 231
234#ifdef GTK2_SUPPORT 232#ifdef GTK2_SUPPORT
235int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help, 233int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist, const char *help,
236 struct hist_browser_timer *hbt __maybe_unused); 234 struct hist_browser_timer *hbt __maybe_unused,
235 float min_pcnt);
237#else 236#else
238static inline 237static inline
239int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused, 238int perf_evlist__gtk_browse_hists(struct perf_evlist *evlist __maybe_unused,
240 const char *help __maybe_unused, 239 const char *help __maybe_unused,
241 struct hist_browser_timer *hbt __maybe_unused) 240 struct hist_browser_timer *hbt __maybe_unused,
241 float min_pcnt __maybe_unused)
242{ 242{
243 return 0; 243 return 0;
244} 244}
diff --git a/tools/perf/util/map.c b/tools/perf/util/map.c
index 6fcb9de62340..8bcdf9e54089 100644
--- a/tools/perf/util/map.c
+++ b/tools/perf/util/map.c
@@ -21,6 +21,7 @@ const char *map_type__name[MAP__NR_TYPES] = {
21static inline int is_anon_memory(const char *filename) 21static inline int is_anon_memory(const char *filename)
22{ 22{
23 return !strcmp(filename, "//anon") || 23 return !strcmp(filename, "//anon") ||
24 !strcmp(filename, "/dev/zero (deleted)") ||
24 !strcmp(filename, "/anon_hugepage (deleted)"); 25 !strcmp(filename, "/anon_hugepage (deleted)");
25} 26}
26 27
diff --git a/tools/perf/util/parse-events.c b/tools/perf/util/parse-events.c
index 6c8bb0fb189b..995fc25db8c6 100644
--- a/tools/perf/util/parse-events.c
+++ b/tools/perf/util/parse-events.c
@@ -860,7 +860,8 @@ int parse_events_terms(struct list_head *terms, const char *str)
860 return 0; 860 return 0;
861 } 861 }
862 862
863 parse_events__free_terms(data.terms); 863 if (data.terms)
864 parse_events__free_terms(data.terms);
864 return ret; 865 return ret;
865} 866}
866 867
@@ -1183,6 +1184,7 @@ static int new_term(struct parse_events_term **_term, int type_val,
1183 term->val.str = str; 1184 term->val.str = str;
1184 break; 1185 break;
1185 default: 1186 default:
1187 free(term);
1186 return -EINVAL; 1188 return -EINVAL;
1187 } 1189 }
1188 1190
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h
index 6b51d47acdba..f3b235ec7bf4 100644
--- a/tools/perf/util/session.h
+++ b/tools/perf/util/session.h
@@ -37,7 +37,6 @@ struct perf_session {
37 int fd; 37 int fd;
38 bool fd_pipe; 38 bool fd_pipe;
39 bool repipe; 39 bool repipe;
40 int cwdlen;
41 char *cwd; 40 char *cwd;
42 struct ordered_samples ordered_samples; 41 struct ordered_samples ordered_samples;
43 char filename[1]; 42 char filename[1];
diff --git a/tools/perf/util/setup.py b/tools/perf/util/setup.py
index 6b0ed322907e..58ea5ca6c255 100644
--- a/tools/perf/util/setup.py
+++ b/tools/perf/util/setup.py
@@ -18,8 +18,9 @@ class install_lib(_install_lib):
18 self.build_dir = build_lib 18 self.build_dir = build_lib
19 19
20 20
21cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] 21cflags = getenv('CFLAGS', '').split()
22cflags += getenv('CFLAGS', '').split() 22# switch off several checks (need to be at the end of cflags list)
23cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ]
23 24
24build_lib = getenv('PYTHON_EXTBUILD_LIB') 25build_lib = getenv('PYTHON_EXTBUILD_LIB')
25build_tmp = getenv('PYTHON_EXTBUILD_TMP') 26build_tmp = getenv('PYTHON_EXTBUILD_TMP')
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c
index 5f52d492590c..313a5a730112 100644
--- a/tools/perf/util/sort.c
+++ b/tools/perf/util/sort.c
@@ -1,5 +1,6 @@
1#include "sort.h" 1#include "sort.h"
2#include "hist.h" 2#include "hist.h"
3#include "symbol.h"
3 4
4regex_t parent_regex; 5regex_t parent_regex;
5const char default_parent_pattern[] = "^sys_|^do_page_fault"; 6const char default_parent_pattern[] = "^sys_|^do_page_fault";
@@ -9,7 +10,7 @@ const char *sort_order = default_sort_order;
9int sort__need_collapse = 0; 10int sort__need_collapse = 0;
10int sort__has_parent = 0; 11int sort__has_parent = 0;
11int sort__has_sym = 0; 12int sort__has_sym = 0;
12int sort__branch_mode = -1; /* -1 = means not set */ 13enum sort_mode sort__mode = SORT_MODE__NORMAL;
13 14
14enum sort_type sort__first_dimension; 15enum sort_type sort__first_dimension;
15 16
@@ -194,7 +195,7 @@ static int _hist_entry__sym_snprintf(struct map *map, struct symbol *sym,
194 if (verbose) { 195 if (verbose) {
195 char o = map ? dso__symtab_origin(map->dso) : '!'; 196 char o = map ? dso__symtab_origin(map->dso) : '!';
196 ret += repsep_snprintf(bf, size, "%-#*llx %c ", 197 ret += repsep_snprintf(bf, size, "%-#*llx %c ",
197 BITS_PER_LONG / 4, ip, o); 198 BITS_PER_LONG / 4 + 2, ip, o);
198 } 199 }
199 200
200 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level); 201 ret += repsep_snprintf(bf + ret, size - ret, "[%c] ", level);
@@ -871,14 +872,6 @@ static struct sort_dimension common_sort_dimensions[] = {
871 DIM(SORT_PARENT, "parent", sort_parent), 872 DIM(SORT_PARENT, "parent", sort_parent),
872 DIM(SORT_CPU, "cpu", sort_cpu), 873 DIM(SORT_CPU, "cpu", sort_cpu),
873 DIM(SORT_SRCLINE, "srcline", sort_srcline), 874 DIM(SORT_SRCLINE, "srcline", sort_srcline),
874 DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
875 DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
876 DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
877 DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
878 DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
879 DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
880 DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
881 DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
882}; 875};
883 876
884#undef DIM 877#undef DIM
@@ -895,6 +888,36 @@ static struct sort_dimension bstack_sort_dimensions[] = {
895 888
896#undef DIM 889#undef DIM
897 890
891#define DIM(d, n, func) [d - __SORT_MEMORY_MODE] = { .name = n, .entry = &(func) }
892
893static struct sort_dimension memory_sort_dimensions[] = {
894 DIM(SORT_LOCAL_WEIGHT, "local_weight", sort_local_weight),
895 DIM(SORT_GLOBAL_WEIGHT, "weight", sort_global_weight),
896 DIM(SORT_MEM_DADDR_SYMBOL, "symbol_daddr", sort_mem_daddr_sym),
897 DIM(SORT_MEM_DADDR_DSO, "dso_daddr", sort_mem_daddr_dso),
898 DIM(SORT_MEM_LOCKED, "locked", sort_mem_locked),
899 DIM(SORT_MEM_TLB, "tlb", sort_mem_tlb),
900 DIM(SORT_MEM_LVL, "mem", sort_mem_lvl),
901 DIM(SORT_MEM_SNOOP, "snoop", sort_mem_snoop),
902};
903
904#undef DIM
905
906static void __sort_dimension__add(struct sort_dimension *sd, enum sort_type idx)
907{
908 if (sd->taken)
909 return;
910
911 if (sd->entry->se_collapse)
912 sort__need_collapse = 1;
913
914 if (list_empty(&hist_entry__sort_list))
915 sort__first_dimension = idx;
916
917 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
918 sd->taken = 1;
919}
920
898int sort_dimension__add(const char *tok) 921int sort_dimension__add(const char *tok)
899{ 922{
900 unsigned int i; 923 unsigned int i;
@@ -915,25 +938,11 @@ int sort_dimension__add(const char *tok)
915 return -EINVAL; 938 return -EINVAL;
916 } 939 }
917 sort__has_parent = 1; 940 sort__has_parent = 1;
918 } else if (sd->entry == &sort_sym || 941 } else if (sd->entry == &sort_sym) {
919 sd->entry == &sort_sym_from ||
920 sd->entry == &sort_sym_to ||
921 sd->entry == &sort_mem_daddr_sym) {
922 sort__has_sym = 1; 942 sort__has_sym = 1;
923 } 943 }
924 944
925 if (sd->taken) 945 __sort_dimension__add(sd, i);
926 return 0;
927
928 if (sd->entry->se_collapse)
929 sort__need_collapse = 1;
930
931 if (list_empty(&hist_entry__sort_list))
932 sort__first_dimension = i;
933
934 list_add_tail(&sd->entry->list, &hist_entry__sort_list);
935 sd->taken = 1;
936
937 return 0; 946 return 0;
938 } 947 }
939 948
@@ -943,24 +952,29 @@ int sort_dimension__add(const char *tok)
943 if (strncasecmp(tok, sd->name, strlen(tok))) 952 if (strncasecmp(tok, sd->name, strlen(tok)))
944 continue; 953 continue;
945 954
946 if (sort__branch_mode != 1) 955 if (sort__mode != SORT_MODE__BRANCH)
947 return -EINVAL; 956 return -EINVAL;
948 957
949 if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to) 958 if (sd->entry == &sort_sym_from || sd->entry == &sort_sym_to)
950 sort__has_sym = 1; 959 sort__has_sym = 1;
951 960
952 if (sd->taken) 961 __sort_dimension__add(sd, i + __SORT_BRANCH_STACK);
953 return 0; 962 return 0;
963 }
954 964
955 if (sd->entry->se_collapse) 965 for (i = 0; i < ARRAY_SIZE(memory_sort_dimensions); i++) {
956 sort__need_collapse = 1; 966 struct sort_dimension *sd = &memory_sort_dimensions[i];
957 967
958 if (list_empty(&hist_entry__sort_list)) 968 if (strncasecmp(tok, sd->name, strlen(tok)))
959 sort__first_dimension = i + __SORT_BRANCH_STACK; 969 continue;
960 970
961 list_add_tail(&sd->entry->list, &hist_entry__sort_list); 971 if (sort__mode != SORT_MODE__MEMORY)
962 sd->taken = 1; 972 return -EINVAL;
973
974 if (sd->entry == &sort_mem_daddr_sym)
975 sort__has_sym = 1;
963 976
977 __sort_dimension__add(sd, i + __SORT_MEMORY_MODE);
964 return 0; 978 return 0;
965 } 979 }
966 980
@@ -993,8 +1007,9 @@ int setup_sorting(void)
993 return ret; 1007 return ret;
994} 1008}
995 1009
996void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, 1010static void sort_entry__setup_elide(struct sort_entry *self,
997 const char *list_name, FILE *fp) 1011 struct strlist *list,
1012 const char *list_name, FILE *fp)
998{ 1013{
999 if (list && strlist__nr_entries(list) == 1) { 1014 if (list && strlist__nr_entries(list) == 1) {
1000 if (fp != NULL) 1015 if (fp != NULL)
@@ -1003,3 +1018,42 @@ void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list,
1003 self->elide = true; 1018 self->elide = true;
1004 } 1019 }
1005} 1020}
1021
1022void sort__setup_elide(FILE *output)
1023{
1024 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1025 "dso", output);
1026 sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list,
1027 "comm", output);
1028 sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list,
1029 "symbol", output);
1030
1031 if (sort__mode == SORT_MODE__BRANCH) {
1032 sort_entry__setup_elide(&sort_dso_from,
1033 symbol_conf.dso_from_list,
1034 "dso_from", output);
1035 sort_entry__setup_elide(&sort_dso_to,
1036 symbol_conf.dso_to_list,
1037 "dso_to", output);
1038 sort_entry__setup_elide(&sort_sym_from,
1039 symbol_conf.sym_from_list,
1040 "sym_from", output);
1041 sort_entry__setup_elide(&sort_sym_to,
1042 symbol_conf.sym_to_list,
1043 "sym_to", output);
1044 } else if (sort__mode == SORT_MODE__MEMORY) {
1045 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1046 "symbol_daddr", output);
1047 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1048 "dso_daddr", output);
1049 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1050 "mem", output);
1051 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1052 "local_weight", output);
1053 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1054 "tlb", output);
1055 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list,
1056 "snoop", output);
1057 }
1058
1059}
diff --git a/tools/perf/util/sort.h b/tools/perf/util/sort.h
index f24bdf64238c..45ac84c1e037 100644
--- a/tools/perf/util/sort.h
+++ b/tools/perf/util/sort.h
@@ -32,7 +32,7 @@ extern const char default_sort_order[];
32extern int sort__need_collapse; 32extern int sort__need_collapse;
33extern int sort__has_parent; 33extern int sort__has_parent;
34extern int sort__has_sym; 34extern int sort__has_sym;
35extern int sort__branch_mode; 35extern enum sort_mode sort__mode;
36extern struct sort_entry sort_comm; 36extern struct sort_entry sort_comm;
37extern struct sort_entry sort_dso; 37extern struct sort_entry sort_dso;
38extern struct sort_entry sort_sym; 38extern struct sort_entry sort_sym;
@@ -117,12 +117,18 @@ static inline struct hist_entry *hist_entry__next_pair(struct hist_entry *he)
117 return NULL; 117 return NULL;
118} 118}
119 119
120static inline void hist_entry__add_pair(struct hist_entry *he, 120static inline void hist_entry__add_pair(struct hist_entry *pair,
121 struct hist_entry *pair) 121 struct hist_entry *he)
122{ 122{
123 list_add_tail(&he->pairs.head, &pair->pairs.node); 123 list_add_tail(&pair->pairs.node, &he->pairs.head);
124} 124}
125 125
126enum sort_mode {
127 SORT_MODE__NORMAL,
128 SORT_MODE__BRANCH,
129 SORT_MODE__MEMORY,
130};
131
126enum sort_type { 132enum sort_type {
127 /* common sort keys */ 133 /* common sort keys */
128 SORT_PID, 134 SORT_PID,
@@ -132,14 +138,6 @@ enum sort_type {
132 SORT_PARENT, 138 SORT_PARENT,
133 SORT_CPU, 139 SORT_CPU,
134 SORT_SRCLINE, 140 SORT_SRCLINE,
135 SORT_LOCAL_WEIGHT,
136 SORT_GLOBAL_WEIGHT,
137 SORT_MEM_DADDR_SYMBOL,
138 SORT_MEM_DADDR_DSO,
139 SORT_MEM_LOCKED,
140 SORT_MEM_TLB,
141 SORT_MEM_LVL,
142 SORT_MEM_SNOOP,
143 141
144 /* branch stack specific sort keys */ 142 /* branch stack specific sort keys */
145 __SORT_BRANCH_STACK, 143 __SORT_BRANCH_STACK,
@@ -148,6 +146,17 @@ enum sort_type {
148 SORT_SYM_FROM, 146 SORT_SYM_FROM,
149 SORT_SYM_TO, 147 SORT_SYM_TO,
150 SORT_MISPREDICT, 148 SORT_MISPREDICT,
149
150 /* memory mode specific sort keys */
151 __SORT_MEMORY_MODE,
152 SORT_LOCAL_WEIGHT = __SORT_MEMORY_MODE,
153 SORT_GLOBAL_WEIGHT,
154 SORT_MEM_DADDR_SYMBOL,
155 SORT_MEM_DADDR_DSO,
156 SORT_MEM_LOCKED,
157 SORT_MEM_TLB,
158 SORT_MEM_LVL,
159 SORT_MEM_SNOOP,
151}; 160};
152 161
153/* 162/*
@@ -172,7 +181,6 @@ extern struct list_head hist_entry__sort_list;
172 181
173int setup_sorting(void); 182int setup_sorting(void);
174extern int sort_dimension__add(const char *); 183extern int sort_dimension__add(const char *);
175void sort_entry__setup_elide(struct sort_entry *self, struct strlist *list, 184void sort__setup_elide(FILE *fp);
176 const char *list_name, FILE *fp);
177 185
178#endif /* __PERF_SORT_H */ 186#endif /* __PERF_SORT_H */
diff --git a/tools/perf/util/stat.c b/tools/perf/util/stat.c
index 23742126f47c..7c59c28afcc5 100644
--- a/tools/perf/util/stat.c
+++ b/tools/perf/util/stat.c
@@ -37,7 +37,7 @@ double stddev_stats(struct stats *stats)
37{ 37{
38 double variance, variance_mean; 38 double variance, variance_mean;
39 39
40 if (!stats->n) 40 if (stats->n < 2)
41 return 0.0; 41 return 0.0;
42 42
43 variance = stats->M2 / (stats->n - 1); 43 variance = stats->M2 / (stats->n - 1);
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 8cf3b5426a9a..d5528e1cc03a 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -32,7 +32,6 @@ int vmlinux_path__nr_entries;
32char **vmlinux_path; 32char **vmlinux_path;
33 33
34struct symbol_conf symbol_conf = { 34struct symbol_conf symbol_conf = {
35 .exclude_other = true,
36 .use_modules = true, 35 .use_modules = true,
37 .try_vmlinux_path = true, 36 .try_vmlinux_path = true,
38 .annotate_src = true, 37 .annotate_src = true,
diff --git a/tools/perf/util/thread.c b/tools/perf/util/thread.c
index 632e40e5ceca..40399cbcca77 100644
--- a/tools/perf/util/thread.c
+++ b/tools/perf/util/thread.c
@@ -14,6 +14,7 @@ struct thread *thread__new(pid_t pid)
14 if (self != NULL) { 14 if (self != NULL) {
15 map_groups__init(&self->mg); 15 map_groups__init(&self->mg);
16 self->pid = pid; 16 self->pid = pid;
17 self->ppid = -1;
17 self->comm = malloc(32); 18 self->comm = malloc(32);
18 if (self->comm) 19 if (self->comm)
19 snprintf(self->comm, 32, ":%d", self->pid); 20 snprintf(self->comm, 32, ":%d", self->pid);
@@ -82,5 +83,8 @@ int thread__fork(struct thread *self, struct thread *parent)
82 for (i = 0; i < MAP__NR_TYPES; ++i) 83 for (i = 0; i < MAP__NR_TYPES; ++i)
83 if (map_groups__clone(&self->mg, &parent->mg, i) < 0) 84 if (map_groups__clone(&self->mg, &parent->mg, i) < 0)
84 return -ENOMEM; 85 return -ENOMEM;
86
87 self->ppid = parent->pid;
88
85 return 0; 89 return 0;
86} 90}
diff --git a/tools/perf/util/thread.h b/tools/perf/util/thread.h
index 5ad266403098..eeb7ac62b9e3 100644
--- a/tools/perf/util/thread.h
+++ b/tools/perf/util/thread.h
@@ -13,6 +13,7 @@ struct thread {
13 }; 13 };
14 struct map_groups mg; 14 struct map_groups mg;
15 pid_t pid; 15 pid_t pid;
16 pid_t ppid;
16 char shortname[3]; 17 char shortname[3];
17 bool comm_set; 18 bool comm_set;
18 char *comm; 19 char *comm;
diff --git a/tools/perf/util/top.c b/tools/perf/util/top.c
index 54d37a4753c5..f857b51b6bde 100644
--- a/tools/perf/util/top.c
+++ b/tools/perf/util/top.c
@@ -23,20 +23,31 @@
23 23
24size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size) 24size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size)
25{ 25{
26 float samples_per_sec = top->samples / top->delay_secs; 26 float samples_per_sec;
27 float ksamples_per_sec = top->kernel_samples / top->delay_secs; 27 float ksamples_per_sec;
28 float esamples_percent = (100.0 * top->exact_samples) / top->samples; 28 float esamples_percent;
29 struct perf_record_opts *opts = &top->record_opts; 29 struct perf_record_opts *opts = &top->record_opts;
30 struct perf_target *target = &opts->target; 30 struct perf_target *target = &opts->target;
31 size_t ret = 0; 31 size_t ret = 0;
32 32
33 if (top->samples) {
34 samples_per_sec = top->samples / top->delay_secs;
35 ksamples_per_sec = top->kernel_samples / top->delay_secs;
36 esamples_percent = (100.0 * top->exact_samples) / top->samples;
37 } else {
38 samples_per_sec = ksamples_per_sec = esamples_percent = 0.0;
39 }
40
33 if (!perf_guest) { 41 if (!perf_guest) {
42 float ksamples_percent = 0.0;
43
44 if (samples_per_sec)
45 ksamples_percent = (100.0 * ksamples_per_sec) /
46 samples_per_sec;
34 ret = SNPRINTF(bf, size, 47 ret = SNPRINTF(bf, size,
35 " PerfTop:%8.0f irqs/sec kernel:%4.1f%%" 48 " PerfTop:%8.0f irqs/sec kernel:%4.1f%%"
36 " exact: %4.1f%% [", samples_per_sec, 49 " exact: %4.1f%% [", samples_per_sec,
37 100.0 - (100.0 * ((samples_per_sec - ksamples_per_sec) / 50 ksamples_percent, esamples_percent);
38 samples_per_sec)),
39 esamples_percent);
40 } else { 51 } else {
41 float us_samples_per_sec = top->us_samples / top->delay_secs; 52 float us_samples_per_sec = top->us_samples / top->delay_secs;
42 float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs; 53 float guest_kernel_samples_per_sec = top->guest_kernel_samples / top->delay_secs;
diff --git a/tools/perf/util/top.h b/tools/perf/util/top.h
index 7ebf357dc9e1..df46be93d902 100644
--- a/tools/perf/util/top.h
+++ b/tools/perf/util/top.h
@@ -26,7 +26,6 @@ struct perf_top {
26 int print_entries, count_filter, delay_secs; 26 int print_entries, count_filter, delay_secs;
27 bool hide_kernel_symbols, hide_user_symbols, zero; 27 bool hide_kernel_symbols, hide_user_symbols, zero;
28 bool use_tui, use_stdio; 28 bool use_tui, use_stdio;
29 bool sort_has_symbols;
30 bool kptr_restrict_warned; 29 bool kptr_restrict_warned;
31 bool vmlinux_warned; 30 bool vmlinux_warned;
32 bool dump_symtab; 31 bool dump_symtab;
@@ -37,6 +36,7 @@ struct perf_top {
37 int realtime_prio; 36 int realtime_prio;
38 int sym_pcnt_filter; 37 int sym_pcnt_filter;
39 const char *sym_filter; 38 const char *sym_filter;
39 float min_percent;
40}; 40};
41 41
42size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size); 42size_t perf_top__header_snprintf(struct perf_top *top, char *bf, size_t size);
diff --git a/tools/perf/util/util.h b/tools/perf/util/util.h
index a45710b70a55..2732fad03908 100644
--- a/tools/perf/util/util.h
+++ b/tools/perf/util/util.h
@@ -72,6 +72,7 @@
72#include "types.h" 72#include "types.h"
73#include <sys/ttydefaults.h> 73#include <sys/ttydefaults.h>
74#include <lk/debugfs.h> 74#include <lk/debugfs.h>
75#include <termios.h>
75 76
76extern const char *graph_line; 77extern const char *graph_line;
77extern const char *graph_dotted_line; 78extern const char *graph_dotted_line;
@@ -221,8 +222,8 @@ extern unsigned char sane_ctype[256];
221#define isalpha(x) sane_istest(x,GIT_ALPHA) 222#define isalpha(x) sane_istest(x,GIT_ALPHA)
222#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT) 223#define isalnum(x) sane_istest(x,GIT_ALPHA | GIT_DIGIT)
223#define isprint(x) sane_istest(x,GIT_PRINT) 224#define isprint(x) sane_istest(x,GIT_PRINT)
224#define islower(x) (sane_istest(x,GIT_ALPHA) && sane_istest(x,0x20)) 225#define islower(x) (sane_istest(x,GIT_ALPHA) && (x & 0x20))
225#define isupper(x) (sane_istest(x,GIT_ALPHA) && !sane_istest(x,0x20)) 226#define isupper(x) (sane_istest(x,GIT_ALPHA) && !(x & 0x20))
226#define tolower(x) sane_case((unsigned char)(x), 0x20) 227#define tolower(x) sane_case((unsigned char)(x), 0x20)
227#define toupper(x) sane_case((unsigned char)(x), 0) 228#define toupper(x) sane_case((unsigned char)(x), 0)
228 229
@@ -274,6 +275,5 @@ void dump_stack(void);
274 275
275extern unsigned int page_size; 276extern unsigned int page_size;
276 277
277struct winsize;
278void get_term_dimensions(struct winsize *ws); 278void get_term_dimensions(struct winsize *ws);
279#endif /* GIT_COMPAT_UTIL_H */ 279#endif /* GIT_COMPAT_UTIL_H */
diff --git a/tools/perf/util/vdso.c b/tools/perf/util/vdso.c
index e60951fcdb12..39159822d58f 100644
--- a/tools/perf/util/vdso.c
+++ b/tools/perf/util/vdso.c
@@ -91,7 +91,7 @@ void vdso__exit(void)
91 91
92struct dso *vdso__dso_findnew(struct list_head *head) 92struct dso *vdso__dso_findnew(struct list_head *head)
93{ 93{
94 struct dso *dso = dsos__find(head, VDSO__MAP_NAME); 94 struct dso *dso = dsos__find(head, VDSO__MAP_NAME, true);
95 95
96 if (!dso) { 96 if (!dso) {
97 char *file; 97 char *file;
diff --git a/tools/power/cpupower/Makefile b/tools/power/cpupower/Makefile
index d875a74a3bdf..cbfec92af327 100644
--- a/tools/power/cpupower/Makefile
+++ b/tools/power/cpupower/Makefile
@@ -128,10 +128,12 @@ UTIL_OBJS = utils/helpers/amd.o utils/helpers/topology.o utils/helpers/msr.o \
128 utils/helpers/sysfs.o utils/helpers/misc.o utils/helpers/cpuid.o \ 128 utils/helpers/sysfs.o utils/helpers/misc.o utils/helpers/cpuid.o \
129 utils/helpers/pci.o utils/helpers/bitmask.o \ 129 utils/helpers/pci.o utils/helpers/bitmask.o \
130 utils/idle_monitor/nhm_idle.o utils/idle_monitor/snb_idle.o \ 130 utils/idle_monitor/nhm_idle.o utils/idle_monitor/snb_idle.o \
131 utils/idle_monitor/hsw_ext_idle.o \
131 utils/idle_monitor/amd_fam14h_idle.o utils/idle_monitor/cpuidle_sysfs.o \ 132 utils/idle_monitor/amd_fam14h_idle.o utils/idle_monitor/cpuidle_sysfs.o \
132 utils/idle_monitor/mperf_monitor.o utils/idle_monitor/cpupower-monitor.o \ 133 utils/idle_monitor/mperf_monitor.o utils/idle_monitor/cpupower-monitor.o \
133 utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \ 134 utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \
134 utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o 135 utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o \
136 utils/cpuidle-set.o
135 137
136UTIL_SRC := $(UTIL_OBJS:.o=.c) 138UTIL_SRC := $(UTIL_OBJS:.o=.c)
137 139
diff --git a/tools/power/cpupower/man/cpupower-monitor.1 b/tools/power/cpupower/man/cpupower-monitor.1
index e01c35d13b6e..914cbb9d9cd0 100644
--- a/tools/power/cpupower/man/cpupower-monitor.1
+++ b/tools/power/cpupower/man/cpupower-monitor.1
@@ -110,13 +110,21 @@ May work poorly on Linux-2.6.20 through 2.6.29, as the \fBacpi-cpufreq \fP
110kernel frequency driver periodically cleared aperf/mperf registers in those 110kernel frequency driver periodically cleared aperf/mperf registers in those
111kernels. 111kernels.
112 112
113.SS "Nehalem" "SandyBridge" 113.SS "Nehalem" "SandyBridge" "HaswellExtended"
114Intel Core and Package sleep state counters. 114Intel Core and Package sleep state counters.
115Threads (hyperthreaded cores) may not be able to enter deeper core states if 115Threads (hyperthreaded cores) may not be able to enter deeper core states if
116its sibling is utilized. 116its sibling is utilized.
117Deepest package sleep states may in reality show up as machine/platform wide 117Deepest package sleep states may in reality show up as machine/platform wide
118sleep states and can only be entered if all cores are idle. Look up Intel 118sleep states and can only be entered if all cores are idle. Look up Intel
119manuals (some are provided in the References section) for further details. 119manuals (some are provided in the References section) for further details.
120The monitors are named after the CPU family where the sleep state capabilities
121got introduced and may not match exactly the CPU name of the platform.
122For example an IvyBridge processor has sleep state capabilities which got
123introduced in Nehalem and SandyBridge processor families.
124Thus on an IvyBridge processor one will get Nehalem and SandyBridge sleep
125state monitors.
126HaswellExtended extra package sleep state capabilities are available only in a
127specific Haswell (family 0x45) and probably also other future processors.
120 128
121.SS "Fam_12h" "Fam_14h" 129.SS "Fam_12h" "Fam_14h"
122AMD laptop and desktop processor (family 12h and 14h) sleep state counters. 130AMD laptop and desktop processor (family 12h and 14h) sleep state counters.
diff --git a/tools/power/cpupower/utils/builtin.h b/tools/power/cpupower/utils/builtin.h
index c10496fbe3c6..2284c8ea4e2a 100644
--- a/tools/power/cpupower/utils/builtin.h
+++ b/tools/power/cpupower/utils/builtin.h
@@ -5,6 +5,7 @@ extern int cmd_set(int argc, const char **argv);
5extern int cmd_info(int argc, const char **argv); 5extern int cmd_info(int argc, const char **argv);
6extern int cmd_freq_set(int argc, const char **argv); 6extern int cmd_freq_set(int argc, const char **argv);
7extern int cmd_freq_info(int argc, const char **argv); 7extern int cmd_freq_info(int argc, const char **argv);
8extern int cmd_idle_set(int argc, const char **argv);
8extern int cmd_idle_info(int argc, const char **argv); 9extern int cmd_idle_info(int argc, const char **argv);
9extern int cmd_monitor(int argc, const char **argv); 10extern int cmd_monitor(int argc, const char **argv);
10 11
diff --git a/tools/power/cpupower/utils/cpuidle-info.c b/tools/power/cpupower/utils/cpuidle-info.c
index 8145af5f93a6..75e66de7e7a7 100644
--- a/tools/power/cpupower/utils/cpuidle-info.c
+++ b/tools/power/cpupower/utils/cpuidle-info.c
@@ -22,7 +22,7 @@
22 22
23static void cpuidle_cpu_output(unsigned int cpu, int verbose) 23static void cpuidle_cpu_output(unsigned int cpu, int verbose)
24{ 24{
25 int idlestates, idlestate; 25 unsigned int idlestates, idlestate;
26 char *tmp; 26 char *tmp;
27 27
28 printf(_ ("Analyzing CPU %d:\n"), cpu); 28 printf(_ ("Analyzing CPU %d:\n"), cpu);
@@ -31,10 +31,8 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose)
31 if (idlestates == 0) { 31 if (idlestates == 0) {
32 printf(_("CPU %u: No idle states\n"), cpu); 32 printf(_("CPU %u: No idle states\n"), cpu);
33 return; 33 return;
34 } else if (idlestates <= 0) {
35 printf(_("CPU %u: Can't read idle state info\n"), cpu);
36 return;
37 } 34 }
35
38 printf(_("Number of idle states: %d\n"), idlestates); 36 printf(_("Number of idle states: %d\n"), idlestates);
39 printf(_("Available idle states:")); 37 printf(_("Available idle states:"));
40 for (idlestate = 0; idlestate < idlestates; idlestate++) { 38 for (idlestate = 0; idlestate < idlestates; idlestate++) {
@@ -50,10 +48,14 @@ static void cpuidle_cpu_output(unsigned int cpu, int verbose)
50 return; 48 return;
51 49
52 for (idlestate = 0; idlestate < idlestates; idlestate++) { 50 for (idlestate = 0; idlestate < idlestates; idlestate++) {
51 int disabled = sysfs_is_idlestate_disabled(cpu, idlestate);
52 /* Disabled interface not supported on older kernels */
53 if (disabled < 0)
54 disabled = 0;
53 tmp = sysfs_get_idlestate_name(cpu, idlestate); 55 tmp = sysfs_get_idlestate_name(cpu, idlestate);
54 if (!tmp) 56 if (!tmp)
55 continue; 57 continue;
56 printf("%s:\n", tmp); 58 printf("%s%s:\n", tmp, (disabled) ? " (DISABLED) " : "");
57 free(tmp); 59 free(tmp);
58 60
59 tmp = sysfs_get_idlestate_desc(cpu, idlestate); 61 tmp = sysfs_get_idlestate_desc(cpu, idlestate);
@@ -98,21 +100,13 @@ static void cpuidle_general_output(void)
98static void proc_cpuidle_cpu_output(unsigned int cpu) 100static void proc_cpuidle_cpu_output(unsigned int cpu)
99{ 101{
100 long max_allowed_cstate = 2000000000; 102 long max_allowed_cstate = 2000000000;
101 int cstates, cstate; 103 unsigned int cstate, cstates;
102 104
103 cstates = sysfs_get_idlestate_count(cpu); 105 cstates = sysfs_get_idlestate_count(cpu);
104 if (cstates == 0) { 106 if (cstates == 0) {
105 /* 107 printf(_("CPU %u: No C-states info\n"), cpu);
106 * Go on and print same useless info as you'd see with
107 * cat /proc/acpi/processor/../power
108 * printf(_("CPU %u: No C-states available\n"), cpu);
109 * return;
110 */
111 } else if (cstates <= 0) {
112 printf(_("CPU %u: Can't read C-state info\n"), cpu);
113 return; 108 return;
114 } 109 }
115 /* printf("Cstates: %d\n", cstates); */
116 110
117 printf(_("active state: C0\n")); 111 printf(_("active state: C0\n"));
118 printf(_("max_cstate: C%u\n"), cstates-1); 112 printf(_("max_cstate: C%u\n"), cstates-1);
diff --git a/tools/power/cpupower/utils/cpuidle-set.c b/tools/power/cpupower/utils/cpuidle-set.c
new file mode 100644
index 000000000000..c78141c5dfac
--- /dev/null
+++ b/tools/power/cpupower/utils/cpuidle-set.c
@@ -0,0 +1,118 @@
1#include <unistd.h>
2#include <stdio.h>
3#include <errno.h>
4#include <stdlib.h>
5#include <limits.h>
6#include <string.h>
7#include <ctype.h>
8
9#include <getopt.h>
10
11#include "cpufreq.h"
12#include "helpers/helpers.h"
13#include "helpers/sysfs.h"
14
15static struct option info_opts[] = {
16 { .name = "disable", .has_arg = required_argument, .flag = NULL, .val = 'd'},
17 { .name = "enable", .has_arg = required_argument, .flag = NULL, .val = 'e'},
18 { },
19};
20
21
22int cmd_idle_set(int argc, char **argv)
23{
24 extern char *optarg;
25 extern int optind, opterr, optopt;
26 int ret = 0, cont = 1, param = 0, idlestate = 0;
27 unsigned int cpu = 0;
28
29 do {
30 ret = getopt_long(argc, argv, "d:e:", info_opts, NULL);
31 if (ret == -1)
32 break;
33 switch (ret) {
34 case '?':
35 param = '?';
36 cont = 0;
37 break;
38 case 'd':
39 if (param) {
40 param = -1;
41 cont = 0;
42 break;
43 }
44 param = ret;
45 idlestate = atoi(optarg);
46 break;
47 case 'e':
48 if (param) {
49 param = -1;
50 cont = 0;
51 break;
52 }
53 param = ret;
54 idlestate = atoi(optarg);
55 break;
56 case -1:
57 cont = 0;
58 break;
59 }
60 } while (cont);
61
62 switch (param) {
63 case -1:
64 printf(_("You can't specify more than one "
65 "output-specific argument\n"));
66 exit(EXIT_FAILURE);
67 case '?':
68 printf(_("invalid or unknown argument\n"));
69 exit(EXIT_FAILURE);
70 }
71
72 /* Default is: set all CPUs */
73 if (bitmask_isallclear(cpus_chosen))
74 bitmask_setall(cpus_chosen);
75
76 for (cpu = bitmask_first(cpus_chosen);
77 cpu <= bitmask_last(cpus_chosen); cpu++) {
78
79 if (!bitmask_isbitset(cpus_chosen, cpu))
80 continue;
81
82 switch (param) {
83
84 case 'd':
85 ret = sysfs_idlestate_disable(cpu, idlestate, 1);
86 if (ret == 0)
87 printf(_("Idlestate %u disabled on CPU %u\n"), idlestate, cpu);
88 else if (ret == -1)
89 printf(_("Idlestate %u not available on CPU %u\n"),
90 idlestate, cpu);
91 else if (ret == -2)
92 printf(_("Idlestate disabling not supported by kernel\n"));
93 else
94 printf(_("Idlestate %u not disabled on CPU %u\n"),
95 idlestate, cpu);
96 break;
97 case 'e':
98 ret = sysfs_idlestate_disable(cpu, idlestate, 0);
99 if (ret == 0)
100 printf(_("Idlestate %u enabled on CPU %u\n"), idlestate, cpu);
101 else if (ret == -1)
102 printf(_("Idlestate %u not available on CPU %u\n"),
103 idlestate, cpu);
104 else if (ret == -2)
105 printf(_("Idlestate enabling not supported by kernel\n"));
106 else
107 printf(_("Idlestate %u not enabled on CPU %u\n"),
108 idlestate, cpu);
109 break;
110 default:
111 /* Not reachable with proper args checking */
112 printf(_("Invalid or unknown argument\n"));
113 exit(EXIT_FAILURE);
114 break;
115 }
116 }
117 return EXIT_SUCCESS;
118}
diff --git a/tools/power/cpupower/utils/cpupower.c b/tools/power/cpupower/utils/cpupower.c
index 52bee591c1c5..7efc570ffbaa 100644
--- a/tools/power/cpupower/utils/cpupower.c
+++ b/tools/power/cpupower/utils/cpupower.c
@@ -17,12 +17,6 @@
17#include "helpers/helpers.h" 17#include "helpers/helpers.h"
18#include "helpers/bitmask.h" 18#include "helpers/bitmask.h"
19 19
20struct cmd_struct {
21 const char *cmd;
22 int (*main)(int, const char **);
23 int needs_root;
24};
25
26#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 20#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
27 21
28static int cmd_help(int argc, const char **argv); 22static int cmd_help(int argc, const char **argv);
@@ -43,10 +37,17 @@ int be_verbose;
43 37
44static void print_help(void); 38static void print_help(void);
45 39
40struct cmd_struct {
41 const char *cmd;
42 int (*main)(int, const char **);
43 int needs_root;
44};
45
46static struct cmd_struct commands[] = { 46static struct cmd_struct commands[] = {
47 { "frequency-info", cmd_freq_info, 0 }, 47 { "frequency-info", cmd_freq_info, 0 },
48 { "frequency-set", cmd_freq_set, 1 }, 48 { "frequency-set", cmd_freq_set, 1 },
49 { "idle-info", cmd_idle_info, 0 }, 49 { "idle-info", cmd_idle_info, 0 },
50 { "idle-set", cmd_idle_set, 1 },
50 { "set", cmd_set, 1 }, 51 { "set", cmd_set, 1 },
51 { "info", cmd_info, 0 }, 52 { "info", cmd_info, 0 },
52 { "monitor", cmd_monitor, 0 }, 53 { "monitor", cmd_monitor, 0 },
diff --git a/tools/power/cpupower/utils/helpers/sysfs.c b/tools/power/cpupower/utils/helpers/sysfs.c
index 38ab91629463..5cdc600e8152 100644
--- a/tools/power/cpupower/utils/helpers/sysfs.c
+++ b/tools/power/cpupower/utils/helpers/sysfs.c
@@ -89,6 +89,33 @@ int sysfs_is_cpu_online(unsigned int cpu)
89 89
90/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */ 90/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
91 91
92
93/* CPUidle idlestate specific /sys/devices/system/cpu/cpuX/cpuidle/ access */
94
95/*
96 * helper function to check whether a file under "../cpuX/cpuidle/stateX/" dir
97 * exists.
98 * For example the functionality to disable c-states was introduced in later
99 * kernel versions, this function can be used to explicitly check for this
100 * feature.
101 *
102 * returns 1 if the file exists, 0 otherwise.
103 */
104unsigned int sysfs_idlestate_file_exists(unsigned int cpu,
105 unsigned int idlestate,
106 const char *fname)
107{
108 char path[SYSFS_PATH_MAX];
109 struct stat statbuf;
110
111
112 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s",
113 cpu, idlestate, fname);
114 if (stat(path, &statbuf) != 0)
115 return 0;
116 return 1;
117}
118
92/* 119/*
93 * helper function to read file from /sys into given buffer 120 * helper function to read file from /sys into given buffer
94 * fname is a relative path under "cpuX/cpuidle/stateX/" dir 121 * fname is a relative path under "cpuX/cpuidle/stateX/" dir
@@ -121,6 +148,40 @@ unsigned int sysfs_idlestate_read_file(unsigned int cpu, unsigned int idlestate,
121 return (unsigned int) numread; 148 return (unsigned int) numread;
122} 149}
123 150
151/*
152 * helper function to write a new value to a /sys file
153 * fname is a relative path under "../cpuX/cpuidle/cstateY/" dir
154 *
155 * Returns the number of bytes written or 0 on error
156 */
157static
158unsigned int sysfs_idlestate_write_file(unsigned int cpu,
159 unsigned int idlestate,
160 const char *fname,
161 const char *value, size_t len)
162{
163 char path[SYSFS_PATH_MAX];
164 int fd;
165 ssize_t numwrite;
166
167 snprintf(path, sizeof(path), PATH_TO_CPU "cpu%u/cpuidle/state%u/%s",
168 cpu, idlestate, fname);
169
170 fd = open(path, O_WRONLY);
171 if (fd == -1)
172 return 0;
173
174 numwrite = write(fd, value, len);
175 if (numwrite < 1) {
176 close(fd);
177 return 0;
178 }
179
180 close(fd);
181
182 return (unsigned int) numwrite;
183}
184
124/* read access to files which contain one numeric value */ 185/* read access to files which contain one numeric value */
125 186
126enum idlestate_value { 187enum idlestate_value {
@@ -128,6 +189,7 @@ enum idlestate_value {
128 IDLESTATE_POWER, 189 IDLESTATE_POWER,
129 IDLESTATE_LATENCY, 190 IDLESTATE_LATENCY,
130 IDLESTATE_TIME, 191 IDLESTATE_TIME,
192 IDLESTATE_DISABLE,
131 MAX_IDLESTATE_VALUE_FILES 193 MAX_IDLESTATE_VALUE_FILES
132}; 194};
133 195
@@ -136,6 +198,7 @@ static const char *idlestate_value_files[MAX_IDLESTATE_VALUE_FILES] = {
136 [IDLESTATE_POWER] = "power", 198 [IDLESTATE_POWER] = "power",
137 [IDLESTATE_LATENCY] = "latency", 199 [IDLESTATE_LATENCY] = "latency",
138 [IDLESTATE_TIME] = "time", 200 [IDLESTATE_TIME] = "time",
201 [IDLESTATE_DISABLE] = "disable",
139}; 202};
140 203
141static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu, 204static unsigned long long sysfs_idlestate_get_one_value(unsigned int cpu,
@@ -205,8 +268,59 @@ static char *sysfs_idlestate_get_one_string(unsigned int cpu,
205 return result; 268 return result;
206} 269}
207 270
271/*
272 * Returns:
273 * 1 if disabled
274 * 0 if enabled
275 * -1 if idlestate is not available
276 * -2 if disabling is not supported by the kernel
277 */
278int sysfs_is_idlestate_disabled(unsigned int cpu,
279 unsigned int idlestate)
280{
281 if (sysfs_get_idlestate_count(cpu) < idlestate)
282 return -1;
283
284 if (!sysfs_idlestate_file_exists(cpu, idlestate,
285 idlestate_value_files[IDLESTATE_DISABLE]))
286 return -2;
287 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_DISABLE);
288}
289
290/*
291 * Pass 1 as last argument to disable or 0 to enable the state
292 * Returns:
293 * 0 on success
294 * negative values on error, for example:
295 * -1 if idlestate is not available
296 * -2 if disabling is not supported by the kernel
297 * -3 No write access to disable/enable C-states
298 */
299int sysfs_idlestate_disable(unsigned int cpu,
300 unsigned int idlestate,
301 unsigned int disable)
302{
303 char value[SYSFS_PATH_MAX];
304 int bytes_written;
305
306 if (sysfs_get_idlestate_count(cpu) < idlestate)
307 return -1;
308
309 if (!sysfs_idlestate_file_exists(cpu, idlestate,
310 idlestate_value_files[IDLESTATE_DISABLE]))
311 return -2;
312
313 snprintf(value, SYSFS_PATH_MAX, "%u", disable);
314
315 bytes_written = sysfs_idlestate_write_file(cpu, idlestate, "disable",
316 value, sizeof(disable));
317 if (bytes_written)
318 return 0;
319 return -3;
320}
321
208unsigned long sysfs_get_idlestate_latency(unsigned int cpu, 322unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
209 unsigned int idlestate) 323 unsigned int idlestate)
210{ 324{
211 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY); 325 return sysfs_idlestate_get_one_value(cpu, idlestate, IDLESTATE_LATENCY);
212} 326}
@@ -238,7 +352,7 @@ char *sysfs_get_idlestate_desc(unsigned int cpu, unsigned int idlestate)
238 * Negativ in error case 352 * Negativ in error case
239 * Zero if cpuidle does not export any C-states 353 * Zero if cpuidle does not export any C-states
240 */ 354 */
241int sysfs_get_idlestate_count(unsigned int cpu) 355unsigned int sysfs_get_idlestate_count(unsigned int cpu)
242{ 356{
243 char file[SYSFS_PATH_MAX]; 357 char file[SYSFS_PATH_MAX];
244 struct stat statbuf; 358 struct stat statbuf;
diff --git a/tools/power/cpupower/utils/helpers/sysfs.h b/tools/power/cpupower/utils/helpers/sysfs.h
index 8cb797bbceb0..d28f11fedbda 100644
--- a/tools/power/cpupower/utils/helpers/sysfs.h
+++ b/tools/power/cpupower/utils/helpers/sysfs.h
@@ -7,8 +7,16 @@
7 7
8extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen); 8extern unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen);
9 9
10extern unsigned int sysfs_idlestate_file_exists(unsigned int cpu,
11 unsigned int idlestate,
12 const char *fname);
13
10extern int sysfs_is_cpu_online(unsigned int cpu); 14extern int sysfs_is_cpu_online(unsigned int cpu);
11 15
16extern int sysfs_is_idlestate_disabled(unsigned int cpu,
17 unsigned int idlestate);
18extern int sysfs_idlestate_disable(unsigned int cpu, unsigned int idlestate,
19 unsigned int disable);
12extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu, 20extern unsigned long sysfs_get_idlestate_latency(unsigned int cpu,
13 unsigned int idlestate); 21 unsigned int idlestate);
14extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu, 22extern unsigned long sysfs_get_idlestate_usage(unsigned int cpu,
@@ -19,7 +27,7 @@ extern char *sysfs_get_idlestate_name(unsigned int cpu,
19 unsigned int idlestate); 27 unsigned int idlestate);
20extern char *sysfs_get_idlestate_desc(unsigned int cpu, 28extern char *sysfs_get_idlestate_desc(unsigned int cpu,
21 unsigned int idlestate); 29 unsigned int idlestate);
22extern int sysfs_get_idlestate_count(unsigned int cpu); 30extern unsigned int sysfs_get_idlestate_count(unsigned int cpu);
23 31
24extern char *sysfs_get_cpuidle_governor(void); 32extern char *sysfs_get_cpuidle_governor(void);
25extern char *sysfs_get_cpuidle_driver(void); 33extern char *sysfs_get_cpuidle_driver(void);
diff --git a/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c
new file mode 100644
index 000000000000..ebeaba6571a3
--- /dev/null
+++ b/tools/power/cpupower/utils/idle_monitor/hsw_ext_idle.c
@@ -0,0 +1,196 @@
1/*
2 * (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
3 *
4 * Licensed under the terms of the GNU GPL License version 2.
5 *
6 * Based on SandyBridge monitor. Implements the new package C-states
7 * (PC8, PC9, PC10) coming with a specific Haswell (family 0x45) CPU.
8 */
9
10#if defined(__i386__) || defined(__x86_64__)
11
12#include <stdio.h>
13#include <stdint.h>
14#include <stdlib.h>
15#include <string.h>
16
17#include "helpers/helpers.h"
18#include "idle_monitor/cpupower-monitor.h"
19
20#define MSR_PKG_C8_RESIDENCY 0x00000630
21#define MSR_PKG_C9_RESIDENCY 0x00000631
22#define MSR_PKG_C10_RESIDENCY 0x00000632
23
24#define MSR_TSC 0x10
25
26enum intel_hsw_ext_id { PC8 = 0, PC9, PC10, HSW_EXT_CSTATE_COUNT,
27 TSC = 0xFFFF };
28
29static int hsw_ext_get_count_percent(unsigned int self_id, double *percent,
30 unsigned int cpu);
31
32static cstate_t hsw_ext_cstates[HSW_EXT_CSTATE_COUNT] = {
33 {
34 .name = "PC8",
35 .desc = N_("Processor Package C8"),
36 .id = PC8,
37 .range = RANGE_PACKAGE,
38 .get_count_percent = hsw_ext_get_count_percent,
39 },
40 {
41 .name = "PC9",
42 .desc = N_("Processor Package C9"),
43 .desc = N_("Processor Package C2"),
44 .id = PC9,
45 .range = RANGE_PACKAGE,
46 .get_count_percent = hsw_ext_get_count_percent,
47 },
48 {
49 .name = "PC10",
50 .desc = N_("Processor Package C10"),
51 .id = PC10,
52 .range = RANGE_PACKAGE,
53 .get_count_percent = hsw_ext_get_count_percent,
54 },
55};
56
57static unsigned long long tsc_at_measure_start;
58static unsigned long long tsc_at_measure_end;
59static unsigned long long *previous_count[HSW_EXT_CSTATE_COUNT];
60static unsigned long long *current_count[HSW_EXT_CSTATE_COUNT];
61/* valid flag for all CPUs. If a MSR read failed it will be zero */
62static int *is_valid;
63
64static int hsw_ext_get_count(enum intel_hsw_ext_id id, unsigned long long *val,
65 unsigned int cpu)
66{
67 int msr;
68
69 switch (id) {
70 case PC8:
71 msr = MSR_PKG_C8_RESIDENCY;
72 break;
73 case PC9:
74 msr = MSR_PKG_C9_RESIDENCY;
75 break;
76 case PC10:
77 msr = MSR_PKG_C10_RESIDENCY;
78 break;
79 case TSC:
80 msr = MSR_TSC;
81 break;
82 default:
83 return -1;
84 };
85 if (read_msr(cpu, msr, val))
86 return -1;
87 return 0;
88}
89
90static int hsw_ext_get_count_percent(unsigned int id, double *percent,
91 unsigned int cpu)
92{
93 *percent = 0.0;
94
95 if (!is_valid[cpu])
96 return -1;
97
98 *percent = (100.0 *
99 (current_count[id][cpu] - previous_count[id][cpu])) /
100 (tsc_at_measure_end - tsc_at_measure_start);
101
102 dprint("%s: previous: %llu - current: %llu - (%u)\n",
103 hsw_ext_cstates[id].name, previous_count[id][cpu],
104 current_count[id][cpu], cpu);
105
106 dprint("%s: tsc_diff: %llu - count_diff: %llu - percent: %2.f (%u)\n",
107 hsw_ext_cstates[id].name,
108 (unsigned long long) tsc_at_measure_end - tsc_at_measure_start,
109 current_count[id][cpu] - previous_count[id][cpu],
110 *percent, cpu);
111
112 return 0;
113}
114
115static int hsw_ext_start(void)
116{
117 int num, cpu;
118 unsigned long long val;
119
120 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
121 for (cpu = 0; cpu < cpu_count; cpu++) {
122 hsw_ext_get_count(num, &val, cpu);
123 previous_count[num][cpu] = val;
124 }
125 }
126 hsw_ext_get_count(TSC, &tsc_at_measure_start, 0);
127 return 0;
128}
129
130static int hsw_ext_stop(void)
131{
132 unsigned long long val;
133 int num, cpu;
134
135 hsw_ext_get_count(TSC, &tsc_at_measure_end, 0);
136
137 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
138 for (cpu = 0; cpu < cpu_count; cpu++) {
139 is_valid[cpu] = !hsw_ext_get_count(num, &val, cpu);
140 current_count[num][cpu] = val;
141 }
142 }
143 return 0;
144}
145
146struct cpuidle_monitor intel_hsw_ext_monitor;
147
148static struct cpuidle_monitor *hsw_ext_register(void)
149{
150 int num;
151
152 if (cpupower_cpu_info.vendor != X86_VENDOR_INTEL
153 || cpupower_cpu_info.family != 6)
154 return NULL;
155
156 switch (cpupower_cpu_info.model) {
157 case 0x45: /* HSW */
158 break;
159 default:
160 return NULL;
161 }
162
163 is_valid = calloc(cpu_count, sizeof(int));
164 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
165 previous_count[num] = calloc(cpu_count,
166 sizeof(unsigned long long));
167 current_count[num] = calloc(cpu_count,
168 sizeof(unsigned long long));
169 }
170 intel_hsw_ext_monitor.name_len = strlen(intel_hsw_ext_monitor.name);
171 return &intel_hsw_ext_monitor;
172}
173
174void hsw_ext_unregister(void)
175{
176 int num;
177 free(is_valid);
178 for (num = 0; num < HSW_EXT_CSTATE_COUNT; num++) {
179 free(previous_count[num]);
180 free(current_count[num]);
181 }
182}
183
184struct cpuidle_monitor intel_hsw_ext_monitor = {
185 .name = "HaswellExtended",
186 .hw_states = hsw_ext_cstates,
187 .hw_states_num = HSW_EXT_CSTATE_COUNT,
188 .start = hsw_ext_start,
189 .stop = hsw_ext_stop,
190 .do_register = hsw_ext_register,
191 .unregister = hsw_ext_unregister,
192 .needs_root = 1,
193 .overflow_s = 922000000 /* 922337203 seconds TSC overflow
194 at 20GHz */
195};
196#endif /* defined(__i386__) || defined(__x86_64__) */
diff --git a/tools/power/cpupower/utils/idle_monitor/idle_monitors.def b/tools/power/cpupower/utils/idle_monitor/idle_monitors.def
index e3f8d9b2b18f..0d6ba4dbb9c7 100644
--- a/tools/power/cpupower/utils/idle_monitor/idle_monitors.def
+++ b/tools/power/cpupower/utils/idle_monitor/idle_monitors.def
@@ -2,6 +2,7 @@
2DEF(amd_fam14h) 2DEF(amd_fam14h)
3DEF(intel_nhm) 3DEF(intel_nhm)
4DEF(intel_snb) 4DEF(intel_snb)
5DEF(intel_hsw_ext)
5DEF(mperf) 6DEF(mperf)
6#endif 7#endif
7DEF(cpuidle_sysfs) 8DEF(cpuidle_sysfs)
diff --git a/tools/power/cpupower/utils/idle_monitor/snb_idle.c b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
index a99b43b97d6d..efc8a69c9aba 100644
--- a/tools/power/cpupower/utils/idle_monitor/snb_idle.c
+++ b/tools/power/cpupower/utils/idle_monitor/snb_idle.c
@@ -155,6 +155,10 @@ static struct cpuidle_monitor *snb_register(void)
155 case 0x2D: /* SNB Xeon */ 155 case 0x2D: /* SNB Xeon */
156 case 0x3A: /* IVB */ 156 case 0x3A: /* IVB */
157 case 0x3E: /* IVB Xeon */ 157 case 0x3E: /* IVB Xeon */
158 case 0x3C: /* HSW */
159 case 0x3F: /* HSW */
160 case 0x45: /* HSW */
161 case 0x46: /* HSW */
158 break; 162 break;
159 default: 163 default:
160 return NULL; 164 return NULL;
diff --git a/tools/scripts/Makefile.include b/tools/scripts/Makefile.include
index f03e681f8891..0d0506d55c71 100644
--- a/tools/scripts/Makefile.include
+++ b/tools/scripts/Makefile.include
@@ -59,7 +59,7 @@ QUIET_SUBDIR0 = +$(MAKE) $(COMMAND_O) -C # space to separate -C and subdir
59QUIET_SUBDIR1 = 59QUIET_SUBDIR1 =
60 60
61ifneq ($(findstring $(MAKEFLAGS),s),s) 61ifneq ($(findstring $(MAKEFLAGS),s),s)
62ifndef V 62ifneq ($(V),1)
63 QUIET_CC = @echo ' ' CC $@; 63 QUIET_CC = @echo ' ' CC $@;
64 QUIET_AR = @echo ' ' AR $@; 64 QUIET_AR = @echo ' ' AR $@;
65 QUIET_LINK = @echo ' ' LINK $@; 65 QUIET_LINK = @echo ' ' LINK $@;
diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl
index 0d7fd8b51544..999eab1bc64f 100755
--- a/tools/testing/ktest/ktest.pl
+++ b/tools/testing/ktest/ktest.pl
@@ -1796,7 +1796,7 @@ sub monitor {
1796 # We already booted into the kernel we are testing, 1796 # We already booted into the kernel we are testing,
1797 # but now we booted into another kernel? 1797 # but now we booted into another kernel?
1798 # Consider this a triple fault. 1798 # Consider this a triple fault.
1799 doprint "Aleady booted in Linux kernel $version, but now\n"; 1799 doprint "Already booted in Linux kernel $version, but now\n";
1800 doprint "we booted into Linux kernel $1.\n"; 1800 doprint "we booted into Linux kernel $1.\n";
1801 doprint "Assuming that this is a triple fault.\n"; 1801 doprint "Assuming that this is a triple fault.\n";
1802 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n"; 1802 doprint "To disable this: set DETECT_TRIPLE_FAULT to 0\n";
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
index 0a63658065f0..4cb14cae3791 100644
--- a/tools/testing/selftests/Makefile
+++ b/tools/testing/selftests/Makefile
@@ -6,6 +6,7 @@ TARGETS += memory-hotplug
6TARGETS += mqueue 6TARGETS += mqueue
7TARGETS += net 7TARGETS += net
8TARGETS += ptrace 8TARGETS += ptrace
9TARGETS += timers
9TARGETS += vm 10TARGETS += vm
10 11
11all: 12all:
diff --git a/tools/testing/selftests/cpu-hotplug/Makefile b/tools/testing/selftests/cpu-hotplug/Makefile
index 12657a5e4bf9..ae5faf9aade2 100644
--- a/tools/testing/selftests/cpu-hotplug/Makefile
+++ b/tools/testing/selftests/cpu-hotplug/Makefile
@@ -1,6 +1,6 @@
1all: 1all:
2 2
3run_tests: 3run_tests:
4 @./on-off-test.sh || echo "cpu-hotplug selftests: [FAIL]" 4 @/bin/sh ./on-off-test.sh || echo "cpu-hotplug selftests: [FAIL]"
5 5
6clean: 6clean:
diff --git a/tools/testing/selftests/kcmp/.gitignore b/tools/testing/selftests/kcmp/.gitignore
new file mode 100644
index 000000000000..5a9b3732b2de
--- /dev/null
+++ b/tools/testing/selftests/kcmp/.gitignore
@@ -0,0 +1,2 @@
1kcmp_test
2kcmp-test-file
diff --git a/tools/testing/selftests/kcmp/Makefile b/tools/testing/selftests/kcmp/Makefile
index 56eb5523dbb8..d7d6bbeeff2f 100644
--- a/tools/testing/selftests/kcmp/Makefile
+++ b/tools/testing/selftests/kcmp/Makefile
@@ -25,5 +25,4 @@ run_tests: all
25 @./kcmp_test || echo "kcmp_test: [FAIL]" 25 @./kcmp_test || echo "kcmp_test: [FAIL]"
26 26
27clean: 27clean:
28 rm -fr ./run_test 28 $(RM) kcmp_test kcmp-test-file
29 rm -fr ./test-file
diff --git a/tools/testing/selftests/memory-hotplug/Makefile b/tools/testing/selftests/memory-hotplug/Makefile
index 0f49c3f5f58d..350bfeda3aa8 100644
--- a/tools/testing/selftests/memory-hotplug/Makefile
+++ b/tools/testing/selftests/memory-hotplug/Makefile
@@ -1,6 +1,6 @@
1all: 1all:
2 2
3run_tests: 3run_tests:
4 @./on-off-test.sh || echo "memory-hotplug selftests: [FAIL]" 4 @/bin/sh ./on-off-test.sh || echo "memory-hotplug selftests: [FAIL]"
5 5
6clean: 6clean:
diff --git a/tools/testing/selftests/net/psock_tpacket.c b/tools/testing/selftests/net/psock_tpacket.c
index c41b58640a05..24adf709bd9d 100644
--- a/tools/testing/selftests/net/psock_tpacket.c
+++ b/tools/testing/selftests/net/psock_tpacket.c
@@ -1,6 +1,7 @@
1/* 1/*
2 * Copyright 2013 Red Hat, Inc. 2 * Copyright 2013 Red Hat, Inc.
3 * Author: Daniel Borkmann <dborkman@redhat.com> 3 * Author: Daniel Borkmann <dborkman@redhat.com>
4 * Chetan Loke <loke.chetan@gmail.com> (TPACKET_V3 usage example)
4 * 5 *
5 * A basic test of packet socket's TPACKET_V1/TPACKET_V2/TPACKET_V3 behavior. 6 * A basic test of packet socket's TPACKET_V1/TPACKET_V2/TPACKET_V3 behavior.
6 * 7 *
@@ -71,18 +72,8 @@
71# define __align_tpacket(x) __attribute__((aligned(TPACKET_ALIGN(x)))) 72# define __align_tpacket(x) __attribute__((aligned(TPACKET_ALIGN(x))))
72#endif 73#endif
73 74
74#define BLOCK_STATUS(x) ((x)->h1.block_status)
75#define BLOCK_NUM_PKTS(x) ((x)->h1.num_pkts)
76#define BLOCK_O2FP(x) ((x)->h1.offset_to_first_pkt)
77#define BLOCK_LEN(x) ((x)->h1.blk_len)
78#define BLOCK_SNUM(x) ((x)->h1.seq_num)
79#define BLOCK_O2PRIV(x) ((x)->offset_to_priv)
80#define BLOCK_PRIV(x) ((void *) ((uint8_t *) (x) + BLOCK_O2PRIV(x)))
81#define BLOCK_HDR_LEN (ALIGN_8(sizeof(struct block_desc)))
82#define ALIGN_8(x) (((x) + 8 - 1) & ~(8 - 1))
83#define BLOCK_PLUS_PRIV(sz_pri) (BLOCK_HDR_LEN + ALIGN_8((sz_pri)))
84
85#define NUM_PACKETS 100 75#define NUM_PACKETS 100
76#define ALIGN_8(x) (((x) + 8 - 1) & ~(8 - 1))
86 77
87struct ring { 78struct ring {
88 struct iovec *rd; 79 struct iovec *rd;
@@ -476,41 +467,30 @@ static uint64_t __v3_prev_block_seq_num = 0;
476 467
477void __v3_test_block_seq_num(struct block_desc *pbd) 468void __v3_test_block_seq_num(struct block_desc *pbd)
478{ 469{
479 if (__v3_prev_block_seq_num + 1 != BLOCK_SNUM(pbd)) { 470 if (__v3_prev_block_seq_num + 1 != pbd->h1.seq_num) {
480 fprintf(stderr, "\nprev_block_seq_num:%"PRIu64", expected " 471 fprintf(stderr, "\nprev_block_seq_num:%"PRIu64", expected "
481 "seq:%"PRIu64" != actual seq:%"PRIu64"\n", 472 "seq:%"PRIu64" != actual seq:%"PRIu64"\n",
482 __v3_prev_block_seq_num, __v3_prev_block_seq_num + 1, 473 __v3_prev_block_seq_num, __v3_prev_block_seq_num + 1,
483 (uint64_t) BLOCK_SNUM(pbd)); 474 (uint64_t) pbd->h1.seq_num);
484 exit(1); 475 exit(1);
485 } 476 }
486 477
487 __v3_prev_block_seq_num = BLOCK_SNUM(pbd); 478 __v3_prev_block_seq_num = pbd->h1.seq_num;
488} 479}
489 480
490static void __v3_test_block_len(struct block_desc *pbd, uint32_t bytes, int block_num) 481static void __v3_test_block_len(struct block_desc *pbd, uint32_t bytes, int block_num)
491{ 482{
492 if (BLOCK_NUM_PKTS(pbd)) { 483 if (pbd->h1.num_pkts && bytes != pbd->h1.blk_len) {
493 if (bytes != BLOCK_LEN(pbd)) { 484 fprintf(stderr, "\nblock:%u with %upackets, expected "
494 fprintf(stderr, "\nblock:%u with %upackets, expected " 485 "len:%u != actual len:%u\n", block_num,
495 "len:%u != actual len:%u\n", block_num, 486 pbd->h1.num_pkts, bytes, pbd->h1.blk_len);
496 BLOCK_NUM_PKTS(pbd), bytes, BLOCK_LEN(pbd)); 487 exit(1);
497 exit(1);
498 }
499 } else {
500 if (BLOCK_LEN(pbd) != BLOCK_PLUS_PRIV(13)) {
501 fprintf(stderr, "\nblock:%u, expected len:%lu != "
502 "actual len:%u\n", block_num, BLOCK_HDR_LEN,
503 BLOCK_LEN(pbd));
504 exit(1);
505 }
506 } 488 }
507} 489}
508 490
509static void __v3_test_block_header(struct block_desc *pbd, const int block_num) 491static void __v3_test_block_header(struct block_desc *pbd, const int block_num)
510{ 492{
511 uint32_t block_status = BLOCK_STATUS(pbd); 493 if ((pbd->h1.block_status & TP_STATUS_USER) == 0) {
512
513 if ((block_status & TP_STATUS_USER) == 0) {
514 fprintf(stderr, "\nblock %u: not in TP_STATUS_USER\n", block_num); 494 fprintf(stderr, "\nblock %u: not in TP_STATUS_USER\n", block_num);
515 exit(1); 495 exit(1);
516 } 496 }
@@ -520,14 +500,15 @@ static void __v3_test_block_header(struct block_desc *pbd, const int block_num)
520 500
521static void __v3_walk_block(struct block_desc *pbd, const int block_num) 501static void __v3_walk_block(struct block_desc *pbd, const int block_num)
522{ 502{
523 int num_pkts = BLOCK_NUM_PKTS(pbd), i; 503 int num_pkts = pbd->h1.num_pkts, i;
524 unsigned long bytes = 0; 504 unsigned long bytes = 0, bytes_with_padding = ALIGN_8(sizeof(*pbd));
525 unsigned long bytes_with_padding = BLOCK_PLUS_PRIV(13);
526 struct tpacket3_hdr *ppd; 505 struct tpacket3_hdr *ppd;
527 506
528 __v3_test_block_header(pbd, block_num); 507 __v3_test_block_header(pbd, block_num);
529 508
530 ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd + BLOCK_O2FP(pbd)); 509 ppd = (struct tpacket3_hdr *) ((uint8_t *) pbd +
510 pbd->h1.offset_to_first_pkt);
511
531 for (i = 0; i < num_pkts; ++i) { 512 for (i = 0; i < num_pkts; ++i) {
532 bytes += ppd->tp_snaplen; 513 bytes += ppd->tp_snaplen;
533 514
@@ -551,7 +532,7 @@ static void __v3_walk_block(struct block_desc *pbd, const int block_num)
551 532
552void __v3_flush_block(struct block_desc *pbd) 533void __v3_flush_block(struct block_desc *pbd)
553{ 534{
554 BLOCK_STATUS(pbd) = TP_STATUS_KERNEL; 535 pbd->h1.block_status = TP_STATUS_KERNEL;
555 __sync_synchronize(); 536 __sync_synchronize();
556} 537}
557 538
@@ -577,7 +558,7 @@ static void walk_v3_rx(int sock, struct ring *ring)
577 while (total_packets < NUM_PACKETS * 2) { 558 while (total_packets < NUM_PACKETS * 2) {
578 pbd = (struct block_desc *) ring->rd[block_num].iov_base; 559 pbd = (struct block_desc *) ring->rd[block_num].iov_base;
579 560
580 while ((BLOCK_STATUS(pbd) & TP_STATUS_USER) == 0) 561 while ((pbd->h1.block_status & TP_STATUS_USER) == 0)
581 poll(&pfd, 1, 1); 562 poll(&pfd, 1, 1);
582 563
583 __v3_walk_block(pbd, block_num); 564 __v3_walk_block(pbd, block_num);
@@ -624,8 +605,8 @@ static void __v1_v2_fill(struct ring *ring, unsigned int blocks)
624static void __v3_fill(struct ring *ring, unsigned int blocks) 605static void __v3_fill(struct ring *ring, unsigned int blocks)
625{ 606{
626 ring->req3.tp_retire_blk_tov = 64; 607 ring->req3.tp_retire_blk_tov = 64;
627 ring->req3.tp_sizeof_priv = 13; 608 ring->req3.tp_sizeof_priv = 0;
628 ring->req3.tp_feature_req_word |= TP_FT_REQ_FILL_RXHASH; 609 ring->req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
629 610
630 ring->req3.tp_block_size = getpagesize() << 2; 611 ring->req3.tp_block_size = getpagesize() << 2;
631 ring->req3.tp_frame_size = TPACKET_ALIGNMENT << 7; 612 ring->req3.tp_frame_size = TPACKET_ALIGNMENT << 7;
diff --git a/tools/testing/selftests/timers/Makefile b/tools/testing/selftests/timers/Makefile
new file mode 100644
index 000000000000..eb2859f4ad21
--- /dev/null
+++ b/tools/testing/selftests/timers/Makefile
@@ -0,0 +1,8 @@
1all:
2 gcc posix_timers.c -o posix_timers -lrt
3
4run_tests: all
5 ./posix_timers
6
7clean:
8 rm -f ./posix_timers
diff --git a/tools/testing/selftests/timers/posix_timers.c b/tools/testing/selftests/timers/posix_timers.c
new file mode 100644
index 000000000000..4fa655d68a81
--- /dev/null
+++ b/tools/testing/selftests/timers/posix_timers.c
@@ -0,0 +1,221 @@
1/*
2 * Copyright (C) 2013 Red Hat, Inc., Frederic Weisbecker <fweisbec@redhat.com>
3 *
4 * Licensed under the terms of the GNU GPL License version 2
5 *
6 * Selftests for a few posix timers interface.
7 *
8 * Kernel loop code stolen from Steven Rostedt <srostedt@redhat.com>
9 */
10
11#include <sys/time.h>
12#include <stdio.h>
13#include <signal.h>
14#include <unistd.h>
15#include <time.h>
16#include <pthread.h>
17
18#define DELAY 2
19#define USECS_PER_SEC 1000000
20
21static volatile int done;
22
23/* Busy loop in userspace to elapse ITIMER_VIRTUAL */
24static void user_loop(void)
25{
26 while (!done);
27}
28
29/*
30 * Try to spend as much time as possible in kernelspace
31 * to elapse ITIMER_PROF.
32 */
33static void kernel_loop(void)
34{
35 void *addr = sbrk(0);
36
37 while (!done) {
38 brk(addr + 4096);
39 brk(addr);
40 }
41}
42
43/*
44 * Sleep until ITIMER_REAL expiration.
45 */
46static void idle_loop(void)
47{
48 pause();
49}
50
51static void sig_handler(int nr)
52{
53 done = 1;
54}
55
56/*
57 * Check the expected timer expiration matches the GTOD elapsed delta since
58 * we armed the timer. Keep a 0.5 sec error margin due to various jitter.
59 */
60static int check_diff(struct timeval start, struct timeval end)
61{
62 long long diff;
63
64 diff = end.tv_usec - start.tv_usec;
65 diff += (end.tv_sec - start.tv_sec) * USECS_PER_SEC;
66
67 if (abs(diff - DELAY * USECS_PER_SEC) > USECS_PER_SEC / 2) {
68 printf("Diff too high: %lld..", diff);
69 return -1;
70 }
71
72 return 0;
73}
74
75static int check_itimer(int which)
76{
77 int err;
78 struct timeval start, end;
79 struct itimerval val = {
80 .it_value.tv_sec = DELAY,
81 };
82
83 printf("Check itimer ");
84
85 if (which == ITIMER_VIRTUAL)
86 printf("virtual... ");
87 else if (which == ITIMER_PROF)
88 printf("prof... ");
89 else if (which == ITIMER_REAL)
90 printf("real... ");
91
92 fflush(stdout);
93
94 done = 0;
95
96 if (which == ITIMER_VIRTUAL)
97 signal(SIGVTALRM, sig_handler);
98 else if (which == ITIMER_PROF)
99 signal(SIGPROF, sig_handler);
100 else if (which == ITIMER_REAL)
101 signal(SIGALRM, sig_handler);
102
103 err = gettimeofday(&start, NULL);
104 if (err < 0) {
105 perror("Can't call gettimeofday()\n");
106 return -1;
107 }
108
109 err = setitimer(which, &val, NULL);
110 if (err < 0) {
111 perror("Can't set timer\n");
112 return -1;
113 }
114
115 if (which == ITIMER_VIRTUAL)
116 user_loop();
117 else if (which == ITIMER_PROF)
118 kernel_loop();
119 else if (which == ITIMER_REAL)
120 idle_loop();
121
122 gettimeofday(&end, NULL);
123 if (err < 0) {
124 perror("Can't call gettimeofday()\n");
125 return -1;
126 }
127
128 if (!check_diff(start, end))
129 printf("[OK]\n");
130 else
131 printf("[FAIL]\n");
132
133 return 0;
134}
135
136static int check_timer_create(int which)
137{
138 int err;
139 timer_t id;
140 struct timeval start, end;
141 struct itimerspec val = {
142 .it_value.tv_sec = DELAY,
143 };
144
145 printf("Check timer_create() ");
146 if (which == CLOCK_THREAD_CPUTIME_ID) {
147 printf("per thread... ");
148 } else if (which == CLOCK_PROCESS_CPUTIME_ID) {
149 printf("per process... ");
150 }
151 fflush(stdout);
152
153 done = 0;
154 timer_create(which, NULL, &id);
155 if (err < 0) {
156 perror("Can't create timer\n");
157 return -1;
158 }
159 signal(SIGALRM, sig_handler);
160
161 err = gettimeofday(&start, NULL);
162 if (err < 0) {
163 perror("Can't call gettimeofday()\n");
164 return -1;
165 }
166
167 err = timer_settime(id, 0, &val, NULL);
168 if (err < 0) {
169 perror("Can't set timer\n");
170 return -1;
171 }
172
173 user_loop();
174
175 gettimeofday(&end, NULL);
176 if (err < 0) {
177 perror("Can't call gettimeofday()\n");
178 return -1;
179 }
180
181 if (!check_diff(start, end))
182 printf("[OK]\n");
183 else
184 printf("[FAIL]\n");
185
186 return 0;
187}
188
189int main(int argc, char **argv)
190{
191 int err;
192
193 printf("Testing posix timers. False negative may happen on CPU execution \n");
194 printf("based timers if other threads run on the CPU...\n");
195
196 if (check_itimer(ITIMER_VIRTUAL) < 0)
197 return -1;
198
199 if (check_itimer(ITIMER_PROF) < 0)
200 return -1;
201
202 if (check_itimer(ITIMER_REAL) < 0)
203 return -1;
204
205 if (check_timer_create(CLOCK_THREAD_CPUTIME_ID) < 0)
206 return -1;
207
208 /*
209 * It's unfortunately hard to reliably test a timer expiration
210 * on parallel multithread cputime. We could arm it to expire
211 * on DELAY * nr_threads, with nr_threads busy looping, then wait
212 * the normal DELAY since the time is elapsing nr_threads faster.
213 * But for that we need to ensure we have real physical free CPUs
214 * to ensure true parallelism. So test only one thread until we
215 * find a better solution.
216 */
217 if (check_timer_create(CLOCK_PROCESS_CPUTIME_ID) < 0)
218 return -1;
219
220 return 0;
221}
diff --git a/tools/testing/selftests/vm/.gitignore b/tools/testing/selftests/vm/.gitignore
new file mode 100644
index 000000000000..ff1bb16cec4f
--- /dev/null
+++ b/tools/testing/selftests/vm/.gitignore
@@ -0,0 +1,4 @@
1hugepage-mmap
2hugepage-shm
3map_hugetlb
4thuge-gen
diff --git a/tools/testing/selftests/vm/Makefile b/tools/testing/selftests/vm/Makefile
index 436d2e81868b..3f94e1afd6cf 100644
--- a/tools/testing/selftests/vm/Makefile
+++ b/tools/testing/selftests/vm/Makefile
@@ -2,13 +2,14 @@
2 2
3CC = $(CROSS_COMPILE)gcc 3CC = $(CROSS_COMPILE)gcc
4CFLAGS = -Wall 4CFLAGS = -Wall
5BINARIES = hugepage-mmap hugepage-shm map_hugetlb thuge-gen hugetlbfstest
5 6
6all: hugepage-mmap hugepage-shm map_hugetlb thuge-gen 7all: $(BINARIES)
7%: %.c 8%: %.c
8 $(CC) $(CFLAGS) -o $@ $^ 9 $(CC) $(CFLAGS) -o $@ $^
9 10
10run_tests: all 11run_tests: all
11 @/bin/sh ./run_vmtests || echo "vmtests: [FAIL]" 12 @/bin/sh ./run_vmtests || (echo "vmtests: [FAIL]"; exit 1)
12 13
13clean: 14clean:
14 $(RM) hugepage-mmap hugepage-shm map_hugetlb 15 $(RM) $(BINARIES)
diff --git a/tools/testing/selftests/vm/hugetlbfstest.c b/tools/testing/selftests/vm/hugetlbfstest.c
new file mode 100644
index 000000000000..ea40ff8c2391
--- /dev/null
+++ b/tools/testing/selftests/vm/hugetlbfstest.c
@@ -0,0 +1,84 @@
1#define _GNU_SOURCE
2#include <assert.h>
3#include <fcntl.h>
4#include <stdio.h>
5#include <stdlib.h>
6#include <string.h>
7#include <sys/mman.h>
8#include <sys/stat.h>
9#include <sys/types.h>
10#include <unistd.h>
11
12typedef unsigned long long u64;
13
14static size_t length = 1 << 24;
15
16static u64 read_rss(void)
17{
18 char buf[4096], *s = buf;
19 int i, fd;
20 u64 rss;
21
22 fd = open("/proc/self/statm", O_RDONLY);
23 assert(fd > 2);
24 memset(buf, 0, sizeof(buf));
25 read(fd, buf, sizeof(buf) - 1);
26 for (i = 0; i < 1; i++)
27 s = strchr(s, ' ') + 1;
28 rss = strtoull(s, NULL, 10);
29 return rss << 12; /* assumes 4k pagesize */
30}
31
32static void do_mmap(int fd, int extra_flags, int unmap)
33{
34 int *p;
35 int flags = MAP_PRIVATE | MAP_POPULATE | extra_flags;
36 u64 before, after;
37
38 before = read_rss();
39 p = mmap(NULL, length, PROT_READ | PROT_WRITE, flags, fd, 0);
40 assert(p != MAP_FAILED ||
41 !"mmap returned an unexpected error");
42 after = read_rss();
43 assert(llabs(after - before - length) < 0x40000 ||
44 !"rss didn't grow as expected");
45 if (!unmap)
46 return;
47 munmap(p, length);
48 after = read_rss();
49 assert(llabs(after - before) < 0x40000 ||
50 !"rss didn't shrink as expected");
51}
52
53static int open_file(const char *path)
54{
55 int fd, err;
56
57 unlink(path);
58 fd = open(path, O_CREAT | O_RDWR | O_TRUNC | O_EXCL
59 | O_LARGEFILE | O_CLOEXEC, 0600);
60 assert(fd > 2);
61 unlink(path);
62 err = ftruncate(fd, length);
63 assert(!err);
64 return fd;
65}
66
67int main(void)
68{
69 int hugefd, fd;
70
71 fd = open_file("/dev/shm/hugetlbhog");
72 hugefd = open_file("/hugepages/hugetlbhog");
73
74 system("echo 100 > /proc/sys/vm/nr_hugepages");
75 do_mmap(-1, MAP_ANONYMOUS, 1);
76 do_mmap(fd, 0, 1);
77 do_mmap(-1, MAP_ANONYMOUS | MAP_HUGETLB, 1);
78 do_mmap(hugefd, 0, 1);
79 do_mmap(hugefd, MAP_HUGETLB, 1);
80 /* Leak the last one to test do_exit() */
81 do_mmap(-1, MAP_ANONYMOUS | MAP_HUGETLB, 0);
82 printf("oll korrekt.\n");
83 return 0;
84}
diff --git a/tools/testing/selftests/vm/run_vmtests b/tools/testing/selftests/vm/run_vmtests
index 4c53cae6c273..c87b6812300d 100644
--- a/tools/testing/selftests/vm/run_vmtests
+++ b/tools/testing/selftests/vm/run_vmtests
@@ -4,6 +4,7 @@
4#we need 256M, below is the size in kB 4#we need 256M, below is the size in kB
5needmem=262144 5needmem=262144
6mnt=./huge 6mnt=./huge
7exitcode=0
7 8
8#get pagesize and freepages from /proc/meminfo 9#get pagesize and freepages from /proc/meminfo
9while read name size unit; do 10while read name size unit; do
@@ -41,6 +42,7 @@ echo "--------------------"
41./hugepage-mmap 42./hugepage-mmap
42if [ $? -ne 0 ]; then 43if [ $? -ne 0 ]; then
43 echo "[FAIL]" 44 echo "[FAIL]"
45 exitcode=1
44else 46else
45 echo "[PASS]" 47 echo "[PASS]"
46fi 48fi
@@ -55,6 +57,7 @@ echo "--------------------"
55./hugepage-shm 57./hugepage-shm
56if [ $? -ne 0 ]; then 58if [ $? -ne 0 ]; then
57 echo "[FAIL]" 59 echo "[FAIL]"
60 exitcode=1
58else 61else
59 echo "[PASS]" 62 echo "[PASS]"
60fi 63fi
@@ -67,6 +70,18 @@ echo "--------------------"
67./map_hugetlb 70./map_hugetlb
68if [ $? -ne 0 ]; then 71if [ $? -ne 0 ]; then
69 echo "[FAIL]" 72 echo "[FAIL]"
73 exitcode=1
74else
75 echo "[PASS]"
76fi
77
78echo "--------------------"
79echo "running hugetlbfstest"
80echo "--------------------"
81./hugetlbfstest
82if [ $? -ne 0 ]; then
83 echo "[FAIL]"
84 exitcode=1
70else 85else
71 echo "[PASS]" 86 echo "[PASS]"
72fi 87fi
@@ -75,3 +90,4 @@ fi
75umount $mnt 90umount $mnt
76rm -rf $mnt 91rm -rf $mnt
77echo $nr_hugepgs > /proc/sys/vm/nr_hugepages 92echo $nr_hugepgs > /proc/sys/vm/nr_hugepages
93exit $exitcode
diff --git a/tools/virtio/linux/module.h b/tools/virtio/linux/module.h
index 3039a7e972b6..28ce95a05997 100644
--- a/tools/virtio/linux/module.h
+++ b/tools/virtio/linux/module.h
@@ -1 +1,6 @@
1#include <linux/export.h> 1#include <linux/export.h>
2
3#define MODULE_LICENSE(__MODULE_LICENSE_value) \
4 static __attribute__((unused)) const char *__MODULE_LICENSE_name = \
5 __MODULE_LICENSE_value
6
diff --git a/tools/virtio/linux/virtio.h b/tools/virtio/linux/virtio.h
index cd801838156f..844783040703 100644
--- a/tools/virtio/linux/virtio.h
+++ b/tools/virtio/linux/virtio.h
@@ -45,9 +45,6 @@ struct virtqueue {
45 void *priv; 45 void *priv;
46}; 46};
47 47
48#define MODULE_LICENSE(__MODULE_LICENSE_value) \
49 const char *__MODULE_LICENSE_name = __MODULE_LICENSE_value
50
51/* Interfaces exported by virtio_ring. */ 48/* Interfaces exported by virtio_ring. */
52int virtqueue_add_sgs(struct virtqueue *vq, 49int virtqueue_add_sgs(struct virtqueue *vq,
53 struct scatterlist *sgs[], 50 struct scatterlist *sgs[],