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 branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Thomas Gleixner:

- plug a memory leak in the intel pmu init code

- clang fixes

- tooling fix to avoid including kernel headers

- a fix for jvmti to generate correct debug information for inlined
code

- replace backtick with a regular shell function

- fix the build in hardened environments

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/intel: Plug memory leak in intel_pmu_init()
x86/asm: Allow again using asm.h when building for the 'bpf' clang target
tools arch s390: Do not include header files from the kernel sources
perf jvmti: Generate correct debug information for inlined code
perf tools: Fix up build in hardened environments
perf tools: Use shell function for perl cflags retrieval

+190 -43
+4 -1
arch/x86/events/intel/core.c
··· 3847 3847 3848 3848 __init int intel_pmu_init(void) 3849 3849 { 3850 + struct attribute **extra_attr = NULL; 3851 + struct attribute **to_free = NULL; 3850 3852 union cpuid10_edx edx; 3851 3853 union cpuid10_eax eax; 3852 3854 union cpuid10_ebx ebx; ··· 3856 3854 unsigned int unused; 3857 3855 struct extra_reg *er; 3858 3856 int version, i; 3859 - struct attribute **extra_attr = NULL; 3860 3857 char *name; 3861 3858 3862 3859 if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { ··· 4295 4294 extra_attr = boot_cpu_has(X86_FEATURE_RTM) ? 4296 4295 hsw_format_attr : nhm_format_attr; 4297 4296 extra_attr = merge_attr(extra_attr, skl_format_attr); 4297 + to_free = extra_attr; 4298 4298 x86_pmu.cpu_events = get_hsw_events_attrs(); 4299 4299 intel_pmu_pebs_data_source_skl( 4300 4300 boot_cpu_data.x86_model == INTEL_FAM6_SKYLAKE_X); ··· 4403 4401 pr_cont("full-width counters, "); 4404 4402 } 4405 4403 4404 + kfree(to_free); 4406 4405 return 0; 4407 4406 } 4408 4407
+2
arch/x86/include/asm/asm.h
··· 136 136 #endif 137 137 138 138 #ifndef __ASSEMBLY__ 139 + #ifndef __BPF__ 139 140 /* 140 141 * This output constraint should be used for any inline asm which has a "call" 141 142 * instruction. Otherwise the asm may be inserted before the frame pointer ··· 145 144 */ 146 145 register unsigned long current_stack_pointer asm(_ASM_SP); 147 146 #define ASM_CALL_CONSTRAINT "+r" (current_stack_pointer) 147 + #endif 148 148 #endif 149 149 150 150 #endif /* _ASM_X86_ASM_H */
+44
tools/arch/s390/include/uapi/asm/perf_regs.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ 2 + #ifndef _ASM_S390_PERF_REGS_H 3 + #define _ASM_S390_PERF_REGS_H 4 + 5 + enum perf_event_s390_regs { 6 + PERF_REG_S390_R0, 7 + PERF_REG_S390_R1, 8 + PERF_REG_S390_R2, 9 + PERF_REG_S390_R3, 10 + PERF_REG_S390_R4, 11 + PERF_REG_S390_R5, 12 + PERF_REG_S390_R6, 13 + PERF_REG_S390_R7, 14 + PERF_REG_S390_R8, 15 + PERF_REG_S390_R9, 16 + PERF_REG_S390_R10, 17 + PERF_REG_S390_R11, 18 + PERF_REG_S390_R12, 19 + PERF_REG_S390_R13, 20 + PERF_REG_S390_R14, 21 + PERF_REG_S390_R15, 22 + PERF_REG_S390_FP0, 23 + PERF_REG_S390_FP1, 24 + PERF_REG_S390_FP2, 25 + PERF_REG_S390_FP3, 26 + PERF_REG_S390_FP4, 27 + PERF_REG_S390_FP5, 28 + PERF_REG_S390_FP6, 29 + PERF_REG_S390_FP7, 30 + PERF_REG_S390_FP8, 31 + PERF_REG_S390_FP9, 32 + PERF_REG_S390_FP10, 33 + PERF_REG_S390_FP11, 34 + PERF_REG_S390_FP12, 35 + PERF_REG_S390_FP13, 36 + PERF_REG_S390_FP14, 37 + PERF_REG_S390_FP15, 38 + PERF_REG_S390_MASK, 39 + PERF_REG_S390_PC, 40 + 41 + PERF_REG_S390_MAX 42 + }; 43 + 44 + #endif /* _ASM_S390_PERF_REGS_H */
+4 -5
tools/perf/Makefile.config
··· 188 188 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) 189 189 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) -lutil 190 190 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) 191 - ifeq ($(CC_NO_CLANG), 1) 192 - PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS)) 193 - endif 191 + PYTHON_EMBED_CCOPTS := $(filter-out -specs=%,$(PYTHON_EMBED_CCOPTS)) 194 192 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) 195 193 endif 196 194 ··· 574 576 endif 575 577 endif 576 578 577 - 578 579 ifdef NO_LIBPERL 579 580 CFLAGS += -DNO_LIBPERL 580 581 else 581 582 PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null) 582 583 PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS)) 583 584 PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS)) 584 - PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` 585 + PERL_EMBED_CCOPTS = $(shell perl -MExtUtils::Embed -e ccopts 2>/dev/null) 586 + PERL_EMBED_CCOPTS := $(filter-out -specs=%,$(PERL_EMBED_CCOPTS)) 587 + PERL_EMBED_LDOPTS := $(filter-out -specs=%,$(PERL_EMBED_LDOPTS)) 585 588 FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) 586 589 587 590 ifneq ($(feature-libperl), 1)
+1 -1
tools/perf/arch/s390/include/perf_regs.h
··· 3 3 4 4 #include <stdlib.h> 5 5 #include <linux/types.h> 6 - #include <../../../../arch/s390/include/uapi/asm/perf_regs.h> 6 + #include <asm/perf_regs.h> 7 7 8 8 void perf_regs_load(u64 *regs); 9 9
+1
tools/perf/check-headers.sh
··· 21 21 arch/arm/include/uapi/asm/perf_regs.h 22 22 arch/arm64/include/uapi/asm/perf_regs.h 23 23 arch/powerpc/include/uapi/asm/perf_regs.h 24 + arch/s390/include/uapi/asm/perf_regs.h 24 25 arch/x86/include/uapi/asm/perf_regs.h 25 26 arch/x86/include/uapi/asm/kvm.h 26 27 arch/x86/include/uapi/asm/kvm_perf.h
+9 -7
tools/perf/jvmti/jvmti_agent.c
··· 384 384 } 385 385 386 386 int 387 - jvmti_write_debug_info(void *agent, uint64_t code, const char *file, 388 - jvmti_line_info_t *li, int nr_lines) 387 + jvmti_write_debug_info(void *agent, uint64_t code, 388 + int nr_lines, jvmti_line_info_t *li, 389 + const char * const * file_names) 389 390 { 390 391 struct jr_code_debug_info rec; 391 - size_t sret, len, size, flen; 392 + size_t sret, len, size, flen = 0; 392 393 uint64_t addr; 393 - const char *fn = file; 394 394 FILE *fp = agent; 395 395 int i; 396 396 ··· 405 405 return -1; 406 406 } 407 407 408 - flen = strlen(file) + 1; 408 + for (i = 0; i < nr_lines; ++i) { 409 + flen += strlen(file_names[i]) + 1; 410 + } 409 411 410 412 rec.p.id = JIT_CODE_DEBUG_INFO; 411 413 size = sizeof(rec); ··· 423 421 * file[] : source file name 424 422 */ 425 423 size += nr_lines * sizeof(struct debug_entry); 426 - size += flen * nr_lines; 424 + size += flen; 427 425 rec.p.total_size = size; 428 426 429 427 /* ··· 454 452 if (sret != 1) 455 453 goto error; 456 454 457 - sret = fwrite_unlocked(fn, flen, 1, fp); 455 + sret = fwrite_unlocked(file_names[i], strlen(file_names[i]) + 1, 1, fp); 458 456 if (sret != 1) 459 457 goto error; 460 458 }
+3 -4
tools/perf/jvmti/jvmti_agent.h
··· 14 14 unsigned long pc; 15 15 int line_number; 16 16 int discrim; /* discriminator -- 0 for now */ 17 + jmethodID methodID; 17 18 } jvmti_line_info_t; 18 19 19 20 void *jvmti_open(void); ··· 23 22 uint64_t vma, void const *code, 24 23 const unsigned int code_size); 25 24 26 - int jvmti_write_debug_info(void *agent, 27 - uint64_t code, 28 - const char *file, 25 + int jvmti_write_debug_info(void *agent, uint64_t code, int nr_lines, 29 26 jvmti_line_info_t *li, 30 - int nr_lines); 27 + const char * const * file_names); 31 28 32 29 #if defined(__cplusplus) 33 30 }
+122 -25
tools/perf/jvmti/libjvmti.c
··· 47 47 tab[lines].pc = (unsigned long)pc; 48 48 tab[lines].line_number = loc_tab[i].line_number; 49 49 tab[lines].discrim = 0; /* not yet used */ 50 + tab[lines].methodID = m; 50 51 lines++; 51 52 } else { 52 53 break; ··· 126 125 return JVMTI_ERROR_NONE; 127 126 } 128 127 128 + static void 129 + copy_class_filename(const char * class_sign, const char * file_name, char * result, size_t max_length) 130 + { 131 + /* 132 + * Assume path name is class hierarchy, this is a common practice with Java programs 133 + */ 134 + if (*class_sign == 'L') { 135 + int j, i = 0; 136 + char *p = strrchr(class_sign, '/'); 137 + if (p) { 138 + /* drop the 'L' prefix and copy up to the final '/' */ 139 + for (i = 0; i < (p - class_sign); i++) 140 + result[i] = class_sign[i+1]; 141 + } 142 + /* 143 + * append file name, we use loops and not string ops to avoid modifying 144 + * class_sign which is used later for the symbol name 145 + */ 146 + for (j = 0; i < (max_length - 1) && file_name && j < strlen(file_name); j++, i++) 147 + result[i] = file_name[j]; 148 + 149 + result[i] = '\0'; 150 + } else { 151 + /* fallback case */ 152 + size_t file_name_len = strlen(file_name); 153 + strncpy(result, file_name, file_name_len < max_length ? file_name_len : max_length); 154 + } 155 + } 156 + 157 + static jvmtiError 158 + get_source_filename(jvmtiEnv *jvmti, jmethodID methodID, char ** buffer) 159 + { 160 + jvmtiError ret; 161 + jclass decl_class; 162 + char *file_name = NULL; 163 + char *class_sign = NULL; 164 + char fn[PATH_MAX]; 165 + size_t len; 166 + 167 + ret = (*jvmti)->GetMethodDeclaringClass(jvmti, methodID, &decl_class); 168 + if (ret != JVMTI_ERROR_NONE) { 169 + print_error(jvmti, "GetMethodDeclaringClass", ret); 170 + return ret; 171 + } 172 + 173 + ret = (*jvmti)->GetSourceFileName(jvmti, decl_class, &file_name); 174 + if (ret != JVMTI_ERROR_NONE) { 175 + print_error(jvmti, "GetSourceFileName", ret); 176 + return ret; 177 + } 178 + 179 + ret = (*jvmti)->GetClassSignature(jvmti, decl_class, &class_sign, NULL); 180 + if (ret != JVMTI_ERROR_NONE) { 181 + print_error(jvmti, "GetClassSignature", ret); 182 + goto free_file_name_error; 183 + } 184 + 185 + copy_class_filename(class_sign, file_name, fn, PATH_MAX); 186 + len = strlen(fn); 187 + *buffer = malloc((len + 1) * sizeof(char)); 188 + if (!*buffer) { 189 + print_error(jvmti, "GetClassSignature", ret); 190 + ret = JVMTI_ERROR_OUT_OF_MEMORY; 191 + goto free_class_sign_error; 192 + } 193 + strcpy(*buffer, fn); 194 + ret = JVMTI_ERROR_NONE; 195 + 196 + free_class_sign_error: 197 + (*jvmti)->Deallocate(jvmti, (unsigned char *)class_sign); 198 + free_file_name_error: 199 + (*jvmti)->Deallocate(jvmti, (unsigned char *)file_name); 200 + 201 + return ret; 202 + } 203 + 204 + static jvmtiError 205 + fill_source_filenames(jvmtiEnv *jvmti, int nr_lines, 206 + const jvmti_line_info_t * line_tab, 207 + char ** file_names) 208 + { 209 + int index; 210 + jvmtiError ret; 211 + 212 + for (index = 0; index < nr_lines; ++index) { 213 + ret = get_source_filename(jvmti, line_tab[index].methodID, &(file_names[index])); 214 + if (ret != JVMTI_ERROR_NONE) 215 + return ret; 216 + } 217 + 218 + return JVMTI_ERROR_NONE; 219 + } 220 + 129 221 static void JNICALL 130 222 compiled_method_load_cb(jvmtiEnv *jvmti, 131 223 jmethodID method, ··· 229 135 const void *compile_info) 230 136 { 231 137 jvmti_line_info_t *line_tab = NULL; 138 + char ** line_file_names = NULL; 232 139 jclass decl_class; 233 140 char *class_sign = NULL; 234 141 char *func_name = NULL; 235 142 char *func_sign = NULL; 236 - char *file_name= NULL; 143 + char *file_name = NULL; 237 144 char fn[PATH_MAX]; 238 145 uint64_t addr = (uint64_t)(uintptr_t)code_addr; 239 146 jvmtiError ret; 240 147 int nr_lines = 0; /* in line_tab[] */ 241 148 size_t len; 149 + int output_debug_info = 0; 242 150 243 151 ret = (*jvmti)->GetMethodDeclaringClass(jvmti, method, 244 152 &decl_class); ··· 254 158 if (ret != JVMTI_ERROR_NONE) { 255 159 warnx("jvmti: cannot get line table for method"); 256 160 nr_lines = 0; 161 + } else if (nr_lines > 0) { 162 + line_file_names = malloc(sizeof(char*) * nr_lines); 163 + if (!line_file_names) { 164 + warnx("jvmti: cannot allocate space for line table method names"); 165 + } else { 166 + memset(line_file_names, 0, sizeof(char*) * nr_lines); 167 + ret = fill_source_filenames(jvmti, nr_lines, line_tab, line_file_names); 168 + if (ret != JVMTI_ERROR_NONE) { 169 + warnx("jvmti: fill_source_filenames failed"); 170 + } else { 171 + output_debug_info = 1; 172 + } 173 + } 257 174 } 258 175 } 259 176 ··· 290 181 goto error; 291 182 } 292 183 293 - /* 294 - * Assume path name is class hierarchy, this is a common practice with Java programs 295 - */ 296 - if (*class_sign == 'L') { 297 - int j, i = 0; 298 - char *p = strrchr(class_sign, '/'); 299 - if (p) { 300 - /* drop the 'L' prefix and copy up to the final '/' */ 301 - for (i = 0; i < (p - class_sign); i++) 302 - fn[i] = class_sign[i+1]; 303 - } 304 - /* 305 - * append file name, we use loops and not string ops to avoid modifying 306 - * class_sign which is used later for the symbol name 307 - */ 308 - for (j = 0; i < (PATH_MAX - 1) && file_name && j < strlen(file_name); j++, i++) 309 - fn[i] = file_name[j]; 310 - fn[i] = '\0'; 311 - } else { 312 - /* fallback case */ 313 - strcpy(fn, file_name); 314 - } 184 + copy_class_filename(class_sign, file_name, fn, PATH_MAX); 185 + 315 186 /* 316 187 * write source line info record if we have it 317 188 */ 318 - if (jvmti_write_debug_info(jvmti_agent, addr, fn, line_tab, nr_lines)) 319 - warnx("jvmti: write_debug_info() failed"); 189 + if (output_debug_info) 190 + if (jvmti_write_debug_info(jvmti_agent, addr, nr_lines, line_tab, (const char * const *) line_file_names)) 191 + warnx("jvmti: write_debug_info() failed"); 320 192 321 193 len = strlen(func_name) + strlen(class_sign) + strlen(func_sign) + 2; 322 194 { ··· 313 223 (*jvmti)->Deallocate(jvmti, (unsigned char *)class_sign); 314 224 (*jvmti)->Deallocate(jvmti, (unsigned char *)file_name); 315 225 free(line_tab); 226 + while (line_file_names && (nr_lines > 0)) { 227 + if (line_file_names[nr_lines - 1]) { 228 + free(line_file_names[nr_lines - 1]); 229 + } 230 + nr_lines -= 1; 231 + } 232 + free(line_file_names); 316 233 } 317 234 318 235 static void JNICALL