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-v5.19-2022-07-29' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux

Pull perf tools fixes from Arnaldo Carvalho de Melo:

- Fix addresses for bss symbols, describing variables used in resolving
data access in tools such as 'perf c2c' and 'perf mem'.

- Skip symbols if SHF_ALLOC flag is not set, a technique used for
listing deprecated symbols, its addresses are zeros, so not useful.

- Remove undefined behavior from bpf_perf_object__next() when dealing
with an empty bpf_objects_list list.

- Make a ARM CoreSight disasm script work with both python2 and
python3.

- Sync x86's cpufeatures header with with the kernel sources.

* tag 'perf-tools-fixes-for-v5.19-2022-07-29' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux:
perf bpf: Remove undefined behavior from bpf_perf_object__next()
perf symbol: Skip symbols if SHF_ALLOC flag is not set
perf symbol: Correct address for bss symbols
perf scripts python: Let script to be python2 compliant
tools headers cpufeatures: Sync with the kernel sources

+78 -31
+1
tools/arch/x86/include/asm/cpufeatures.h
··· 302 302 #define X86_FEATURE_RETPOLINE_LFENCE (11*32+13) /* "" Use LFENCE for Spectre variant 2 */ 303 303 #define X86_FEATURE_RETHUNK (11*32+14) /* "" Use REturn THUNK */ 304 304 #define X86_FEATURE_UNRET (11*32+15) /* "" AMD BTB untrain return */ 305 + #define X86_FEATURE_USE_IBPB_FW (11*32+16) /* "" Use IBPB during runtime firmware calls */ 305 306 306 307 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */ 307 308 #define X86_FEATURE_AVX_VNNI (12*32+ 4) /* AVX VNNI instructions */
+18 -16
tools/perf/scripts/python/arm-cs-trace-disasm.py
··· 61 61 62 62 def get_offset(perf_dict, field): 63 63 if field in perf_dict: 64 - return f"+0x{perf_dict[field]:x}" 64 + return "+%#x" % perf_dict[field] 65 65 return "" 66 66 67 67 def get_dso_file_path(dso_name, dso_build_id): ··· 76 76 else: 77 77 append = "/elf" 78 78 79 - dso_path = f"{os.environ['PERF_BUILDID_DIR']}/{dso_name}/{dso_build_id}{append}" 79 + dso_path = os.environ['PERF_BUILDID_DIR'] + "/" + dso_name + "/" + dso_build_id + append; 80 80 # Replace duplicate slash chars to single slash char 81 81 dso_path = dso_path.replace('//', '/', 1) 82 82 return dso_path ··· 94 94 start_addr = start_addr - dso_start; 95 95 stop_addr = stop_addr - dso_start; 96 96 disasm = [ options.objdump_name, "-d", "-z", 97 - f"--start-address=0x{start_addr:x}", 98 - f"--stop-address=0x{stop_addr:x}" ] 97 + "--start-address="+format(start_addr,"#x"), 98 + "--stop-address="+format(stop_addr,"#x") ] 99 99 disasm += [ dso_fname ] 100 100 disasm_output = check_output(disasm).decode('utf-8').split('\n') 101 101 disasm_cache[addr_range] = disasm_output ··· 109 109 m = disasm_re.search(line) 110 110 if m is None: 111 111 continue 112 - print(f"\t{line}") 112 + print("\t" + line) 113 113 114 114 def print_sample(sample): 115 - print(f"Sample = {{ cpu: {sample['cpu']:04} addr: 0x{sample['addr']:016x} " \ 116 - f"phys_addr: 0x{sample['phys_addr']:016x} ip: 0x{sample['ip']:016x} " \ 117 - f"pid: {sample['pid']} tid: {sample['tid']} period: {sample['period']} time: {sample['time']} }}") 115 + print("Sample = { cpu: %04d addr: 0x%016x phys_addr: 0x%016x ip: 0x%016x " \ 116 + "pid: %d tid: %d period: %d time: %d }" % \ 117 + (sample['cpu'], sample['addr'], sample['phys_addr'], \ 118 + sample['ip'], sample['pid'], sample['tid'], \ 119 + sample['period'], sample['time'])) 118 120 119 121 def trace_begin(): 120 122 print('ARM CoreSight Trace Data Assembler Dump') ··· 133 131 cpu = sample["cpu"] 134 132 pid = sample["pid"] 135 133 tid = sample["tid"] 136 - return f"{comm:>16} {pid:>5}/{tid:<5} [{cpu:04}] {sec:9}.{ns:09} " 134 + return "%16s %5u/%-5u [%04u] %9u.%09u " % (comm, pid, tid, cpu, sec, ns) 137 135 138 136 # This code is copied from intel-pt-events.py for printing source code 139 137 # line and symbols. ··· 173 171 glb_line_number = line_number 174 172 glb_source_file_name = source_file_name 175 173 176 - print(f"{start_str}{src_str}") 174 + print(start_str, src_str) 177 175 178 176 def process_event(param_dict): 179 177 global cache_size ··· 190 188 symbol = get_optional(param_dict, "symbol") 191 189 192 190 if (options.verbose == True): 193 - print(f"Event type: {name}") 191 + print("Event type: %s" % name) 194 192 print_sample(sample) 195 193 196 194 # If cannot find dso so cannot dump assembler, bail out ··· 199 197 200 198 # Validate dso start and end addresses 201 199 if ((dso_start == '[unknown]') or (dso_end == '[unknown]')): 202 - print(f"Failed to find valid dso map for dso {dso}") 200 + print("Failed to find valid dso map for dso %s" % dso) 203 201 return 204 202 205 203 if (name[0:12] == "instructions"): ··· 246 244 247 245 # Handle CS_ETM_TRACE_ON packet if start_addr=0 and stop_addr=4 248 246 if (start_addr == 0 and stop_addr == 4): 249 - print(f"CPU{cpu}: CS_ETM_TRACE_ON packet is inserted") 247 + print("CPU%d: CS_ETM_TRACE_ON packet is inserted" % cpu) 250 248 return 251 249 252 250 if (start_addr < int(dso_start) or start_addr > int(dso_end)): 253 - print(f"Start address 0x{start_addr:x} is out of range [ 0x{dso_start:x} .. 0x{dso_end:x} ] for dso {dso}") 251 + print("Start address 0x%x is out of range [ 0x%x .. 0x%x ] for dso %s" % (start_addr, int(dso_start), int(dso_end), dso)) 254 252 return 255 253 256 254 if (stop_addr < int(dso_start) or stop_addr > int(dso_end)): 257 - print(f"Stop address 0x{stop_addr:x} is out of range [ 0x{dso_start:x} .. 0x{dso_end:x} ] for dso {dso}") 255 + print("Stop address 0x%x is out of range [ 0x%x .. 0x%x ] for dso %s" % (stop_addr, int(dso_start), int(dso_end), dso)) 258 256 return 259 257 260 258 if (options.objdump_name != None): ··· 269 267 if path.exists(dso_fname): 270 268 print_disam(dso_fname, dso_vm_start, start_addr, stop_addr) 271 269 else: 272 - print(f"Failed to find dso {dso} for address range [ 0x{start_addr:x} .. 0x{stop_addr:x} ]") 270 + print("Failed to find dso %s for address range [ 0x%x .. 0x%x ]" % (dso, start_addr, stop_addr)) 273 271 274 272 print_srccode(comm, param_dict, sample, symbol, dso)
+7 -11
tools/perf/util/bpf-loader.c
··· 63 63 static struct bpf_perf_object * 64 64 bpf_perf_object__next(struct bpf_perf_object *prev) 65 65 { 66 - struct bpf_perf_object *next; 66 + if (!prev) { 67 + if (list_empty(&bpf_objects_list)) 68 + return NULL; 67 69 68 - if (!prev) 69 - next = list_first_entry(&bpf_objects_list, 70 - struct bpf_perf_object, 71 - list); 72 - else 73 - next = list_next_entry(prev, list); 74 - 75 - /* Empty list is noticed here so don't need checking on entry. */ 76 - if (&next->list == &bpf_objects_list) 70 + return list_first_entry(&bpf_objects_list, struct bpf_perf_object, list); 71 + } 72 + if (list_is_last(&prev->list, &bpf_objects_list)) 77 73 return NULL; 78 74 79 - return next; 75 + return list_next_entry(prev, list); 80 76 } 81 77 82 78 #define bpf_perf_object__for_each(perf_obj, tmp) \
+52 -4
tools/perf/util/symbol-elf.c
··· 233 233 return NULL; 234 234 } 235 235 236 + static int elf_read_program_header(Elf *elf, u64 vaddr, GElf_Phdr *phdr) 237 + { 238 + size_t i, phdrnum; 239 + u64 sz; 240 + 241 + if (elf_getphdrnum(elf, &phdrnum)) 242 + return -1; 243 + 244 + for (i = 0; i < phdrnum; i++) { 245 + if (gelf_getphdr(elf, i, phdr) == NULL) 246 + return -1; 247 + 248 + if (phdr->p_type != PT_LOAD) 249 + continue; 250 + 251 + sz = max(phdr->p_memsz, phdr->p_filesz); 252 + if (!sz) 253 + continue; 254 + 255 + if (vaddr >= phdr->p_vaddr && (vaddr < phdr->p_vaddr + sz)) 256 + return 0; 257 + } 258 + 259 + /* Not found any valid program header */ 260 + return -1; 261 + } 262 + 236 263 static bool want_demangle(bool is_kernel_sym) 237 264 { 238 265 return is_kernel_sym ? symbol_conf.demangle_kernel : symbol_conf.demangle; ··· 1236 1209 sym.st_value); 1237 1210 used_opd = true; 1238 1211 } 1212 + 1239 1213 /* 1240 1214 * When loading symbols in a data mapping, ABS symbols (which 1241 1215 * has a value of SHN_ABS in its st_shndx) failed at ··· 1254 1226 goto out_elf_end; 1255 1227 1256 1228 gelf_getshdr(sec, &shdr); 1229 + 1230 + /* 1231 + * If the attribute bit SHF_ALLOC is not set, the section 1232 + * doesn't occupy memory during process execution. 1233 + * E.g. ".gnu.warning.*" section is used by linker to generate 1234 + * warnings when calling deprecated functions, the symbols in 1235 + * the section aren't loaded to memory during process execution, 1236 + * so skip them. 1237 + */ 1238 + if (!(shdr.sh_flags & SHF_ALLOC)) 1239 + continue; 1257 1240 1258 1241 secstrs = secstrs_sym; 1259 1242 ··· 1301 1262 goto out_elf_end; 1302 1263 } else if ((used_opd && runtime_ss->adjust_symbols) || 1303 1264 (!used_opd && syms_ss->adjust_symbols)) { 1265 + GElf_Phdr phdr; 1266 + 1267 + if (elf_read_program_header(syms_ss->elf, 1268 + (u64)sym.st_value, &phdr)) { 1269 + pr_warning("%s: failed to find program header for " 1270 + "symbol: %s st_value: %#" PRIx64 "\n", 1271 + __func__, elf_name, (u64)sym.st_value); 1272 + continue; 1273 + } 1304 1274 pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " " 1305 - "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__, 1306 - (u64)sym.st_value, (u64)shdr.sh_addr, 1307 - (u64)shdr.sh_offset); 1308 - sym.st_value -= shdr.sh_addr - shdr.sh_offset; 1275 + "p_vaddr: %#" PRIx64 " p_offset: %#" PRIx64 "\n", 1276 + __func__, (u64)sym.st_value, (u64)phdr.p_vaddr, 1277 + (u64)phdr.p_offset); 1278 + sym.st_value -= phdr.p_vaddr - phdr.p_offset; 1309 1279 } 1310 1280 1311 1281 demangled = demangle_sym(dso, kmodule, elf_name);