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

Merge branch 'perf/urgent' into perf/core, to pick up fixes

Signed-off-by: Ingo Molnar <mingo@kernel.org>

+180 -37
+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 */
+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