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.

perf perf_regs: Accurately compute register names for CSKY

CSKY needs the e_flags to determine the ABI level and know whether
additional registers are encoded or not. Wire this up now that the
e_flags for a thread can be determined.

Signed-off-by: Ian Rogers <irogers@google.com>
Cc: Aditya Bodkhe <aditya.b1@linux.ibm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Athira Rajeev <atrajeev@linux.ibm.com>
Cc: Chun-Tse Shao <ctshao@google.com>
Cc: Guo Ren <guoren@kernel.org>
Cc: Howard Chu <howardchu95@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: James Clark <james.clark@linaro.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Sergei Trofimovich <slyich@gmail.com>
Cc: Shimin Guo <shimin.guo@skydio.com>
Cc: Stephen Brennan <stephen.s.brennan@oracle.com>
Cc: Swapnil Sapkal <swapnil.sapkal@amd.com>
Cc: Tianyou Li <tianyou.li@intel.com>
[ Conditionally define EF_CSKY_ABIMASK and EF_CSKY_ABIV2 for older distros ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ian Rogers and committed by
Arnaldo Carvalho de Melo
0403930f 4e66527f

+62 -38
+20 -8
tools/perf/builtin-script.c
··· 717 717 return 0; 718 718 } 719 719 720 - static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, uint16_t e_machine, 720 + static int perf_sample__fprintf_regs(struct regs_dump *regs, uint64_t mask, 721 + uint16_t e_machine, uint32_t e_flags, 721 722 FILE *fp) 722 723 { 723 724 unsigned i = 0, r; ··· 731 730 732 731 for_each_set_bit(r, (unsigned long *) &mask, sizeof(mask) * 8) { 733 732 u64 val = regs->regs[i++]; 734 - printed += fprintf(fp, "%5s:0x%"PRIx64" ", perf_reg_name(r, e_machine), val); 733 + printed += fprintf(fp, "%5s:0x%"PRIx64" ", 734 + perf_reg_name(r, e_machine, e_flags), 735 + val); 735 736 } 736 737 737 738 return printed; ··· 790 787 } 791 788 792 789 static int perf_sample__fprintf_iregs(struct perf_sample *sample, 793 - struct perf_event_attr *attr, uint16_t e_machine, FILE *fp) 790 + struct perf_event_attr *attr, 791 + uint16_t e_machine, 792 + uint32_t e_flags, 793 + FILE *fp) 794 794 { 795 795 if (!sample->intr_regs) 796 796 return 0; 797 797 798 798 return perf_sample__fprintf_regs(perf_sample__intr_regs(sample), 799 - attr->sample_regs_intr, e_machine, fp); 799 + attr->sample_regs_intr, e_machine, e_flags, fp); 800 800 } 801 801 802 802 static int perf_sample__fprintf_uregs(struct perf_sample *sample, 803 - struct perf_event_attr *attr, uint16_t e_machine, FILE *fp) 803 + struct perf_event_attr *attr, 804 + uint16_t e_machine, 805 + uint32_t e_flags, 806 + FILE *fp) 804 807 { 805 808 if (!sample->user_regs) 806 809 return 0; 807 810 808 811 return perf_sample__fprintf_regs(perf_sample__user_regs(sample), 809 - attr->sample_regs_user, e_machine, fp); 812 + attr->sample_regs_user, e_machine, e_flags, fp); 810 813 } 811 814 812 815 static int perf_sample__fprintf_start(struct perf_script *script, ··· 2427 2418 struct evsel_script *es = evsel->priv; 2428 2419 FILE *fp = es->fp; 2429 2420 char str[PAGE_SIZE_NAME_LEN]; 2421 + uint32_t e_flags; 2430 2422 2431 2423 if (output[type].fields == 0) 2432 2424 return; ··· 2516 2506 2517 2507 if (PRINT_FIELD(IREGS)) { 2518 2508 perf_sample__fprintf_iregs(sample, attr, 2519 - thread__e_machine(thread, machine, /*e_flags=*/NULL), 2509 + thread__e_machine(thread, machine, &e_flags), 2510 + e_flags, 2520 2511 fp); 2521 2512 } 2522 2513 2523 2514 if (PRINT_FIELD(UREGS)) { 2524 2515 perf_sample__fprintf_uregs(sample, attr, 2525 - thread__e_machine(thread, machine, /*e_flags=*/NULL), 2516 + thread__e_machine(thread, machine, &e_flags), 2517 + e_flags, 2526 2518 fp); 2527 2519 } 2528 2520
+2 -2
tools/perf/util/parse-regs-options.c
··· 21 21 if (((1ULL << reg) & mask) == 0) 22 22 continue; 23 23 24 - name = perf_reg_name(reg, EM_HOST); 24 + name = perf_reg_name(reg, EM_HOST, EF_HOST); 25 25 if (name && (!last_name || strcmp(last_name, name))) 26 26 fprintf(fp, "%s%s", reg > 0 ? " " : "", name); 27 27 last_name = name; ··· 39 39 if (((1ULL << reg) & mask) == 0) 40 40 continue; 41 41 42 - name = perf_reg_name(reg, EM_HOST); 42 + name = perf_reg_name(reg, EM_HOST, EF_HOST); 43 43 if (!name) 44 44 continue; 45 45
+13 -6
tools/perf/util/perf-regs-arch/perf_regs_csky.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 - 2 + #include <elf.h> 3 + #ifndef EF_CSKY_ABIMASK 4 + #define EF_CSKY_ABIMASK 0XF0000000 5 + #endif 6 + #ifndef EF_CSKY_ABIV2 7 + #define EF_CSKY_ABIV2 0X20000000 8 + #endif 3 9 #include "../perf_regs.h" 10 + #undef __CSKYABIV2__ 11 + #define __CSKYABIV2__ 1 // Always want the V2 register definitions. 4 12 #include "../../arch/csky/include/uapi/asm/perf_regs.h" 5 13 6 - const char *__perf_reg_name_csky(int id) 14 + const char *__perf_reg_name_csky(int id, uint32_t e_flags) 7 15 { 16 + if (id >= PERF_REG_CSKY_EXREGS0 && (e_flags & EF_CSKY_ABIMASK) == EF_CSKY_ABIV2) 17 + return NULL; 18 + 8 19 switch (id) { 9 20 case PERF_REG_CSKY_A0: 10 21 return "a0"; ··· 51 40 return "lr"; 52 41 case PERF_REG_CSKY_PC: 53 42 return "pc"; 54 - #if defined(__CSKYABIV2__) 55 43 case PERF_REG_CSKY_EXREGS0: 56 44 return "exregs0"; 57 45 case PERF_REG_CSKY_EXREGS1: ··· 87 77 return "hi"; 88 78 case PERF_REG_CSKY_LO: 89 79 return "lo"; 90 - #endif 91 80 default: 92 81 return NULL; 93 82 } 94 - 95 - return NULL; 96 83 } 97 84 98 85 uint64_t __perf_reg_ip_csky(void)
+2 -2
tools/perf/util/perf_regs.c
··· 23 23 return 0; 24 24 } 25 25 26 - const char *perf_reg_name(int id, uint16_t e_machine) 26 + const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags) 27 27 { 28 28 const char *reg_name = NULL; 29 29 ··· 35 35 reg_name = __perf_reg_name_arm64(id); 36 36 break; 37 37 case EM_CSKY: 38 - reg_name = __perf_reg_name_csky(id); 38 + reg_name = __perf_reg_name_csky(id, e_flags); 39 39 break; 40 40 case EM_LOONGARCH: 41 41 reg_name = __perf_reg_name_loongarch(id);
+2 -2
tools/perf/util/perf_regs.h
··· 16 16 uint64_t arch__intr_reg_mask(void); 17 17 uint64_t arch__user_reg_mask(void); 18 18 19 - const char *perf_reg_name(int id, uint16_t e_machine); 19 + const char *perf_reg_name(int id, uint16_t e_machine, uint32_t e_flags); 20 20 int perf_reg_value(u64 *valp, struct regs_dump *regs, int id); 21 21 uint64_t perf_arch_reg_ip(uint16_t e_machine); 22 22 uint64_t perf_arch_reg_sp(uint16_t e_machine); ··· 26 26 const char *__perf_reg_name_arm(int id); 27 27 uint64_t __perf_reg_ip_arm(void); 28 28 uint64_t __perf_reg_sp_arm(void); 29 - const char *__perf_reg_name_csky(int id); 29 + const char *__perf_reg_name_csky(int id, uint32_t e_flags); 30 30 uint64_t __perf_reg_ip_csky(void); 31 31 uint64_t __perf_reg_sp_csky(void); 32 32 const char *__perf_reg_name_loongarch(int id);
+10 -7
tools/perf/util/scripting-engines/trace-event-python.c
··· 714 714 _PyUnicode_FromString(decode)); 715 715 } 716 716 717 - static void regs_map(struct regs_dump *regs, uint64_t mask, uint16_t e_machine, char *bf, int size) 717 + static void regs_map(struct regs_dump *regs, uint64_t mask, uint16_t e_machine, uint32_t e_flags, 718 + char *bf, int size) 718 719 { 719 720 unsigned int i = 0, r; 720 721 int printed = 0; ··· 733 732 734 733 printed += scnprintf(bf + printed, size - printed, 735 734 "%5s:0x%" PRIx64 " ", 736 - perf_reg_name(r, e_machine), val); 735 + perf_reg_name(r, e_machine, e_flags), val); 737 736 } 738 737 } 739 738 ··· 742 741 static int set_regs_in_dict(PyObject *dict, 743 742 struct perf_sample *sample, 744 743 struct evsel *evsel, 745 - uint16_t e_machine) 744 + uint16_t e_machine, 745 + uint32_t e_flags) 746 746 { 747 747 struct perf_event_attr *attr = &evsel->core.attr; 748 748 ··· 755 753 if (!bf) 756 754 return -1; 757 755 758 - regs_map(sample->intr_regs, attr->sample_regs_intr, e_machine, bf, size); 756 + regs_map(sample->intr_regs, attr->sample_regs_intr, e_machine, e_flags, bf, size); 759 757 760 758 pydict_set_item_string_decref(dict, "iregs", 761 759 _PyUnicode_FromString(bf)); ··· 767 765 if (!bf) 768 766 return -1; 769 767 } 770 - regs_map(sample->user_regs, attr->sample_regs_user, e_machine, bf, size); 768 + regs_map(sample->user_regs, attr->sample_regs_user, e_machine, e_flags, bf, size); 771 769 772 770 pydict_set_item_string_decref(dict, "uregs", 773 771 _PyUnicode_FromString(bf)); ··· 839 837 PyObject *dict, *dict_sample, *brstack, *brstacksym; 840 838 struct machine *machine; 841 839 uint16_t e_machine = EM_HOST; 840 + uint32_t e_flags = EF_HOST; 842 841 843 842 dict = PyDict_New(); 844 843 if (!dict) ··· 928 925 929 926 if (al->thread) { 930 927 machine = maps__machine(thread__maps(al->thread)); 931 - e_machine = thread__e_machine(al->thread, machine, /*e_flags=*/NULL); 928 + e_machine = thread__e_machine(al->thread, machine, &e_flags); 932 929 } 933 - if (set_regs_in_dict(dict, sample, evsel, e_machine)) 930 + if (set_regs_in_dict(dict, sample, evsel, e_machine, e_flags)) 934 931 Py_FatalError("Failed to setting regs in dict"); 935 932 936 933 return dict;
+13 -11
tools/perf/util/session.c
··· 959 959 } 960 960 } 961 961 962 - static void regs_dump__printf(u64 mask, u64 *regs, uint16_t e_machine) 962 + static void regs_dump__printf(u64 mask, u64 *regs, uint16_t e_machine, uint32_t e_flags) 963 963 { 964 964 unsigned rid, i = 0; 965 965 ··· 967 967 u64 val = regs[i++]; 968 968 969 969 printf(".... %-5s 0x%016" PRIx64 "\n", 970 - perf_reg_name(rid, e_machine), val); 970 + perf_reg_name(rid, e_machine, e_flags), val); 971 971 } 972 972 } 973 973 ··· 985 985 return regs_abi[d->abi]; 986 986 } 987 987 988 - static void regs__printf(const char *type, struct regs_dump *regs, uint16_t e_machine) 988 + static void regs__printf(const char *type, struct regs_dump *regs, 989 + uint16_t e_machine, uint32_t e_flags) 989 990 { 990 991 u64 mask = regs->mask; 991 992 ··· 995 994 mask, 996 995 regs_dump_abi(regs)); 997 996 998 - regs_dump__printf(mask, regs->regs, e_machine); 997 + regs_dump__printf(mask, regs->regs, e_machine, e_flags); 999 998 } 1000 999 1001 - static void regs_user__printf(struct perf_sample *sample, uint16_t e_machine) 1000 + static void regs_user__printf(struct perf_sample *sample, uint16_t e_machine, uint32_t e_flags) 1002 1001 { 1003 1002 struct regs_dump *user_regs; 1004 1003 ··· 1008 1007 user_regs = perf_sample__user_regs(sample); 1009 1008 1010 1009 if (user_regs->regs) 1011 - regs__printf("user", user_regs, e_machine); 1010 + regs__printf("user", user_regs, e_machine, e_flags); 1012 1011 } 1013 1012 1014 - static void regs_intr__printf(struct perf_sample *sample, uint16_t e_machine) 1013 + static void regs_intr__printf(struct perf_sample *sample, uint16_t e_machine, uint32_t e_flags) 1015 1014 { 1016 1015 struct regs_dump *intr_regs; 1017 1016 ··· 1021 1020 intr_regs = perf_sample__intr_regs(sample); 1022 1021 1023 1022 if (intr_regs->regs) 1024 - regs__printf("intr", intr_regs, e_machine); 1023 + regs__printf("intr", intr_regs, e_machine, e_flags); 1025 1024 } 1026 1025 1027 1026 static void stack_user__printf(struct stack_dump *dump) ··· 1116 1115 u64 sample_type; 1117 1116 char str[PAGE_SIZE_NAME_LEN]; 1118 1117 uint16_t e_machine = EM_NONE; 1118 + uint32_t e_flags = 0; 1119 1119 1120 1120 if (!dump_trace) 1121 1121 return; ··· 1126 1124 if (sample_type & (PERF_SAMPLE_REGS_USER | PERF_SAMPLE_REGS_INTR)) { 1127 1125 struct thread *thread = machine__find_thread(machine, sample->pid, sample->pid); 1128 1126 1129 - e_machine = thread__e_machine(thread, machine, /*e_flags=*/NULL); 1127 + e_machine = thread__e_machine(thread, machine, &e_flags); 1130 1128 } 1131 1129 1132 1130 printf("(IP, 0x%x): %d/%d: %#" PRIx64 " period: %" PRIu64 " addr: %#" PRIx64 "\n", ··· 1140 1138 branch_stack__printf(sample, evsel); 1141 1139 1142 1140 if (sample_type & PERF_SAMPLE_REGS_USER) 1143 - regs_user__printf(sample, e_machine); 1141 + regs_user__printf(sample, e_machine, e_flags); 1144 1142 1145 1143 if (sample_type & PERF_SAMPLE_REGS_INTR) 1146 - regs_intr__printf(sample, e_machine); 1144 + regs_intr__printf(sample, e_machine, e_flags); 1147 1145 1148 1146 if (sample_type & PERF_SAMPLE_STACK_USER) 1149 1147 stack_user__printf(&sample->user_stack);