Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'perf-tools-fixes-for-v6.12-1-2024-10-08' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools

Pull perf tools fixes from Arnaldo Carvalho de Melo:

- Fix an assert() to handle captured and unprocessed ARM CoreSight CPU
traces

- Fix static build compilation error when libdw isn't installed or is
too old

- Add missing include when building with
!HAVE_DWARF_GETLOCATIONS_SUPPORT

- Add missing refcount put on 32-bit DSOs

- Fix disassembly of user space binaries by setting the binary_type of
DSO when loading

- Update headers with the kernel sources, including asound.h, sched.h,
fcntl, msr-index.h, irq_vectors.h, socket.h, list_sort.c and arm64's
cputype.h

* tag 'perf-tools-fixes-for-v6.12-1-2024-10-08' of git://git.kernel.org/pub/scm/linux/kernel/git/perf/perf-tools:
perf cs-etm: Fix the assert() to handle captured and unprocessed cpu trace
perf build: Fix build feature-dwarf_getlocations fail for old libdw
perf build: Fix static compilation error when libdw is not installed
perf dwarf-aux: Fix build with !HAVE_DWARF_GETLOCATIONS_SUPPORT
tools headers arm64: Sync arm64's cputype.h with the kernel sources
perf tools: Cope with differences for lib/list_sort.c copy from the kernel
tools check_headers.sh: Add check variant that excludes some hunks
perf beauty: Update copy of linux/socket.h with the kernel sources
tools headers UAPI: Sync the linux/in.h with the kernel sources
perf trace beauty: Update the arch/x86/include/asm/irq_vectors.h copy with the kernel sources
tools arch x86: Sync the msr-index.h copy with the kernel sources
tools include UAPI: Sync linux/fcntl.h copy with the kernel sources
tools include UAPI: Sync linux/sched.h copy with the kernel sources
tools include UAPI: Sync sound/asound.h copy with the kernel sources
perf vdso: Missed put on 32-bit dsos
perf symbol: Set binary_type of dso when loading

+170 -34
+2
tools/arch/arm64/include/asm/cputype.h
··· 143 143 #define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039 144 144 145 145 #define AMPERE_CPU_PART_AMPERE1 0xAC3 146 + #define AMPERE_CPU_PART_AMPERE1A 0xAC4 146 147 147 148 #define MICROSOFT_CPU_PART_AZURE_COBALT_100 0xD49 /* Based on r0p0 of ARM Neoverse N2 */ 148 149 ··· 213 212 #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX) 214 213 #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX) 215 214 #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) 215 + #define MIDR_AMPERE1A MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1A) 216 216 #define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100) 217 217 218 218 /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
+2
tools/arch/x86/include/asm/msr-index.h
··· 247 247 #define MSR_INTEGRITY_CAPS_ARRAY_BIST BIT(MSR_INTEGRITY_CAPS_ARRAY_BIST_BIT) 248 248 #define MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT 4 249 249 #define MSR_INTEGRITY_CAPS_PERIODIC_BIST BIT(MSR_INTEGRITY_CAPS_PERIODIC_BIST_BIT) 250 + #define MSR_INTEGRITY_CAPS_SBAF_BIT 8 251 + #define MSR_INTEGRITY_CAPS_SBAF BIT(MSR_INTEGRITY_CAPS_SBAF_BIT) 250 252 #define MSR_INTEGRITY_CAPS_SAF_GEN_MASK GENMASK_ULL(10, 9) 251 253 252 254 #define MSR_LBR_NHM_FROM 0x00000680
+4 -1
tools/build/feature/Makefile
··· 172 172 ifeq ($(findstring -static,${LDFLAGS}),-static) 173 173 DWARFLIBS += -lelf -lz -llzma -lbz2 -lzstd 174 174 175 - LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw) 175 + LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw).0.0 176 176 LIBDW_VERSION_1 := $(word 1, $(subst ., ,$(LIBDW_VERSION))) 177 177 LIBDW_VERSION_2 := $(word 2, $(subst ., ,$(LIBDW_VERSION))) 178 178 ··· 181 181 ifeq ($(shell test $(LIBDW_VERSION_2) -lt 177; echo $$?),0) 182 182 DWARFLIBS += -lebl 183 183 endif 184 + 185 + # Must put -ldl after -lebl for dependency 186 + DWARFLIBS += -ldl 184 187 endif 185 188 186 189 $(OUTPUT)test-dwarf.bin:
+1 -1
tools/include/uapi/linux/in.h
··· 141 141 */ 142 142 #define IP_PMTUDISC_INTERFACE 4 143 143 /* weaker version of IP_PMTUDISC_INTERFACE, which allows packets to get 144 - * fragmented if they exeed the interface mtu 144 + * fragmented if they exceed the interface mtu 145 145 */ 146 146 #define IP_PMTUDISC_OMIT 5 147 147
+5 -2
tools/perf/Makefile.config
··· 147 147 endif 148 148 DWARFLIBS := -ldw 149 149 ifeq ($(findstring -static,${LDFLAGS}),-static) 150 - DWARFLIBS += -lelf -ldl -lz -llzma -lbz2 -lzstd 150 + DWARFLIBS += -lelf -lz -llzma -lbz2 -lzstd 151 151 152 - LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw) 152 + LIBDW_VERSION := $(shell $(PKG_CONFIG) --modversion libdw).0.0 153 153 LIBDW_VERSION_1 := $(word 1, $(subst ., ,$(LIBDW_VERSION))) 154 154 LIBDW_VERSION_2 := $(word 2, $(subst ., ,$(LIBDW_VERSION))) 155 155 ··· 158 158 ifeq ($(shell test $(LIBDW_VERSION_2) -lt 177; echo $$?),0) 159 159 DWARFLIBS += -lebl 160 160 endif 161 + 162 + # Must put -ldl after -lebl for dependency 163 + DWARFLIBS += -ldl 161 164 endif 162 165 FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS) 163 166 FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) $(DWARFLIBS)
+31
tools/perf/check-header_ignore_hunks/lib/list_sort.c
··· 1 + @@ -1,5 +1,6 @@ 2 + // SPDX-License-Identifier: GPL-2.0 3 + #include <linux/kernel.h> 4 + +#include <linux/bug.h> 5 + #include <linux/compiler.h> 6 + #include <linux/export.h> 7 + #include <linux/string.h> 8 + @@ -52,6 +53,7 @@ 9 + struct list_head *a, struct list_head *b) 10 + { 11 + struct list_head *tail = head; 12 + + u8 count = 0; 13 + 14 + for (;;) { 15 + /* if equal, take 'a' -- important for sort stability */ 16 + @@ -77,6 +79,15 @@ 17 + /* Finish linking remainder of list b on to tail */ 18 + tail->next = b; 19 + do { 20 + + /* 21 + + * If the merge is highly unbalanced (e.g. the input is 22 + + * already sorted), this loop may run many iterations. 23 + + * Continue callbacks to the client even though no 24 + + * element comparison is needed, so the client's cmp() 25 + + * routine can invoke cond_resched() periodically. 26 + + */ 27 + + if (unlikely(!++count)) 28 + + cmp(priv, b, b); 29 + b->prev = tail; 30 + tail = b; 31 + b = b->next;
+28 -1
tools/perf/check-headers.sh
··· 136 136 check_2 "tools/perf/trace/beauty/$file" "$file" "$@" 137 137 } 138 138 139 + check_ignore_some_hunks () { 140 + orig_file="$1" 141 + tools_file="tools/$orig_file" 142 + hunks_to_ignore="tools/perf/check-header_ignore_hunks/$orig_file" 143 + 144 + if [ ! -f "$hunks_to_ignore" ]; then 145 + echo "$hunks_to_ignore not found. Skipping $orig_file check." 146 + FAILURES+=( 147 + "$tools_file $orig_file" 148 + ) 149 + return 150 + fi 151 + 152 + cmd="diff -u \"$tools_file\" \"$orig_file\" | grep -vf \"$hunks_to_ignore\" | wc -l | grep -qw 0" 153 + 154 + if [ -f "$orig_file" ] && ! eval "$cmd" 155 + then 156 + FAILURES+=( 157 + "$tools_file $orig_file" 158 + ) 159 + fi 160 + } 161 + 162 + 139 163 # Check if we have the kernel headers (tools/perf/../../include), else 140 164 # we're probably on a detached tarball, so no point in trying to check 141 165 # differences. ··· 193 169 check include/linux/build_bug.h '-I "^#\(ifndef\|endif\)\( \/\/\)* static_assert$"' 194 170 check include/linux/ctype.h '-I "isdigit("' 195 171 check lib/ctype.c '-I "^EXPORT_SYMBOL" -I "^#include <linux/export.h>" -B' 196 - check lib/list_sort.c '-I "^#include <linux/bug.h>"' 197 172 198 173 # diff non-symmetric files 199 174 check_2 tools/perf/arch/x86/entry/syscalls/syscall_32.tbl arch/x86/entry/syscalls/syscall_32.tbl ··· 209 186 # check duplicated library files 210 187 check_2 tools/perf/util/hashmap.h tools/lib/bpf/hashmap.h 211 188 check_2 tools/perf/util/hashmap.c tools/lib/bpf/hashmap.c 189 + 190 + # Files with larger differences 191 + 192 + check_ignore_some_hunks lib/list_sort.c 212 193 213 194 cd tools/perf || exit 214 195
+2 -2
tools/perf/trace/beauty/arch/x86/include/asm/irq_vectors.h
··· 18 18 * Vectors 0 ... 31 : system traps and exceptions - hardcoded events 19 19 * Vectors 32 ... 127 : device interrupts 20 20 * Vector 128 : legacy int80 syscall interface 21 - * Vectors 129 ... LOCAL_TIMER_VECTOR-1 22 - * Vectors LOCAL_TIMER_VECTOR ... 255 : special interrupts 21 + * Vectors 129 ... FIRST_SYSTEM_VECTOR-1 : device interrupts 22 + * Vectors FIRST_SYSTEM_VECTOR ... 255 : special interrupts 23 23 * 24 24 * 64-bit x86 has per CPU IDT tables, 32-bit has one shared IDT table. 25 25 *
+5
tools/perf/trace/beauty/fs_at_flags.sh
··· 13 13 regex='^[[:space:]]*#[[:space:]]*define[[:space:]]+AT_([^_]+[[:alnum:]_]+)[[:space:]]+(0x[[:xdigit:]]+)[[:space:]]*.*' 14 14 # AT_EACCESS is only meaningful to faccessat, so we will special case it there... 15 15 # AT_STATX_SYNC_TYPE is not a bit, its a mask of AT_STATX_SYNC_AS_STAT, AT_STATX_FORCE_SYNC and AT_STATX_DONT_SYNC 16 + # AT_HANDLE_FID and AT_HANDLE_MNT_ID_UNIQUE are reusing values and are valid only for name_to_handle_at() 17 + # AT_RENAME_NOREPLACE reuses 0x1 and is valid only for renameat2() 16 18 grep -E $regex ${linux_fcntl} | \ 17 19 grep -v AT_EACCESS | \ 18 20 grep -v AT_STATX_SYNC_TYPE | \ 21 + grep -v AT_HANDLE_FID | \ 22 + grep -v AT_HANDLE_MNT_ID_UNIQUE | \ 23 + grep -v AT_RENAME_NOREPLACE | \ 19 24 sed -r "s/$regex/\2 \1/g" | \ 20 25 xargs printf "\t[ilog2(%s) + 1] = \"%s\",\n" 21 26 printf "};\n"
+1
tools/perf/trace/beauty/include/linux/socket.h
··· 327 327 * plain text and require encryption 328 328 */ 329 329 330 + #define MSG_SOCK_DEVMEM 0x2000000 /* Receive devmem skbs as cmsg */ 330 331 #define MSG_ZEROCOPY 0x4000000 /* Use user data in kernel path */ 331 332 #define MSG_SPLICE_PAGES 0x8000000 /* Splice the pages from the iterator in sendmsg() */ 332 333 #define MSG_FASTOPEN 0x20000000 /* Send data in TCP SYN */
+60 -24
tools/perf/trace/beauty/include/uapi/linux/fcntl.h
··· 16 16 17 17 #define F_DUPFD_QUERY (F_LINUX_SPECIFIC_BASE + 3) 18 18 19 + /* Was the file just created? */ 20 + #define F_CREATED_QUERY (F_LINUX_SPECIFIC_BASE + 4) 21 + 19 22 /* 20 23 * Cancel a blocking posix lock; internal use only until we expose an 21 24 * asynchronous lock api to userspace: ··· 90 87 #define DN_ATTRIB 0x00000020 /* File changed attibutes */ 91 88 #define DN_MULTISHOT 0x80000000 /* Don't remove notifier */ 92 89 90 + #define AT_FDCWD -100 /* Special value for dirfd used to 91 + indicate openat should use the 92 + current working directory. */ 93 + 94 + 95 + /* Generic flags for the *at(2) family of syscalls. */ 96 + 97 + /* Reserved for per-syscall flags 0xff. */ 98 + #define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic 99 + links. */ 100 + /* Reserved for per-syscall flags 0x200 */ 101 + #define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */ 102 + #define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount 103 + traversal. */ 104 + #define AT_EMPTY_PATH 0x1000 /* Allow empty relative 105 + pathname to operate on dirfd 106 + directly. */ 93 107 /* 94 - * The constants AT_REMOVEDIR and AT_EACCESS have the same value. AT_EACCESS is 95 - * meaningful only to faccessat, while AT_REMOVEDIR is meaningful only to 96 - * unlinkat. The two functions do completely different things and therefore, 97 - * the flags can be allowed to overlap. For example, passing AT_REMOVEDIR to 98 - * faccessat would be undefined behavior and thus treating it equivalent to 99 - * AT_EACCESS is valid undefined behavior. 108 + * These flags are currently statx(2)-specific, but they could be made generic 109 + * in the future and so they should not be used for other per-syscall flags. 100 110 */ 101 - #define AT_FDCWD -100 /* Special value used to indicate 102 - openat should use the current 103 - working directory. */ 104 - #define AT_SYMLINK_NOFOLLOW 0x100 /* Do not follow symbolic links. */ 111 + #define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required from statx() */ 112 + #define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */ 113 + #define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd with the server */ 114 + #define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the server */ 115 + 116 + #define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */ 117 + 118 + /* 119 + * Per-syscall flags for the *at(2) family of syscalls. 120 + * 121 + * These are flags that are so syscall-specific that a user passing these flags 122 + * to the wrong syscall is so "clearly wrong" that we can safely call such 123 + * usage "undefined behaviour". 124 + * 125 + * For example, the constants AT_REMOVEDIR and AT_EACCESS have the same value. 126 + * AT_EACCESS is meaningful only to faccessat, while AT_REMOVEDIR is meaningful 127 + * only to unlinkat. The two functions do completely different things and 128 + * therefore, the flags can be allowed to overlap. For example, passing 129 + * AT_REMOVEDIR to faccessat would be undefined behavior and thus treating it 130 + * equivalent to AT_EACCESS is valid undefined behavior. 131 + * 132 + * Note for implementers: When picking a new per-syscall AT_* flag, try to 133 + * reuse already existing flags first. This leaves us with as many unused bits 134 + * as possible, so we can use them for generic bits in the future if necessary. 135 + */ 136 + 137 + /* Flags for renameat2(2) (must match legacy RENAME_* flags). */ 138 + #define AT_RENAME_NOREPLACE 0x0001 139 + #define AT_RENAME_EXCHANGE 0x0002 140 + #define AT_RENAME_WHITEOUT 0x0004 141 + 142 + /* Flag for faccessat(2). */ 105 143 #define AT_EACCESS 0x200 /* Test access permitted for 106 144 effective IDs, not real IDs. */ 145 + /* Flag for unlinkat(2). */ 107 146 #define AT_REMOVEDIR 0x200 /* Remove directory instead of 108 147 unlinking file. */ 109 - #define AT_SYMLINK_FOLLOW 0x400 /* Follow symbolic links. */ 110 - #define AT_NO_AUTOMOUNT 0x800 /* Suppress terminal automount traversal */ 111 - #define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */ 148 + /* Flags for name_to_handle_at(2). */ 149 + #define AT_HANDLE_FID 0x200 /* File handle is needed to compare 150 + object identity and may not be 151 + usable with open_by_handle_at(2). */ 152 + #define AT_HANDLE_MNT_ID_UNIQUE 0x001 /* Return the u64 unique mount ID. */ 112 153 113 - #define AT_STATX_SYNC_TYPE 0x6000 /* Type of synchronisation required from statx() */ 114 - #define AT_STATX_SYNC_AS_STAT 0x0000 /* - Do whatever stat() does */ 115 - #define AT_STATX_FORCE_SYNC 0x2000 /* - Force the attributes to be sync'd with the server */ 116 - #define AT_STATX_DONT_SYNC 0x4000 /* - Don't sync attributes with the server */ 117 - 118 - #define AT_RECURSIVE 0x8000 /* Apply to the entire subtree */ 119 - 120 - /* Flags for name_to_handle_at(2). We reuse AT_ flag space to save bits... */ 121 - #define AT_HANDLE_FID AT_REMOVEDIR /* file handle is needed to 122 - compare object identity and may not 123 - be usable to open_by_handle_at(2) */ 124 154 #if defined(__KERNEL__) 125 155 #define AT_GETATTR_NOSEC 0x80000000 126 156 #endif
+1
tools/perf/trace/beauty/include/uapi/linux/sched.h
··· 118 118 /* SCHED_ISO: reserved but not implemented yet */ 119 119 #define SCHED_IDLE 5 120 120 #define SCHED_DEADLINE 6 121 + #define SCHED_EXT 7 121 122 122 123 /* Can be ORed in to make sure the process is reverted back to SCHED_NORMAL on fork */ 123 124 #define SCHED_RESET_ON_FORK 0x40000000
+16 -1
tools/perf/trace/beauty/include/uapi/sound/asound.h
··· 869 869 * Timer section - /dev/snd/timer 870 870 */ 871 871 872 - #define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 7) 872 + #define SNDRV_TIMER_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 8) 873 873 874 874 enum { 875 875 SNDRV_TIMER_CLASS_NONE = -1, ··· 894 894 #define SNDRV_TIMER_GLOBAL_RTC 1 /* unused */ 895 895 #define SNDRV_TIMER_GLOBAL_HPET 2 896 896 #define SNDRV_TIMER_GLOBAL_HRTIMER 3 897 + #define SNDRV_TIMER_GLOBAL_UDRIVEN 4 897 898 898 899 /* info flags */ 899 900 #define SNDRV_TIMER_FLG_SLAVE (1<<0) /* cannot be controlled */ ··· 975 974 }; 976 975 #endif 977 976 977 + /* 978 + * This structure describes the userspace-driven timer. Such timers are purely virtual, 979 + * and can only be triggered from software (for instance, by userspace application). 980 + */ 981 + struct snd_timer_uinfo { 982 + /* To pretend being a normal timer, we need to know the resolution in ns. */ 983 + __u64 resolution; 984 + int fd; 985 + unsigned int id; 986 + unsigned char reserved[16]; 987 + }; 988 + 978 989 #define SNDRV_TIMER_IOCTL_PVERSION _IOR('T', 0x00, int) 979 990 #define SNDRV_TIMER_IOCTL_NEXT_DEVICE _IOWR('T', 0x01, struct snd_timer_id) 980 991 #define SNDRV_TIMER_IOCTL_TREAD_OLD _IOW('T', 0x02, int) ··· 1003 990 #define SNDRV_TIMER_IOCTL_CONTINUE _IO('T', 0xa2) 1004 991 #define SNDRV_TIMER_IOCTL_PAUSE _IO('T', 0xa3) 1005 992 #define SNDRV_TIMER_IOCTL_TREAD64 _IOW('T', 0xa4, int) 993 + #define SNDRV_TIMER_IOCTL_CREATE _IOWR('T', 0xa5, struct snd_timer_uinfo) 994 + #define SNDRV_TIMER_IOCTL_TRIGGER _IO('T', 0xa6) 1006 995 1007 996 #if __BITS_PER_LONG == 64 1008 997 #define SNDRV_TIMER_IOCTL_TREAD SNDRV_TIMER_IOCTL_TREAD_OLD
+4
tools/perf/trace/beauty/msg_flags.c
··· 11 11 #ifndef MSG_BATCH 12 12 #define MSG_BATCH 0x40000 13 13 #endif 14 + #ifndef MSG_SOCK_DEVMEM 15 + #define MSG_SOCK_DEVMEM 0x2000000 16 + #endif 14 17 #ifndef MSG_ZEROCOPY 15 18 #define MSG_ZEROCOPY 0x4000000 16 19 #endif ··· 60 57 P_MSG_FLAG(MORE); 61 58 P_MSG_FLAG(WAITFORONE); 62 59 P_MSG_FLAG(BATCH); 60 + P_MSG_FLAG(SOCK_DEVMEM); 63 61 P_MSG_FLAG(ZEROCOPY); 64 62 P_MSG_FLAG(SPLICE_PAGES); 65 63 P_MSG_FLAG(FASTOPEN);
+1 -1
tools/perf/util/cs-etm.c
··· 3323 3323 * Don't create decoders for empty queues, mainly because 3324 3324 * etmq->format is unknown for empty queues. 3325 3325 */ 3326 - assert(empty == (etmq->format == UNSET)); 3326 + assert(empty || etmq->format != UNSET); 3327 3327 if (empty) 3328 3328 continue; 3329 3329
+1
tools/perf/util/dwarf-aux.h
··· 9 9 #include <elfutils/libdw.h> 10 10 #include <elfutils/libdwfl.h> 11 11 #include <elfutils/version.h> 12 + #include <errno.h> 12 13 13 14 struct strbuf; 14 15
+3
tools/perf/util/symbol.c
··· 1931 1931 if (next_slot) { 1932 1932 ss_pos++; 1933 1933 1934 + if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND) 1935 + dso__set_binary_type(dso, symtab_type); 1936 + 1934 1937 if (syms_ss && runtime_ss) 1935 1938 break; 1936 1939 } else {
+3 -1
tools/perf/util/vdso.c
··· 308 308 if (!dso) { 309 309 dso = dsos__find(&machine->dsos, DSO__NAME_VDSO, 310 310 true); 311 - if (dso && dso_type != dso__type(dso, machine)) 311 + if (dso && dso_type != dso__type(dso, machine)) { 312 + dso__put(dso); 312 313 dso = NULL; 314 + } 313 315 } 314 316 break; 315 317 case DSO__TYPE_X32BIT: