diff options
Diffstat (limited to 'tools/perf')
34 files changed, 315 insertions, 102 deletions
| diff --git a/tools/perf/arch/arm/entry/syscalls/syscall.tbl b/tools/perf/arch/arm/entry/syscalls/syscall.tbl index 27c1d5ebcd91..b07e699aaa3c 100644 --- a/tools/perf/arch/arm/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/arm/entry/syscalls/syscall.tbl @@ -482,3 +482,5 @@  465	common	listxattrat			sys_listxattrat  466	common	removexattrat			sys_removexattrat  467	common	open_tree_attr			sys_open_tree_attr +468	common	file_getattr			sys_file_getattr +469	common	file_setattr			sys_file_setattr diff --git a/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl b/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl index 1e8c44c7b614..7a7049c2c307 100644 --- a/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl +++ b/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl @@ -382,3 +382,5 @@  465	n64	listxattrat			sys_listxattrat  466	n64	removexattrat			sys_removexattrat  467	n64	open_tree_attr			sys_open_tree_attr +468	n64	file_getattr			sys_file_getattr +469	n64	file_setattr			sys_file_setattr diff --git a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl index 9a084bdb8926..b453e80dfc00 100644 --- a/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/powerpc/entry/syscalls/syscall.tbl @@ -558,3 +558,5 @@  465	common	listxattrat			sys_listxattrat  466	common	removexattrat			sys_removexattrat  467	common	open_tree_attr			sys_open_tree_attr +468	common	file_getattr			sys_file_getattr +469	common	file_setattr			sys_file_setattr diff --git a/tools/perf/arch/s390/entry/syscalls/syscall.tbl b/tools/perf/arch/s390/entry/syscalls/syscall.tbl index a4569b96ef06..8a6744d658db 100644 --- a/tools/perf/arch/s390/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/s390/entry/syscalls/syscall.tbl @@ -470,3 +470,5 @@  465  common	listxattrat		sys_listxattrat			sys_listxattrat  466  common	removexattrat		sys_removexattrat		sys_removexattrat  467  common	open_tree_attr		sys_open_tree_attr		sys_open_tree_attr +468  common	file_getattr		sys_file_getattr		sys_file_getattr +469  common	file_setattr		sys_file_setattr		sys_file_setattr diff --git a/tools/perf/arch/sh/entry/syscalls/syscall.tbl b/tools/perf/arch/sh/entry/syscalls/syscall.tbl index 52a7652fcff6..5e9c9eff5539 100644 --- a/tools/perf/arch/sh/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/sh/entry/syscalls/syscall.tbl @@ -471,3 +471,5 @@  465	common	listxattrat			sys_listxattrat  466	common	removexattrat			sys_removexattrat  467	common	open_tree_attr			sys_open_tree_attr +468	common	file_getattr			sys_file_getattr +469	common	file_setattr			sys_file_setattr diff --git a/tools/perf/arch/sparc/entry/syscalls/syscall.tbl b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl index 83e45eb6c095..ebb7d06d1044 100644 --- a/tools/perf/arch/sparc/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/sparc/entry/syscalls/syscall.tbl @@ -513,3 +513,5 @@  465	common	listxattrat			sys_listxattrat  466	common	removexattrat			sys_removexattrat  467	common	open_tree_attr			sys_open_tree_attr +468	common	file_getattr			sys_file_getattr +469	common	file_setattr			sys_file_setattr diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_32.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_32.tbl index ac007ea00979..4877e16da69a 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_32.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_32.tbl @@ -473,3 +473,5 @@  465	i386	listxattrat		sys_listxattrat  466	i386	removexattrat		sys_removexattrat  467	i386	open_tree_attr		sys_open_tree_attr +468	i386	file_getattr		sys_file_getattr +469	i386	file_setattr		sys_file_setattr diff --git a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl index cfb5ca41e30d..92cf0fe2291e 100644 --- a/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl +++ b/tools/perf/arch/x86/entry/syscalls/syscall_64.tbl @@ -391,6 +391,8 @@  465	common	listxattrat		sys_listxattrat  466	common	removexattrat		sys_removexattrat  467	common	open_tree_attr		sys_open_tree_attr +468	common	file_getattr		sys_file_getattr +469	common	file_setattr		sys_file_setattr  #  # Due to a historical design error, certain syscalls are numbered differently diff --git a/tools/perf/arch/x86/tests/topdown.c b/tools/perf/arch/x86/tests/topdown.c index 8d0ea7a4bbc1..1eba3b4594ef 100644 --- a/tools/perf/arch/x86/tests/topdown.c +++ b/tools/perf/arch/x86/tests/topdown.c @@ -1,6 +1,7 @@  // SPDX-License-Identifier: GPL-2.0  #include "arch-tests.h"  #include "../util/topdown.h" +#include "debug.h"  #include "evlist.h"  #include "parse-events.h"  #include "pmu.h" diff --git a/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl index f657a77314f8..374e4cb788d8 100644 --- a/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl +++ b/tools/perf/arch/xtensa/entry/syscalls/syscall.tbl @@ -438,3 +438,5 @@  465	common	listxattrat			sys_listxattrat  466	common	removexattrat			sys_removexattrat  467	common	open_tree_attr			sys_open_tree_attr +468	common	file_getattr			sys_file_getattr +469	common	file_setattr			sys_file_setattr diff --git a/tools/perf/bench/inject-buildid.c b/tools/perf/bench/inject-buildid.c index aad572a78d7f..12387ea88b9a 100644 --- a/tools/perf/bench/inject-buildid.c +++ b/tools/perf/bench/inject-buildid.c @@ -85,7 +85,7 @@ static int add_dso(const char *fpath, const struct stat *sb __maybe_unused,  	if (typeflag == FTW_D || typeflag == FTW_SL)  		return 0; -	if (filename__read_build_id(fpath, &bid) < 0) +	if (filename__read_build_id(fpath, &bid, /*block=*/true) < 0)  		return 0;  	dso->name = realpath(fpath, NULL); diff --git a/tools/perf/builtin-buildid-cache.c b/tools/perf/builtin-buildid-cache.c index c98104481c8a..2e0f2004696a 100644 --- a/tools/perf/builtin-buildid-cache.c +++ b/tools/perf/builtin-buildid-cache.c @@ -180,7 +180,7 @@ static int build_id_cache__add_file(const char *filename, struct nsinfo *nsi)  	struct nscookie nsc;  	nsinfo__mountns_enter(nsi, &nsc); -	err = filename__read_build_id(filename, &bid); +	err = filename__read_build_id(filename, &bid, /*block=*/true);  	nsinfo__mountns_exit(&nsc);  	if (err < 0) {  		pr_debug("Couldn't read a build-id in %s\n", filename); @@ -204,7 +204,7 @@ static int build_id_cache__remove_file(const char *filename, struct nsinfo *nsi)  	int err;  	nsinfo__mountns_enter(nsi, &nsc); -	err = filename__read_build_id(filename, &bid); +	err = filename__read_build_id(filename, &bid, /*block=*/true);  	nsinfo__mountns_exit(&nsc);  	if (err < 0) {  		pr_debug("Couldn't read a build-id in %s\n", filename); @@ -280,7 +280,7 @@ static bool dso__missing_buildid_cache(struct dso *dso, int parm __maybe_unused)  	if (!dso__build_id_filename(dso, filename, sizeof(filename), false))  		return true; -	if (filename__read_build_id(filename, &bid) == -1) { +	if (filename__read_build_id(filename, &bid, /*block=*/true) == -1) {  		if (errno == ENOENT)  			return false; @@ -309,7 +309,7 @@ static int build_id_cache__update_file(const char *filename, struct nsinfo *nsi)  	int err;  	nsinfo__mountns_enter(nsi, &nsc); -	err = filename__read_build_id(filename, &bid); +	err = filename__read_build_id(filename, &bid, /*block=*/true);  	nsinfo__mountns_exit(&nsc);  	if (err < 0) {  		pr_debug("Couldn't read a build-id in %s\n", filename); diff --git a/tools/perf/builtin-inject.c b/tools/perf/builtin-inject.c index 40ba6a94f719..a114b3fa1bea 100644 --- a/tools/perf/builtin-inject.c +++ b/tools/perf/builtin-inject.c @@ -680,12 +680,12 @@ static int dso__read_build_id(struct dso *dso)  	mutex_lock(dso__lock(dso));  	nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); -	if (filename__read_build_id(dso__long_name(dso), &bid) > 0) +	if (filename__read_build_id(dso__long_name(dso), &bid, /*block=*/true) > 0)  		dso__set_build_id(dso, &bid);  	else if (dso__nsinfo(dso)) {  		char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso)); -		if (new_name && filename__read_build_id(new_name, &bid) > 0) +		if (new_name && filename__read_build_id(new_name, &bid, /*block=*/true) > 0)  			dso__set_build_id(dso, &bid);  		free(new_name);  	} diff --git a/tools/perf/builtin-lock.c b/tools/perf/builtin-lock.c index fd49703021fd..078634461df2 100644 --- a/tools/perf/builtin-lock.c +++ b/tools/perf/builtin-lock.c @@ -2009,6 +2009,7 @@ static int __cmd_contention(int argc, const char **argv)  		.owner = show_lock_owner,  		.cgroups = RB_ROOT,  	}; +	struct perf_env host_env;  	lockhash_table = calloc(LOCKHASH_SIZE, sizeof(*lockhash_table));  	if (!lockhash_table) @@ -2024,7 +2025,10 @@ static int __cmd_contention(int argc, const char **argv)  	eops.mmap		 = perf_event__process_mmap;  	eops.tracing_data	 = perf_event__process_tracing_data; -	session = perf_session__new(use_bpf ? NULL : &data, &eops); +	perf_env__init(&host_env); +	session = __perf_session__new(use_bpf ? NULL : &data, &eops, +				/*trace_event_repipe=*/false, &host_env); +  	if (IS_ERR(session)) {  		pr_err("Initializing perf session failed\n");  		err = PTR_ERR(session); @@ -2142,6 +2146,7 @@ out_delete:  	evlist__delete(con.evlist);  	lock_contention_finish(&con);  	perf_session__delete(session); +	perf_env__exit(&host_env);  	zfree(&lockhash_table);  	return err;  } diff --git a/tools/perf/tests/pe-file-parsing.c b/tools/perf/tests/pe-file-parsing.c index 30c7da79e109..8b31d1d05f90 100644 --- a/tools/perf/tests/pe-file-parsing.c +++ b/tools/perf/tests/pe-file-parsing.c @@ -37,7 +37,7 @@ static int run_dir(const char *d)  	size_t idx;  	scnprintf(filename, PATH_MAX, "%s/pe-file.exe", d); -	ret = filename__read_build_id(filename, &bid); +	ret = filename__read_build_id(filename, &bid, /*block=*/true);  	TEST_ASSERT_VAL("Failed to read build_id",  			ret == sizeof(expect_build_id));  	TEST_ASSERT_VAL("Wrong build_id", !memcmp(bid.data, expect_build_id, @@ -49,7 +49,7 @@ static int run_dir(const char *d)  			!strcmp(debuglink, expect_debuglink));  	scnprintf(debugfile, PATH_MAX, "%s/%s", d, debuglink); -	ret = filename__read_build_id(debugfile, &bid); +	ret = filename__read_build_id(debugfile, &bid, /*block=*/true);  	TEST_ASSERT_VAL("Failed to read debug file build_id",  			ret == sizeof(expect_build_id));  	TEST_ASSERT_VAL("Wrong build_id", !memcmp(bid.data, expect_build_id, diff --git a/tools/perf/tests/sdt.c b/tools/perf/tests/sdt.c index 93baee2eae42..6132f1af3e22 100644 --- a/tools/perf/tests/sdt.c +++ b/tools/perf/tests/sdt.c @@ -31,7 +31,7 @@ static int build_id_cache__add_file(const char *filename)  	struct build_id bid = { .size = 0, };  	int err; -	err = filename__read_build_id(filename, &bid); +	err = filename__read_build_id(filename, &bid, /*block=*/true);  	if (err < 0) {  		pr_debug("Failed to read build id of %s\n", filename);  		return err; diff --git a/tools/perf/tests/shell/test_bpf_metadata.sh b/tools/perf/tests/shell/test_bpf_metadata.sh index 69e3c2055134..be67d56e0f09 100755 --- a/tools/perf/tests/shell/test_bpf_metadata.sh +++ b/tools/perf/tests/shell/test_bpf_metadata.sh @@ -61,7 +61,7 @@ test_bpf_metadata() {  		/perf_version/ {  			if (entry) print $NF;  		} -	' | egrep "$VERS" > /dev/null +	' | grep -qF "$VERS"  	then  		echo "Basic BPF metadata test [Failed invalid output]"  		err=1 diff --git a/tools/perf/trace/beauty/include/uapi/linux/fcntl.h b/tools/perf/trace/beauty/include/uapi/linux/fcntl.h index a15ac2fa4b20..f291ab4f94eb 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/fcntl.h +++ b/tools/perf/trace/beauty/include/uapi/linux/fcntl.h @@ -90,10 +90,28 @@  #define DN_ATTRIB	0x00000020	/* File changed attibutes */  #define DN_MULTISHOT	0x80000000	/* Don't remove notifier */ +/* Reserved kernel ranges [-100], [-10000, -40000]. */  #define AT_FDCWD		-100    /* Special value for dirfd used to  					   indicate openat should use the  					   current working directory. */ +/* + * The concept of process and threads in userland and the kernel is a confusing + * one - within the kernel every thread is a 'task' with its own individual PID, + * however from userland's point of view threads are grouped by a single PID, + * which is that of the 'thread group leader', typically the first thread + * spawned. + * + * To cut the Gideon knot, for internal kernel usage, we refer to + * PIDFD_SELF_THREAD to refer to the current thread (or task from a kernel + * perspective), and PIDFD_SELF_THREAD_GROUP to refer to the current thread + * group leader... + */ +#define PIDFD_SELF_THREAD		-10000 /* Current thread. */ +#define PIDFD_SELF_THREAD_GROUP		-10001 /* Current thread group leader. */ + +#define FD_PIDFS_ROOT			-10002 /* Root of the pidfs filesystem */ +#define FD_INVALID			-10009 /* Invalid file descriptor: -10000 - EBADF = -10009 */  /* Generic flags for the *at(2) family of syscalls. */ diff --git a/tools/perf/trace/beauty/include/uapi/linux/fs.h b/tools/perf/trace/beauty/include/uapi/linux/fs.h index 0098b0ce8ccb..0bd678a4a10e 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/fs.h +++ b/tools/perf/trace/beauty/include/uapi/linux/fs.h @@ -60,6 +60,17 @@  #define RENAME_EXCHANGE		(1 << 1)	/* Exchange source and dest */  #define RENAME_WHITEOUT		(1 << 2)	/* Whiteout source */ +/* + * The root inode of procfs is guaranteed to always have the same inode number. + * For programs that make heavy use of procfs, verifying that the root is a + * real procfs root and using openat2(RESOLVE_{NO_{XDEV,MAGICLINKS},BENEATH}) + * will allow you to make sure you are never tricked into operating on the + * wrong procfs file. + */ +enum procfs_ino { +	PROCFS_ROOT_INO = 1, +}; +  struct file_clone_range {  	__s64 src_fd;  	__u64 src_offset; @@ -91,6 +102,63 @@ struct fs_sysfs_path {  	__u8			name[128];  }; +/* Protection info capability flags */ +#define	LBMD_PI_CAP_INTEGRITY		(1 << 0) +#define	LBMD_PI_CAP_REFTAG		(1 << 1) + +/* Checksum types for Protection Information */ +#define LBMD_PI_CSUM_NONE		0 +#define LBMD_PI_CSUM_IP			1 +#define LBMD_PI_CSUM_CRC16_T10DIF	2 +#define LBMD_PI_CSUM_CRC64_NVME		4 + +/* sizeof first published struct */ +#define LBMD_SIZE_VER0			16 + +/* + * Logical block metadata capability descriptor + * If the device does not support metadata, all the fields will be zero. + * Applications must check lbmd_flags to determine whether metadata is + * supported or not. + */ +struct logical_block_metadata_cap { +	/* Bitmask of logical block metadata capability flags */ +	__u32	lbmd_flags; +	/* +	 * The amount of data described by each unit of logical block +	 * metadata +	 */ +	__u16	lbmd_interval; +	/* +	 * Size in bytes of the logical block metadata associated with each +	 * interval +	 */ +	__u8	lbmd_size; +	/* +	 * Size in bytes of the opaque block tag associated with each +	 * interval +	 */ +	__u8	lbmd_opaque_size; +	/* +	 * Offset in bytes of the opaque block tag within the logical block +	 * metadata +	 */ +	__u8	lbmd_opaque_offset; +	/* Size in bytes of the T10 PI tuple associated with each interval */ +	__u8	lbmd_pi_size; +	/* Offset in bytes of T10 PI tuple within the logical block metadata */ +	__u8	lbmd_pi_offset; +	/* T10 PI guard tag type */ +	__u8	lbmd_guard_tag_type; +	/* Size in bytes of the T10 PI application tag */ +	__u8	lbmd_app_tag_size; +	/* Size in bytes of the T10 PI reference tag */ +	__u8	lbmd_ref_tag_size; +	/* Size in bytes of the T10 PI storage tag */ +	__u8	lbmd_storage_tag_size; +	__u8	pad; +}; +  /* extent-same (dedupe) ioctls; these MUST match the btrfs ioctl definitions */  #define FILE_DEDUPE_RANGE_SAME		0  #define FILE_DEDUPE_RANGE_DIFFERS	1 @@ -149,6 +217,24 @@ struct fsxattr {  };  /* + * Variable size structure for file_[sg]et_attr(). + * + * Note. This is alternative to the structure 'struct file_kattr'/'struct fsxattr'. + * As this structure is passed to/from userspace with its size, this can + * be versioned based on the size. + */ +struct file_attr { +	__u64 fa_xflags;	/* xflags field value (get/set) */ +	__u32 fa_extsize;	/* extsize field value (get/set)*/ +	__u32 fa_nextents;	/* nextents field value (get)   */ +	__u32 fa_projid;	/* project identifier (get/set) */ +	__u32 fa_cowextsize;	/* CoW extsize field value (get/set) */ +}; + +#define FILE_ATTR_SIZE_VER0 24 +#define FILE_ATTR_SIZE_LATEST FILE_ATTR_SIZE_VER0 + +/*   * Flags for the fsx_xflags field   */  #define FS_XFLAG_REALTIME	0x00000001	/* data in realtime volume */ @@ -247,6 +333,8 @@ struct fsxattr {   * also /sys/kernel/debug/ for filesystems with debugfs exports   */  #define FS_IOC_GETFSSYSFSPATH		_IOR(0x15, 1, struct fs_sysfs_path) +/* Get logical block metadata capability details */ +#define FS_IOC_GETLBMD_CAP		_IOWR(0x15, 2, struct logical_block_metadata_cap)  /*   * Inode flags (FS_IOC_GETFLAGS / FS_IOC_SETFLAGS) diff --git a/tools/perf/trace/beauty/include/uapi/linux/prctl.h b/tools/perf/trace/beauty/include/uapi/linux/prctl.h index 3b93fb906e3c..ed3aed264aeb 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/prctl.h +++ b/tools/perf/trace/beauty/include/uapi/linux/prctl.h @@ -244,6 +244,8 @@ struct prctl_mm_map {  # define PR_MTE_TAG_MASK		(0xffffUL << PR_MTE_TAG_SHIFT)  /* Unused; kept only for source compatibility */  # define PR_MTE_TCF_SHIFT		1 +/* MTE tag check store only */ +# define PR_MTE_STORE_ONLY		(1UL << 19)  /* RISC-V pointer masking tag length */  # define PR_PMLEN_SHIFT			24  # define PR_PMLEN_MASK			(0x7fUL << PR_PMLEN_SHIFT) @@ -255,7 +257,12 @@ struct prctl_mm_map {  /* Dispatch syscalls to a userspace handler */  #define PR_SET_SYSCALL_USER_DISPATCH	59  # define PR_SYS_DISPATCH_OFF		0 -# define PR_SYS_DISPATCH_ON		1 +/* Enable dispatch except for the specified range */ +# define PR_SYS_DISPATCH_EXCLUSIVE_ON	1 +/* Enable dispatch for the specified range */ +# define PR_SYS_DISPATCH_INCLUSIVE_ON	2 +/* Legacy name for backwards compatibility */ +# define PR_SYS_DISPATCH_ON		PR_SYS_DISPATCH_EXCLUSIVE_ON  /* The control values for the user space selector when dispatch is enabled */  # define SYSCALL_DISPATCH_FILTER_ALLOW	0  # define SYSCALL_DISPATCH_FILTER_BLOCK	1 diff --git a/tools/perf/trace/beauty/include/uapi/linux/vhost.h b/tools/perf/trace/beauty/include/uapi/linux/vhost.h index d4b3e2ae1314..c57674a6aa0d 100644 --- a/tools/perf/trace/beauty/include/uapi/linux/vhost.h +++ b/tools/perf/trace/beauty/include/uapi/linux/vhost.h @@ -235,4 +235,39 @@   */  #define VHOST_VDPA_GET_VRING_SIZE	_IOWR(VHOST_VIRTIO, 0x82,	\  					      struct vhost_vring_state) + +/* Extended features manipulation */ +#define VHOST_GET_FEATURES_ARRAY _IOR(VHOST_VIRTIO, 0x83, \ +				       struct vhost_features_array) +#define VHOST_SET_FEATURES_ARRAY _IOW(VHOST_VIRTIO, 0x83, \ +				       struct vhost_features_array) + +/* fork_owner values for vhost */ +#define VHOST_FORK_OWNER_KTHREAD 0 +#define VHOST_FORK_OWNER_TASK 1 + +/** + * VHOST_SET_FORK_FROM_OWNER - Set the fork_owner flag for the vhost device, + * This ioctl must called before VHOST_SET_OWNER. + * Only available when CONFIG_VHOST_ENABLE_FORK_OWNER_CONTROL=y + * + * @param fork_owner: An 8-bit value that determines the vhost thread mode + * + * When fork_owner is set to VHOST_FORK_OWNER_TASK(default value): + *   - Vhost will create vhost worker as tasks forked from the owner, + *     inheriting all of the owner's attributes. + * + * When fork_owner is set to VHOST_FORK_OWNER_KTHREAD: + *   - Vhost will create vhost workers as kernel threads. + */ +#define VHOST_SET_FORK_FROM_OWNER _IOW(VHOST_VIRTIO, 0x84, __u8) + +/** + * VHOST_GET_FORK_OWNER - Get the current fork_owner flag for the vhost device. + * Only available when CONFIG_VHOST_ENABLE_FORK_OWNER_CONTROL=y + * + * @return: An 8-bit value indicating the current thread mode. + */ +#define VHOST_GET_FORK_FROM_OWNER _IOR(VHOST_VIRTIO, 0x85, __u8) +  #endif diff --git a/tools/perf/util/bpf-event.c b/tools/perf/util/bpf-event.c index 5b6d3e899e11..2298cd396c42 100644 --- a/tools/perf/util/bpf-event.c +++ b/tools/perf/util/bpf-event.c @@ -657,9 +657,15 @@ static int perf_event__synthesize_one_bpf_prog(struct perf_session *session,  		info_node->info_linear = info_linear;  		info_node->metadata = NULL;  		if (!perf_env__insert_bpf_prog_info(env, info_node)) { -			free(info_linear); +			/* +			 * Insert failed, likely because of a duplicate event +			 * made by the sideband thread. Ignore synthesizing the +			 * metadata. +			 */  			free(info_node); +			goto out;  		} +		/* info_linear is now owned by info_node and shouldn't be freed below. */  		info_linear = NULL;  		/* @@ -827,18 +833,18 @@ int perf_event__synthesize_bpf_events(struct perf_session *session,  	return err;  } -static void perf_env__add_bpf_info(struct perf_env *env, u32 id) +static int perf_env__add_bpf_info(struct perf_env *env, u32 id)  {  	struct bpf_prog_info_node *info_node;  	struct perf_bpil *info_linear;  	struct btf *btf = NULL;  	u64 arrays;  	u32 btf_id; -	int fd; +	int fd, err = 0;  	fd = bpf_prog_get_fd_by_id(id);  	if (fd < 0) -		return; +		return -EINVAL;  	arrays = 1UL << PERF_BPIL_JITED_KSYMS;  	arrays |= 1UL << PERF_BPIL_JITED_FUNC_LENS; @@ -852,6 +858,7 @@ static void perf_env__add_bpf_info(struct perf_env *env, u32 id)  	info_linear = get_bpf_prog_info_linear(fd, arrays);  	if (IS_ERR_OR_NULL(info_linear)) {  		pr_debug("%s: failed to get BPF program info. aborting\n", __func__); +		err = PTR_ERR(info_linear);  		goto out;  	} @@ -862,38 +869,46 @@ static void perf_env__add_bpf_info(struct perf_env *env, u32 id)  		info_node->info_linear = info_linear;  		info_node->metadata = bpf_metadata_create(&info_linear->info);  		if (!perf_env__insert_bpf_prog_info(env, info_node)) { +			pr_debug("%s: duplicate add bpf info request for id %u\n", +				 __func__, btf_id);  			free(info_linear);  			free(info_node); +			goto out;  		} -	} else +	} else {  		free(info_linear); +		err = -ENOMEM; +		goto out; +	}  	if (btf_id == 0)  		goto out;  	btf = btf__load_from_kernel_by_id(btf_id); -	if (libbpf_get_error(btf)) { -		pr_debug("%s: failed to get BTF of id %u, aborting\n", -			 __func__, btf_id); -		goto out; +	if (!btf) { +		err = -errno; +		pr_debug("%s: failed to get BTF of id %u %d\n", __func__, btf_id, err); +	} else { +		perf_env__fetch_btf(env, btf_id, btf);  	} -	perf_env__fetch_btf(env, btf_id, btf);  out:  	btf__free(btf);  	close(fd); +	return err;  }  static int bpf_event__sb_cb(union perf_event *event, void *data)  {  	struct perf_env *env = data; +	int ret = 0;  	if (event->header.type != PERF_RECORD_BPF_EVENT)  		return -1;  	switch (event->bpf.type) {  	case PERF_BPF_EVENT_PROG_LOAD: -		perf_env__add_bpf_info(env, event->bpf.id); +		ret = perf_env__add_bpf_info(env, event->bpf.id);  	case PERF_BPF_EVENT_PROG_UNLOAD:  		/* @@ -907,7 +922,7 @@ static int bpf_event__sb_cb(union perf_event *event, void *data)  		break;  	} -	return 0; +	return ret;  }  int evlist__add_bpf_sb_event(struct evlist *evlist, struct perf_env *env) diff --git a/tools/perf/util/bpf-utils.c b/tools/perf/util/bpf-utils.c index 80b1d2b3729b..5a66dc8594aa 100644 --- a/tools/perf/util/bpf-utils.c +++ b/tools/perf/util/bpf-utils.c @@ -20,7 +20,7 @@ struct bpil_array_desc {  				 */  }; -static struct bpil_array_desc bpil_array_desc[] = { +static const struct bpil_array_desc bpil_array_desc[] = {  	[PERF_BPIL_JITED_INSNS] = {  		offsetof(struct bpf_prog_info, jited_prog_insns),  		offsetof(struct bpf_prog_info, jited_prog_len), @@ -115,7 +115,7 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)  	__u32 info_len = sizeof(info);  	__u32 data_len = 0;  	int i, err; -	void *ptr; +	__u8 *ptr;  	if (arrays >> PERF_BPIL_LAST_ARRAY)  		return ERR_PTR(-EINVAL); @@ -126,15 +126,15 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)  		pr_debug("can't get prog info: %s", strerror(errno));  		return ERR_PTR(-EFAULT);  	} +	if (info.type >= __MAX_BPF_PROG_TYPE) +		pr_debug("%s:%d: unexpected program type %u\n", __func__, __LINE__, info.type);  	/* step 2: calculate total size of all arrays */  	for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { +		const struct bpil_array_desc *desc = &bpil_array_desc[i];  		bool include_array = (arrays & (1UL << i)) > 0; -		struct bpil_array_desc *desc;  		__u32 count, size; -		desc = bpil_array_desc + i; -  		/* kernel is too old to support this field */  		if (info_len < desc->array_offset + sizeof(__u32) ||  		    info_len < desc->count_offset + sizeof(__u32) || @@ -163,19 +163,20 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)  	ptr = info_linear->data;  	for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { -		struct bpil_array_desc *desc; +		const struct bpil_array_desc *desc = &bpil_array_desc[i];  		__u32 count, size;  		if ((arrays & (1UL << i)) == 0)  			continue; -		desc  = bpil_array_desc + i;  		count = bpf_prog_info_read_offset_u32(&info, desc->count_offset);  		size  = bpf_prog_info_read_offset_u32(&info, desc->size_offset);  		bpf_prog_info_set_offset_u32(&info_linear->info,  					     desc->count_offset, count);  		bpf_prog_info_set_offset_u32(&info_linear->info,  					     desc->size_offset, size); +		assert(ptr >= info_linear->data); +		assert(ptr < &info_linear->data[data_len]);  		bpf_prog_info_set_offset_u64(&info_linear->info,  					     desc->array_offset,  					     ptr_to_u64(ptr)); @@ -189,27 +190,45 @@ get_bpf_prog_info_linear(int fd, __u64 arrays)  		free(info_linear);  		return ERR_PTR(-EFAULT);  	} +	if (info_linear->info.type >= __MAX_BPF_PROG_TYPE) { +		pr_debug("%s:%d: unexpected program type %u\n", +			 __func__, __LINE__, info_linear->info.type); +	}  	/* step 6: verify the data */ +	ptr = info_linear->data;  	for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { -		struct bpil_array_desc *desc; -		__u32 v1, v2; +		const struct bpil_array_desc *desc = &bpil_array_desc[i]; +		__u32 count1, count2, size1, size2; +		__u64 ptr2;  		if ((arrays & (1UL << i)) == 0)  			continue; -		desc = bpil_array_desc + i; -		v1 = bpf_prog_info_read_offset_u32(&info, desc->count_offset); -		v2 = bpf_prog_info_read_offset_u32(&info_linear->info, +		count1 = bpf_prog_info_read_offset_u32(&info, desc->count_offset); +		count2 = bpf_prog_info_read_offset_u32(&info_linear->info,  						   desc->count_offset); -		if (v1 != v2) -			pr_warning("%s: mismatch in element count\n", __func__); +		if (count1 != count2) { +			pr_warning("%s: mismatch in element count %u vs %u\n", __func__, count1, count2); +			free(info_linear); +			return ERR_PTR(-ERANGE); +		} -		v1 = bpf_prog_info_read_offset_u32(&info, desc->size_offset); -		v2 = bpf_prog_info_read_offset_u32(&info_linear->info, +		size1 = bpf_prog_info_read_offset_u32(&info, desc->size_offset); +		size2 = bpf_prog_info_read_offset_u32(&info_linear->info,  						   desc->size_offset); -		if (v1 != v2) -			pr_warning("%s: mismatch in rec size\n", __func__); +		if (size1 != size2) { +			pr_warning("%s: mismatch in rec size %u vs %u\n", __func__, size1, size2); +			free(info_linear); +			return ERR_PTR(-ERANGE); +		} +		ptr2 = bpf_prog_info_read_offset_u64(&info_linear->info, desc->array_offset); +		if (ptr_to_u64(ptr) != ptr2) { +			pr_warning("%s: mismatch in array %p vs %llx\n", __func__, ptr, ptr2); +			free(info_linear); +			return ERR_PTR(-ERANGE); +		} +		ptr += roundup(count1 * size1, sizeof(__u64));  	}  	/* step 7: update info_len and data_len */ @@ -224,13 +243,12 @@ void bpil_addr_to_offs(struct perf_bpil *info_linear)  	int i;  	for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { -		struct bpil_array_desc *desc; +		const struct bpil_array_desc *desc = &bpil_array_desc[i];  		__u64 addr, offs;  		if ((info_linear->arrays & (1UL << i)) == 0)  			continue; -		desc = bpil_array_desc + i;  		addr = bpf_prog_info_read_offset_u64(&info_linear->info,  						     desc->array_offset);  		offs = addr - ptr_to_u64(info_linear->data); @@ -244,13 +262,12 @@ void bpil_offs_to_addr(struct perf_bpil *info_linear)  	int i;  	for (i = PERF_BPIL_FIRST_ARRAY; i < PERF_BPIL_LAST_ARRAY; ++i) { -		struct bpil_array_desc *desc; +		const struct bpil_array_desc *desc = &bpil_array_desc[i];  		__u64 addr, offs;  		if ((info_linear->arrays & (1UL << i)) == 0)  			continue; -		desc = bpil_array_desc + i;  		offs = bpf_prog_info_read_offset_u64(&info_linear->info,  						     desc->array_offset);  		addr = offs + ptr_to_u64(info_linear->data); diff --git a/tools/perf/util/build-id.c b/tools/perf/util/build-id.c index a7018a3b0437..bf7f3268b9a2 100644 --- a/tools/perf/util/build-id.c +++ b/tools/perf/util/build-id.c @@ -115,7 +115,7 @@ int filename__snprintf_build_id(const char *pathname, char *sbuild_id, size_t sb  	struct build_id bid = { .size = 0, };  	int ret; -	ret = filename__read_build_id(pathname, &bid); +	ret = filename__read_build_id(pathname, &bid, /*block=*/true);  	if (ret < 0)  		return ret; @@ -841,7 +841,7 @@ static int filename__read_build_id_ns(const char *filename,  	int ret;  	nsinfo__mountns_enter(nsi, &nsc); -	ret = filename__read_build_id(filename, bid); +	ret = filename__read_build_id(filename, bid, /*block=*/true);  	nsinfo__mountns_exit(&nsc);  	return ret; diff --git a/tools/perf/util/debuginfo.c b/tools/perf/util/debuginfo.c index a44c70f93156..bb9ebd84ec2d 100644 --- a/tools/perf/util/debuginfo.c +++ b/tools/perf/util/debuginfo.c @@ -110,8 +110,12 @@ struct debuginfo *debuginfo__new(const char *path)  	if (!dso)  		goto out; -	/* Set the build id for DSO_BINARY_TYPE__BUILDID_DEBUGINFO */ -	if (is_regular_file(path) && filename__read_build_id(path, &bid) > 0) +	/* +	 * Set the build id for DSO_BINARY_TYPE__BUILDID_DEBUGINFO. Don't block +	 * incase the path isn't for a regular file. +	 */ +	assert(!dso__has_build_id(dso)); +	if (filename__read_build_id(path, &bid, /*block=*/false) > 0)  		dso__set_build_id(dso, &bid);  	for (type = distro_dwarf_types; diff --git a/tools/perf/util/dsos.c b/tools/perf/util/dsos.c index 0a7645c7fae7..64c1d65b0149 100644 --- a/tools/perf/util/dsos.c +++ b/tools/perf/util/dsos.c @@ -81,13 +81,13 @@ static int dsos__read_build_ids_cb(struct dso *dso, void *data)  		return 0;  	}  	nsinfo__mountns_enter(dso__nsinfo(dso), &nsc); -	if (filename__read_build_id(dso__long_name(dso), &bid) > 0) { +	if (filename__read_build_id(dso__long_name(dso), &bid, /*block=*/true) > 0) {  		dso__set_build_id(dso, &bid);  		args->have_build_id = true;  	} else if (errno == ENOENT && dso__nsinfo(dso)) {  		char *new_name = dso__filename_with_chroot(dso, dso__long_name(dso)); -		if (new_name && filename__read_build_id(new_name, &bid) > 0) { +		if (new_name && filename__read_build_id(new_name, &bid, /*block=*/true) > 0) {  			dso__set_build_id(dso, &bid);  			args->have_build_id = true;  		} diff --git a/tools/perf/util/include/linux/linkage.h b/tools/perf/util/include/linux/linkage.h index 89979ca23c3f..34e2fdfe7300 100644 --- a/tools/perf/util/include/linux/linkage.h +++ b/tools/perf/util/include/linux/linkage.h @@ -120,7 +120,7 @@  #endif  // In the kernel sources (include/linux/cfi_types.h), this has a different -// definition when CONFIG_CFI_CLANG is used, for tools/ just use the !clang +// definition when CONFIG_CFI is used, for tools/ just use the !cfi  // definition:  #ifndef SYM_TYPED_START  #define SYM_TYPED_START(name, linkage, align...)        \ 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 8fabddc1c0da..72c7a4e15d61 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 @@ -32,7 +32,7 @@ static void intel_pt_insn_decoder(struct insn *insn,  	intel_pt_insn->rel = 0;  	intel_pt_insn->emulated_ptwrite = false; -	if (insn_is_avx(insn)) { +	if (insn_is_avx_or_xop(insn)) {  		intel_pt_insn->op = INTEL_PT_OP_OTHER;  		intel_pt_insn->branch = INTEL_PT_BR_NO_BRANCH;  		intel_pt_insn->length = insn->length; diff --git a/tools/perf/util/maps.c b/tools/perf/util/maps.c index 85b2a93a59ac..779f6230130a 100644 --- a/tools/perf/util/maps.c +++ b/tools/perf/util/maps.c @@ -477,6 +477,7 @@ static int __maps__insert(struct maps *maps, struct map *new)  	}  	/* Insert the value at the end. */  	maps_by_address[nr_maps] = map__get(new); +	map__set_kmap_maps(new, maps);  	if (maps_by_name)  		maps_by_name[nr_maps] = map__get(new); @@ -502,8 +503,6 @@ static int __maps__insert(struct maps *maps, struct map *new)  	if (map__end(new) < map__start(new))  		RC_CHK_ACCESS(maps)->ends_broken = true; -	map__set_kmap_maps(new, maps); -  	return 0;  } @@ -891,6 +890,7 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)  		if (before) {  			map__put(maps_by_address[i]);  			maps_by_address[i] = before; +			map__set_kmap_maps(before, maps);  			if (maps_by_name) {  				map__put(maps_by_name[ni]); @@ -918,6 +918,7 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)  			 */  			map__put(maps_by_address[i]);  			maps_by_address[i] = map__get(new); +			map__set_kmap_maps(new, maps);  			if (maps_by_name) {  				map__put(maps_by_name[ni]); @@ -942,14 +943,13 @@ static int __maps__fixup_overlap_and_insert(struct maps *maps, struct map *new)  				 */  				map__put(maps_by_address[i]);  				maps_by_address[i] = map__get(new); +				map__set_kmap_maps(new, maps);  				if (maps_by_name) {  					map__put(maps_by_name[ni]);  					maps_by_name[ni] = map__get(new);  				} -				map__set_kmap_maps(new, maps); -  				check_invariants(maps);  				return err;  			} @@ -1019,6 +1019,7 @@ int maps__copy_from(struct maps *dest, struct maps *parent)  				err = unwind__prepare_access(dest, new, NULL);  				if (!err) {  					dest_maps_by_address[i] = new; +					map__set_kmap_maps(new, dest);  					if (dest_maps_by_name)  						dest_maps_by_name[i] = map__get(new);  					RC_CHK_ACCESS(dest)->nr_maps = i + 1; diff --git a/tools/perf/util/symbol-elf.c b/tools/perf/util/symbol-elf.c index 6d2c280a1730..1346fd180653 100644 --- a/tools/perf/util/symbol-elf.c +++ b/tools/perf/util/symbol-elf.c @@ -873,13 +873,17 @@ out:  #ifdef HAVE_LIBBFD_BUILDID_SUPPORT -static int read_build_id(const char *filename, struct build_id *bid) +static int read_build_id(const char *filename, struct build_id *bid, bool block)  {  	size_t size = sizeof(bid->data); -	int err = -1; +	int err = -1, fd;  	bfd *abfd; -	abfd = bfd_openr(filename, NULL); +	fd = open(filename, block ? O_RDONLY : (O_RDONLY | O_NONBLOCK)); +	if (fd < 0) +		return -1; + +	abfd = bfd_fdopenr(filename, /*target=*/NULL, fd);  	if (!abfd)  		return -1; @@ -902,7 +906,7 @@ out_close:  #else // HAVE_LIBBFD_BUILDID_SUPPORT -static int read_build_id(const char *filename, struct build_id *bid) +static int read_build_id(const char *filename, struct build_id *bid, bool block)  {  	size_t size = sizeof(bid->data);  	int fd, err = -1; @@ -911,7 +915,7 @@ static int read_build_id(const char *filename, struct build_id *bid)  	if (size < BUILD_ID_SIZE)  		goto out; -	fd = open(filename, O_RDONLY); +	fd = open(filename, block ? O_RDONLY : (O_RDONLY | O_NONBLOCK));  	if (fd < 0)  		goto out; @@ -934,7 +938,7 @@ out:  #endif // HAVE_LIBBFD_BUILDID_SUPPORT -int filename__read_build_id(const char *filename, struct build_id *bid) +int filename__read_build_id(const char *filename, struct build_id *bid, bool block)  {  	struct kmod_path m = { .name = NULL, };  	char path[PATH_MAX]; @@ -958,9 +962,10 @@ int filename__read_build_id(const char *filename, struct build_id *bid)  		}  		close(fd);  		filename = path; +		block = true;  	} -	err = read_build_id(filename, bid); +	err = read_build_id(filename, bid, block);  	if (m.comp)  		unlink(filename); diff --git a/tools/perf/util/symbol-minimal.c b/tools/perf/util/symbol-minimal.c index 7201494c5c20..41e4ebe5eac5 100644 --- a/tools/perf/util/symbol-minimal.c +++ b/tools/perf/util/symbol-minimal.c @@ -4,7 +4,6 @@  #include <errno.h>  #include <unistd.h> -#include <stdio.h>  #include <fcntl.h>  #include <string.h>  #include <stdlib.h> @@ -86,13 +85,10 @@ int filename__read_debuglink(const char *filename __maybe_unused,  /*   * Just try PT_NOTE header otherwise fails   */ -int filename__read_build_id(const char *filename, struct build_id *bid) +int filename__read_build_id(const char *filename, struct build_id *bid, bool block)  { -	FILE *fp; -	int ret = -1; +	int fd, ret = -1;  	bool need_swap = false, elf32; -	u8 e_ident[EI_NIDENT]; -	int i;  	union {  		struct {  			Elf32_Ehdr ehdr32; @@ -103,28 +99,27 @@ int filename__read_build_id(const char *filename, struct build_id *bid)  			Elf64_Phdr *phdr64;  		};  	} hdrs; -	void *phdr; -	size_t phdr_size; -	void *buf = NULL; -	size_t buf_size = 0; +	void *phdr, *buf = NULL; +	ssize_t phdr_size, ehdr_size, buf_size = 0; -	fp = fopen(filename, "r"); -	if (fp == NULL) +	fd = open(filename, block ? O_RDONLY : (O_RDONLY | O_NONBLOCK)); +	if (fd < 0)  		return -1; -	if (fread(e_ident, sizeof(e_ident), 1, fp) != 1) +	if (read(fd, hdrs.ehdr32.e_ident, EI_NIDENT) != EI_NIDENT)  		goto out; -	if (memcmp(e_ident, ELFMAG, SELFMAG) || -	    e_ident[EI_VERSION] != EV_CURRENT) +	if (memcmp(hdrs.ehdr32.e_ident, ELFMAG, SELFMAG) || +	    hdrs.ehdr32.e_ident[EI_VERSION] != EV_CURRENT)  		goto out; -	need_swap = check_need_swap(e_ident[EI_DATA]); -	elf32 = e_ident[EI_CLASS] == ELFCLASS32; +	need_swap = check_need_swap(hdrs.ehdr32.e_ident[EI_DATA]); +	elf32 = hdrs.ehdr32.e_ident[EI_CLASS] == ELFCLASS32; +	ehdr_size = (elf32 ? sizeof(hdrs.ehdr32) : sizeof(hdrs.ehdr64)) - EI_NIDENT; -	if (fread(elf32 ? (void *)&hdrs.ehdr32 : (void *)&hdrs.ehdr64, -		  elf32 ? sizeof(hdrs.ehdr32) : sizeof(hdrs.ehdr64), -		  1, fp) != 1) +	if (read(fd, +		 (elf32 ? (void *)&hdrs.ehdr32 : (void *)&hdrs.ehdr64) + EI_NIDENT, +		 ehdr_size) != ehdr_size)  		goto out;  	if (need_swap) { @@ -138,14 +133,18 @@ int filename__read_build_id(const char *filename, struct build_id *bid)  			hdrs.ehdr64.e_phnum = bswap_16(hdrs.ehdr64.e_phnum);  		}  	} -	phdr_size = elf32 ? hdrs.ehdr32.e_phentsize * hdrs.ehdr32.e_phnum -			  : hdrs.ehdr64.e_phentsize * hdrs.ehdr64.e_phnum; +	if ((elf32 && hdrs.ehdr32.e_phentsize != sizeof(Elf32_Phdr)) || +	    (!elf32 && hdrs.ehdr64.e_phentsize != sizeof(Elf64_Phdr))) +		goto out; + +	phdr_size = elf32 ? sizeof(Elf32_Phdr) * hdrs.ehdr32.e_phnum +			  : sizeof(Elf64_Phdr) * hdrs.ehdr64.e_phnum;  	phdr = malloc(phdr_size);  	if (phdr == NULL)  		goto out; -	fseek(fp, elf32 ? hdrs.ehdr32.e_phoff : hdrs.ehdr64.e_phoff, SEEK_SET); -	if (fread(phdr, phdr_size, 1, fp) != 1) +	lseek(fd, elf32 ? hdrs.ehdr32.e_phoff : hdrs.ehdr64.e_phoff, SEEK_SET); +	if (read(fd, phdr, phdr_size) != phdr_size)  		goto out_free;  	if (elf32) @@ -153,8 +152,8 @@ int filename__read_build_id(const char *filename, struct build_id *bid)  	else  		hdrs.phdr64 = phdr; -	for (i = 0; i < elf32 ? hdrs.ehdr32.e_phnum : hdrs.ehdr64.e_phnum; i++) { -		size_t p_filesz; +	for (int i = 0; i < (elf32 ? hdrs.ehdr32.e_phnum : hdrs.ehdr64.e_phnum); i++) { +		ssize_t p_filesz;  		if (need_swap) {  			if (elf32) { @@ -180,8 +179,8 @@ int filename__read_build_id(const char *filename, struct build_id *bid)  				goto out_free;  			buf = tmp;  		} -		fseek(fp, elf32 ? hdrs.phdr32[i].p_offset : hdrs.phdr64[i].p_offset, SEEK_SET); -		if (fread(buf, p_filesz, 1, fp) != 1) +		lseek(fd, elf32 ? hdrs.phdr32[i].p_offset : hdrs.phdr64[i].p_offset, SEEK_SET); +		if (read(fd, buf, p_filesz) != p_filesz)  			goto out_free;  		ret = read_build_id(buf, p_filesz, bid, need_swap); @@ -194,7 +193,7 @@ out_free:  	free(buf);  	free(phdr);  out: -	fclose(fp); +	close(fd);  	return ret;  } @@ -324,7 +323,7 @@ int dso__load_sym(struct dso *dso, struct map *map __maybe_unused,  	if (ret >= 0)  		RC_CHK_ACCESS(dso)->is_64_bit = ret; -	if (filename__read_build_id(ss->name, &bid) > 0) +	if (filename__read_build_id(ss->name, &bid, /*block=*/true) > 0)  		dso__set_build_id(dso, &bid);  	return 0;  } diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index e816e4220d33..3fed54de5401 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c @@ -1869,14 +1869,14 @@ int dso__load(struct dso *dso, struct map *map)  	/*  	 * Read the build id if possible. This is required for -	 * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work +	 * DSO_BINARY_TYPE__BUILDID_DEBUGINFO to work. Don't block in case path +	 * isn't for a regular file.  	 */ -	if (!dso__has_build_id(dso) && -	    is_regular_file(dso__long_name(dso))) { +	if (!dso__has_build_id(dso)) {  		struct build_id bid = { .size = 0, };  		__symbol__join_symfs(name, PATH_MAX, dso__long_name(dso)); -		if (filename__read_build_id(name, &bid) > 0) +		if (filename__read_build_id(name, &bid, /*block=*/false) > 0)  			dso__set_build_id(dso, &bid);  	} diff --git a/tools/perf/util/symbol.h b/tools/perf/util/symbol.h index 3fb5d146d9b1..347106218799 100644 --- a/tools/perf/util/symbol.h +++ b/tools/perf/util/symbol.h @@ -140,7 +140,7 @@ struct symbol *dso__next_symbol(struct symbol *sym);  enum dso_type dso__type_fd(int fd); -int filename__read_build_id(const char *filename, struct build_id *id); +int filename__read_build_id(const char *filename, struct build_id *id, bool block);  int sysfs__read_build_id(const char *filename, struct build_id *bid);  int modules__parse(const char *filename, void *arg,  		   int (*process_module)(void *arg, const char *name, diff --git a/tools/perf/util/synthetic-events.c b/tools/perf/util/synthetic-events.c index cb2c1ace304a..fcd1fd13c30e 100644 --- a/tools/perf/util/synthetic-events.c +++ b/tools/perf/util/synthetic-events.c @@ -401,7 +401,7 @@ static void perf_record_mmap2__read_build_id(struct perf_record_mmap2 *event,  	nsi = nsinfo__new(event->pid);  	nsinfo__mountns_enter(nsi, &nc); -	rc = filename__read_build_id(event->filename, &bid) > 0 ? 0 : -1; +	rc = filename__read_build_id(event->filename, &bid, /*block=*/false) > 0 ? 0 : -1;  	nsinfo__mountns_exit(&nc);  	nsinfo__put(nsi); | 
