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

perf: arm_pmu: Remove event index to counter remapping

Xscale and Armv6 PMUs defined the cycle counter at 0 and event counters
starting at 1 and had 1:1 event index to counter numbering. On Armv7 and
later, this changed the cycle counter to 31 and event counters start at
0. The drivers for Armv7 and PMUv3 kept the old event index numbering
and introduced an event index to counter conversion. The conversion uses
masking to convert from event index to a counter number. This operation
relies on having at most 32 counters so that the cycle counter index 0
can be transformed to counter number 31.

Armv9.4 adds support for an additional fixed function counter
(instructions) which increases possible counters to more than 32, and
the conversion won't work anymore as a simple subtract and mask. The
primary reason for the translation (other than history) seems to be to
have a contiguous mask of counters 0-N. Keeping that would result in
more complicated index to counter conversions. Instead, store a mask of
available counters rather than just number of events. That provides more
information in addition to the number of events.

No (intended) functional changes.

Acked-by: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Tested-by: James Clark <james.clark@linaro.org>
Link: https://lore.kernel.org/r/20240731-arm-pmu-3-9-icntr-v3-1-280a8d7ff465@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>

authored by

Rob Herring (Arm) and committed by
Will Deacon
bf5ffc8c 48b03512

+75 -106
+3 -3
arch/arm64/kvm/pmu-emul.c
··· 910 910 struct arm_pmu *arm_pmu = kvm->arch.arm_pmu; 911 911 912 912 /* 913 - * The arm_pmu->num_events considers the cycle counter as well. 914 - * Ignore that and return only the general-purpose counters. 913 + * The arm_pmu->cntr_mask considers the fixed counter(s) as well. 914 + * Ignore those and return only the general-purpose counters. 915 915 */ 916 - return arm_pmu->num_events - 1; 916 + return bitmap_weight(arm_pmu->cntr_mask, ARMV8_PMU_MAX_GENERAL_COUNTERS); 917 917 } 918 918 919 919 static void kvm_arm_set_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu)
+2 -2
drivers/perf/apple_m1_cpu_pmu.c
··· 400 400 401 401 regs = get_irq_regs(); 402 402 403 - for (idx = 0; idx < cpu_pmu->num_events; idx++) { 403 + for_each_set_bit(idx, cpu_pmu->cntr_mask, M1_PMU_NR_COUNTERS) { 404 404 struct perf_event *event = cpuc->events[idx]; 405 405 struct perf_sample_data data; 406 406 ··· 560 560 cpu_pmu->reset = m1_pmu_reset; 561 561 cpu_pmu->set_event_filter = m1_pmu_set_event_filter; 562 562 563 - cpu_pmu->num_events = M1_PMU_NR_COUNTERS; 563 + bitmap_set(cpu_pmu->cntr_mask, 0, M1_PMU_NR_COUNTERS); 564 564 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; 565 565 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group; 566 566 return 0;
+6 -5
drivers/perf/arm_pmu.c
··· 522 522 { 523 523 struct arm_pmu *armpmu = to_arm_pmu(pmu); 524 524 struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events); 525 - bool enabled = !bitmap_empty(hw_events->used_mask, armpmu->num_events); 525 + bool enabled = !bitmap_empty(hw_events->used_mask, ARMPMU_MAX_HWEVENTS); 526 526 527 527 /* For task-bound events we may be called on other CPUs */ 528 528 if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus)) ··· 742 742 struct perf_event *event; 743 743 int idx; 744 744 745 - for (idx = 0; idx < armpmu->num_events; idx++) { 745 + for_each_set_bit(idx, armpmu->cntr_mask, ARMPMU_MAX_HWEVENTS) { 746 746 event = hw_events->events[idx]; 747 747 if (!event) 748 748 continue; ··· 772 772 { 773 773 struct arm_pmu *armpmu = container_of(b, struct arm_pmu, cpu_pm_nb); 774 774 struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events); 775 - bool enabled = !bitmap_empty(hw_events->used_mask, armpmu->num_events); 775 + bool enabled = !bitmap_empty(hw_events->used_mask, ARMPMU_MAX_HWEVENTS); 776 776 777 777 if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus)) 778 778 return NOTIFY_DONE; ··· 924 924 if (ret) 925 925 goto out_destroy; 926 926 927 - pr_info("enabled with %s PMU driver, %d counters available%s\n", 928 - pmu->name, pmu->num_events, 927 + pr_info("enabled with %s PMU driver, %d (%*pb) counters available%s\n", 928 + pmu->name, bitmap_weight(pmu->cntr_mask, ARMPMU_MAX_HWEVENTS), 929 + ARMPMU_MAX_HWEVENTS, &pmu->cntr_mask, 929 930 has_nmi ? ", using NMIs" : ""); 930 931 931 932 kvm_host_pmu_init(pmu);
+21 -41
drivers/perf/arm_pmuv3.c
··· 454 454 /* 455 455 * Perf Events' indices 456 456 */ 457 - #define ARMV8_IDX_CYCLE_COUNTER 0 458 - #define ARMV8_IDX_COUNTER0 1 459 - #define ARMV8_IDX_CYCLE_COUNTER_USER 32 457 + #define ARMV8_IDX_CYCLE_COUNTER 31 460 458 461 459 /* 462 460 * We unconditionally enable ARMv8.5-PMU long event counter support ··· 487 489 return !armv8pmu_event_has_user_read(event) && 488 490 armv8pmu_event_is_64bit(event) && 489 491 !armv8pmu_has_long_event(cpu_pmu) && 490 - (idx != ARMV8_IDX_CYCLE_COUNTER); 492 + (idx < ARMV8_PMU_MAX_GENERAL_COUNTERS); 491 493 } 492 494 493 495 /* 494 496 * ARMv8 low level PMU access 495 497 */ 496 - 497 - /* 498 - * Perf Event to low level counters mapping 499 - */ 500 - #define ARMV8_IDX_TO_COUNTER(x) \ 501 - (((x) - ARMV8_IDX_COUNTER0) & ARMV8_PMU_COUNTER_MASK) 502 - 503 498 static u64 armv8pmu_pmcr_read(void) 504 499 { 505 500 return read_pmcr(); ··· 512 521 513 522 static int armv8pmu_counter_has_overflowed(u32 pmnc, int idx) 514 523 { 515 - return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx)); 524 + return pmnc & BIT(idx); 516 525 } 517 526 518 527 static u64 armv8pmu_read_evcntr(int idx) 519 528 { 520 - u32 counter = ARMV8_IDX_TO_COUNTER(idx); 521 - 522 - return read_pmevcntrn(counter); 529 + return read_pmevcntrn(idx); 523 530 } 524 531 525 532 static u64 armv8pmu_read_hw_counter(struct perf_event *event) ··· 546 557 return false; 547 558 548 559 if (armv8pmu_has_long_event(cpu_pmu) || 549 - idx == ARMV8_IDX_CYCLE_COUNTER) 560 + idx >= ARMV8_PMU_MAX_GENERAL_COUNTERS) 550 561 return true; 551 562 552 563 return false; ··· 584 595 585 596 static void armv8pmu_write_evcntr(int idx, u64 value) 586 597 { 587 - u32 counter = ARMV8_IDX_TO_COUNTER(idx); 588 - 589 - write_pmevcntrn(counter, value); 598 + write_pmevcntrn(idx, value); 590 599 } 591 600 592 601 static void armv8pmu_write_hw_counter(struct perf_event *event, ··· 615 628 616 629 static void armv8pmu_write_evtype(int idx, unsigned long val) 617 630 { 618 - u32 counter = ARMV8_IDX_TO_COUNTER(idx); 619 631 unsigned long mask = ARMV8_PMU_EVTYPE_EVENT | 620 632 ARMV8_PMU_INCLUDE_EL2 | 621 633 ARMV8_PMU_EXCLUDE_EL0 | ··· 624 638 mask |= ARMV8_PMU_EVTYPE_TC | ARMV8_PMU_EVTYPE_TH; 625 639 626 640 val &= mask; 627 - write_pmevtypern(counter, val); 641 + write_pmevtypern(idx, val); 628 642 } 629 643 630 644 static void armv8pmu_write_event_type(struct perf_event *event) ··· 653 667 654 668 static u32 armv8pmu_event_cnten_mask(struct perf_event *event) 655 669 { 656 - int counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); 670 + int counter = event->hw.idx; 657 671 u32 mask = BIT(counter); 658 672 659 673 if (armv8pmu_event_is_chained(event)) ··· 712 726 713 727 static void armv8pmu_enable_event_irq(struct perf_event *event) 714 728 { 715 - u32 counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); 716 - armv8pmu_enable_intens(BIT(counter)); 729 + armv8pmu_enable_intens(BIT(event->hw.idx)); 717 730 } 718 731 719 732 static void armv8pmu_disable_intens(u32 mask) ··· 726 741 727 742 static void armv8pmu_disable_event_irq(struct perf_event *event) 728 743 { 729 - u32 counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); 730 - armv8pmu_disable_intens(BIT(counter)); 744 + armv8pmu_disable_intens(BIT(event->hw.idx)); 731 745 } 732 746 733 747 static u32 armv8pmu_getreset_flags(void) ··· 770 786 struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events); 771 787 772 788 /* Clear any unused counters to avoid leaking their contents */ 773 - for_each_clear_bit(i, cpuc->used_mask, cpu_pmu->num_events) { 789 + for_each_andnot_bit(i, cpu_pmu->cntr_mask, cpuc->used_mask, 790 + ARMPMU_MAX_HWEVENTS) { 774 791 if (i == ARMV8_IDX_CYCLE_COUNTER) 775 792 write_pmccntr(0); 776 793 else ··· 854 869 * to prevent skews in group events. 855 870 */ 856 871 armv8pmu_stop(cpu_pmu); 857 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 872 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMPMU_MAX_HWEVENTS) { 858 873 struct perf_event *event = cpuc->events[idx]; 859 874 struct hw_perf_event *hwc; 860 875 ··· 893 908 { 894 909 int idx; 895 910 896 - for (idx = ARMV8_IDX_COUNTER0; idx < cpu_pmu->num_events; idx++) { 911 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV8_PMU_MAX_GENERAL_COUNTERS) { 897 912 if (!test_and_set_bit(idx, cpuc->used_mask)) 898 913 return idx; 899 914 } ··· 909 924 * Chaining requires two consecutive event counters, where 910 925 * the lower idx must be even. 911 926 */ 912 - for (idx = ARMV8_IDX_COUNTER0 + 1; idx < cpu_pmu->num_events; idx += 2) { 927 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV8_PMU_MAX_GENERAL_COUNTERS) { 928 + if (!(idx & 0x1)) 929 + continue; 913 930 if (!test_and_set_bit(idx, cpuc->used_mask)) { 914 931 /* Check if the preceding even counter is available */ 915 932 if (!test_and_set_bit(idx - 1, cpuc->used_mask)) ··· 965 978 if (!sysctl_perf_user_access || !armv8pmu_event_has_user_read(event)) 966 979 return 0; 967 980 968 - /* 969 - * We remap the cycle counter index to 32 to 970 - * match the offset applied to the rest of 971 - * the counter indices. 972 - */ 973 - if (event->hw.idx == ARMV8_IDX_CYCLE_COUNTER) 974 - return ARMV8_IDX_CYCLE_COUNTER_USER; 975 - 976 - return event->hw.idx; 981 + return event->hw.idx + 1; 977 982 } 978 983 979 984 /* ··· 1190 1211 probe->present = true; 1191 1212 1192 1213 /* Read the nb of CNTx counters supported from PMNC */ 1193 - cpu_pmu->num_events = FIELD_GET(ARMV8_PMU_PMCR_N, armv8pmu_pmcr_read()); 1214 + bitmap_set(cpu_pmu->cntr_mask, 1215 + 0, FIELD_GET(ARMV8_PMU_PMCR_N, armv8pmu_pmcr_read())); 1194 1216 1195 1217 /* Add the CPU cycles counter */ 1196 - cpu_pmu->num_events += 1; 1218 + set_bit(ARMV8_IDX_CYCLE_COUNTER, cpu_pmu->cntr_mask); 1197 1219 1198 1220 pmceid[0] = pmceid_raw[0] = read_pmceid0(); 1199 1221 pmceid[1] = pmceid_raw[1] = read_pmceid1();
+4 -2
drivers/perf/arm_v6_pmu.c
··· 64 64 ARMV6_CYCLE_COUNTER = 0, 65 65 ARMV6_COUNTER0, 66 66 ARMV6_COUNTER1, 67 + ARMV6_NUM_COUNTERS 67 68 }; 68 69 69 70 /* ··· 255 254 */ 256 255 armv6_pmcr_write(pmcr); 257 256 258 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 257 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV6_NUM_COUNTERS) { 259 258 struct perf_event *event = cpuc->events[idx]; 260 259 struct hw_perf_event *hwc; 261 260 ··· 392 391 cpu_pmu->start = armv6pmu_start; 393 392 cpu_pmu->stop = armv6pmu_stop; 394 393 cpu_pmu->map_event = armv6_map_event; 395 - cpu_pmu->num_events = 3; 394 + 395 + bitmap_set(cpu_pmu->cntr_mask, 0, ARMV6_NUM_COUNTERS); 396 396 } 397 397 398 398 static int armv6_1136_pmu_init(struct arm_pmu *cpu_pmu)
+29 -48
drivers/perf/arm_v7_pmu.c
··· 649 649 /* 650 650 * Perf Events' indices 651 651 */ 652 - #define ARMV7_IDX_CYCLE_COUNTER 0 653 - #define ARMV7_IDX_COUNTER0 1 654 - #define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \ 655 - (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1) 656 - 657 - #define ARMV7_MAX_COUNTERS 32 658 - #define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1) 659 - 652 + #define ARMV7_IDX_CYCLE_COUNTER 31 653 + #define ARMV7_IDX_COUNTER_MAX 31 660 654 /* 661 655 * ARMv7 low level PMNC access 662 656 */ 663 - 664 - /* 665 - * Perf Event to low level counters mapping 666 - */ 667 - #define ARMV7_IDX_TO_COUNTER(x) \ 668 - (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK) 669 657 670 658 /* 671 659 * Per-CPU PMNC: config reg ··· 713 725 714 726 static inline int armv7_pmnc_counter_valid(struct arm_pmu *cpu_pmu, int idx) 715 727 { 716 - return idx >= ARMV7_IDX_CYCLE_COUNTER && 717 - idx <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); 728 + return test_bit(idx, cpu_pmu->cntr_mask); 718 729 } 719 730 720 731 static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx) 721 732 { 722 - return pmnc & BIT(ARMV7_IDX_TO_COUNTER(idx)); 733 + return pmnc & BIT(idx); 723 734 } 724 735 725 736 static inline void armv7_pmnc_select_counter(int idx) 726 737 { 727 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 728 - asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter)); 738 + asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (idx)); 729 739 isb(); 730 740 } 731 741 ··· 773 787 774 788 static inline void armv7_pmnc_enable_counter(int idx) 775 789 { 776 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 777 - asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter))); 790 + asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(idx))); 778 791 } 779 792 780 793 static inline void armv7_pmnc_disable_counter(int idx) 781 794 { 782 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 783 - asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter))); 795 + asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(idx))); 784 796 } 785 797 786 798 static inline void armv7_pmnc_enable_intens(int idx) 787 799 { 788 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 789 - asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter))); 800 + asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(idx))); 790 801 } 791 802 792 803 static inline void armv7_pmnc_disable_intens(int idx) 793 804 { 794 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 795 - asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter))); 805 + asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(idx))); 796 806 isb(); 797 807 /* Clear the overflow flag in case an interrupt is pending. */ 798 - asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter))); 808 + asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(idx))); 799 809 isb(); 800 810 } 801 811 ··· 835 853 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); 836 854 pr_info("CCNT =0x%08x\n", val); 837 855 838 - for (cnt = ARMV7_IDX_COUNTER0; 839 - cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) { 856 + for_each_set_bit(cnt, cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX) { 840 857 armv7_pmnc_select_counter(cnt); 841 858 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); 842 - pr_info("CNT[%d] count =0x%08x\n", 843 - ARMV7_IDX_TO_COUNTER(cnt), val); 859 + pr_info("CNT[%d] count =0x%08x\n", cnt, val); 844 860 asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val)); 845 - pr_info("CNT[%d] evtsel=0x%08x\n", 846 - ARMV7_IDX_TO_COUNTER(cnt), val); 861 + pr_info("CNT[%d] evtsel=0x%08x\n", cnt, val); 847 862 } 848 863 } 849 864 #endif ··· 937 958 */ 938 959 regs = get_irq_regs(); 939 960 940 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 961 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMPMU_MAX_HWEVENTS) { 941 962 struct perf_event *event = cpuc->events[idx]; 942 963 struct hw_perf_event *hwc; 943 964 ··· 1006 1027 * For anything other than a cycle counter, try and use 1007 1028 * the events counters 1008 1029 */ 1009 - for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) { 1030 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX) { 1010 1031 if (!test_and_set_bit(idx, cpuc->used_mask)) 1011 1032 return idx; 1012 1033 } ··· 1052 1073 static void armv7pmu_reset(void *info) 1053 1074 { 1054 1075 struct arm_pmu *cpu_pmu = (struct arm_pmu *)info; 1055 - u32 idx, nb_cnt = cpu_pmu->num_events, val; 1076 + u32 idx, val; 1056 1077 1057 1078 if (cpu_pmu->secure_access) { 1058 1079 asm volatile("mrc p15, 0, %0, c1, c1, 1" : "=r" (val)); ··· 1061 1082 } 1062 1083 1063 1084 /* The counter and interrupt enable registers are unknown at reset. */ 1064 - for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) { 1085 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMPMU_MAX_HWEVENTS) { 1065 1086 armv7_pmnc_disable_counter(idx); 1066 1087 armv7_pmnc_disable_intens(idx); 1067 1088 } ··· 1140 1161 1141 1162 static void armv7_read_num_pmnc_events(void *info) 1142 1163 { 1143 - int *nb_cnt = info; 1164 + int nb_cnt; 1165 + struct arm_pmu *cpu_pmu = info; 1144 1166 1145 1167 /* Read the nb of CNTx counters supported from PMNC */ 1146 - *nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; 1168 + nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; 1169 + bitmap_set(cpu_pmu->cntr_mask, 0, nb_cnt); 1147 1170 1148 1171 /* Add the CPU cycles counter */ 1149 - *nb_cnt += 1; 1172 + set_bit(ARMV7_IDX_CYCLE_COUNTER, cpu_pmu->cntr_mask); 1150 1173 } 1151 1174 1152 1175 static int armv7_probe_num_events(struct arm_pmu *arm_pmu) 1153 1176 { 1154 1177 return smp_call_function_any(&arm_pmu->supported_cpus, 1155 1178 armv7_read_num_pmnc_events, 1156 - &arm_pmu->num_events, 1); 1179 + arm_pmu, 1); 1157 1180 } 1158 1181 1159 1182 static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu) ··· 1505 1524 { 1506 1525 u32 vval, fval; 1507 1526 struct arm_pmu *cpu_pmu = info; 1508 - u32 idx, nb_cnt = cpu_pmu->num_events; 1527 + u32 idx; 1509 1528 1510 1529 armv7pmu_reset(info); 1511 1530 ··· 1519 1538 venum_post_pmresr(vval, fval); 1520 1539 1521 1540 /* Reset PMxEVNCTCR to sane default */ 1522 - for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) { 1541 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX) { 1523 1542 armv7_pmnc_select_counter(idx); 1524 1543 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0)); 1525 1544 } ··· 1543 1562 * Lower bits are reserved for use by the counters (see 1544 1563 * armv7pmu_get_event_idx() for more info) 1545 1564 */ 1546 - bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1; 1565 + bit += bitmap_weight(cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX); 1547 1566 1548 1567 return bit; 1549 1568 } ··· 1826 1845 { 1827 1846 u32 vval, fval; 1828 1847 struct arm_pmu *cpu_pmu = info; 1829 - u32 idx, nb_cnt = cpu_pmu->num_events; 1848 + u32 idx; 1830 1849 1831 1850 armv7pmu_reset(info); 1832 1851 ··· 1841 1860 venum_post_pmresr(vval, fval); 1842 1861 1843 1862 /* Reset PMxEVNCTCR to sane default */ 1844 - for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) { 1863 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX) { 1845 1864 armv7_pmnc_select_counter(idx); 1846 1865 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0)); 1847 1866 } ··· 1864 1883 * Lower bits are reserved for use by the counters (see 1865 1884 * armv7pmu_get_event_idx() for more info) 1866 1885 */ 1867 - bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1; 1886 + bit += bitmap_weight(cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX); 1868 1887 1869 1888 return bit; 1870 1889 }
+8 -4
drivers/perf/arm_xscale_pmu.c
··· 53 53 XSCALE_COUNTER2, 54 54 XSCALE_COUNTER3, 55 55 }; 56 + #define XSCALE1_NUM_COUNTERS 3 57 + #define XSCALE2_NUM_COUNTERS 5 56 58 57 59 static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = { 58 60 PERF_MAP_ALL_UNSUPPORTED, ··· 170 168 171 169 regs = get_irq_regs(); 172 170 173 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 171 + for_each_set_bit(idx, cpu_pmu->cntr_mask, XSCALE1_NUM_COUNTERS) { 174 172 struct perf_event *event = cpuc->events[idx]; 175 173 struct hw_perf_event *hwc; 176 174 ··· 366 364 cpu_pmu->start = xscale1pmu_start; 367 365 cpu_pmu->stop = xscale1pmu_stop; 368 366 cpu_pmu->map_event = xscale_map_event; 369 - cpu_pmu->num_events = 3; 367 + 368 + bitmap_set(cpu_pmu->cntr_mask, 0, XSCALE1_NUM_COUNTERS); 370 369 371 370 return 0; 372 371 } ··· 503 500 504 501 regs = get_irq_regs(); 505 502 506 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 503 + for_each_set_bit(idx, cpu_pmu->cntr_mask, XSCALE2_NUM_COUNTERS) { 507 504 struct perf_event *event = cpuc->events[idx]; 508 505 struct hw_perf_event *hwc; 509 506 ··· 722 719 cpu_pmu->start = xscale2pmu_start; 723 720 cpu_pmu->stop = xscale2pmu_stop; 724 721 cpu_pmu->map_event = xscale_map_event; 725 - cpu_pmu->num_events = 5; 722 + 723 + bitmap_set(cpu_pmu->cntr_mask, 0, XSCALE2_NUM_COUNTERS); 726 724 727 725 return 0; 728 726 }
+1 -1
include/linux/perf/arm_pmu.h
··· 96 96 void (*stop)(struct arm_pmu *); 97 97 void (*reset)(void *); 98 98 int (*map_event)(struct perf_event *event); 99 - int num_events; 99 + DECLARE_BITMAP(cntr_mask, ARMPMU_MAX_HWEVENTS); 100 100 bool secure_access; /* 32-bit ARM only */ 101 101 #define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40 102 102 DECLARE_BITMAP(pmceid_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
+1
include/linux/perf/arm_pmuv3.h
··· 6 6 #ifndef __PERF_ARM_PMUV3_H 7 7 #define __PERF_ARM_PMUV3_H 8 8 9 + #define ARMV8_PMU_MAX_GENERAL_COUNTERS 31 9 10 #define ARMV8_PMU_MAX_COUNTERS 32 10 11 #define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1) 11 12