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

MIPS: perf: Add hardware perf events support for Loongson-3

This patch enable hardware performance counter support for Loongson-3's
perf events.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
Cc: Steven J. Hill <Steven.Hill@imgtec.com>
Cc: linux-mips@linux-mips.org
Cc: Fuxin Zhang <zhangfx@lemote.com>
Cc: Zhangjin Wu <wuzhangjin@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/9618/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Huacai Chen and committed by
Ralf Baechle
f14ceff7 a2e50f53

+72 -1
+1 -1
arch/mips/Kconfig
··· 2390 2390 2391 2391 config HW_PERF_EVENTS 2392 2392 bool "Enable hardware performance counter support for perf events" 2393 - depends on PERF_EVENTS && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP) 2393 + depends on PERF_EVENTS && OPROFILE=n && (CPU_MIPS32 || CPU_MIPS64 || CPU_R10000 || CPU_SB1 || CPU_CAVIUM_OCTEON || CPU_XLP || CPU_LOONGSON3) 2394 2394 default y 2395 2395 help 2396 2396 Enable hardware performance counter support for perf events. If
+71
arch/mips/kernel/perf_event_mipsxx.c
··· 825 825 [PERF_COUNT_HW_BRANCH_MISSES] = { 0x27, CNTR_ODD, T }, 826 826 }; 827 827 828 + static const struct mips_perf_event loongson3_event_map[PERF_COUNT_HW_MAX] = { 829 + [PERF_COUNT_HW_CPU_CYCLES] = { 0x00, CNTR_EVEN }, 830 + [PERF_COUNT_HW_INSTRUCTIONS] = { 0x00, CNTR_ODD }, 831 + [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = { 0x01, CNTR_EVEN }, 832 + [PERF_COUNT_HW_BRANCH_MISSES] = { 0x01, CNTR_ODD }, 833 + }; 834 + 828 835 static const struct mips_perf_event octeon_event_map[PERF_COUNT_HW_MAX] = { 829 836 [PERF_COUNT_HW_CPU_CYCLES] = { 0x01, CNTR_ALL }, 830 837 [PERF_COUNT_HW_INSTRUCTIONS] = { 0x03, CNTR_ALL }, ··· 1011 1004 [C(OP_WRITE)] = { 1012 1005 [C(RESULT_ACCESS)] = { 0x27, CNTR_EVEN, T }, 1013 1006 [C(RESULT_MISS)] = { 0x27, CNTR_ODD, T }, 1007 + }, 1008 + }, 1009 + }; 1010 + 1011 + static const struct mips_perf_event loongson3_cache_map 1012 + [PERF_COUNT_HW_CACHE_MAX] 1013 + [PERF_COUNT_HW_CACHE_OP_MAX] 1014 + [PERF_COUNT_HW_CACHE_RESULT_MAX] = { 1015 + [C(L1D)] = { 1016 + /* 1017 + * Like some other architectures (e.g. ARM), the performance 1018 + * counters don't differentiate between read and write 1019 + * accesses/misses, so this isn't strictly correct, but it's the 1020 + * best we can do. Writes and reads get combined. 1021 + */ 1022 + [C(OP_READ)] = { 1023 + [C(RESULT_MISS)] = { 0x04, CNTR_ODD }, 1024 + }, 1025 + [C(OP_WRITE)] = { 1026 + [C(RESULT_MISS)] = { 0x04, CNTR_ODD }, 1027 + }, 1028 + }, 1029 + [C(L1I)] = { 1030 + [C(OP_READ)] = { 1031 + [C(RESULT_MISS)] = { 0x04, CNTR_EVEN }, 1032 + }, 1033 + [C(OP_WRITE)] = { 1034 + [C(RESULT_MISS)] = { 0x04, CNTR_EVEN }, 1035 + }, 1036 + }, 1037 + [C(DTLB)] = { 1038 + [C(OP_READ)] = { 1039 + [C(RESULT_MISS)] = { 0x09, CNTR_ODD }, 1040 + }, 1041 + [C(OP_WRITE)] = { 1042 + [C(RESULT_MISS)] = { 0x09, CNTR_ODD }, 1043 + }, 1044 + }, 1045 + [C(ITLB)] = { 1046 + [C(OP_READ)] = { 1047 + [C(RESULT_MISS)] = { 0x0c, CNTR_ODD }, 1048 + }, 1049 + [C(OP_WRITE)] = { 1050 + [C(RESULT_MISS)] = { 0x0c, CNTR_ODD }, 1051 + }, 1052 + }, 1053 + [C(BPU)] = { 1054 + /* Using the same code for *HW_BRANCH* */ 1055 + [C(OP_READ)] = { 1056 + [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN }, 1057 + [C(RESULT_MISS)] = { 0x02, CNTR_ODD }, 1058 + }, 1059 + [C(OP_WRITE)] = { 1060 + [C(RESULT_ACCESS)] = { 0x02, CNTR_EVEN }, 1061 + [C(RESULT_MISS)] = { 0x02, CNTR_ODD }, 1014 1062 }, 1015 1063 }, 1016 1064 }; ··· 1604 1542 else 1605 1543 raw_event.cntr_mask = 1606 1544 raw_id > 127 ? CNTR_ODD : CNTR_EVEN; 1545 + break; 1546 + case CPU_LOONGSON3: 1547 + raw_event.cntr_mask = raw_id > 127 ? CNTR_ODD : CNTR_EVEN; 1548 + break; 1607 1549 } 1608 1550 1609 1551 raw_event.event_id = base_id; ··· 1736 1670 mipspmu.name = "mips/loongson1"; 1737 1671 mipspmu.general_event_map = &mipsxxcore_event_map; 1738 1672 mipspmu.cache_event_map = &mipsxxcore_cache_map; 1673 + break; 1674 + case CPU_LOONGSON3: 1675 + mipspmu.name = "mips/loongson3"; 1676 + mipspmu.general_event_map = &loongson3_event_map; 1677 + mipspmu.cache_event_map = &loongson3_cache_map; 1739 1678 break; 1740 1679 case CPU_CAVIUM_OCTEON: 1741 1680 case CPU_CAVIUM_OCTEON_PLUS: