diff options
author | Ingo Molnar <mingo@kernel.org> | 2019-01-03 08:05:16 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2019-01-03 08:05:16 -0500 |
commit | 2573be22e5b6f24a0cabc97715c808c47e29eaaf (patch) | |
tree | d00e6cc4c2718c0122fc1a7bbd804864037deae0 | |
parent | 6d101ba6be2a26a3e1f513b5e293f0fd2b79ec5c (diff) | |
parent | b25756df5b28cd7b6e91200fc5012e7c76e8ec69 (diff) |
Merge tag 'perf-core-for-mingo-4.21-20190103' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent
Pull perf/core improvements and fixes from Arnaldo Carvalho de Melo:
perf c2c:
Jiri Olsa:
- Change the default coalesce setup to from '--coalesce pid,iaddr' to just '--coalesce iaddr'.
- Increase the HITM ratio limit for displayed cachelines.
perf script:
Andi Kleen:
- Fix LBR skid dump problems in brstackinsn.
perf trace:
Arnaldo Carvalho de Melo:
- Check if the raw_syscalls:sys_{enter,exit} are setup before setting tp filter.
- Do not hardcode the size of the tracepoint common_ fields.
- Beautify USBDEFFS_ ioctl commands.
Colin Ian King:
- Use correct SECCOMP prefix spelling, "SECOMP_*" -> "SECCOMP_*".
perf python:
Jiri Olsa:
- Do not force closing original perf descriptor in evlist.get_pollfd().
tools misc:
Jiri Olsa:
- Allow overriding CFLAGS and LDFLAGS.
perf build:
Stanislav Fomichev:
- Don't unconditionally link the libbfd feature test to -liberty and -lz
thread-stack:
Adrian Hunter:
- Fix processing for the idle task, having a stack per cpu.
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
27 files changed, 620 insertions, 166 deletions
diff --git a/tools/build/Makefile.feature b/tools/build/Makefile.feature index d47b8f73e2e7..5467c6bf9ceb 100644 --- a/tools/build/Makefile.feature +++ b/tools/build/Makefile.feature | |||
@@ -82,8 +82,8 @@ FEATURE_TESTS_EXTRA := \ | |||
82 | cplus-demangle \ | 82 | cplus-demangle \ |
83 | hello \ | 83 | hello \ |
84 | libbabeltrace \ | 84 | libbabeltrace \ |
85 | liberty \ | 85 | libbfd-liberty \ |
86 | liberty-z \ | 86 | libbfd-liberty-z \ |
87 | libunwind-debug-frame \ | 87 | libunwind-debug-frame \ |
88 | libunwind-debug-frame-arm \ | 88 | libunwind-debug-frame-arm \ |
89 | libunwind-debug-frame-aarch64 \ | 89 | libunwind-debug-frame-aarch64 \ |
diff --git a/tools/build/feature/Makefile b/tools/build/feature/Makefile index 2dbcc0d00f52..7ceb4441b627 100644 --- a/tools/build/feature/Makefile +++ b/tools/build/feature/Makefile | |||
@@ -17,8 +17,8 @@ FILES= \ | |||
17 | test-libbfd.bin \ | 17 | test-libbfd.bin \ |
18 | test-disassembler-four-args.bin \ | 18 | test-disassembler-four-args.bin \ |
19 | test-reallocarray.bin \ | 19 | test-reallocarray.bin \ |
20 | test-liberty.bin \ | 20 | test-libbfd-liberty.bin \ |
21 | test-liberty-z.bin \ | 21 | test-libbfd-liberty-z.bin \ |
22 | test-cplus-demangle.bin \ | 22 | test-cplus-demangle.bin \ |
23 | test-libelf.bin \ | 23 | test-libelf.bin \ |
24 | test-libelf-getphdrnum.bin \ | 24 | test-libelf-getphdrnum.bin \ |
@@ -210,7 +210,7 @@ $(OUTPUT)test-libpython-version.bin: | |||
210 | $(BUILD) | 210 | $(BUILD) |
211 | 211 | ||
212 | $(OUTPUT)test-libbfd.bin: | 212 | $(OUTPUT)test-libbfd.bin: |
213 | $(BUILD) -DPACKAGE='"perf"' -lbfd -lz -liberty -ldl | 213 | $(BUILD) -DPACKAGE='"perf"' -lbfd -ldl |
214 | 214 | ||
215 | $(OUTPUT)test-disassembler-four-args.bin: | 215 | $(OUTPUT)test-disassembler-four-args.bin: |
216 | $(BUILD) -DPACKAGE='"perf"' -lbfd -lopcodes | 216 | $(BUILD) -DPACKAGE='"perf"' -lbfd -lopcodes |
@@ -218,10 +218,10 @@ $(OUTPUT)test-disassembler-four-args.bin: | |||
218 | $(OUTPUT)test-reallocarray.bin: | 218 | $(OUTPUT)test-reallocarray.bin: |
219 | $(BUILD) | 219 | $(BUILD) |
220 | 220 | ||
221 | $(OUTPUT)test-liberty.bin: | 221 | $(OUTPUT)test-libbfd-liberty.bin: |
222 | $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty | 222 | $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty |
223 | 223 | ||
224 | $(OUTPUT)test-liberty-z.bin: | 224 | $(OUTPUT)test-libbfd-liberty-z.bin: |
225 | $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty -lz | 225 | $(CC) $(CFLAGS) -Wall -Werror -o $@ test-libbfd.c -DPACKAGE='"perf"' $(LDFLAGS) -lbfd -ldl -liberty -lz |
226 | 226 | ||
227 | $(OUTPUT)test-cplus-demangle.bin: | 227 | $(OUTPUT)test-cplus-demangle.bin: |
diff --git a/tools/gpio/Makefile b/tools/gpio/Makefile index 240eda014b37..6ecdd1067826 100644 --- a/tools/gpio/Makefile +++ b/tools/gpio/Makefile | |||
@@ -12,7 +12,7 @@ endif | |||
12 | # (this improves performance and avoids hard-to-debug behaviour); | 12 | # (this improves performance and avoids hard-to-debug behaviour); |
13 | MAKEFLAGS += -r | 13 | MAKEFLAGS += -r |
14 | 14 | ||
15 | CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include | 15 | override CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include |
16 | 16 | ||
17 | ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon | 17 | ALL_TARGETS := lsgpio gpio-hammer gpio-event-mon |
18 | ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) | 18 | ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS)) |
diff --git a/tools/include/uapi/linux/usbdevice_fs.h b/tools/include/uapi/linux/usbdevice_fs.h new file mode 100644 index 000000000000..964e87217be4 --- /dev/null +++ b/tools/include/uapi/linux/usbdevice_fs.h | |||
@@ -0,0 +1,201 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0+ WITH Linux-syscall-note */ | ||
2 | /*****************************************************************************/ | ||
3 | |||
4 | /* | ||
5 | * usbdevice_fs.h -- USB device file system. | ||
6 | * | ||
7 | * Copyright (C) 2000 | ||
8 | * Thomas Sailer (sailer@ife.ee.ethz.ch) | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License as published by | ||
12 | * the Free Software Foundation; either version 2 of the License, or | ||
13 | * (at your option) any later version. | ||
14 | * | ||
15 | * This program is distributed in the hope that it will be useful, | ||
16 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
18 | * GNU General Public License for more details. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License | ||
21 | * along with this program; if not, write to the Free Software | ||
22 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | * | ||
24 | * History: | ||
25 | * 0.1 04.01.2000 Created | ||
26 | */ | ||
27 | |||
28 | /*****************************************************************************/ | ||
29 | |||
30 | #ifndef _UAPI_LINUX_USBDEVICE_FS_H | ||
31 | #define _UAPI_LINUX_USBDEVICE_FS_H | ||
32 | |||
33 | #include <linux/types.h> | ||
34 | #include <linux/magic.h> | ||
35 | |||
36 | /* --------------------------------------------------------------------- */ | ||
37 | |||
38 | /* usbdevfs ioctl codes */ | ||
39 | |||
40 | struct usbdevfs_ctrltransfer { | ||
41 | __u8 bRequestType; | ||
42 | __u8 bRequest; | ||
43 | __u16 wValue; | ||
44 | __u16 wIndex; | ||
45 | __u16 wLength; | ||
46 | __u32 timeout; /* in milliseconds */ | ||
47 | void __user *data; | ||
48 | }; | ||
49 | |||
50 | struct usbdevfs_bulktransfer { | ||
51 | unsigned int ep; | ||
52 | unsigned int len; | ||
53 | unsigned int timeout; /* in milliseconds */ | ||
54 | void __user *data; | ||
55 | }; | ||
56 | |||
57 | struct usbdevfs_setinterface { | ||
58 | unsigned int interface; | ||
59 | unsigned int altsetting; | ||
60 | }; | ||
61 | |||
62 | struct usbdevfs_disconnectsignal { | ||
63 | unsigned int signr; | ||
64 | void __user *context; | ||
65 | }; | ||
66 | |||
67 | #define USBDEVFS_MAXDRIVERNAME 255 | ||
68 | |||
69 | struct usbdevfs_getdriver { | ||
70 | unsigned int interface; | ||
71 | char driver[USBDEVFS_MAXDRIVERNAME + 1]; | ||
72 | }; | ||
73 | |||
74 | struct usbdevfs_connectinfo { | ||
75 | unsigned int devnum; | ||
76 | unsigned char slow; | ||
77 | }; | ||
78 | |||
79 | #define USBDEVFS_URB_SHORT_NOT_OK 0x01 | ||
80 | #define USBDEVFS_URB_ISO_ASAP 0x02 | ||
81 | #define USBDEVFS_URB_BULK_CONTINUATION 0x04 | ||
82 | #define USBDEVFS_URB_NO_FSBR 0x20 /* Not used */ | ||
83 | #define USBDEVFS_URB_ZERO_PACKET 0x40 | ||
84 | #define USBDEVFS_URB_NO_INTERRUPT 0x80 | ||
85 | |||
86 | #define USBDEVFS_URB_TYPE_ISO 0 | ||
87 | #define USBDEVFS_URB_TYPE_INTERRUPT 1 | ||
88 | #define USBDEVFS_URB_TYPE_CONTROL 2 | ||
89 | #define USBDEVFS_URB_TYPE_BULK 3 | ||
90 | |||
91 | struct usbdevfs_iso_packet_desc { | ||
92 | unsigned int length; | ||
93 | unsigned int actual_length; | ||
94 | unsigned int status; | ||
95 | }; | ||
96 | |||
97 | struct usbdevfs_urb { | ||
98 | unsigned char type; | ||
99 | unsigned char endpoint; | ||
100 | int status; | ||
101 | unsigned int flags; | ||
102 | void __user *buffer; | ||
103 | int buffer_length; | ||
104 | int actual_length; | ||
105 | int start_frame; | ||
106 | union { | ||
107 | int number_of_packets; /* Only used for isoc urbs */ | ||
108 | unsigned int stream_id; /* Only used with bulk streams */ | ||
109 | }; | ||
110 | int error_count; | ||
111 | unsigned int signr; /* signal to be sent on completion, | ||
112 | or 0 if none should be sent. */ | ||
113 | void __user *usercontext; | ||
114 | struct usbdevfs_iso_packet_desc iso_frame_desc[0]; | ||
115 | }; | ||
116 | |||
117 | /* ioctls for talking directly to drivers */ | ||
118 | struct usbdevfs_ioctl { | ||
119 | int ifno; /* interface 0..N ; negative numbers reserved */ | ||
120 | int ioctl_code; /* MUST encode size + direction of data so the | ||
121 | * macros in <asm/ioctl.h> give correct values */ | ||
122 | void __user *data; /* param buffer (in, or out) */ | ||
123 | }; | ||
124 | |||
125 | /* You can do most things with hubs just through control messages, | ||
126 | * except find out what device connects to what port. */ | ||
127 | struct usbdevfs_hub_portinfo { | ||
128 | char nports; /* number of downstream ports in this hub */ | ||
129 | char port [127]; /* e.g. port 3 connects to device 27 */ | ||
130 | }; | ||
131 | |||
132 | /* System and bus capability flags */ | ||
133 | #define USBDEVFS_CAP_ZERO_PACKET 0x01 | ||
134 | #define USBDEVFS_CAP_BULK_CONTINUATION 0x02 | ||
135 | #define USBDEVFS_CAP_NO_PACKET_SIZE_LIM 0x04 | ||
136 | #define USBDEVFS_CAP_BULK_SCATTER_GATHER 0x08 | ||
137 | #define USBDEVFS_CAP_REAP_AFTER_DISCONNECT 0x10 | ||
138 | #define USBDEVFS_CAP_MMAP 0x20 | ||
139 | #define USBDEVFS_CAP_DROP_PRIVILEGES 0x40 | ||
140 | |||
141 | /* USBDEVFS_DISCONNECT_CLAIM flags & struct */ | ||
142 | |||
143 | /* disconnect-and-claim if the driver matches the driver field */ | ||
144 | #define USBDEVFS_DISCONNECT_CLAIM_IF_DRIVER 0x01 | ||
145 | /* disconnect-and-claim except when the driver matches the driver field */ | ||
146 | #define USBDEVFS_DISCONNECT_CLAIM_EXCEPT_DRIVER 0x02 | ||
147 | |||
148 | struct usbdevfs_disconnect_claim { | ||
149 | unsigned int interface; | ||
150 | unsigned int flags; | ||
151 | char driver[USBDEVFS_MAXDRIVERNAME + 1]; | ||
152 | }; | ||
153 | |||
154 | struct usbdevfs_streams { | ||
155 | unsigned int num_streams; /* Not used by USBDEVFS_FREE_STREAMS */ | ||
156 | unsigned int num_eps; | ||
157 | unsigned char eps[0]; | ||
158 | }; | ||
159 | |||
160 | /* | ||
161 | * USB_SPEED_* values returned by USBDEVFS_GET_SPEED are defined in | ||
162 | * linux/usb/ch9.h | ||
163 | */ | ||
164 | |||
165 | #define USBDEVFS_CONTROL _IOWR('U', 0, struct usbdevfs_ctrltransfer) | ||
166 | #define USBDEVFS_CONTROL32 _IOWR('U', 0, struct usbdevfs_ctrltransfer32) | ||
167 | #define USBDEVFS_BULK _IOWR('U', 2, struct usbdevfs_bulktransfer) | ||
168 | #define USBDEVFS_BULK32 _IOWR('U', 2, struct usbdevfs_bulktransfer32) | ||
169 | #define USBDEVFS_RESETEP _IOR('U', 3, unsigned int) | ||
170 | #define USBDEVFS_SETINTERFACE _IOR('U', 4, struct usbdevfs_setinterface) | ||
171 | #define USBDEVFS_SETCONFIGURATION _IOR('U', 5, unsigned int) | ||
172 | #define USBDEVFS_GETDRIVER _IOW('U', 8, struct usbdevfs_getdriver) | ||
173 | #define USBDEVFS_SUBMITURB _IOR('U', 10, struct usbdevfs_urb) | ||
174 | #define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32) | ||
175 | #define USBDEVFS_DISCARDURB _IO('U', 11) | ||
176 | #define USBDEVFS_REAPURB _IOW('U', 12, void *) | ||
177 | #define USBDEVFS_REAPURB32 _IOW('U', 12, __u32) | ||
178 | #define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *) | ||
179 | #define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, __u32) | ||
180 | #define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal) | ||
181 | #define USBDEVFS_DISCSIGNAL32 _IOR('U', 14, struct usbdevfs_disconnectsignal32) | ||
182 | #define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int) | ||
183 | #define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int) | ||
184 | #define USBDEVFS_CONNECTINFO _IOW('U', 17, struct usbdevfs_connectinfo) | ||
185 | #define USBDEVFS_IOCTL _IOWR('U', 18, struct usbdevfs_ioctl) | ||
186 | #define USBDEVFS_IOCTL32 _IOWR('U', 18, struct usbdevfs_ioctl32) | ||
187 | #define USBDEVFS_HUB_PORTINFO _IOR('U', 19, struct usbdevfs_hub_portinfo) | ||
188 | #define USBDEVFS_RESET _IO('U', 20) | ||
189 | #define USBDEVFS_CLEAR_HALT _IOR('U', 21, unsigned int) | ||
190 | #define USBDEVFS_DISCONNECT _IO('U', 22) | ||
191 | #define USBDEVFS_CONNECT _IO('U', 23) | ||
192 | #define USBDEVFS_CLAIM_PORT _IOR('U', 24, unsigned int) | ||
193 | #define USBDEVFS_RELEASE_PORT _IOR('U', 25, unsigned int) | ||
194 | #define USBDEVFS_GET_CAPABILITIES _IOR('U', 26, __u32) | ||
195 | #define USBDEVFS_DISCONNECT_CLAIM _IOR('U', 27, struct usbdevfs_disconnect_claim) | ||
196 | #define USBDEVFS_ALLOC_STREAMS _IOR('U', 28, struct usbdevfs_streams) | ||
197 | #define USBDEVFS_FREE_STREAMS _IOR('U', 29, struct usbdevfs_streams) | ||
198 | #define USBDEVFS_DROP_PRIVILEGES _IOW('U', 30, __u32) | ||
199 | #define USBDEVFS_GET_SPEED _IO('U', 31) | ||
200 | |||
201 | #endif /* _UAPI_LINUX_USBDEVICE_FS_H */ | ||
diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config index 07c1857c3d7a..b441c88cafa1 100644 --- a/tools/perf/Makefile.config +++ b/tools/perf/Makefile.config | |||
@@ -702,18 +702,20 @@ endif | |||
702 | 702 | ||
703 | ifeq ($(feature-libbfd), 1) | 703 | ifeq ($(feature-libbfd), 1) |
704 | EXTLIBS += -lbfd | 704 | EXTLIBS += -lbfd |
705 | else | ||
706 | # we are on a system that requires -liberty and (maybe) -lz | ||
707 | # to link against -lbfd; test each case individually here | ||
705 | 708 | ||
706 | # call all detections now so we get correct | 709 | # call all detections now so we get correct |
707 | # status in VF output | 710 | # status in VF output |
708 | $(call feature_check,liberty) | 711 | $(call feature_check,libbfd-liberty) |
709 | $(call feature_check,liberty-z) | 712 | $(call feature_check,libbfd-liberty-z) |
710 | $(call feature_check,cplus-demangle) | ||
711 | 713 | ||
712 | ifeq ($(feature-liberty), 1) | 714 | ifeq ($(feature-libbfd-liberty), 1) |
713 | EXTLIBS += -liberty | 715 | EXTLIBS += -lbfd -liberty |
714 | else | 716 | else |
715 | ifeq ($(feature-liberty-z), 1) | 717 | ifeq ($(feature-libbfd-liberty-z), 1) |
716 | EXTLIBS += -liberty -lz | 718 | EXTLIBS += -lbfd -liberty -lz |
717 | endif | 719 | endif |
718 | endif | 720 | endif |
719 | endif | 721 | endif |
@@ -723,24 +725,24 @@ ifdef NO_DEMANGLE | |||
723 | else | 725 | else |
724 | ifdef HAVE_CPLUS_DEMANGLE_SUPPORT | 726 | ifdef HAVE_CPLUS_DEMANGLE_SUPPORT |
725 | EXTLIBS += -liberty | 727 | EXTLIBS += -liberty |
726 | CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT | ||
727 | else | 728 | else |
728 | ifneq ($(feature-libbfd), 1) | 729 | ifeq ($(filter -liberty,$(EXTLIBS)),) |
729 | ifneq ($(feature-liberty), 1) | 730 | $(call feature_check,cplus-demangle) |
730 | ifneq ($(feature-liberty-z), 1) | 731 | |
731 | # we dont have neither HAVE_CPLUS_DEMANGLE_SUPPORT | 732 | # we dont have neither HAVE_CPLUS_DEMANGLE_SUPPORT |
732 | # or any of 'bfd iberty z' trinity | 733 | # or any of 'bfd iberty z' trinity |
733 | ifeq ($(feature-cplus-demangle), 1) | 734 | ifeq ($(feature-cplus-demangle), 1) |
734 | EXTLIBS += -liberty | 735 | EXTLIBS += -liberty |
735 | CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT | 736 | else |
736 | else | 737 | msg := $(warning No bfd.h/libbfd found, please install binutils-dev[el]/zlib-static/libiberty-dev to gain symbol demangling) |
737 | msg := $(warning No bfd.h/libbfd found, please install binutils-dev[el]/zlib-static/libiberty-dev to gain symbol demangling) | 738 | CFLAGS += -DNO_DEMANGLE |
738 | CFLAGS += -DNO_DEMANGLE | ||
739 | endif | ||
740 | endif | ||
741 | endif | 739 | endif |
742 | endif | 740 | endif |
743 | endif | 741 | endif |
742 | |||
743 | ifneq ($(filter -liberty,$(EXTLIBS)),) | ||
744 | CFLAGS += -DHAVE_CPLUS_DEMANGLE_SUPPORT | ||
745 | endif | ||
744 | endif | 746 | endif |
745 | 747 | ||
746 | ifneq ($(filter -lbfd,$(EXTLIBS)),) | 748 | ifneq ($(filter -lbfd,$(EXTLIBS)),) |
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf index bd23e3f30895..ff29c3372ec3 100644 --- a/tools/perf/Makefile.perf +++ b/tools/perf/Makefile.perf | |||
@@ -497,6 +497,12 @@ prctl_option_tbl := $(srctree)/tools/perf/trace/beauty/prctl_option.sh | |||
497 | $(prctl_option_array): $(prctl_hdr_dir)/prctl.h $(prctl_option_tbl) | 497 | $(prctl_option_array): $(prctl_hdr_dir)/prctl.h $(prctl_option_tbl) |
498 | $(Q)$(SHELL) '$(prctl_option_tbl)' $(prctl_hdr_dir) > $@ | 498 | $(Q)$(SHELL) '$(prctl_option_tbl)' $(prctl_hdr_dir) > $@ |
499 | 499 | ||
500 | usbdevfs_ioctl_array := $(beauty_ioctl_outdir)/usbdevfs_ioctl_array.c | ||
501 | usbdevfs_ioctl_tbl := $(srctree)/tools/perf/trace/beauty/usbdevfs_ioctl.sh | ||
502 | |||
503 | $(usbdevfs_ioctl_array): $(linux_uapi_dir)/usbdevice_fs.h $(usbdevfs_ioctl_tbl) | ||
504 | $(Q)$(SHELL) '$(usbdevfs_ioctl_tbl)' $(linux_uapi_dir) > $@ | ||
505 | |||
500 | x86_arch_prctl_code_array := $(beauty_outdir)/x86_arch_prctl_code_array.c | 506 | x86_arch_prctl_code_array := $(beauty_outdir)/x86_arch_prctl_code_array.c |
501 | x86_arch_prctl_code_tbl := $(srctree)/tools/perf/trace/beauty/x86_arch_prctl.sh | 507 | x86_arch_prctl_code_tbl := $(srctree)/tools/perf/trace/beauty/x86_arch_prctl.sh |
502 | 508 | ||
@@ -624,6 +630,7 @@ prepare: $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h archheaders $(drm_ioc | |||
624 | $(mount_flags_array) \ | 630 | $(mount_flags_array) \ |
625 | $(perf_ioctl_array) \ | 631 | $(perf_ioctl_array) \ |
626 | $(prctl_option_array) \ | 632 | $(prctl_option_array) \ |
633 | $(usbdevfs_ioctl_array) \ | ||
627 | $(x86_arch_prctl_code_array) \ | 634 | $(x86_arch_prctl_code_array) \ |
628 | $(rename_flags_array) \ | 635 | $(rename_flags_array) \ |
629 | $(arch_errno_name_array) | 636 | $(arch_errno_name_array) |
@@ -923,6 +930,7 @@ clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clea | |||
923 | $(OUTPUT)$(vhost_virtio_ioctl_array) \ | 930 | $(OUTPUT)$(vhost_virtio_ioctl_array) \ |
924 | $(OUTPUT)$(perf_ioctl_array) \ | 931 | $(OUTPUT)$(perf_ioctl_array) \ |
925 | $(OUTPUT)$(prctl_option_array) \ | 932 | $(OUTPUT)$(prctl_option_array) \ |
933 | $(OUTPUT)$(usbdevfs_ioctl_array) \ | ||
926 | $(OUTPUT)$(x86_arch_prctl_code_array) \ | 934 | $(OUTPUT)$(x86_arch_prctl_code_array) \ |
927 | $(OUTPUT)$(rename_flags_array) \ | 935 | $(OUTPUT)$(rename_flags_array) \ |
928 | $(OUTPUT)$(arch_errno_name_array) | 936 | $(OUTPUT)$(arch_errno_name_array) |
diff --git a/tools/perf/builtin-c2c.c b/tools/perf/builtin-c2c.c index f3aa9d02a5ab..d340d2e42776 100644 --- a/tools/perf/builtin-c2c.c +++ b/tools/perf/builtin-c2c.c | |||
@@ -68,7 +68,7 @@ struct c2c_hist_entry { | |||
68 | struct hist_entry he; | 68 | struct hist_entry he; |
69 | }; | 69 | }; |
70 | 70 | ||
71 | static char const *coalesce_default = "pid,iaddr"; | 71 | static char const *coalesce_default = "iaddr"; |
72 | 72 | ||
73 | struct perf_c2c { | 73 | struct perf_c2c { |
74 | struct perf_tool tool; | 74 | struct perf_tool tool; |
@@ -1878,7 +1878,7 @@ static int c2c_hists__reinit(struct c2c_hists *c2c_hists, | |||
1878 | return hpp_list__parse(&c2c_hists->list, output, sort); | 1878 | return hpp_list__parse(&c2c_hists->list, output, sort); |
1879 | } | 1879 | } |
1880 | 1880 | ||
1881 | #define DISPLAY_LINE_LIMIT 0.0005 | 1881 | #define DISPLAY_LINE_LIMIT 0.001 |
1882 | 1882 | ||
1883 | static bool he__display(struct hist_entry *he, struct c2c_stats *stats) | 1883 | static bool he__display(struct hist_entry *he, struct c2c_stats *stats) |
1884 | { | 1884 | { |
diff --git a/tools/perf/builtin-script.c b/tools/perf/builtin-script.c index 3728b50e52e2..d079f36d342d 100644 --- a/tools/perf/builtin-script.c +++ b/tools/perf/builtin-script.c | |||
@@ -1073,9 +1073,18 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, | |||
1073 | 1073 | ||
1074 | /* | 1074 | /* |
1075 | * Print final block upto sample | 1075 | * Print final block upto sample |
1076 | * | ||
1077 | * Due to pipeline delays the LBRs might be missing a branch | ||
1078 | * or two, which can result in very large or negative blocks | ||
1079 | * between final branch and sample. When this happens just | ||
1080 | * continue walking after the last TO until we hit a branch. | ||
1076 | */ | 1081 | */ |
1077 | start = br->entries[0].to; | 1082 | start = br->entries[0].to; |
1078 | end = sample->ip; | 1083 | end = sample->ip; |
1084 | if (end < start) { | ||
1085 | /* Missing jump. Scan 128 bytes for the next branch */ | ||
1086 | end = start + 128; | ||
1087 | } | ||
1079 | len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true); | 1088 | len = grab_bb(buffer, start, end, machine, thread, &x.is64bit, &x.cpumode, true); |
1080 | printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp); | 1089 | printed += ip__fprintf_sym(start, thread, x.cpumode, x.cpu, &lastsym, attr, fp); |
1081 | if (len <= 0) { | 1090 | if (len <= 0) { |
@@ -1084,7 +1093,6 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, | |||
1084 | machine, thread, &x.is64bit, &x.cpumode, false); | 1093 | machine, thread, &x.is64bit, &x.cpumode, false); |
1085 | if (len <= 0) | 1094 | if (len <= 0) |
1086 | goto out; | 1095 | goto out; |
1087 | |||
1088 | printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip, | 1096 | printed += fprintf(fp, "\t%016" PRIx64 "\t%s\n", sample->ip, |
1089 | dump_insn(&x, sample->ip, buffer, len, NULL)); | 1097 | dump_insn(&x, sample->ip, buffer, len, NULL)); |
1090 | if (PRINT_FIELD(SRCCODE)) | 1098 | if (PRINT_FIELD(SRCCODE)) |
@@ -1096,6 +1104,13 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, | |||
1096 | dump_insn(&x, start + off, buffer + off, len - off, &ilen)); | 1104 | dump_insn(&x, start + off, buffer + off, len - off, &ilen)); |
1097 | if (ilen == 0) | 1105 | if (ilen == 0) |
1098 | break; | 1106 | break; |
1107 | if (arch_is_branch(buffer + off, len - off, x.is64bit) && start + off != sample->ip) { | ||
1108 | /* | ||
1109 | * Hit a missing branch. Just stop. | ||
1110 | */ | ||
1111 | printed += fprintf(fp, "\t... not reaching sample ...\n"); | ||
1112 | break; | ||
1113 | } | ||
1099 | if (PRINT_FIELD(SRCCODE)) | 1114 | if (PRINT_FIELD(SRCCODE)) |
1100 | print_srccode(thread, x.cpumode, start + off); | 1115 | print_srccode(thread, x.cpumode, start + off); |
1101 | } | 1116 | } |
@@ -1167,7 +1182,7 @@ static int perf_sample__fprintf_callindent(struct perf_sample *sample, | |||
1167 | struct addr_location *al, FILE *fp) | 1182 | struct addr_location *al, FILE *fp) |
1168 | { | 1183 | { |
1169 | struct perf_event_attr *attr = &evsel->attr; | 1184 | struct perf_event_attr *attr = &evsel->attr; |
1170 | size_t depth = thread_stack__depth(thread); | 1185 | size_t depth = thread_stack__depth(thread, sample->cpu); |
1171 | const char *name = NULL; | 1186 | const char *name = NULL; |
1172 | static int spacing; | 1187 | static int spacing; |
1173 | int len = 0; | 1188 | int len = 0; |
@@ -1701,7 +1716,7 @@ static bool show_event(struct perf_sample *sample, | |||
1701 | struct thread *thread, | 1716 | struct thread *thread, |
1702 | struct addr_location *al) | 1717 | struct addr_location *al) |
1703 | { | 1718 | { |
1704 | int depth = thread_stack__depth(thread); | 1719 | int depth = thread_stack__depth(thread, sample->cpu); |
1705 | 1720 | ||
1706 | if (!symbol_conf.graph_function) | 1721 | if (!symbol_conf.graph_function) |
1707 | return true; | 1722 | return true; |
diff --git a/tools/perf/builtin-trace.c b/tools/perf/builtin-trace.c index ebde59e61133..adbf28183560 100644 --- a/tools/perf/builtin-trace.c +++ b/tools/perf/builtin-trace.c | |||
@@ -60,6 +60,7 @@ | |||
60 | #include <linux/stringify.h> | 60 | #include <linux/stringify.h> |
61 | #include <linux/time64.h> | 61 | #include <linux/time64.h> |
62 | #include <fcntl.h> | 62 | #include <fcntl.h> |
63 | #include <sys/sysmacros.h> | ||
63 | 64 | ||
64 | #include "sane_ctype.h" | 65 | #include "sane_ctype.h" |
65 | 66 | ||
@@ -112,8 +113,9 @@ struct trace { | |||
112 | } stats; | 113 | } stats; |
113 | unsigned int max_stack; | 114 | unsigned int max_stack; |
114 | unsigned int min_stack; | 115 | unsigned int min_stack; |
115 | bool sort_events; | 116 | int raw_augmented_syscalls_args_size; |
116 | bool raw_augmented_syscalls; | 117 | bool raw_augmented_syscalls; |
118 | bool sort_events; | ||
117 | bool not_ev_qualifier; | 119 | bool not_ev_qualifier; |
118 | bool live; | 120 | bool live; |
119 | bool full_time; | 121 | bool full_time; |
@@ -283,12 +285,17 @@ out_delete: | |||
283 | return -ENOENT; | 285 | return -ENOENT; |
284 | } | 286 | } |
285 | 287 | ||
286 | static int perf_evsel__init_augmented_syscall_tp(struct perf_evsel *evsel) | 288 | static int perf_evsel__init_augmented_syscall_tp(struct perf_evsel *evsel, struct perf_evsel *tp) |
287 | { | 289 | { |
288 | struct syscall_tp *sc = evsel->priv = malloc(sizeof(struct syscall_tp)); | 290 | struct syscall_tp *sc = evsel->priv = malloc(sizeof(struct syscall_tp)); |
289 | 291 | ||
290 | if (evsel->priv != NULL) { /* field, sizeof_field, offsetof_field */ | 292 | if (evsel->priv != NULL) { |
291 | if (__tp_field__init_uint(&sc->id, sizeof(long), sizeof(long long), evsel->needs_swap)) | 293 | struct tep_format_field *syscall_id = perf_evsel__field(tp, "id"); |
294 | if (syscall_id == NULL) | ||
295 | syscall_id = perf_evsel__field(tp, "__syscall_nr"); | ||
296 | if (syscall_id == NULL) | ||
297 | goto out_delete; | ||
298 | if (__tp_field__init_uint(&sc->id, syscall_id->size, syscall_id->offset, evsel->needs_swap)) | ||
292 | goto out_delete; | 299 | goto out_delete; |
293 | 300 | ||
294 | return 0; | 301 | return 0; |
@@ -974,9 +981,9 @@ struct thread_trace { | |||
974 | char *name; | 981 | char *name; |
975 | } filename; | 982 | } filename; |
976 | struct { | 983 | struct { |
977 | int max; | 984 | int max; |
978 | char **table; | 985 | struct file *table; |
979 | } paths; | 986 | } files; |
980 | 987 | ||
981 | struct intlist *syscall_stats; | 988 | struct intlist *syscall_stats; |
982 | }; | 989 | }; |
@@ -986,7 +993,7 @@ static struct thread_trace *thread_trace__new(void) | |||
986 | struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace)); | 993 | struct thread_trace *ttrace = zalloc(sizeof(struct thread_trace)); |
987 | 994 | ||
988 | if (ttrace) | 995 | if (ttrace) |
989 | ttrace->paths.max = -1; | 996 | ttrace->files.max = -1; |
990 | 997 | ||
991 | ttrace->syscall_stats = intlist__new(NULL); | 998 | ttrace->syscall_stats = intlist__new(NULL); |
992 | 999 | ||
@@ -1030,30 +1037,48 @@ void syscall_arg__set_ret_scnprintf(struct syscall_arg *arg, | |||
1030 | 1037 | ||
1031 | static const size_t trace__entry_str_size = 2048; | 1038 | static const size_t trace__entry_str_size = 2048; |
1032 | 1039 | ||
1033 | static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) | 1040 | static struct file *thread_trace__files_entry(struct thread_trace *ttrace, int fd) |
1034 | { | 1041 | { |
1035 | struct thread_trace *ttrace = thread__priv(thread); | 1042 | if (fd > ttrace->files.max) { |
1036 | 1043 | struct file *nfiles = realloc(ttrace->files.table, (fd + 1) * sizeof(struct file)); | |
1037 | if (fd > ttrace->paths.max) { | ||
1038 | char **npath = realloc(ttrace->paths.table, (fd + 1) * sizeof(char *)); | ||
1039 | 1044 | ||
1040 | if (npath == NULL) | 1045 | if (nfiles == NULL) |
1041 | return -1; | 1046 | return NULL; |
1042 | 1047 | ||
1043 | if (ttrace->paths.max != -1) { | 1048 | if (ttrace->files.max != -1) { |
1044 | memset(npath + ttrace->paths.max + 1, 0, | 1049 | memset(nfiles + ttrace->files.max + 1, 0, |
1045 | (fd - ttrace->paths.max) * sizeof(char *)); | 1050 | (fd - ttrace->files.max) * sizeof(struct file)); |
1046 | } else { | 1051 | } else { |
1047 | memset(npath, 0, (fd + 1) * sizeof(char *)); | 1052 | memset(nfiles, 0, (fd + 1) * sizeof(struct file)); |
1048 | } | 1053 | } |
1049 | 1054 | ||
1050 | ttrace->paths.table = npath; | 1055 | ttrace->files.table = nfiles; |
1051 | ttrace->paths.max = fd; | 1056 | ttrace->files.max = fd; |
1052 | } | 1057 | } |
1053 | 1058 | ||
1054 | ttrace->paths.table[fd] = strdup(pathname); | 1059 | return ttrace->files.table + fd; |
1060 | } | ||
1055 | 1061 | ||
1056 | return ttrace->paths.table[fd] != NULL ? 0 : -1; | 1062 | struct file *thread__files_entry(struct thread *thread, int fd) |
1063 | { | ||
1064 | return thread_trace__files_entry(thread__priv(thread), fd); | ||
1065 | } | ||
1066 | |||
1067 | static int trace__set_fd_pathname(struct thread *thread, int fd, const char *pathname) | ||
1068 | { | ||
1069 | struct thread_trace *ttrace = thread__priv(thread); | ||
1070 | struct file *file = thread_trace__files_entry(ttrace, fd); | ||
1071 | |||
1072 | if (file != NULL) { | ||
1073 | struct stat st; | ||
1074 | if (stat(pathname, &st) == 0) | ||
1075 | file->dev_maj = major(st.st_rdev); | ||
1076 | file->pathname = strdup(pathname); | ||
1077 | if (file->pathname) | ||
1078 | return 0; | ||
1079 | } | ||
1080 | |||
1081 | return -1; | ||
1057 | } | 1082 | } |
1058 | 1083 | ||
1059 | static int thread__read_fd_path(struct thread *thread, int fd) | 1084 | static int thread__read_fd_path(struct thread *thread, int fd) |
@@ -1093,7 +1118,7 @@ static const char *thread__fd_path(struct thread *thread, int fd, | |||
1093 | if (fd < 0) | 1118 | if (fd < 0) |
1094 | return NULL; | 1119 | return NULL; |
1095 | 1120 | ||
1096 | if ((fd > ttrace->paths.max || ttrace->paths.table[fd] == NULL)) { | 1121 | if ((fd > ttrace->files.max || ttrace->files.table[fd].pathname == NULL)) { |
1097 | if (!trace->live) | 1122 | if (!trace->live) |
1098 | return NULL; | 1123 | return NULL; |
1099 | ++trace->stats.proc_getname; | 1124 | ++trace->stats.proc_getname; |
@@ -1101,7 +1126,7 @@ static const char *thread__fd_path(struct thread *thread, int fd, | |||
1101 | return NULL; | 1126 | return NULL; |
1102 | } | 1127 | } |
1103 | 1128 | ||
1104 | return ttrace->paths.table[fd]; | 1129 | return ttrace->files.table[fd].pathname; |
1105 | } | 1130 | } |
1106 | 1131 | ||
1107 | size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg) | 1132 | size_t syscall_arg__scnprintf_fd(char *bf, size_t size, struct syscall_arg *arg) |
@@ -1140,8 +1165,8 @@ static size_t syscall_arg__scnprintf_close_fd(char *bf, size_t size, | |||
1140 | size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); | 1165 | size_t printed = syscall_arg__scnprintf_fd(bf, size, arg); |
1141 | struct thread_trace *ttrace = thread__priv(arg->thread); | 1166 | struct thread_trace *ttrace = thread__priv(arg->thread); |
1142 | 1167 | ||
1143 | if (ttrace && fd >= 0 && fd <= ttrace->paths.max) | 1168 | if (ttrace && fd >= 0 && fd <= ttrace->files.max) |
1144 | zfree(&ttrace->paths.table[fd]); | 1169 | zfree(&ttrace->files.table[fd].pathname); |
1145 | 1170 | ||
1146 | return printed; | 1171 | return printed; |
1147 | } | 1172 | } |
@@ -1768,16 +1793,16 @@ static int trace__fprintf_sample(struct trace *trace, struct perf_evsel *evsel, | |||
1768 | return printed; | 1793 | return printed; |
1769 | } | 1794 | } |
1770 | 1795 | ||
1771 | static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sample, int *augmented_args_size, bool raw_augmented) | 1796 | static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sample, int *augmented_args_size, int raw_augmented_args_size) |
1772 | { | 1797 | { |
1773 | void *augmented_args = NULL; | 1798 | void *augmented_args = NULL; |
1774 | /* | 1799 | /* |
1775 | * For now with BPF raw_augmented we hook into raw_syscalls:sys_enter | 1800 | * For now with BPF raw_augmented we hook into raw_syscalls:sys_enter |
1776 | * and there we get all 6 syscall args plus the tracepoint common | 1801 | * and there we get all 6 syscall args plus the tracepoint common fields |
1777 | * fields (sizeof(long)) and the syscall_nr (another long). So we check | 1802 | * that gets calculated at the start and the syscall_nr (another long). |
1778 | * if that is the case and if so don't look after the sc->args_size, | 1803 | * So we check if that is the case and if so don't look after the |
1779 | * but always after the full raw_syscalls:sys_enter payload, which is | 1804 | * sc->args_size but always after the full raw_syscalls:sys_enter payload, |
1780 | * fixed. | 1805 | * which is fixed. |
1781 | * | 1806 | * |
1782 | * We'll revisit this later to pass s->args_size to the BPF augmenter | 1807 | * We'll revisit this later to pass s->args_size to the BPF augmenter |
1783 | * (now tools/perf/examples/bpf/augmented_raw_syscalls.c, so that it | 1808 | * (now tools/perf/examples/bpf/augmented_raw_syscalls.c, so that it |
@@ -1785,7 +1810,7 @@ static void *syscall__augmented_args(struct syscall *sc, struct perf_sample *sam | |||
1785 | * use syscalls:sys_enter_NAME, so that we reduce the kernel/userspace | 1810 | * use syscalls:sys_enter_NAME, so that we reduce the kernel/userspace |
1786 | * traffic to just what is needed for each syscall. | 1811 | * traffic to just what is needed for each syscall. |
1787 | */ | 1812 | */ |
1788 | int args_size = raw_augmented ? (8 * (int)sizeof(long)) : sc->args_size; | 1813 | int args_size = raw_augmented_args_size ?: sc->args_size; |
1789 | 1814 | ||
1790 | *augmented_args_size = sample->raw_size - args_size; | 1815 | *augmented_args_size = sample->raw_size - args_size; |
1791 | if (*augmented_args_size > 0) | 1816 | if (*augmented_args_size > 0) |
@@ -1839,7 +1864,7 @@ static int trace__sys_enter(struct trace *trace, struct perf_evsel *evsel, | |||
1839 | * here and avoid using augmented syscalls when the evsel is the raw_syscalls one. | 1864 | * here and avoid using augmented syscalls when the evsel is the raw_syscalls one. |
1840 | */ | 1865 | */ |
1841 | if (evsel != trace->syscalls.events.sys_enter) | 1866 | if (evsel != trace->syscalls.events.sys_enter) |
1842 | augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size, trace->raw_augmented_syscalls); | 1867 | augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size, trace->raw_augmented_syscalls_args_size); |
1843 | ttrace->entry_time = sample->time; | 1868 | ttrace->entry_time = sample->time; |
1844 | msg = ttrace->entry_str; | 1869 | msg = ttrace->entry_str; |
1845 | printed += scnprintf(msg + printed, trace__entry_str_size - printed, "%s(", sc->name); | 1870 | printed += scnprintf(msg + printed, trace__entry_str_size - printed, "%s(", sc->name); |
@@ -1897,7 +1922,7 @@ static int trace__fprintf_sys_enter(struct trace *trace, struct perf_evsel *evse | |||
1897 | goto out_put; | 1922 | goto out_put; |
1898 | 1923 | ||
1899 | args = perf_evsel__sc_tp_ptr(evsel, args, sample); | 1924 | args = perf_evsel__sc_tp_ptr(evsel, args, sample); |
1900 | augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size, trace->raw_augmented_syscalls); | 1925 | augmented_args = syscall__augmented_args(sc, sample, &augmented_args_size, trace->raw_augmented_syscalls_args_size); |
1901 | syscall__scnprintf_args(sc, msg, sizeof(msg), args, augmented_args, augmented_args_size, trace, thread); | 1926 | syscall__scnprintf_args(sc, msg, sizeof(msg), args, augmented_args, augmented_args_size, trace, thread); |
1902 | fprintf(trace->output, "%s", msg); | 1927 | fprintf(trace->output, "%s", msg); |
1903 | err = 0; | 1928 | err = 0; |
@@ -2686,7 +2711,9 @@ static int trace__set_ev_qualifier_filter(struct trace *trace) | |||
2686 | { | 2711 | { |
2687 | if (trace->syscalls.map) | 2712 | if (trace->syscalls.map) |
2688 | return trace__set_ev_qualifier_bpf_filter(trace); | 2713 | return trace__set_ev_qualifier_bpf_filter(trace); |
2689 | return trace__set_ev_qualifier_tp_filter(trace); | 2714 | if (trace->syscalls.events.sys_enter) |
2715 | return trace__set_ev_qualifier_tp_filter(trace); | ||
2716 | return 0; | ||
2690 | } | 2717 | } |
2691 | 2718 | ||
2692 | static int bpf_map__set_filter_pids(struct bpf_map *map __maybe_unused, | 2719 | static int bpf_map__set_filter_pids(struct bpf_map *map __maybe_unused, |
@@ -3812,13 +3839,6 @@ int cmd_trace(int argc, const char **argv) | |||
3812 | * syscall. | 3839 | * syscall. |
3813 | */ | 3840 | */ |
3814 | if (trace.syscalls.events.augmented) { | 3841 | if (trace.syscalls.events.augmented) { |
3815 | evsel = trace.syscalls.events.augmented; | ||
3816 | |||
3817 | if (perf_evsel__init_augmented_syscall_tp(evsel) || | ||
3818 | perf_evsel__init_augmented_syscall_tp_args(evsel)) | ||
3819 | goto out; | ||
3820 | evsel->handler = trace__sys_enter; | ||
3821 | |||
3822 | evlist__for_each_entry(trace.evlist, evsel) { | 3842 | evlist__for_each_entry(trace.evlist, evsel) { |
3823 | bool raw_syscalls_sys_exit = strcmp(perf_evsel__name(evsel), "raw_syscalls:sys_exit") == 0; | 3843 | bool raw_syscalls_sys_exit = strcmp(perf_evsel__name(evsel), "raw_syscalls:sys_exit") == 0; |
3824 | 3844 | ||
@@ -3827,9 +3847,41 @@ int cmd_trace(int argc, const char **argv) | |||
3827 | goto init_augmented_syscall_tp; | 3847 | goto init_augmented_syscall_tp; |
3828 | } | 3848 | } |
3829 | 3849 | ||
3850 | if (strcmp(perf_evsel__name(evsel), "raw_syscalls:sys_enter") == 0) { | ||
3851 | struct perf_evsel *augmented = trace.syscalls.events.augmented; | ||
3852 | if (perf_evsel__init_augmented_syscall_tp(augmented, evsel) || | ||
3853 | perf_evsel__init_augmented_syscall_tp_args(augmented)) | ||
3854 | goto out; | ||
3855 | augmented->handler = trace__sys_enter; | ||
3856 | } | ||
3857 | |||
3830 | if (strstarts(perf_evsel__name(evsel), "syscalls:sys_exit_")) { | 3858 | if (strstarts(perf_evsel__name(evsel), "syscalls:sys_exit_")) { |
3859 | struct syscall_tp *sc; | ||
3831 | init_augmented_syscall_tp: | 3860 | init_augmented_syscall_tp: |
3832 | perf_evsel__init_augmented_syscall_tp(evsel); | 3861 | if (perf_evsel__init_augmented_syscall_tp(evsel, evsel)) |
3862 | goto out; | ||
3863 | sc = evsel->priv; | ||
3864 | /* | ||
3865 | * For now with BPF raw_augmented we hook into | ||
3866 | * raw_syscalls:sys_enter and there we get all | ||
3867 | * 6 syscall args plus the tracepoint common | ||
3868 | * fields and the syscall_nr (another long). | ||
3869 | * So we check if that is the case and if so | ||
3870 | * don't look after the sc->args_size but | ||
3871 | * always after the full raw_syscalls:sys_enter | ||
3872 | * payload, which is fixed. | ||
3873 | * | ||
3874 | * We'll revisit this later to pass | ||
3875 | * s->args_size to the BPF augmenter (now | ||
3876 | * tools/perf/examples/bpf/augmented_raw_syscalls.c, | ||
3877 | * so that it copies only what we need for each | ||
3878 | * syscall, like what happens when we use | ||
3879 | * syscalls:sys_enter_NAME, so that we reduce | ||
3880 | * the kernel/userspace traffic to just what is | ||
3881 | * needed for each syscall. | ||
3882 | */ | ||
3883 | if (trace.raw_augmented_syscalls) | ||
3884 | trace.raw_augmented_syscalls_args_size = (6 + 1) * sizeof(long) + sc->id.offset; | ||
3833 | perf_evsel__init_augmented_syscall_tp_ret(evsel); | 3885 | perf_evsel__init_augmented_syscall_tp_ret(evsel); |
3834 | evsel->handler = trace__sys_exit; | 3886 | evsel->handler = trace__sys_exit; |
3835 | } | 3887 | } |
diff --git a/tools/perf/check-headers.sh b/tools/perf/check-headers.sh index 8e811ea0cf85..6cb98f8570a2 100755 --- a/tools/perf/check-headers.sh +++ b/tools/perf/check-headers.sh | |||
@@ -14,6 +14,7 @@ include/uapi/linux/perf_event.h | |||
14 | include/uapi/linux/prctl.h | 14 | include/uapi/linux/prctl.h |
15 | include/uapi/linux/sched.h | 15 | include/uapi/linux/sched.h |
16 | include/uapi/linux/stat.h | 16 | include/uapi/linux/stat.h |
17 | include/uapi/linux/usbdevice_fs.h | ||
17 | include/uapi/linux/vhost.h | 18 | include/uapi/linux/vhost.h |
18 | include/uapi/sound/asound.h | 19 | include/uapi/sound/asound.h |
19 | include/linux/bits.h | 20 | include/linux/bits.h |
diff --git a/tools/perf/trace/beauty/beauty.h b/tools/perf/trace/beauty/beauty.h index 83c5b202e00e..139d485a6f16 100644 --- a/tools/perf/trace/beauty/beauty.h +++ b/tools/perf/trace/beauty/beauty.h | |||
@@ -32,6 +32,13 @@ size_t strarray__scnprintf_flags(struct strarray *sa, char *bf, size_t size, boo | |||
32 | struct trace; | 32 | struct trace; |
33 | struct thread; | 33 | struct thread; |
34 | 34 | ||
35 | struct file { | ||
36 | char *pathname; | ||
37 | int dev_maj; | ||
38 | }; | ||
39 | |||
40 | struct file *thread__files_entry(struct thread *thread, int fd); | ||
41 | |||
35 | struct strarrays { | 42 | struct strarrays { |
36 | int nr_entries; | 43 | int nr_entries; |
37 | struct strarray **entries; | 44 | struct strarray **entries; |
diff --git a/tools/perf/trace/beauty/ioctl.c b/tools/perf/trace/beauty/ioctl.c index 9efeb6a936c2..620350d41209 100644 --- a/tools/perf/trace/beauty/ioctl.c +++ b/tools/perf/trace/beauty/ioctl.c | |||
@@ -112,6 +112,17 @@ static size_t ioctl__scnprintf_perf_cmd(int nr, int dir, char *bf, size_t size) | |||
112 | return scnprintf(bf, size, "(%#x, %#x, %#x)", 0xAE, nr, dir); | 112 | return scnprintf(bf, size, "(%#x, %#x, %#x)", 0xAE, nr, dir); |
113 | } | 113 | } |
114 | 114 | ||
115 | static size_t ioctl__scnprintf_usbdevfs_cmd(int nr, int dir, char *bf, size_t size) | ||
116 | { | ||
117 | #include "trace/beauty/generated/ioctl/usbdevfs_ioctl_array.c" | ||
118 | static DEFINE_STRARRAY(usbdevfs_ioctl_cmds, ""); | ||
119 | |||
120 | if (nr < strarray__usbdevfs_ioctl_cmds.nr_entries && strarray__usbdevfs_ioctl_cmds.entries[nr] != NULL) | ||
121 | return scnprintf(bf, size, "USBDEVFS_%s", strarray__usbdevfs_ioctl_cmds.entries[nr]); | ||
122 | |||
123 | return scnprintf(bf, size, "(%c, %#x, %#x)", 'U', nr, dir); | ||
124 | } | ||
125 | |||
115 | static size_t ioctl__scnprintf_cmd(unsigned long cmd, char *bf, size_t size, bool show_prefix) | 126 | static size_t ioctl__scnprintf_cmd(unsigned long cmd, char *bf, size_t size, bool show_prefix) |
116 | { | 127 | { |
117 | const char *prefix = "_IOC_"; | 128 | const char *prefix = "_IOC_"; |
@@ -157,9 +168,20 @@ static size_t ioctl__scnprintf_cmd(unsigned long cmd, char *bf, size_t size, boo | |||
157 | return printed + scnprintf(bf + printed, size - printed, ", %#x, %#x, %#x)", type, nr, sz); | 168 | return printed + scnprintf(bf + printed, size - printed, ", %#x, %#x, %#x)", type, nr, sz); |
158 | } | 169 | } |
159 | 170 | ||
171 | #ifndef USB_DEVICE_MAJOR | ||
172 | #define USB_DEVICE_MAJOR 189 | ||
173 | #endif // USB_DEVICE_MAJOR | ||
174 | |||
160 | size_t syscall_arg__scnprintf_ioctl_cmd(char *bf, size_t size, struct syscall_arg *arg) | 175 | size_t syscall_arg__scnprintf_ioctl_cmd(char *bf, size_t size, struct syscall_arg *arg) |
161 | { | 176 | { |
162 | unsigned long cmd = arg->val; | 177 | unsigned long cmd = arg->val; |
178 | unsigned int fd = syscall_arg__val(arg, 0); | ||
179 | struct file *file = thread__files_entry(arg->thread, fd); | ||
180 | |||
181 | if (file != NULL) { | ||
182 | if (file->dev_maj == USB_DEVICE_MAJOR) | ||
183 | return ioctl__scnprintf_usbdevfs_cmd(_IOC_NR(cmd), _IOC_DIR(cmd), bf, size); | ||
184 | } | ||
163 | 185 | ||
164 | return ioctl__scnprintf_cmd(cmd, bf, size, arg->show_string_prefix); | 186 | return ioctl__scnprintf_cmd(cmd, bf, size, arg->show_string_prefix); |
165 | } | 187 | } |
diff --git a/tools/perf/trace/beauty/mmap.c b/tools/perf/trace/beauty/mmap.c index eb31089790e3..859a8a9db2c6 100644 --- a/tools/perf/trace/beauty/mmap.c +++ b/tools/perf/trace/beauty/mmap.c | |||
@@ -18,8 +18,8 @@ static size_t syscall_arg__scnprintf_mmap_prot(char *bf, size_t size, | |||
18 | } | 18 | } |
19 | 19 | ||
20 | P_MMAP_PROT(READ); | 20 | P_MMAP_PROT(READ); |
21 | P_MMAP_PROT(EXEC); | ||
22 | P_MMAP_PROT(WRITE); | 21 | P_MMAP_PROT(WRITE); |
22 | P_MMAP_PROT(EXEC); | ||
23 | P_MMAP_PROT(SEM); | 23 | P_MMAP_PROT(SEM); |
24 | P_MMAP_PROT(GROWSDOWN); | 24 | P_MMAP_PROT(GROWSDOWN); |
25 | P_MMAP_PROT(GROWSUP); | 25 | P_MMAP_PROT(GROWSUP); |
diff --git a/tools/perf/trace/beauty/seccomp.c b/tools/perf/trace/beauty/seccomp.c index 4600c28a3cfe..637722e2796b 100644 --- a/tools/perf/trace/beauty/seccomp.c +++ b/tools/perf/trace/beauty/seccomp.c | |||
@@ -9,7 +9,7 @@ | |||
9 | static size_t syscall_arg__scnprintf_seccomp_op(char *bf, size_t size, struct syscall_arg *arg) | 9 | static size_t syscall_arg__scnprintf_seccomp_op(char *bf, size_t size, struct syscall_arg *arg) |
10 | { | 10 | { |
11 | bool show_prefix = arg->show_string_prefix; | 11 | bool show_prefix = arg->show_string_prefix; |
12 | const char *prefix = "SECOMP_SET_MODE_"; | 12 | const char *prefix = "SECCOMP_SET_MODE_"; |
13 | int op = arg->val; | 13 | int op = arg->val; |
14 | size_t printed = 0; | 14 | size_t printed = 0; |
15 | 15 | ||
@@ -34,7 +34,7 @@ static size_t syscall_arg__scnprintf_seccomp_flags(char *bf, size_t size, | |||
34 | struct syscall_arg *arg) | 34 | struct syscall_arg *arg) |
35 | { | 35 | { |
36 | bool show_prefix = arg->show_string_prefix; | 36 | bool show_prefix = arg->show_string_prefix; |
37 | const char *prefix = "SECOMP_FILTER_FLAG_"; | 37 | const char *prefix = "SECCOMP_FILTER_FLAG_"; |
38 | int printed = 0, flags = arg->val; | 38 | int printed = 0, flags = arg->val; |
39 | 39 | ||
40 | #define P_FLAG(n) \ | 40 | #define P_FLAG(n) \ |
diff --git a/tools/perf/trace/beauty/usbdevfs_ioctl.sh b/tools/perf/trace/beauty/usbdevfs_ioctl.sh new file mode 100755 index 000000000000..930b80f422e8 --- /dev/null +++ b/tools/perf/trace/beauty/usbdevfs_ioctl.sh | |||
@@ -0,0 +1,19 @@ | |||
1 | #!/bin/sh | ||
2 | # SPDX-License-Identifier: LGPL-2.1 | ||
3 | |||
4 | [ $# -eq 1 ] && header_dir=$1 || header_dir=tools/include/uapi/linux/ | ||
5 | |||
6 | printf "static const char *usbdevfs_ioctl_cmds[] = {\n" | ||
7 | regex="^#[[:space:]]*define[[:space:]]+USBDEVFS_(\w+)[[:space:]]+_IO[WR]{0,2}\([[:space:]]*'U'[[:space:]]*,[[:space:]]*([[:digit:]]+).*" | ||
8 | egrep $regex ${header_dir}/usbdevice_fs.h | egrep -v 'USBDEVFS_\w+32[[:space:]]' | \ | ||
9 | sed -r "s/$regex/\2 \1/g" | \ | ||
10 | sort | xargs printf "\t[%s] = \"%s\",\n" | ||
11 | printf "};\n\n" | ||
12 | printf "#if 0\n" | ||
13 | printf "static const char *usbdevfs_ioctl_32_cmds[] = {\n" | ||
14 | regex="^#[[:space:]]*define[[:space:]]+USBDEVFS_(\w+)[[:space:]]+_IO[WR]{0,2}\([[:space:]]*'U'[[:space:]]*,[[:space:]]*([[:digit:]]+).*" | ||
15 | egrep $regex ${header_dir}/usbdevice_fs.h | egrep 'USBDEVFS_\w+32[[:space:]]' | \ | ||
16 | sed -r "s/$regex/\2 \1/g" | \ | ||
17 | sort | xargs printf "\t[%s] = \"%s\",\n" | ||
18 | printf "};\n" | ||
19 | printf "#endif\n" | ||
diff --git a/tools/perf/util/dump-insn.c b/tools/perf/util/dump-insn.c index 10988d3de7ce..2bd8585db93c 100644 --- a/tools/perf/util/dump-insn.c +++ b/tools/perf/util/dump-insn.c | |||
@@ -13,3 +13,11 @@ const char *dump_insn(struct perf_insn *x __maybe_unused, | |||
13 | *lenp = 0; | 13 | *lenp = 0; |
14 | return "?"; | 14 | return "?"; |
15 | } | 15 | } |
16 | |||
17 | __weak | ||
18 | int arch_is_branch(const unsigned char *buf __maybe_unused, | ||
19 | size_t len __maybe_unused, | ||
20 | int x86_64 __maybe_unused) | ||
21 | { | ||
22 | return 0; | ||
23 | } | ||
diff --git a/tools/perf/util/dump-insn.h b/tools/perf/util/dump-insn.h index 0e06280a8860..650125061530 100644 --- a/tools/perf/util/dump-insn.h +++ b/tools/perf/util/dump-insn.h | |||
@@ -20,4 +20,6 @@ struct perf_insn { | |||
20 | 20 | ||
21 | const char *dump_insn(struct perf_insn *x, u64 ip, | 21 | const char *dump_insn(struct perf_insn *x, u64 ip, |
22 | u8 *inbuf, int inlen, int *lenp); | 22 | u8 *inbuf, int inlen, int *lenp); |
23 | int arch_is_branch(const unsigned char *buf, size_t len, int x86_64); | ||
24 | |||
23 | #endif | 25 | #endif |
diff --git a/tools/perf/util/intel-bts.c b/tools/perf/util/intel-bts.c index 7b27d77306c2..ee6ca65f81f4 100644 --- a/tools/perf/util/intel-bts.c +++ b/tools/perf/util/intel-bts.c | |||
@@ -451,7 +451,7 @@ static int intel_bts_process_buffer(struct intel_bts_queue *btsq, | |||
451 | continue; | 451 | continue; |
452 | intel_bts_get_branch_type(btsq, branch); | 452 | intel_bts_get_branch_type(btsq, branch); |
453 | if (btsq->bts->synth_opts.thread_stack) | 453 | if (btsq->bts->synth_opts.thread_stack) |
454 | thread_stack__event(thread, btsq->sample_flags, | 454 | thread_stack__event(thread, btsq->cpu, btsq->sample_flags, |
455 | le64_to_cpu(branch->from), | 455 | le64_to_cpu(branch->from), |
456 | le64_to_cpu(branch->to), | 456 | le64_to_cpu(branch->to), |
457 | btsq->intel_pt_insn.length, | 457 | btsq->intel_pt_insn.length, |
@@ -523,7 +523,7 @@ static int intel_bts_process_queue(struct intel_bts_queue *btsq, u64 *timestamp) | |||
523 | !btsq->bts->synth_opts.thread_stack && thread && | 523 | !btsq->bts->synth_opts.thread_stack && thread && |
524 | (!old_buffer || btsq->bts->sampling_mode || | 524 | (!old_buffer || btsq->bts->sampling_mode || |
525 | (btsq->bts->snapshot_mode && !buffer->consecutive))) | 525 | (btsq->bts->snapshot_mode && !buffer->consecutive))) |
526 | thread_stack__set_trace_nr(thread, buffer->buffer_nr + 1); | 526 | thread_stack__set_trace_nr(thread, btsq->cpu, buffer->buffer_nr + 1); |
527 | 527 | ||
528 | err = intel_bts_process_buffer(btsq, buffer, thread); | 528 | err = intel_bts_process_buffer(btsq, buffer, thread); |
529 | 529 | ||
diff --git a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c index 54818828023b..1c0e289f01e6 100644 --- a/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c +++ b/tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c | |||
@@ -180,6 +180,14 @@ int intel_pt_get_insn(const unsigned char *buf, size_t len, int x86_64, | |||
180 | return 0; | 180 | return 0; |
181 | } | 181 | } |
182 | 182 | ||
183 | int arch_is_branch(const unsigned char *buf, size_t len, int x86_64) | ||
184 | { | ||
185 | struct intel_pt_insn in; | ||
186 | if (intel_pt_get_insn(buf, len, x86_64, &in) < 0) | ||
187 | return -1; | ||
188 | return in.branch != INTEL_PT_BR_NO_BRANCH; | ||
189 | } | ||
190 | |||
183 | const char *dump_insn(struct perf_insn *x, uint64_t ip __maybe_unused, | 191 | const char *dump_insn(struct perf_insn *x, uint64_t ip __maybe_unused, |
184 | u8 *inbuf, int inlen, int *lenp) | 192 | u8 *inbuf, int inlen, int *lenp) |
185 | { | 193 | { |
diff --git a/tools/perf/util/intel-pt.c b/tools/perf/util/intel-pt.c index 149ff361ca78..2e72373ec6df 100644 --- a/tools/perf/util/intel-pt.c +++ b/tools/perf/util/intel-pt.c | |||
@@ -1174,7 +1174,7 @@ static void intel_pt_prep_sample(struct intel_pt *pt, | |||
1174 | intel_pt_prep_b_sample(pt, ptq, event, sample); | 1174 | intel_pt_prep_b_sample(pt, ptq, event, sample); |
1175 | 1175 | ||
1176 | if (pt->synth_opts.callchain) { | 1176 | if (pt->synth_opts.callchain) { |
1177 | thread_stack__sample(ptq->thread, ptq->chain, | 1177 | thread_stack__sample(ptq->thread, ptq->cpu, ptq->chain, |
1178 | pt->synth_opts.callchain_sz + 1, | 1178 | pt->synth_opts.callchain_sz + 1, |
1179 | sample->ip, pt->kernel_start); | 1179 | sample->ip, pt->kernel_start); |
1180 | sample->callchain = ptq->chain; | 1180 | sample->callchain = ptq->chain; |
@@ -1526,11 +1526,11 @@ static int intel_pt_sample(struct intel_pt_queue *ptq) | |||
1526 | return 0; | 1526 | return 0; |
1527 | 1527 | ||
1528 | if (pt->synth_opts.callchain || pt->synth_opts.thread_stack) | 1528 | if (pt->synth_opts.callchain || pt->synth_opts.thread_stack) |
1529 | thread_stack__event(ptq->thread, ptq->flags, state->from_ip, | 1529 | thread_stack__event(ptq->thread, ptq->cpu, ptq->flags, state->from_ip, |
1530 | state->to_ip, ptq->insn_len, | 1530 | state->to_ip, ptq->insn_len, |
1531 | state->trace_nr); | 1531 | state->trace_nr); |
1532 | else | 1532 | else |
1533 | thread_stack__set_trace_nr(ptq->thread, state->trace_nr); | 1533 | thread_stack__set_trace_nr(ptq->thread, ptq->cpu, state->trace_nr); |
1534 | 1534 | ||
1535 | if (pt->sample_branches) { | 1535 | if (pt->sample_branches) { |
1536 | err = intel_pt_synth_branch_sample(ptq); | 1536 | err = intel_pt_synth_branch_sample(ptq); |
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index 47628e85c5eb..dda0ac978b1e 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c | |||
@@ -939,7 +939,8 @@ static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist, | |||
939 | 939 | ||
940 | file = PyFile_FromFile(fp, "perf", "r", NULL); | 940 | file = PyFile_FromFile(fp, "perf", "r", NULL); |
941 | #else | 941 | #else |
942 | file = PyFile_FromFd(evlist->pollfd.entries[i].fd, "perf", "r", -1, NULL, NULL, NULL, 1); | 942 | file = PyFile_FromFd(evlist->pollfd.entries[i].fd, "perf", "r", -1, |
943 | NULL, NULL, NULL, 0); | ||
943 | #endif | 944 | #endif |
944 | if (file == NULL) | 945 | if (file == NULL) |
945 | goto free_list; | 946 | goto free_list; |
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 78a067777144..5456c84c7dd1 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -1527,6 +1527,13 @@ struct thread *perf_session__findnew(struct perf_session *session, pid_t pid) | |||
1527 | return machine__findnew_thread(&session->machines.host, -1, pid); | 1527 | return machine__findnew_thread(&session->machines.host, -1, pid); |
1528 | } | 1528 | } |
1529 | 1529 | ||
1530 | /* | ||
1531 | * Threads are identified by pid and tid, and the idle task has pid == tid == 0. | ||
1532 | * So here a single thread is created for that, but actually there is a separate | ||
1533 | * idle task per cpu, so there should be one 'struct thread' per cpu, but there | ||
1534 | * is only 1. That causes problems for some tools, requiring workarounds. For | ||
1535 | * example get_idle_thread() in builtin-sched.c, or thread_stack__per_cpu(). | ||
1536 | */ | ||
1530 | int perf_session__register_idle_thread(struct perf_session *session) | 1537 | int perf_session__register_idle_thread(struct perf_session *session) |
1531 | { | 1538 | { |
1532 | struct thread *thread; | 1539 | struct thread *thread; |
diff --git a/tools/perf/util/thread-stack.c b/tools/perf/util/thread-stack.c index 61a4286a74dc..d52f27f373ce 100644 --- a/tools/perf/util/thread-stack.c +++ b/tools/perf/util/thread-stack.c | |||
@@ -15,6 +15,7 @@ | |||
15 | 15 | ||
16 | #include <linux/rbtree.h> | 16 | #include <linux/rbtree.h> |
17 | #include <linux/list.h> | 17 | #include <linux/list.h> |
18 | #include <linux/log2.h> | ||
18 | #include <errno.h> | 19 | #include <errno.h> |
19 | #include "thread.h" | 20 | #include "thread.h" |
20 | #include "event.h" | 21 | #include "event.h" |
@@ -60,6 +61,7 @@ struct thread_stack_entry { | |||
60 | * @last_time: last timestamp | 61 | * @last_time: last timestamp |
61 | * @crp: call/return processor | 62 | * @crp: call/return processor |
62 | * @comm: current comm | 63 | * @comm: current comm |
64 | * @arr_sz: size of array if this is the first element of an array | ||
63 | */ | 65 | */ |
64 | struct thread_stack { | 66 | struct thread_stack { |
65 | struct thread_stack_entry *stack; | 67 | struct thread_stack_entry *stack; |
@@ -71,8 +73,19 @@ struct thread_stack { | |||
71 | u64 last_time; | 73 | u64 last_time; |
72 | struct call_return_processor *crp; | 74 | struct call_return_processor *crp; |
73 | struct comm *comm; | 75 | struct comm *comm; |
76 | unsigned int arr_sz; | ||
74 | }; | 77 | }; |
75 | 78 | ||
79 | /* | ||
80 | * Assume pid == tid == 0 identifies the idle task as defined by | ||
81 | * perf_session__register_idle_thread(). The idle task is really 1 task per cpu, | ||
82 | * and therefore requires a stack for each cpu. | ||
83 | */ | ||
84 | static inline bool thread_stack__per_cpu(struct thread *thread) | ||
85 | { | ||
86 | return !(thread->tid || thread->pid_); | ||
87 | } | ||
88 | |||
76 | static int thread_stack__grow(struct thread_stack *ts) | 89 | static int thread_stack__grow(struct thread_stack *ts) |
77 | { | 90 | { |
78 | struct thread_stack_entry *new_stack; | 91 | struct thread_stack_entry *new_stack; |
@@ -91,19 +104,14 @@ static int thread_stack__grow(struct thread_stack *ts) | |||
91 | return 0; | 104 | return 0; |
92 | } | 105 | } |
93 | 106 | ||
94 | static struct thread_stack *thread_stack__new(struct thread *thread, | 107 | static int thread_stack__init(struct thread_stack *ts, struct thread *thread, |
95 | struct call_return_processor *crp) | 108 | struct call_return_processor *crp) |
96 | { | 109 | { |
97 | struct thread_stack *ts; | 110 | int err; |
98 | |||
99 | ts = zalloc(sizeof(struct thread_stack)); | ||
100 | if (!ts) | ||
101 | return NULL; | ||
102 | 111 | ||
103 | if (thread_stack__grow(ts)) { | 112 | err = thread_stack__grow(ts); |
104 | free(ts); | 113 | if (err) |
105 | return NULL; | 114 | return err; |
106 | } | ||
107 | 115 | ||
108 | if (thread->mg && thread->mg->machine) | 116 | if (thread->mg && thread->mg->machine) |
109 | ts->kernel_start = machine__kernel_start(thread->mg->machine); | 117 | ts->kernel_start = machine__kernel_start(thread->mg->machine); |
@@ -111,9 +119,72 @@ static struct thread_stack *thread_stack__new(struct thread *thread, | |||
111 | ts->kernel_start = 1ULL << 63; | 119 | ts->kernel_start = 1ULL << 63; |
112 | ts->crp = crp; | 120 | ts->crp = crp; |
113 | 121 | ||
122 | return 0; | ||
123 | } | ||
124 | |||
125 | static struct thread_stack *thread_stack__new(struct thread *thread, int cpu, | ||
126 | struct call_return_processor *crp) | ||
127 | { | ||
128 | struct thread_stack *ts = thread->ts, *new_ts; | ||
129 | unsigned int old_sz = ts ? ts->arr_sz : 0; | ||
130 | unsigned int new_sz = 1; | ||
131 | |||
132 | if (thread_stack__per_cpu(thread) && cpu > 0) | ||
133 | new_sz = roundup_pow_of_two(cpu + 1); | ||
134 | |||
135 | if (!ts || new_sz > old_sz) { | ||
136 | new_ts = calloc(new_sz, sizeof(*ts)); | ||
137 | if (!new_ts) | ||
138 | return NULL; | ||
139 | if (ts) | ||
140 | memcpy(new_ts, ts, old_sz * sizeof(*ts)); | ||
141 | new_ts->arr_sz = new_sz; | ||
142 | zfree(&thread->ts); | ||
143 | thread->ts = new_ts; | ||
144 | ts = new_ts; | ||
145 | } | ||
146 | |||
147 | if (thread_stack__per_cpu(thread) && cpu > 0 && | ||
148 | (unsigned int)cpu < ts->arr_sz) | ||
149 | ts += cpu; | ||
150 | |||
151 | if (!ts->stack && | ||
152 | thread_stack__init(ts, thread, crp)) | ||
153 | return NULL; | ||
154 | |||
114 | return ts; | 155 | return ts; |
115 | } | 156 | } |
116 | 157 | ||
158 | static struct thread_stack *thread__cpu_stack(struct thread *thread, int cpu) | ||
159 | { | ||
160 | struct thread_stack *ts = thread->ts; | ||
161 | |||
162 | if (cpu < 0) | ||
163 | cpu = 0; | ||
164 | |||
165 | if (!ts || (unsigned int)cpu >= ts->arr_sz) | ||
166 | return NULL; | ||
167 | |||
168 | ts += cpu; | ||
169 | |||
170 | if (!ts->stack) | ||
171 | return NULL; | ||
172 | |||
173 | return ts; | ||
174 | } | ||
175 | |||
176 | static inline struct thread_stack *thread__stack(struct thread *thread, | ||
177 | int cpu) | ||
178 | { | ||
179 | if (!thread) | ||
180 | return NULL; | ||
181 | |||
182 | if (thread_stack__per_cpu(thread)) | ||
183 | return thread__cpu_stack(thread, cpu); | ||
184 | |||
185 | return thread->ts; | ||
186 | } | ||
187 | |||
117 | static int thread_stack__push(struct thread_stack *ts, u64 ret_addr, | 188 | static int thread_stack__push(struct thread_stack *ts, u64 ret_addr, |
118 | bool trace_end) | 189 | bool trace_end) |
119 | { | 190 | { |
@@ -226,25 +297,37 @@ static int __thread_stack__flush(struct thread *thread, struct thread_stack *ts) | |||
226 | 297 | ||
227 | int thread_stack__flush(struct thread *thread) | 298 | int thread_stack__flush(struct thread *thread) |
228 | { | 299 | { |
229 | if (thread->ts) | 300 | struct thread_stack *ts = thread->ts; |
230 | return __thread_stack__flush(thread, thread->ts); | 301 | unsigned int pos; |
302 | int err = 0; | ||
231 | 303 | ||
232 | return 0; | 304 | if (ts) { |
305 | for (pos = 0; pos < ts->arr_sz; pos++) { | ||
306 | int ret = __thread_stack__flush(thread, ts + pos); | ||
307 | |||
308 | if (ret) | ||
309 | err = ret; | ||
310 | } | ||
311 | } | ||
312 | |||
313 | return err; | ||
233 | } | 314 | } |
234 | 315 | ||
235 | int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, | 316 | int thread_stack__event(struct thread *thread, int cpu, u32 flags, u64 from_ip, |
236 | u64 to_ip, u16 insn_len, u64 trace_nr) | 317 | u64 to_ip, u16 insn_len, u64 trace_nr) |
237 | { | 318 | { |
319 | struct thread_stack *ts = thread__stack(thread, cpu); | ||
320 | |||
238 | if (!thread) | 321 | if (!thread) |
239 | return -EINVAL; | 322 | return -EINVAL; |
240 | 323 | ||
241 | if (!thread->ts) { | 324 | if (!ts) { |
242 | thread->ts = thread_stack__new(thread, NULL); | 325 | ts = thread_stack__new(thread, cpu, NULL); |
243 | if (!thread->ts) { | 326 | if (!ts) { |
244 | pr_warning("Out of memory: no thread stack\n"); | 327 | pr_warning("Out of memory: no thread stack\n"); |
245 | return -ENOMEM; | 328 | return -ENOMEM; |
246 | } | 329 | } |
247 | thread->ts->trace_nr = trace_nr; | 330 | ts->trace_nr = trace_nr; |
248 | } | 331 | } |
249 | 332 | ||
250 | /* | 333 | /* |
@@ -252,14 +335,14 @@ int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, | |||
252 | * the stack might be completely invalid. Better to report nothing than | 335 | * the stack might be completely invalid. Better to report nothing than |
253 | * to report something misleading, so flush the stack. | 336 | * to report something misleading, so flush the stack. |
254 | */ | 337 | */ |
255 | if (trace_nr != thread->ts->trace_nr) { | 338 | if (trace_nr != ts->trace_nr) { |
256 | if (thread->ts->trace_nr) | 339 | if (ts->trace_nr) |
257 | __thread_stack__flush(thread, thread->ts); | 340 | __thread_stack__flush(thread, ts); |
258 | thread->ts->trace_nr = trace_nr; | 341 | ts->trace_nr = trace_nr; |
259 | } | 342 | } |
260 | 343 | ||
261 | /* Stop here if thread_stack__process() is in use */ | 344 | /* Stop here if thread_stack__process() is in use */ |
262 | if (thread->ts->crp) | 345 | if (ts->crp) |
263 | return 0; | 346 | return 0; |
264 | 347 | ||
265 | if (flags & PERF_IP_FLAG_CALL) { | 348 | if (flags & PERF_IP_FLAG_CALL) { |
@@ -270,7 +353,7 @@ int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, | |||
270 | ret_addr = from_ip + insn_len; | 353 | ret_addr = from_ip + insn_len; |
271 | if (ret_addr == to_ip) | 354 | if (ret_addr == to_ip) |
272 | return 0; /* Zero-length calls are excluded */ | 355 | return 0; /* Zero-length calls are excluded */ |
273 | return thread_stack__push(thread->ts, ret_addr, | 356 | return thread_stack__push(ts, ret_addr, |
274 | flags & PERF_IP_FLAG_TRACE_END); | 357 | flags & PERF_IP_FLAG_TRACE_END); |
275 | } else if (flags & PERF_IP_FLAG_TRACE_BEGIN) { | 358 | } else if (flags & PERF_IP_FLAG_TRACE_BEGIN) { |
276 | /* | 359 | /* |
@@ -280,32 +363,52 @@ int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, | |||
280 | * address, so try to pop that. Also, do not expect a call made | 363 | * address, so try to pop that. Also, do not expect a call made |
281 | * when the trace ended, to return, so pop that. | 364 | * when the trace ended, to return, so pop that. |
282 | */ | 365 | */ |
283 | thread_stack__pop(thread->ts, to_ip); | 366 | thread_stack__pop(ts, to_ip); |
284 | thread_stack__pop_trace_end(thread->ts); | 367 | thread_stack__pop_trace_end(ts); |
285 | } else if ((flags & PERF_IP_FLAG_RETURN) && from_ip) { | 368 | } else if ((flags & PERF_IP_FLAG_RETURN) && from_ip) { |
286 | thread_stack__pop(thread->ts, to_ip); | 369 | thread_stack__pop(ts, to_ip); |
287 | } | 370 | } |
288 | 371 | ||
289 | return 0; | 372 | return 0; |
290 | } | 373 | } |
291 | 374 | ||
292 | void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr) | 375 | void thread_stack__set_trace_nr(struct thread *thread, int cpu, u64 trace_nr) |
293 | { | 376 | { |
294 | if (!thread || !thread->ts) | 377 | struct thread_stack *ts = thread__stack(thread, cpu); |
378 | |||
379 | if (!ts) | ||
295 | return; | 380 | return; |
296 | 381 | ||
297 | if (trace_nr != thread->ts->trace_nr) { | 382 | if (trace_nr != ts->trace_nr) { |
298 | if (thread->ts->trace_nr) | 383 | if (ts->trace_nr) |
299 | __thread_stack__flush(thread, thread->ts); | 384 | __thread_stack__flush(thread, ts); |
300 | thread->ts->trace_nr = trace_nr; | 385 | ts->trace_nr = trace_nr; |
301 | } | 386 | } |
302 | } | 387 | } |
303 | 388 | ||
389 | static void __thread_stack__free(struct thread *thread, struct thread_stack *ts) | ||
390 | { | ||
391 | __thread_stack__flush(thread, ts); | ||
392 | zfree(&ts->stack); | ||
393 | } | ||
394 | |||
395 | static void thread_stack__reset(struct thread *thread, struct thread_stack *ts) | ||
396 | { | ||
397 | unsigned int arr_sz = ts->arr_sz; | ||
398 | |||
399 | __thread_stack__free(thread, ts); | ||
400 | memset(ts, 0, sizeof(*ts)); | ||
401 | ts->arr_sz = arr_sz; | ||
402 | } | ||
403 | |||
304 | void thread_stack__free(struct thread *thread) | 404 | void thread_stack__free(struct thread *thread) |
305 | { | 405 | { |
306 | if (thread->ts) { | 406 | struct thread_stack *ts = thread->ts; |
307 | __thread_stack__flush(thread, thread->ts); | 407 | unsigned int pos; |
308 | zfree(&thread->ts->stack); | 408 | |
409 | if (ts) { | ||
410 | for (pos = 0; pos < ts->arr_sz; pos++) | ||
411 | __thread_stack__free(thread, ts + pos); | ||
309 | zfree(&thread->ts); | 412 | zfree(&thread->ts); |
310 | } | 413 | } |
311 | } | 414 | } |
@@ -315,9 +418,11 @@ static inline u64 callchain_context(u64 ip, u64 kernel_start) | |||
315 | return ip < kernel_start ? PERF_CONTEXT_USER : PERF_CONTEXT_KERNEL; | 418 | return ip < kernel_start ? PERF_CONTEXT_USER : PERF_CONTEXT_KERNEL; |
316 | } | 419 | } |
317 | 420 | ||
318 | void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, | 421 | void thread_stack__sample(struct thread *thread, int cpu, |
422 | struct ip_callchain *chain, | ||
319 | size_t sz, u64 ip, u64 kernel_start) | 423 | size_t sz, u64 ip, u64 kernel_start) |
320 | { | 424 | { |
425 | struct thread_stack *ts = thread__stack(thread, cpu); | ||
321 | u64 context = callchain_context(ip, kernel_start); | 426 | u64 context = callchain_context(ip, kernel_start); |
322 | u64 last_context; | 427 | u64 last_context; |
323 | size_t i, j; | 428 | size_t i, j; |
@@ -330,15 +435,15 @@ void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, | |||
330 | chain->ips[0] = context; | 435 | chain->ips[0] = context; |
331 | chain->ips[1] = ip; | 436 | chain->ips[1] = ip; |
332 | 437 | ||
333 | if (!thread || !thread->ts) { | 438 | if (!ts) { |
334 | chain->nr = 2; | 439 | chain->nr = 2; |
335 | return; | 440 | return; |
336 | } | 441 | } |
337 | 442 | ||
338 | last_context = context; | 443 | last_context = context; |
339 | 444 | ||
340 | for (i = 2, j = 1; i < sz && j <= thread->ts->cnt; i++, j++) { | 445 | for (i = 2, j = 1; i < sz && j <= ts->cnt; i++, j++) { |
341 | ip = thread->ts->stack[thread->ts->cnt - j].ret_addr; | 446 | ip = ts->stack[ts->cnt - j].ret_addr; |
342 | context = callchain_context(ip, kernel_start); | 447 | context = callchain_context(ip, kernel_start); |
343 | if (context != last_context) { | 448 | if (context != last_context) { |
344 | if (i >= sz - 1) | 449 | if (i >= sz - 1) |
@@ -449,7 +554,7 @@ static int thread_stack__pop_cp(struct thread *thread, struct thread_stack *ts, | |||
449 | return 1; | 554 | return 1; |
450 | } | 555 | } |
451 | 556 | ||
452 | static int thread_stack__bottom(struct thread *thread, struct thread_stack *ts, | 557 | static int thread_stack__bottom(struct thread_stack *ts, |
453 | struct perf_sample *sample, | 558 | struct perf_sample *sample, |
454 | struct addr_location *from_al, | 559 | struct addr_location *from_al, |
455 | struct addr_location *to_al, u64 ref) | 560 | struct addr_location *to_al, u64 ref) |
@@ -474,7 +579,7 @@ static int thread_stack__bottom(struct thread *thread, struct thread_stack *ts, | |||
474 | if (!cp) | 579 | if (!cp) |
475 | return -ENOMEM; | 580 | return -ENOMEM; |
476 | 581 | ||
477 | return thread_stack__push_cp(thread->ts, ip, sample->time, ref, cp, | 582 | return thread_stack__push_cp(ts, ip, sample->time, ref, cp, |
478 | true, false); | 583 | true, false); |
479 | } | 584 | } |
480 | 585 | ||
@@ -590,24 +695,19 @@ int thread_stack__process(struct thread *thread, struct comm *comm, | |||
590 | struct addr_location *to_al, u64 ref, | 695 | struct addr_location *to_al, u64 ref, |
591 | struct call_return_processor *crp) | 696 | struct call_return_processor *crp) |
592 | { | 697 | { |
593 | struct thread_stack *ts = thread->ts; | 698 | struct thread_stack *ts = thread__stack(thread, sample->cpu); |
594 | int err = 0; | 699 | int err = 0; |
595 | 700 | ||
596 | if (ts) { | 701 | if (ts && !ts->crp) { |
597 | if (!ts->crp) { | 702 | /* Supersede thread_stack__event() */ |
598 | /* Supersede thread_stack__event() */ | 703 | thread_stack__reset(thread, ts); |
599 | thread_stack__free(thread); | 704 | ts = NULL; |
600 | thread->ts = thread_stack__new(thread, crp); | 705 | } |
601 | if (!thread->ts) | 706 | |
602 | return -ENOMEM; | 707 | if (!ts) { |
603 | ts = thread->ts; | 708 | ts = thread_stack__new(thread, sample->cpu, crp); |
604 | ts->comm = comm; | 709 | if (!ts) |
605 | } | ||
606 | } else { | ||
607 | thread->ts = thread_stack__new(thread, crp); | ||
608 | if (!thread->ts) | ||
609 | return -ENOMEM; | 710 | return -ENOMEM; |
610 | ts = thread->ts; | ||
611 | ts->comm = comm; | 711 | ts->comm = comm; |
612 | } | 712 | } |
613 | 713 | ||
@@ -621,8 +721,7 @@ int thread_stack__process(struct thread *thread, struct comm *comm, | |||
621 | 721 | ||
622 | /* If the stack is empty, put the current symbol on the stack */ | 722 | /* If the stack is empty, put the current symbol on the stack */ |
623 | if (!ts->cnt) { | 723 | if (!ts->cnt) { |
624 | err = thread_stack__bottom(thread, ts, sample, from_al, to_al, | 724 | err = thread_stack__bottom(ts, sample, from_al, to_al, ref); |
625 | ref); | ||
626 | if (err) | 725 | if (err) |
627 | return err; | 726 | return err; |
628 | } | 727 | } |
@@ -671,9 +770,11 @@ int thread_stack__process(struct thread *thread, struct comm *comm, | |||
671 | return err; | 770 | return err; |
672 | } | 771 | } |
673 | 772 | ||
674 | size_t thread_stack__depth(struct thread *thread) | 773 | size_t thread_stack__depth(struct thread *thread, int cpu) |
675 | { | 774 | { |
676 | if (!thread->ts) | 775 | struct thread_stack *ts = thread__stack(thread, cpu); |
776 | |||
777 | if (!ts) | ||
677 | return 0; | 778 | return 0; |
678 | return thread->ts->cnt; | 779 | return ts->cnt; |
679 | } | 780 | } |
diff --git a/tools/perf/util/thread-stack.h b/tools/perf/util/thread-stack.h index f97c00a8c251..1f626f4a1c40 100644 --- a/tools/perf/util/thread-stack.h +++ b/tools/perf/util/thread-stack.h | |||
@@ -80,14 +80,14 @@ struct call_return_processor { | |||
80 | void *data; | 80 | void *data; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | int thread_stack__event(struct thread *thread, u32 flags, u64 from_ip, | 83 | int thread_stack__event(struct thread *thread, int cpu, u32 flags, u64 from_ip, |
84 | u64 to_ip, u16 insn_len, u64 trace_nr); | 84 | u64 to_ip, u16 insn_len, u64 trace_nr); |
85 | void thread_stack__set_trace_nr(struct thread *thread, u64 trace_nr); | 85 | void thread_stack__set_trace_nr(struct thread *thread, int cpu, u64 trace_nr); |
86 | void thread_stack__sample(struct thread *thread, struct ip_callchain *chain, | 86 | void thread_stack__sample(struct thread *thread, int cpu, struct ip_callchain *chain, |
87 | size_t sz, u64 ip, u64 kernel_start); | 87 | size_t sz, u64 ip, u64 kernel_start); |
88 | int thread_stack__flush(struct thread *thread); | 88 | int thread_stack__flush(struct thread *thread); |
89 | void thread_stack__free(struct thread *thread); | 89 | void thread_stack__free(struct thread *thread); |
90 | size_t thread_stack__depth(struct thread *thread); | 90 | size_t thread_stack__depth(struct thread *thread, int cpu); |
91 | 91 | ||
92 | struct call_return_processor * | 92 | struct call_return_processor * |
93 | call_return_processor__new(int (*process)(struct call_return *cr, void *data), | 93 | call_return_processor__new(int (*process)(struct call_return *cr, void *data), |
diff --git a/tools/power/x86/turbostat/Makefile b/tools/power/x86/turbostat/Makefile index 2ab25aa38263..1598b4fa0b11 100644 --- a/tools/power/x86/turbostat/Makefile +++ b/tools/power/x86/turbostat/Makefile | |||
@@ -9,13 +9,13 @@ ifeq ("$(origin O)", "command line") | |||
9 | endif | 9 | endif |
10 | 10 | ||
11 | turbostat : turbostat.c | 11 | turbostat : turbostat.c |
12 | CFLAGS += -Wall | 12 | override CFLAGS += -Wall |
13 | CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' | 13 | override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' |
14 | CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"' | 14 | override CFLAGS += -DINTEL_FAMILY_HEADER='"../../../../arch/x86/include/asm/intel-family.h"' |
15 | 15 | ||
16 | %: %.c | 16 | %: %.c |
17 | @mkdir -p $(BUILD_OUTPUT) | 17 | @mkdir -p $(BUILD_OUTPUT) |
18 | $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ | 18 | $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) |
19 | 19 | ||
20 | .PHONY : clean | 20 | .PHONY : clean |
21 | clean : | 21 | clean : |
diff --git a/tools/power/x86/x86_energy_perf_policy/Makefile b/tools/power/x86/x86_energy_perf_policy/Makefile index f4534fb8b951..ae7a0e09b722 100644 --- a/tools/power/x86/x86_energy_perf_policy/Makefile +++ b/tools/power/x86/x86_energy_perf_policy/Makefile | |||
@@ -9,12 +9,12 @@ ifeq ("$(origin O)", "command line") | |||
9 | endif | 9 | endif |
10 | 10 | ||
11 | x86_energy_perf_policy : x86_energy_perf_policy.c | 11 | x86_energy_perf_policy : x86_energy_perf_policy.c |
12 | CFLAGS += -Wall | 12 | override CFLAGS += -Wall |
13 | CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' | 13 | override CFLAGS += -DMSRHEADER='"../../../../arch/x86/include/asm/msr-index.h"' |
14 | 14 | ||
15 | %: %.c | 15 | %: %.c |
16 | @mkdir -p $(BUILD_OUTPUT) | 16 | @mkdir -p $(BUILD_OUTPUT) |
17 | $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ | 17 | $(CC) $(CFLAGS) $< -o $(BUILD_OUTPUT)/$@ $(LDFLAGS) |
18 | 18 | ||
19 | .PHONY : clean | 19 | .PHONY : clean |
20 | clean : | 20 | clean : |
diff --git a/tools/thermal/tmon/Makefile b/tools/thermal/tmon/Makefile index 735a510230c3..89a2444c1df2 100644 --- a/tools/thermal/tmon/Makefile +++ b/tools/thermal/tmon/Makefile | |||
@@ -6,13 +6,13 @@ VERSION = 1.0 | |||
6 | 6 | ||
7 | BINDIR=usr/bin | 7 | BINDIR=usr/bin |
8 | WARNFLAGS=-Wall -Wshadow -W -Wformat -Wimplicit-function-declaration -Wimplicit-int | 8 | WARNFLAGS=-Wall -Wshadow -W -Wformat -Wimplicit-function-declaration -Wimplicit-int |
9 | CFLAGS+= -O1 ${WARNFLAGS} | 9 | override CFLAGS+= -O1 ${WARNFLAGS} |
10 | # Add "-fstack-protector" only if toolchain supports it. | 10 | # Add "-fstack-protector" only if toolchain supports it. |
11 | CFLAGS+= $(call cc-option,-fstack-protector) | 11 | override CFLAGS+= $(call cc-option,-fstack-protector-strong) |
12 | CC?= $(CROSS_COMPILE)gcc | 12 | CC?= $(CROSS_COMPILE)gcc |
13 | PKG_CONFIG?= pkg-config | 13 | PKG_CONFIG?= pkg-config |
14 | 14 | ||
15 | CFLAGS+=-D VERSION=\"$(VERSION)\" | 15 | override CFLAGS+=-D VERSION=\"$(VERSION)\" |
16 | LDFLAGS+= | 16 | LDFLAGS+= |
17 | TARGET=tmon | 17 | TARGET=tmon |
18 | 18 | ||
@@ -29,7 +29,7 @@ TMON_LIBS += $(shell $(PKG_CONFIG) --libs $(STATIC) panelw ncursesw 2> /dev/null | |||
29 | $(PKG_CONFIG) --libs $(STATIC) panel ncurses 2> /dev/null || \ | 29 | $(PKG_CONFIG) --libs $(STATIC) panel ncurses 2> /dev/null || \ |
30 | echo -lpanel -lncurses) | 30 | echo -lpanel -lncurses) |
31 | 31 | ||
32 | CFLAGS += $(shell $(PKG_CONFIG) --cflags $(STATIC) panelw ncursesw 2> /dev/null || \ | 32 | override CFLAGS += $(shell $(PKG_CONFIG) --cflags $(STATIC) panelw ncursesw 2> /dev/null || \ |
33 | $(PKG_CONFIG) --cflags $(STATIC) panel ncurses 2> /dev/null) | 33 | $(PKG_CONFIG) --cflags $(STATIC) panel ncurses 2> /dev/null) |
34 | 34 | ||
35 | OBJS = tmon.o tui.o sysfs.o pid.o | 35 | OBJS = tmon.o tui.o sysfs.o pid.o |