.. | .. |
---|
28 | 28 | #include <linux/bitops.h> |
---|
29 | 29 | #include <linux/device.h> |
---|
30 | 30 | #include <linux/nospec.h> |
---|
| 31 | +#include <linux/static_call.h> |
---|
31 | 32 | |
---|
32 | 33 | #include <asm/apic.h> |
---|
33 | 34 | #include <asm/stacktrace.h> |
---|
.. | .. |
---|
44 | 45 | #include "perf_event.h" |
---|
45 | 46 | |
---|
46 | 47 | struct x86_pmu x86_pmu __read_mostly; |
---|
| 48 | +static struct pmu pmu; |
---|
47 | 49 | |
---|
48 | 50 | DEFINE_PER_CPU(struct cpu_hw_events, cpu_hw_events) = { |
---|
49 | 51 | .enabled = 1, |
---|
| 52 | + .pmu = &pmu, |
---|
50 | 53 | }; |
---|
51 | 54 | |
---|
| 55 | +DEFINE_STATIC_KEY_FALSE(rdpmc_never_available_key); |
---|
52 | 56 | DEFINE_STATIC_KEY_FALSE(rdpmc_always_available_key); |
---|
| 57 | + |
---|
| 58 | +/* |
---|
| 59 | + * This here uses DEFINE_STATIC_CALL_NULL() to get a static_call defined |
---|
| 60 | + * from just a typename, as opposed to an actual function. |
---|
| 61 | + */ |
---|
| 62 | +DEFINE_STATIC_CALL_NULL(x86_pmu_handle_irq, *x86_pmu.handle_irq); |
---|
| 63 | +DEFINE_STATIC_CALL_NULL(x86_pmu_disable_all, *x86_pmu.disable_all); |
---|
| 64 | +DEFINE_STATIC_CALL_NULL(x86_pmu_enable_all, *x86_pmu.enable_all); |
---|
| 65 | +DEFINE_STATIC_CALL_NULL(x86_pmu_enable, *x86_pmu.enable); |
---|
| 66 | +DEFINE_STATIC_CALL_NULL(x86_pmu_disable, *x86_pmu.disable); |
---|
| 67 | + |
---|
| 68 | +DEFINE_STATIC_CALL_NULL(x86_pmu_add, *x86_pmu.add); |
---|
| 69 | +DEFINE_STATIC_CALL_NULL(x86_pmu_del, *x86_pmu.del); |
---|
| 70 | +DEFINE_STATIC_CALL_NULL(x86_pmu_read, *x86_pmu.read); |
---|
| 71 | + |
---|
| 72 | +DEFINE_STATIC_CALL_NULL(x86_pmu_schedule_events, *x86_pmu.schedule_events); |
---|
| 73 | +DEFINE_STATIC_CALL_NULL(x86_pmu_get_event_constraints, *x86_pmu.get_event_constraints); |
---|
| 74 | +DEFINE_STATIC_CALL_NULL(x86_pmu_put_event_constraints, *x86_pmu.put_event_constraints); |
---|
| 75 | + |
---|
| 76 | +DEFINE_STATIC_CALL_NULL(x86_pmu_start_scheduling, *x86_pmu.start_scheduling); |
---|
| 77 | +DEFINE_STATIC_CALL_NULL(x86_pmu_commit_scheduling, *x86_pmu.commit_scheduling); |
---|
| 78 | +DEFINE_STATIC_CALL_NULL(x86_pmu_stop_scheduling, *x86_pmu.stop_scheduling); |
---|
| 79 | + |
---|
| 80 | +DEFINE_STATIC_CALL_NULL(x86_pmu_sched_task, *x86_pmu.sched_task); |
---|
| 81 | +DEFINE_STATIC_CALL_NULL(x86_pmu_swap_task_ctx, *x86_pmu.swap_task_ctx); |
---|
| 82 | + |
---|
| 83 | +DEFINE_STATIC_CALL_NULL(x86_pmu_drain_pebs, *x86_pmu.drain_pebs); |
---|
| 84 | +DEFINE_STATIC_CALL_NULL(x86_pmu_pebs_aliases, *x86_pmu.pebs_aliases); |
---|
53 | 85 | |
---|
54 | 86 | u64 __read_mostly hw_cache_event_ids |
---|
55 | 87 | [PERF_COUNT_HW_CACHE_MAX] |
---|
.. | .. |
---|
70 | 102 | struct hw_perf_event *hwc = &event->hw; |
---|
71 | 103 | int shift = 64 - x86_pmu.cntval_bits; |
---|
72 | 104 | u64 prev_raw_count, new_raw_count; |
---|
73 | | - int idx = hwc->idx; |
---|
74 | 105 | u64 delta; |
---|
75 | 106 | |
---|
76 | | - if (idx == INTEL_PMC_IDX_FIXED_BTS) |
---|
| 107 | + if (unlikely(!hwc->event_base)) |
---|
77 | 108 | return 0; |
---|
| 109 | + |
---|
| 110 | + if (unlikely(is_topdown_count(event)) && x86_pmu.update_topdown_event) |
---|
| 111 | + return x86_pmu.update_topdown_event(event); |
---|
78 | 112 | |
---|
79 | 113 | /* |
---|
80 | 114 | * Careful: an NMI might modify the previous event value. |
---|
.. | .. |
---|
340 | 374 | if (!atomic_inc_not_zero(&pmc_refcount)) { |
---|
341 | 375 | mutex_lock(&pmc_reserve_mutex); |
---|
342 | 376 | if (atomic_read(&pmc_refcount) == 0) { |
---|
343 | | - if (!reserve_pmc_hardware()) |
---|
| 377 | + if (!reserve_pmc_hardware()) { |
---|
344 | 378 | err = -EBUSY; |
---|
345 | | - else |
---|
| 379 | + } else { |
---|
346 | 380 | reserve_ds_buffers(); |
---|
| 381 | + reserve_lbr_buffers(); |
---|
| 382 | + } |
---|
347 | 383 | } |
---|
348 | 384 | if (!err) |
---|
349 | 385 | atomic_inc(&pmc_refcount); |
---|
.. | .. |
---|
358 | 394 | if (atomic_dec_and_mutex_lock(&pmc_refcount, &pmc_reserve_mutex)) { |
---|
359 | 395 | release_pmc_hardware(); |
---|
360 | 396 | release_ds_buffers(); |
---|
| 397 | + release_lbr_buffers(); |
---|
361 | 398 | mutex_unlock(&pmc_reserve_mutex); |
---|
362 | 399 | } |
---|
363 | 400 | } |
---|
.. | .. |
---|
565 | 602 | return -EINVAL; |
---|
566 | 603 | } |
---|
567 | 604 | |
---|
| 605 | + /* sample_regs_user never support XMM registers */ |
---|
| 606 | + if (unlikely(event->attr.sample_regs_user & PERF_REG_EXTENDED_MASK)) |
---|
| 607 | + return -EINVAL; |
---|
| 608 | + /* |
---|
| 609 | + * Besides the general purpose registers, XMM registers may |
---|
| 610 | + * be collected in PEBS on some platforms, e.g. Icelake |
---|
| 611 | + */ |
---|
| 612 | + if (unlikely(event->attr.sample_regs_intr & PERF_REG_EXTENDED_MASK)) { |
---|
| 613 | + if (!(event->pmu->capabilities & PERF_PMU_CAP_EXTENDED_REGS)) |
---|
| 614 | + return -EINVAL; |
---|
| 615 | + |
---|
| 616 | + if (!event->attr.precise_ip) |
---|
| 617 | + return -EINVAL; |
---|
| 618 | + } |
---|
| 619 | + |
---|
568 | 620 | return x86_setup_perfctr(event); |
---|
569 | 621 | } |
---|
570 | 622 | |
---|
.. | .. |
---|
602 | 654 | int idx; |
---|
603 | 655 | |
---|
604 | 656 | for (idx = 0; idx < x86_pmu.num_counters; idx++) { |
---|
| 657 | + struct hw_perf_event *hwc = &cpuc->events[idx]->hw; |
---|
605 | 658 | u64 val; |
---|
606 | 659 | |
---|
607 | 660 | if (!test_bit(idx, cpuc->active_mask)) |
---|
.. | .. |
---|
611 | 664 | continue; |
---|
612 | 665 | val &= ~ARCH_PERFMON_EVENTSEL_ENABLE; |
---|
613 | 666 | wrmsrl(x86_pmu_config_addr(idx), val); |
---|
| 667 | + if (is_counter_pair(hwc)) |
---|
| 668 | + wrmsrl(x86_pmu_config_addr(idx + 1), 0); |
---|
614 | 669 | } |
---|
615 | 670 | } |
---|
616 | 671 | |
---|
.. | .. |
---|
641 | 696 | cpuc->enabled = 0; |
---|
642 | 697 | barrier(); |
---|
643 | 698 | |
---|
644 | | - x86_pmu.disable_all(); |
---|
| 699 | + static_call(x86_pmu_disable_all)(); |
---|
645 | 700 | } |
---|
646 | 701 | |
---|
647 | 702 | void x86_pmu_enable_all(int added) |
---|
.. | .. |
---|
659 | 714 | } |
---|
660 | 715 | } |
---|
661 | 716 | |
---|
662 | | -static struct pmu pmu; |
---|
663 | | - |
---|
664 | 717 | static inline int is_x86_event(struct perf_event *event) |
---|
665 | 718 | { |
---|
666 | 719 | return event->pmu == &pmu; |
---|
667 | 720 | } |
---|
668 | 721 | |
---|
| 722 | +struct pmu *x86_get_pmu(unsigned int cpu) |
---|
| 723 | +{ |
---|
| 724 | + struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); |
---|
| 725 | + |
---|
| 726 | + /* |
---|
| 727 | + * All CPUs of the hybrid type have been offline. |
---|
| 728 | + * The x86_get_pmu() should not be invoked. |
---|
| 729 | + */ |
---|
| 730 | + if (WARN_ON_ONCE(!cpuc->pmu)) |
---|
| 731 | + return &pmu; |
---|
| 732 | + |
---|
| 733 | + return cpuc->pmu; |
---|
| 734 | +} |
---|
669 | 735 | /* |
---|
670 | 736 | * Event scheduler state: |
---|
671 | 737 | * |
---|
.. | .. |
---|
679 | 745 | int counter; /* counter index */ |
---|
680 | 746 | int unassigned; /* number of events to be assigned left */ |
---|
681 | 747 | int nr_gp; /* number of GP counters used */ |
---|
682 | | - unsigned long used[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; |
---|
| 748 | + u64 used; |
---|
683 | 749 | }; |
---|
684 | 750 | |
---|
685 | 751 | /* Total max is X86_PMC_IDX_MAX, but we are O(n!) limited */ |
---|
.. | .. |
---|
736 | 802 | sched->saved_states--; |
---|
737 | 803 | sched->state = sched->saved[sched->saved_states]; |
---|
738 | 804 | |
---|
739 | | - /* continue with next counter: */ |
---|
740 | | - clear_bit(sched->state.counter++, sched->state.used); |
---|
| 805 | + /* this assignment didn't work out */ |
---|
| 806 | + /* XXX broken vs EVENT_PAIR */ |
---|
| 807 | + sched->state.used &= ~BIT_ULL(sched->state.counter); |
---|
| 808 | + |
---|
| 809 | + /* try the next one */ |
---|
| 810 | + sched->state.counter++; |
---|
741 | 811 | |
---|
742 | 812 | return true; |
---|
743 | 813 | } |
---|
.. | .. |
---|
762 | 832 | if (c->idxmsk64 & (~0ULL << INTEL_PMC_IDX_FIXED)) { |
---|
763 | 833 | idx = INTEL_PMC_IDX_FIXED; |
---|
764 | 834 | for_each_set_bit_from(idx, c->idxmsk, X86_PMC_IDX_MAX) { |
---|
765 | | - if (!__test_and_set_bit(idx, sched->state.used)) |
---|
766 | | - goto done; |
---|
| 835 | + u64 mask = BIT_ULL(idx); |
---|
| 836 | + |
---|
| 837 | + if (sched->state.used & mask) |
---|
| 838 | + continue; |
---|
| 839 | + |
---|
| 840 | + sched->state.used |= mask; |
---|
| 841 | + goto done; |
---|
767 | 842 | } |
---|
768 | 843 | } |
---|
769 | 844 | |
---|
770 | 845 | /* Grab the first unused counter starting with idx */ |
---|
771 | 846 | idx = sched->state.counter; |
---|
772 | 847 | for_each_set_bit_from(idx, c->idxmsk, INTEL_PMC_IDX_FIXED) { |
---|
773 | | - if (!__test_and_set_bit(idx, sched->state.used)) { |
---|
774 | | - if (sched->state.nr_gp++ >= sched->max_gp) |
---|
775 | | - return false; |
---|
| 848 | + u64 mask = BIT_ULL(idx); |
---|
776 | 849 | |
---|
777 | | - goto done; |
---|
778 | | - } |
---|
| 850 | + if (c->flags & PERF_X86_EVENT_PAIR) |
---|
| 851 | + mask |= mask << 1; |
---|
| 852 | + |
---|
| 853 | + if (sched->state.used & mask) |
---|
| 854 | + continue; |
---|
| 855 | + |
---|
| 856 | + if (sched->state.nr_gp++ >= sched->max_gp) |
---|
| 857 | + return false; |
---|
| 858 | + |
---|
| 859 | + sched->state.used |= mask; |
---|
| 860 | + goto done; |
---|
779 | 861 | } |
---|
780 | 862 | |
---|
781 | 863 | return false; |
---|
.. | .. |
---|
852 | 934 | int x86_schedule_events(struct cpu_hw_events *cpuc, int n, int *assign) |
---|
853 | 935 | { |
---|
854 | 936 | struct event_constraint *c; |
---|
855 | | - unsigned long used_mask[BITS_TO_LONGS(X86_PMC_IDX_MAX)]; |
---|
856 | 937 | struct perf_event *e; |
---|
857 | | - int i, wmin, wmax, unsched = 0; |
---|
| 938 | + int n0, i, wmin, wmax, unsched = 0; |
---|
858 | 939 | struct hw_perf_event *hwc; |
---|
| 940 | + u64 used_mask = 0; |
---|
859 | 941 | |
---|
860 | | - bitmap_zero(used_mask, X86_PMC_IDX_MAX); |
---|
| 942 | + /* |
---|
| 943 | + * Compute the number of events already present; see x86_pmu_add(), |
---|
| 944 | + * validate_group() and x86_pmu_commit_txn(). For the former two |
---|
| 945 | + * cpuc->n_events hasn't been updated yet, while for the latter |
---|
| 946 | + * cpuc->n_txn contains the number of events added in the current |
---|
| 947 | + * transaction. |
---|
| 948 | + */ |
---|
| 949 | + n0 = cpuc->n_events; |
---|
| 950 | + if (cpuc->txn_flags & PERF_PMU_TXN_ADD) |
---|
| 951 | + n0 -= cpuc->n_txn; |
---|
861 | 952 | |
---|
862 | | - if (x86_pmu.start_scheduling) |
---|
863 | | - x86_pmu.start_scheduling(cpuc); |
---|
| 953 | + static_call_cond(x86_pmu_start_scheduling)(cpuc); |
---|
864 | 954 | |
---|
865 | 955 | for (i = 0, wmin = X86_PMC_IDX_MAX, wmax = 0; i < n; i++) { |
---|
866 | | - cpuc->event_constraint[i] = NULL; |
---|
867 | | - c = x86_pmu.get_event_constraints(cpuc, i, cpuc->event_list[i]); |
---|
868 | | - cpuc->event_constraint[i] = c; |
---|
| 956 | + c = cpuc->event_constraint[i]; |
---|
| 957 | + |
---|
| 958 | + /* |
---|
| 959 | + * Previously scheduled events should have a cached constraint, |
---|
| 960 | + * while new events should not have one. |
---|
| 961 | + */ |
---|
| 962 | + WARN_ON_ONCE((c && i >= n0) || (!c && i < n0)); |
---|
| 963 | + |
---|
| 964 | + /* |
---|
| 965 | + * Request constraints for new events; or for those events that |
---|
| 966 | + * have a dynamic constraint -- for those the constraint can |
---|
| 967 | + * change due to external factors (sibling state, allow_tfa). |
---|
| 968 | + */ |
---|
| 969 | + if (!c || (c->flags & PERF_X86_EVENT_DYNAMIC)) { |
---|
| 970 | + c = static_call(x86_pmu_get_event_constraints)(cpuc, i, cpuc->event_list[i]); |
---|
| 971 | + cpuc->event_constraint[i] = c; |
---|
| 972 | + } |
---|
869 | 973 | |
---|
870 | 974 | wmin = min(wmin, c->weight); |
---|
871 | 975 | wmax = max(wmax, c->weight); |
---|
.. | .. |
---|
875 | 979 | * fastpath, try to reuse previous register |
---|
876 | 980 | */ |
---|
877 | 981 | for (i = 0; i < n; i++) { |
---|
| 982 | + u64 mask; |
---|
| 983 | + |
---|
878 | 984 | hwc = &cpuc->event_list[i]->hw; |
---|
879 | 985 | c = cpuc->event_constraint[i]; |
---|
880 | 986 | |
---|
.. | .. |
---|
886 | 992 | if (!test_bit(hwc->idx, c->idxmsk)) |
---|
887 | 993 | break; |
---|
888 | 994 | |
---|
| 995 | + mask = BIT_ULL(hwc->idx); |
---|
| 996 | + if (is_counter_pair(hwc)) |
---|
| 997 | + mask |= mask << 1; |
---|
| 998 | + |
---|
889 | 999 | /* not already used */ |
---|
890 | | - if (test_bit(hwc->idx, used_mask)) |
---|
| 1000 | + if (used_mask & mask) |
---|
891 | 1001 | break; |
---|
892 | 1002 | |
---|
893 | | - __set_bit(hwc->idx, used_mask); |
---|
| 1003 | + used_mask |= mask; |
---|
| 1004 | + |
---|
894 | 1005 | if (assign) |
---|
895 | 1006 | assign[i] = hwc->idx; |
---|
896 | 1007 | } |
---|
.. | .. |
---|
913 | 1024 | READ_ONCE(cpuc->excl_cntrs->exclusive_present)) |
---|
914 | 1025 | gpmax /= 2; |
---|
915 | 1026 | |
---|
| 1027 | + /* |
---|
| 1028 | + * Reduce the amount of available counters to allow fitting |
---|
| 1029 | + * the extra Merge events needed by large increment events. |
---|
| 1030 | + */ |
---|
| 1031 | + if (x86_pmu.flags & PMU_FL_PAIR) { |
---|
| 1032 | + gpmax = x86_pmu.num_counters - cpuc->n_pair; |
---|
| 1033 | + WARN_ON(gpmax <= 0); |
---|
| 1034 | + } |
---|
| 1035 | + |
---|
916 | 1036 | unsched = perf_assign_events(cpuc->event_constraint, n, wmin, |
---|
917 | 1037 | wmax, gpmax, assign); |
---|
918 | 1038 | } |
---|
.. | .. |
---|
930 | 1050 | if (!unsched && assign) { |
---|
931 | 1051 | for (i = 0; i < n; i++) { |
---|
932 | 1052 | e = cpuc->event_list[i]; |
---|
933 | | - e->hw.flags |= PERF_X86_EVENT_COMMITTED; |
---|
934 | | - if (x86_pmu.commit_scheduling) |
---|
935 | | - x86_pmu.commit_scheduling(cpuc, i, assign[i]); |
---|
| 1053 | + static_call_cond(x86_pmu_commit_scheduling)(cpuc, i, assign[i]); |
---|
936 | 1054 | } |
---|
937 | 1055 | } else { |
---|
938 | | - for (i = 0; i < n; i++) { |
---|
| 1056 | + for (i = n0; i < n; i++) { |
---|
939 | 1057 | e = cpuc->event_list[i]; |
---|
940 | | - /* |
---|
941 | | - * do not put_constraint() on comitted events, |
---|
942 | | - * because they are good to go |
---|
943 | | - */ |
---|
944 | | - if ((e->hw.flags & PERF_X86_EVENT_COMMITTED)) |
---|
945 | | - continue; |
---|
946 | 1058 | |
---|
947 | 1059 | /* |
---|
948 | 1060 | * release events that failed scheduling |
---|
949 | 1061 | */ |
---|
950 | | - if (x86_pmu.put_event_constraints) |
---|
951 | | - x86_pmu.put_event_constraints(cpuc, e); |
---|
| 1062 | + static_call_cond(x86_pmu_put_event_constraints)(cpuc, e); |
---|
| 1063 | + |
---|
| 1064 | + cpuc->event_constraint[i] = NULL; |
---|
952 | 1065 | } |
---|
953 | 1066 | } |
---|
954 | 1067 | |
---|
955 | | - if (x86_pmu.stop_scheduling) |
---|
956 | | - x86_pmu.stop_scheduling(cpuc); |
---|
| 1068 | + static_call_cond(x86_pmu_stop_scheduling)(cpuc); |
---|
957 | 1069 | |
---|
958 | 1070 | return unsched ? -EINVAL : 0; |
---|
| 1071 | +} |
---|
| 1072 | + |
---|
| 1073 | +static int add_nr_metric_event(struct cpu_hw_events *cpuc, |
---|
| 1074 | + struct perf_event *event) |
---|
| 1075 | +{ |
---|
| 1076 | + if (is_metric_event(event)) { |
---|
| 1077 | + if (cpuc->n_metric == INTEL_TD_METRIC_NUM) |
---|
| 1078 | + return -EINVAL; |
---|
| 1079 | + cpuc->n_metric++; |
---|
| 1080 | + cpuc->n_txn_metric++; |
---|
| 1081 | + } |
---|
| 1082 | + |
---|
| 1083 | + return 0; |
---|
| 1084 | +} |
---|
| 1085 | + |
---|
| 1086 | +static void del_nr_metric_event(struct cpu_hw_events *cpuc, |
---|
| 1087 | + struct perf_event *event) |
---|
| 1088 | +{ |
---|
| 1089 | + if (is_metric_event(event)) |
---|
| 1090 | + cpuc->n_metric--; |
---|
| 1091 | +} |
---|
| 1092 | + |
---|
| 1093 | +static int collect_event(struct cpu_hw_events *cpuc, struct perf_event *event, |
---|
| 1094 | + int max_count, int n) |
---|
| 1095 | +{ |
---|
| 1096 | + |
---|
| 1097 | + if (x86_pmu.intel_cap.perf_metrics && add_nr_metric_event(cpuc, event)) |
---|
| 1098 | + return -EINVAL; |
---|
| 1099 | + |
---|
| 1100 | + if (n >= max_count + cpuc->n_metric) |
---|
| 1101 | + return -EINVAL; |
---|
| 1102 | + |
---|
| 1103 | + cpuc->event_list[n] = event; |
---|
| 1104 | + if (is_counter_pair(&event->hw)) { |
---|
| 1105 | + cpuc->n_pair++; |
---|
| 1106 | + cpuc->n_txn_pair++; |
---|
| 1107 | + } |
---|
| 1108 | + |
---|
| 1109 | + return 0; |
---|
959 | 1110 | } |
---|
960 | 1111 | |
---|
961 | 1112 | /* |
---|
.. | .. |
---|
971 | 1122 | |
---|
972 | 1123 | /* current number of events already accepted */ |
---|
973 | 1124 | n = cpuc->n_events; |
---|
| 1125 | + if (!cpuc->n_events) |
---|
| 1126 | + cpuc->pebs_output = 0; |
---|
| 1127 | + |
---|
| 1128 | + if (!cpuc->is_fake && leader->attr.precise_ip) { |
---|
| 1129 | + /* |
---|
| 1130 | + * For PEBS->PT, if !aux_event, the group leader (PT) went |
---|
| 1131 | + * away, the group was broken down and this singleton event |
---|
| 1132 | + * can't schedule any more. |
---|
| 1133 | + */ |
---|
| 1134 | + if (is_pebs_pt(leader) && !leader->aux_event) |
---|
| 1135 | + return -EINVAL; |
---|
| 1136 | + |
---|
| 1137 | + /* |
---|
| 1138 | + * pebs_output: 0: no PEBS so far, 1: PT, 2: DS |
---|
| 1139 | + */ |
---|
| 1140 | + if (cpuc->pebs_output && |
---|
| 1141 | + cpuc->pebs_output != is_pebs_pt(leader) + 1) |
---|
| 1142 | + return -EINVAL; |
---|
| 1143 | + |
---|
| 1144 | + cpuc->pebs_output = is_pebs_pt(leader) + 1; |
---|
| 1145 | + } |
---|
974 | 1146 | |
---|
975 | 1147 | if (is_x86_event(leader)) { |
---|
976 | | - if (n >= max_count) |
---|
| 1148 | + if (collect_event(cpuc, leader, max_count, n)) |
---|
977 | 1149 | return -EINVAL; |
---|
978 | | - cpuc->event_list[n] = leader; |
---|
979 | 1150 | n++; |
---|
980 | 1151 | } |
---|
| 1152 | + |
---|
981 | 1153 | if (!dogrp) |
---|
982 | 1154 | return n; |
---|
983 | 1155 | |
---|
984 | 1156 | for_each_sibling_event(event, leader) { |
---|
985 | | - if (!is_x86_event(event) || |
---|
986 | | - event->state <= PERF_EVENT_STATE_OFF) |
---|
| 1157 | + if (!is_x86_event(event) || event->state <= PERF_EVENT_STATE_OFF) |
---|
987 | 1158 | continue; |
---|
988 | 1159 | |
---|
989 | | - if (n >= max_count) |
---|
| 1160 | + if (collect_event(cpuc, event, max_count, n)) |
---|
990 | 1161 | return -EINVAL; |
---|
991 | 1162 | |
---|
992 | | - cpuc->event_list[n] = event; |
---|
993 | 1163 | n++; |
---|
994 | 1164 | } |
---|
995 | 1165 | return n; |
---|
.. | .. |
---|
999 | 1169 | struct cpu_hw_events *cpuc, int i) |
---|
1000 | 1170 | { |
---|
1001 | 1171 | struct hw_perf_event *hwc = &event->hw; |
---|
| 1172 | + int idx; |
---|
1002 | 1173 | |
---|
1003 | | - hwc->idx = cpuc->assign[i]; |
---|
| 1174 | + idx = hwc->idx = cpuc->assign[i]; |
---|
1004 | 1175 | hwc->last_cpu = smp_processor_id(); |
---|
1005 | 1176 | hwc->last_tag = ++cpuc->tags[i]; |
---|
1006 | 1177 | |
---|
1007 | | - if (hwc->idx == INTEL_PMC_IDX_FIXED_BTS) { |
---|
| 1178 | + switch (hwc->idx) { |
---|
| 1179 | + case INTEL_PMC_IDX_FIXED_BTS: |
---|
| 1180 | + case INTEL_PMC_IDX_FIXED_VLBR: |
---|
1008 | 1181 | hwc->config_base = 0; |
---|
1009 | 1182 | hwc->event_base = 0; |
---|
1010 | | - } else if (hwc->idx >= INTEL_PMC_IDX_FIXED) { |
---|
| 1183 | + break; |
---|
| 1184 | + |
---|
| 1185 | + case INTEL_PMC_IDX_METRIC_BASE ... INTEL_PMC_IDX_METRIC_END: |
---|
| 1186 | + /* All the metric events are mapped onto the fixed counter 3. */ |
---|
| 1187 | + idx = INTEL_PMC_IDX_FIXED_SLOTS; |
---|
| 1188 | + /* fall through */ |
---|
| 1189 | + case INTEL_PMC_IDX_FIXED ... INTEL_PMC_IDX_FIXED_BTS-1: |
---|
1011 | 1190 | hwc->config_base = MSR_ARCH_PERFMON_FIXED_CTR_CTRL; |
---|
1012 | | - hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + (hwc->idx - INTEL_PMC_IDX_FIXED); |
---|
1013 | | - hwc->event_base_rdpmc = (hwc->idx - INTEL_PMC_IDX_FIXED) | 1<<30; |
---|
1014 | | - } else { |
---|
| 1191 | + hwc->event_base = MSR_ARCH_PERFMON_FIXED_CTR0 + |
---|
| 1192 | + (idx - INTEL_PMC_IDX_FIXED); |
---|
| 1193 | + hwc->event_base_rdpmc = (idx - INTEL_PMC_IDX_FIXED) | |
---|
| 1194 | + INTEL_PMC_FIXED_RDPMC_BASE; |
---|
| 1195 | + break; |
---|
| 1196 | + |
---|
| 1197 | + default: |
---|
1015 | 1198 | hwc->config_base = x86_pmu_config_addr(hwc->idx); |
---|
1016 | 1199 | hwc->event_base = x86_pmu_event_addr(hwc->idx); |
---|
1017 | 1200 | hwc->event_base_rdpmc = x86_pmu_rdpmc_index(hwc->idx); |
---|
| 1201 | + break; |
---|
1018 | 1202 | } |
---|
| 1203 | +} |
---|
| 1204 | + |
---|
| 1205 | +/** |
---|
| 1206 | + * x86_perf_rdpmc_index - Return PMC counter used for event |
---|
| 1207 | + * @event: the perf_event to which the PMC counter was assigned |
---|
| 1208 | + * |
---|
| 1209 | + * The counter assigned to this performance event may change if interrupts |
---|
| 1210 | + * are enabled. This counter should thus never be used while interrupts are |
---|
| 1211 | + * enabled. Before this function is used to obtain the assigned counter the |
---|
| 1212 | + * event should be checked for validity using, for example, |
---|
| 1213 | + * perf_event_read_local(), within the same interrupt disabled section in |
---|
| 1214 | + * which this counter is planned to be used. |
---|
| 1215 | + * |
---|
| 1216 | + * Return: The index of the performance monitoring counter assigned to |
---|
| 1217 | + * @perf_event. |
---|
| 1218 | + */ |
---|
| 1219 | +int x86_perf_rdpmc_index(struct perf_event *event) |
---|
| 1220 | +{ |
---|
| 1221 | + lockdep_assert_irqs_disabled(); |
---|
| 1222 | + |
---|
| 1223 | + return event->hw.event_base_rdpmc; |
---|
1019 | 1224 | } |
---|
1020 | 1225 | |
---|
1021 | 1226 | static inline int match_prev_assignment(struct hw_perf_event *hwc, |
---|
.. | .. |
---|
1098 | 1303 | cpuc->enabled = 1; |
---|
1099 | 1304 | barrier(); |
---|
1100 | 1305 | |
---|
1101 | | - x86_pmu.enable_all(added); |
---|
| 1306 | + static_call(x86_pmu_enable_all)(added); |
---|
1102 | 1307 | } |
---|
1103 | 1308 | |
---|
1104 | 1309 | static DEFINE_PER_CPU(u64 [X86_PMC_IDX_MAX], pmc_prev_left); |
---|
.. | .. |
---|
1114 | 1319 | s64 period = hwc->sample_period; |
---|
1115 | 1320 | int ret = 0, idx = hwc->idx; |
---|
1116 | 1321 | |
---|
1117 | | - if (idx == INTEL_PMC_IDX_FIXED_BTS) |
---|
| 1322 | + if (unlikely(!hwc->event_base)) |
---|
1118 | 1323 | return 0; |
---|
| 1324 | + |
---|
| 1325 | + if (unlikely(is_topdown_count(event)) && |
---|
| 1326 | + x86_pmu.set_topdown_event_period) |
---|
| 1327 | + return x86_pmu.set_topdown_event_period(event); |
---|
1119 | 1328 | |
---|
1120 | 1329 | /* |
---|
1121 | 1330 | * If we are way outside a reasonable range then just skip forward: |
---|
.. | .. |
---|
1156 | 1365 | wrmsrl(hwc->event_base, (u64)(-left) & x86_pmu.cntval_mask); |
---|
1157 | 1366 | |
---|
1158 | 1367 | /* |
---|
| 1368 | + * Sign extend the Merge event counter's upper 16 bits since |
---|
| 1369 | + * we currently declare a 48-bit counter width |
---|
| 1370 | + */ |
---|
| 1371 | + if (is_counter_pair(hwc)) |
---|
| 1372 | + wrmsrl(x86_pmu_event_addr(idx + 1), 0xffff); |
---|
| 1373 | + |
---|
| 1374 | + /* |
---|
1159 | 1375 | * Due to erratum on certan cpu we need |
---|
1160 | 1376 | * a second write to be sure the register |
---|
1161 | 1377 | * is updated properly |
---|
.. | .. |
---|
1181 | 1397 | * Add a single event to the PMU. |
---|
1182 | 1398 | * |
---|
1183 | 1399 | * The event is added to the group of enabled events |
---|
1184 | | - * but only if it can be scehduled with existing events. |
---|
| 1400 | + * but only if it can be scheduled with existing events. |
---|
1185 | 1401 | */ |
---|
1186 | 1402 | static int x86_pmu_add(struct perf_event *event, int flags) |
---|
1187 | 1403 | { |
---|
.. | .. |
---|
1212 | 1428 | if (cpuc->txn_flags & PERF_PMU_TXN_ADD) |
---|
1213 | 1429 | goto done_collect; |
---|
1214 | 1430 | |
---|
1215 | | - ret = x86_pmu.schedule_events(cpuc, n, assign); |
---|
| 1431 | + ret = static_call(x86_pmu_schedule_events)(cpuc, n, assign); |
---|
1216 | 1432 | if (ret) |
---|
1217 | 1433 | goto out; |
---|
1218 | 1434 | /* |
---|
.. | .. |
---|
1230 | 1446 | cpuc->n_added += n - n0; |
---|
1231 | 1447 | cpuc->n_txn += n - n0; |
---|
1232 | 1448 | |
---|
1233 | | - if (x86_pmu.add) { |
---|
1234 | | - /* |
---|
1235 | | - * This is before x86_pmu_enable() will call x86_pmu_start(), |
---|
1236 | | - * so we enable LBRs before an event needs them etc.. |
---|
1237 | | - */ |
---|
1238 | | - x86_pmu.add(event); |
---|
1239 | | - } |
---|
| 1449 | + /* |
---|
| 1450 | + * This is before x86_pmu_enable() will call x86_pmu_start(), |
---|
| 1451 | + * so we enable LBRs before an event needs them etc.. |
---|
| 1452 | + */ |
---|
| 1453 | + static_call_cond(x86_pmu_add)(event); |
---|
1240 | 1454 | |
---|
1241 | 1455 | ret = 0; |
---|
1242 | 1456 | out: |
---|
.. | .. |
---|
1264 | 1478 | cpuc->events[idx] = event; |
---|
1265 | 1479 | __set_bit(idx, cpuc->active_mask); |
---|
1266 | 1480 | __set_bit(idx, cpuc->running); |
---|
1267 | | - x86_pmu.enable(event); |
---|
| 1481 | + static_call(x86_pmu_enable)(event); |
---|
1268 | 1482 | perf_event_update_userpage(event); |
---|
1269 | 1483 | } |
---|
1270 | 1484 | |
---|
.. | .. |
---|
1334 | 1548 | struct hw_perf_event *hwc = &event->hw; |
---|
1335 | 1549 | |
---|
1336 | 1550 | if (test_bit(hwc->idx, cpuc->active_mask)) { |
---|
1337 | | - x86_pmu.disable(event); |
---|
| 1551 | + static_call(x86_pmu_disable)(event); |
---|
1338 | 1552 | __clear_bit(hwc->idx, cpuc->active_mask); |
---|
1339 | 1553 | cpuc->events[hwc->idx] = NULL; |
---|
1340 | 1554 | WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); |
---|
.. | .. |
---|
1355 | 1569 | { |
---|
1356 | 1570 | struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events); |
---|
1357 | 1571 | int i; |
---|
1358 | | - |
---|
1359 | | - /* |
---|
1360 | | - * event is descheduled |
---|
1361 | | - */ |
---|
1362 | | - event->hw.flags &= ~PERF_X86_EVENT_COMMITTED; |
---|
1363 | 1572 | |
---|
1364 | 1573 | /* |
---|
1365 | 1574 | * If we're called during a txn, we only need to undo x86_pmu.add. |
---|
.. | .. |
---|
1389 | 1598 | if (i >= cpuc->n_events - cpuc->n_added) |
---|
1390 | 1599 | --cpuc->n_added; |
---|
1391 | 1600 | |
---|
1392 | | - if (x86_pmu.put_event_constraints) |
---|
1393 | | - x86_pmu.put_event_constraints(cpuc, event); |
---|
| 1601 | + static_call_cond(x86_pmu_put_event_constraints)(cpuc, event); |
---|
1394 | 1602 | |
---|
1395 | 1603 | /* Delete the array entry. */ |
---|
1396 | 1604 | while (++i < cpuc->n_events) { |
---|
1397 | 1605 | cpuc->event_list[i-1] = cpuc->event_list[i]; |
---|
1398 | 1606 | cpuc->event_constraint[i-1] = cpuc->event_constraint[i]; |
---|
1399 | 1607 | } |
---|
| 1608 | + cpuc->event_constraint[i-1] = NULL; |
---|
1400 | 1609 | --cpuc->n_events; |
---|
| 1610 | + if (x86_pmu.intel_cap.perf_metrics) |
---|
| 1611 | + del_nr_metric_event(cpuc, event); |
---|
1401 | 1612 | |
---|
1402 | 1613 | perf_event_update_userpage(event); |
---|
1403 | 1614 | |
---|
1404 | 1615 | do_del: |
---|
1405 | | - if (x86_pmu.del) { |
---|
1406 | | - /* |
---|
1407 | | - * This is after x86_pmu_stop(); so we disable LBRs after any |
---|
1408 | | - * event can need them etc.. |
---|
1409 | | - */ |
---|
1410 | | - x86_pmu.del(event); |
---|
1411 | | - } |
---|
| 1616 | + |
---|
| 1617 | + /* |
---|
| 1618 | + * This is after x86_pmu_stop(); so we disable LBRs after any |
---|
| 1619 | + * event can need them etc.. |
---|
| 1620 | + */ |
---|
| 1621 | + static_call_cond(x86_pmu_del)(event); |
---|
1412 | 1622 | } |
---|
1413 | 1623 | |
---|
1414 | 1624 | int x86_pmu_handle_irq(struct pt_regs *regs) |
---|
.. | .. |
---|
1486 | 1696 | return NMI_DONE; |
---|
1487 | 1697 | |
---|
1488 | 1698 | start_clock = sched_clock(); |
---|
1489 | | - ret = x86_pmu.handle_irq(regs); |
---|
| 1699 | + ret = static_call(x86_pmu_handle_irq)(regs); |
---|
1490 | 1700 | finish_clock = sched_clock(); |
---|
1491 | 1701 | |
---|
1492 | 1702 | perf_sample_event_took(finish_clock - start_clock); |
---|
.. | .. |
---|
1562 | 1772 | |
---|
1563 | 1773 | } |
---|
1564 | 1774 | |
---|
1565 | | -static struct attribute_group x86_pmu_format_group = { |
---|
| 1775 | +static struct attribute_group x86_pmu_format_group __ro_after_init = { |
---|
1566 | 1776 | .name = "format", |
---|
1567 | 1777 | .attrs = NULL, |
---|
1568 | 1778 | }; |
---|
1569 | 1779 | |
---|
1570 | | -/* |
---|
1571 | | - * Remove all undefined events (x86_pmu.event_map(id) == 0) |
---|
1572 | | - * out of events_attr attributes. |
---|
1573 | | - */ |
---|
1574 | | -static void __init filter_events(struct attribute **attrs) |
---|
1575 | | -{ |
---|
1576 | | - struct device_attribute *d; |
---|
1577 | | - struct perf_pmu_events_attr *pmu_attr; |
---|
1578 | | - int offset = 0; |
---|
1579 | | - int i, j; |
---|
1580 | | - |
---|
1581 | | - for (i = 0; attrs[i]; i++) { |
---|
1582 | | - d = (struct device_attribute *)attrs[i]; |
---|
1583 | | - pmu_attr = container_of(d, struct perf_pmu_events_attr, attr); |
---|
1584 | | - /* str trumps id */ |
---|
1585 | | - if (pmu_attr->event_str) |
---|
1586 | | - continue; |
---|
1587 | | - if (x86_pmu.event_map(i + offset)) |
---|
1588 | | - continue; |
---|
1589 | | - |
---|
1590 | | - for (j = i; attrs[j]; j++) |
---|
1591 | | - attrs[j] = attrs[j + 1]; |
---|
1592 | | - |
---|
1593 | | - /* Check the shifted attr. */ |
---|
1594 | | - i--; |
---|
1595 | | - |
---|
1596 | | - /* |
---|
1597 | | - * event_map() is index based, the attrs array is organized |
---|
1598 | | - * by increasing event index. If we shift the events, then |
---|
1599 | | - * we need to compensate for the event_map(), otherwise |
---|
1600 | | - * we are looking up the wrong event in the map |
---|
1601 | | - */ |
---|
1602 | | - offset++; |
---|
1603 | | - } |
---|
1604 | | -} |
---|
1605 | | - |
---|
1606 | | -/* Merge two pointer arrays */ |
---|
1607 | | -__init struct attribute **merge_attr(struct attribute **a, struct attribute **b) |
---|
1608 | | -{ |
---|
1609 | | - struct attribute **new; |
---|
1610 | | - int j, i; |
---|
1611 | | - |
---|
1612 | | - for (j = 0; a[j]; j++) |
---|
1613 | | - ; |
---|
1614 | | - for (i = 0; b[i]; i++) |
---|
1615 | | - j++; |
---|
1616 | | - j++; |
---|
1617 | | - |
---|
1618 | | - new = kmalloc_array(j, sizeof(struct attribute *), GFP_KERNEL); |
---|
1619 | | - if (!new) |
---|
1620 | | - return NULL; |
---|
1621 | | - |
---|
1622 | | - j = 0; |
---|
1623 | | - for (i = 0; a[i]; i++) |
---|
1624 | | - new[j++] = a[i]; |
---|
1625 | | - for (i = 0; b[i]; i++) |
---|
1626 | | - new[j++] = b[i]; |
---|
1627 | | - new[j] = NULL; |
---|
1628 | | - |
---|
1629 | | - return new; |
---|
1630 | | -} |
---|
1631 | | - |
---|
1632 | 1780 | ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, char *page) |
---|
1633 | 1781 | { |
---|
1634 | | - struct perf_pmu_events_attr *pmu_attr = \ |
---|
| 1782 | + struct perf_pmu_events_attr *pmu_attr = |
---|
1635 | 1783 | container_of(attr, struct perf_pmu_events_attr, attr); |
---|
1636 | | - u64 config = x86_pmu.event_map(pmu_attr->id); |
---|
| 1784 | + u64 config = 0; |
---|
| 1785 | + |
---|
| 1786 | + if (pmu_attr->id < x86_pmu.max_events) |
---|
| 1787 | + config = x86_pmu.event_map(pmu_attr->id); |
---|
1637 | 1788 | |
---|
1638 | 1789 | /* string trumps id */ |
---|
1639 | 1790 | if (pmu_attr->event_str) |
---|
.. | .. |
---|
1693 | 1844 | NULL, |
---|
1694 | 1845 | }; |
---|
1695 | 1846 | |
---|
1696 | | -static struct attribute_group x86_pmu_events_group = { |
---|
| 1847 | +/* |
---|
| 1848 | + * Remove all undefined events (x86_pmu.event_map(id) == 0) |
---|
| 1849 | + * out of events_attr attributes. |
---|
| 1850 | + */ |
---|
| 1851 | +static umode_t |
---|
| 1852 | +is_visible(struct kobject *kobj, struct attribute *attr, int idx) |
---|
| 1853 | +{ |
---|
| 1854 | + struct perf_pmu_events_attr *pmu_attr; |
---|
| 1855 | + |
---|
| 1856 | + if (idx >= x86_pmu.max_events) |
---|
| 1857 | + return 0; |
---|
| 1858 | + |
---|
| 1859 | + pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr.attr); |
---|
| 1860 | + /* str trumps id */ |
---|
| 1861 | + return pmu_attr->event_str || x86_pmu.event_map(idx) ? attr->mode : 0; |
---|
| 1862 | +} |
---|
| 1863 | + |
---|
| 1864 | +static struct attribute_group x86_pmu_events_group __ro_after_init = { |
---|
1697 | 1865 | .name = "events", |
---|
1698 | 1866 | .attrs = events_attr, |
---|
| 1867 | + .is_visible = is_visible, |
---|
1699 | 1868 | }; |
---|
1700 | 1869 | |
---|
1701 | 1870 | ssize_t x86_event_sysfs_show(char *page, u64 config, u64 event) |
---|
.. | .. |
---|
1740 | 1909 | static struct attribute_group x86_pmu_attr_group; |
---|
1741 | 1910 | static struct attribute_group x86_pmu_caps_group; |
---|
1742 | 1911 | |
---|
| 1912 | +static void x86_pmu_static_call_update(void) |
---|
| 1913 | +{ |
---|
| 1914 | + static_call_update(x86_pmu_handle_irq, x86_pmu.handle_irq); |
---|
| 1915 | + static_call_update(x86_pmu_disable_all, x86_pmu.disable_all); |
---|
| 1916 | + static_call_update(x86_pmu_enable_all, x86_pmu.enable_all); |
---|
| 1917 | + static_call_update(x86_pmu_enable, x86_pmu.enable); |
---|
| 1918 | + static_call_update(x86_pmu_disable, x86_pmu.disable); |
---|
| 1919 | + |
---|
| 1920 | + static_call_update(x86_pmu_add, x86_pmu.add); |
---|
| 1921 | + static_call_update(x86_pmu_del, x86_pmu.del); |
---|
| 1922 | + static_call_update(x86_pmu_read, x86_pmu.read); |
---|
| 1923 | + |
---|
| 1924 | + static_call_update(x86_pmu_schedule_events, x86_pmu.schedule_events); |
---|
| 1925 | + static_call_update(x86_pmu_get_event_constraints, x86_pmu.get_event_constraints); |
---|
| 1926 | + static_call_update(x86_pmu_put_event_constraints, x86_pmu.put_event_constraints); |
---|
| 1927 | + |
---|
| 1928 | + static_call_update(x86_pmu_start_scheduling, x86_pmu.start_scheduling); |
---|
| 1929 | + static_call_update(x86_pmu_commit_scheduling, x86_pmu.commit_scheduling); |
---|
| 1930 | + static_call_update(x86_pmu_stop_scheduling, x86_pmu.stop_scheduling); |
---|
| 1931 | + |
---|
| 1932 | + static_call_update(x86_pmu_sched_task, x86_pmu.sched_task); |
---|
| 1933 | + static_call_update(x86_pmu_swap_task_ctx, x86_pmu.swap_task_ctx); |
---|
| 1934 | + |
---|
| 1935 | + static_call_update(x86_pmu_drain_pebs, x86_pmu.drain_pebs); |
---|
| 1936 | + static_call_update(x86_pmu_pebs_aliases, x86_pmu.pebs_aliases); |
---|
| 1937 | +} |
---|
| 1938 | + |
---|
| 1939 | +static void _x86_pmu_read(struct perf_event *event) |
---|
| 1940 | +{ |
---|
| 1941 | + x86_perf_event_update(event); |
---|
| 1942 | +} |
---|
| 1943 | + |
---|
1743 | 1944 | static int __init init_hw_perf_events(void) |
---|
1744 | 1945 | { |
---|
1745 | 1946 | struct x86_pmu_quirk *quirk; |
---|
.. | .. |
---|
1753 | 1954 | break; |
---|
1754 | 1955 | case X86_VENDOR_AMD: |
---|
1755 | 1956 | err = amd_pmu_init(); |
---|
| 1957 | + break; |
---|
| 1958 | + case X86_VENDOR_HYGON: |
---|
| 1959 | + err = amd_pmu_init(); |
---|
| 1960 | + x86_pmu.name = "HYGON"; |
---|
| 1961 | + break; |
---|
| 1962 | + case X86_VENDOR_ZHAOXIN: |
---|
| 1963 | + case X86_VENDOR_CENTAUR: |
---|
| 1964 | + err = zhaoxin_pmu_init(); |
---|
1756 | 1965 | break; |
---|
1757 | 1966 | default: |
---|
1758 | 1967 | err = -ENOTSUPP; |
---|
.. | .. |
---|
1787 | 1996 | |
---|
1788 | 1997 | x86_pmu_format_group.attrs = x86_pmu.format_attrs; |
---|
1789 | 1998 | |
---|
1790 | | - if (x86_pmu.caps_attrs) { |
---|
1791 | | - struct attribute **tmp; |
---|
1792 | | - |
---|
1793 | | - tmp = merge_attr(x86_pmu_caps_group.attrs, x86_pmu.caps_attrs); |
---|
1794 | | - if (!WARN_ON(!tmp)) |
---|
1795 | | - x86_pmu_caps_group.attrs = tmp; |
---|
1796 | | - } |
---|
1797 | | - |
---|
1798 | | - if (x86_pmu.event_attrs) |
---|
1799 | | - x86_pmu_events_group.attrs = x86_pmu.event_attrs; |
---|
1800 | | - |
---|
1801 | 1999 | if (!x86_pmu.events_sysfs_show) |
---|
1802 | 2000 | x86_pmu_events_group.attrs = &empty_attrs; |
---|
1803 | | - else |
---|
1804 | | - filter_events(x86_pmu_events_group.attrs); |
---|
1805 | 2001 | |
---|
1806 | | - if (x86_pmu.cpu_events) { |
---|
1807 | | - struct attribute **tmp; |
---|
1808 | | - |
---|
1809 | | - tmp = merge_attr(x86_pmu_events_group.attrs, x86_pmu.cpu_events); |
---|
1810 | | - if (!WARN_ON(!tmp)) |
---|
1811 | | - x86_pmu_events_group.attrs = tmp; |
---|
1812 | | - } |
---|
1813 | | - |
---|
1814 | | - if (x86_pmu.attrs) { |
---|
1815 | | - struct attribute **tmp; |
---|
1816 | | - |
---|
1817 | | - tmp = merge_attr(x86_pmu_attr_group.attrs, x86_pmu.attrs); |
---|
1818 | | - if (!WARN_ON(!tmp)) |
---|
1819 | | - x86_pmu_attr_group.attrs = tmp; |
---|
1820 | | - } |
---|
| 2002 | + pmu.attr_update = x86_pmu.attr_update; |
---|
1821 | 2003 | |
---|
1822 | 2004 | pr_info("... version: %d\n", x86_pmu.version); |
---|
1823 | 2005 | pr_info("... bit width: %d\n", x86_pmu.cntval_bits); |
---|
.. | .. |
---|
1826 | 2008 | pr_info("... max period: %016Lx\n", x86_pmu.max_period); |
---|
1827 | 2009 | pr_info("... fixed-purpose events: %d\n", x86_pmu.num_counters_fixed); |
---|
1828 | 2010 | pr_info("... event mask: %016Lx\n", x86_pmu.intel_ctrl); |
---|
| 2011 | + |
---|
| 2012 | + if (!x86_pmu.read) |
---|
| 2013 | + x86_pmu.read = _x86_pmu_read; |
---|
| 2014 | + |
---|
| 2015 | + x86_pmu_static_call_update(); |
---|
1829 | 2016 | |
---|
1830 | 2017 | /* |
---|
1831 | 2018 | * Install callbacks. Core will call them for each online |
---|
.. | .. |
---|
1863 | 2050 | } |
---|
1864 | 2051 | early_initcall(init_hw_perf_events); |
---|
1865 | 2052 | |
---|
1866 | | -static inline void x86_pmu_read(struct perf_event *event) |
---|
| 2053 | +static void x86_pmu_read(struct perf_event *event) |
---|
1867 | 2054 | { |
---|
1868 | | - if (x86_pmu.read) |
---|
1869 | | - return x86_pmu.read(event); |
---|
1870 | | - x86_perf_event_update(event); |
---|
| 2055 | + static_call(x86_pmu_read)(event); |
---|
1871 | 2056 | } |
---|
1872 | 2057 | |
---|
1873 | 2058 | /* |
---|
.. | .. |
---|
1891 | 2076 | |
---|
1892 | 2077 | perf_pmu_disable(pmu); |
---|
1893 | 2078 | __this_cpu_write(cpu_hw_events.n_txn, 0); |
---|
| 2079 | + __this_cpu_write(cpu_hw_events.n_txn_pair, 0); |
---|
| 2080 | + __this_cpu_write(cpu_hw_events.n_txn_metric, 0); |
---|
1894 | 2081 | } |
---|
1895 | 2082 | |
---|
1896 | 2083 | /* |
---|
.. | .. |
---|
1916 | 2103 | */ |
---|
1917 | 2104 | __this_cpu_sub(cpu_hw_events.n_added, __this_cpu_read(cpu_hw_events.n_txn)); |
---|
1918 | 2105 | __this_cpu_sub(cpu_hw_events.n_events, __this_cpu_read(cpu_hw_events.n_txn)); |
---|
| 2106 | + __this_cpu_sub(cpu_hw_events.n_pair, __this_cpu_read(cpu_hw_events.n_txn_pair)); |
---|
| 2107 | + __this_cpu_sub(cpu_hw_events.n_metric, __this_cpu_read(cpu_hw_events.n_txn_metric)); |
---|
1919 | 2108 | perf_pmu_enable(pmu); |
---|
1920 | 2109 | } |
---|
1921 | 2110 | |
---|
.. | .. |
---|
1944 | 2133 | if (!x86_pmu_initialized()) |
---|
1945 | 2134 | return -EAGAIN; |
---|
1946 | 2135 | |
---|
1947 | | - ret = x86_pmu.schedule_events(cpuc, n, assign); |
---|
| 2136 | + ret = static_call(x86_pmu_schedule_events)(cpuc, n, assign); |
---|
1948 | 2137 | if (ret) |
---|
1949 | 2138 | return ret; |
---|
1950 | 2139 | |
---|
.. | .. |
---|
2004 | 2193 | if (IS_ERR(fake_cpuc)) |
---|
2005 | 2194 | return PTR_ERR(fake_cpuc); |
---|
2006 | 2195 | |
---|
2007 | | - c = x86_pmu.get_event_constraints(fake_cpuc, -1, event); |
---|
| 2196 | + c = x86_pmu.get_event_constraints(fake_cpuc, 0, event); |
---|
2008 | 2197 | |
---|
2009 | 2198 | if (!c || !c->weight) |
---|
2010 | 2199 | ret = -EINVAL; |
---|
.. | .. |
---|
2052 | 2241 | if (n < 0) |
---|
2053 | 2242 | goto out; |
---|
2054 | 2243 | |
---|
2055 | | - fake_cpuc->n_events = n; |
---|
2056 | | - |
---|
| 2244 | + fake_cpuc->n_events = 0; |
---|
2057 | 2245 | ret = x86_pmu.schedule_events(fake_cpuc, n, NULL); |
---|
2058 | 2246 | |
---|
2059 | 2247 | out: |
---|
.. | .. |
---|
2106 | 2294 | return err; |
---|
2107 | 2295 | } |
---|
2108 | 2296 | |
---|
2109 | | -static void refresh_pce(void *ignored) |
---|
2110 | | -{ |
---|
2111 | | - load_mm_cr4(this_cpu_read(cpu_tlbstate.loaded_mm)); |
---|
2112 | | -} |
---|
2113 | | - |
---|
2114 | 2297 | static void x86_pmu_event_mapped(struct perf_event *event, struct mm_struct *mm) |
---|
2115 | 2298 | { |
---|
2116 | 2299 | if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED)) |
---|
.. | .. |
---|
2123 | 2306 | * userspace with CR4.PCE clear while another task is still |
---|
2124 | 2307 | * doing on_each_cpu_mask() to propagate CR4.PCE. |
---|
2125 | 2308 | * |
---|
2126 | | - * For now, this can't happen because all callers hold mmap_sem |
---|
| 2309 | + * For now, this can't happen because all callers hold mmap_lock |
---|
2127 | 2310 | * for write. If this changes, we'll need a different solution. |
---|
2128 | 2311 | */ |
---|
2129 | | - lockdep_assert_held_exclusive(&mm->mmap_sem); |
---|
| 2312 | + mmap_assert_write_locked(mm); |
---|
2130 | 2313 | |
---|
2131 | 2314 | if (atomic_inc_return(&mm->context.perf_rdpmc_allowed) == 1) |
---|
2132 | | - on_each_cpu_mask(mm_cpumask(mm), refresh_pce, NULL, 1); |
---|
| 2315 | + on_each_cpu_mask(mm_cpumask(mm), cr4_update_pce, NULL, 1); |
---|
2133 | 2316 | } |
---|
2134 | 2317 | |
---|
2135 | 2318 | static void x86_pmu_event_unmapped(struct perf_event *event, struct mm_struct *mm) |
---|
.. | .. |
---|
2139 | 2322 | return; |
---|
2140 | 2323 | |
---|
2141 | 2324 | if (atomic_dec_and_test(&mm->context.perf_rdpmc_allowed)) |
---|
2142 | | - on_each_cpu_mask(mm_cpumask(mm), refresh_pce, NULL, 1); |
---|
| 2325 | + on_each_cpu_mask(mm_cpumask(mm), cr4_update_pce, NULL, 1); |
---|
2143 | 2326 | } |
---|
2144 | 2327 | |
---|
2145 | 2328 | static int x86_pmu_event_idx(struct perf_event *event) |
---|
2146 | 2329 | { |
---|
2147 | | - int idx = event->hw.idx; |
---|
| 2330 | + struct hw_perf_event *hwc = &event->hw; |
---|
2148 | 2331 | |
---|
2149 | | - if (!(event->hw.flags & PERF_X86_EVENT_RDPMC_ALLOWED)) |
---|
| 2332 | + if (!(hwc->flags & PERF_X86_EVENT_RDPMC_ALLOWED)) |
---|
2150 | 2333 | return 0; |
---|
2151 | 2334 | |
---|
2152 | | - if (x86_pmu.num_counters_fixed && idx >= INTEL_PMC_IDX_FIXED) { |
---|
2153 | | - idx -= INTEL_PMC_IDX_FIXED; |
---|
2154 | | - idx |= 1 << 30; |
---|
2155 | | - } |
---|
2156 | | - |
---|
2157 | | - return idx + 1; |
---|
| 2335 | + if (is_metric_idx(hwc->idx)) |
---|
| 2336 | + return INTEL_PMC_FIXED_RDPMC_METRICS + 1; |
---|
| 2337 | + else |
---|
| 2338 | + return hwc->event_base_rdpmc + 1; |
---|
2158 | 2339 | } |
---|
2159 | 2340 | |
---|
2160 | 2341 | static ssize_t get_attr_rdpmc(struct device *cdev, |
---|
.. | .. |
---|
2181 | 2362 | if (x86_pmu.attr_rdpmc_broken) |
---|
2182 | 2363 | return -ENOTSUPP; |
---|
2183 | 2364 | |
---|
2184 | | - if ((val == 2) != (x86_pmu.attr_rdpmc == 2)) { |
---|
| 2365 | + if (val != x86_pmu.attr_rdpmc) { |
---|
2185 | 2366 | /* |
---|
2186 | | - * Changing into or out of always available, aka |
---|
2187 | | - * perf-event-bypassing mode. This path is extremely slow, |
---|
| 2367 | + * Changing into or out of never available or always available, |
---|
| 2368 | + * aka perf-event-bypassing mode. This path is extremely slow, |
---|
2188 | 2369 | * but only root can trigger it, so it's okay. |
---|
2189 | 2370 | */ |
---|
| 2371 | + if (val == 0) |
---|
| 2372 | + static_branch_inc(&rdpmc_never_available_key); |
---|
| 2373 | + else if (x86_pmu.attr_rdpmc == 0) |
---|
| 2374 | + static_branch_dec(&rdpmc_never_available_key); |
---|
| 2375 | + |
---|
2190 | 2376 | if (val == 2) |
---|
2191 | 2377 | static_branch_inc(&rdpmc_always_available_key); |
---|
2192 | | - else |
---|
| 2378 | + else if (x86_pmu.attr_rdpmc == 2) |
---|
2193 | 2379 | static_branch_dec(&rdpmc_always_available_key); |
---|
2194 | | - on_each_cpu(refresh_pce, NULL, 1); |
---|
2195 | | - } |
---|
2196 | 2380 | |
---|
2197 | | - x86_pmu.attr_rdpmc = val; |
---|
| 2381 | + on_each_cpu(cr4_update_pce, NULL, 1); |
---|
| 2382 | + x86_pmu.attr_rdpmc = val; |
---|
| 2383 | + } |
---|
2198 | 2384 | |
---|
2199 | 2385 | return count; |
---|
2200 | 2386 | } |
---|
.. | .. |
---|
2206 | 2392 | NULL, |
---|
2207 | 2393 | }; |
---|
2208 | 2394 | |
---|
2209 | | -static struct attribute_group x86_pmu_attr_group = { |
---|
| 2395 | +static struct attribute_group x86_pmu_attr_group __ro_after_init = { |
---|
2210 | 2396 | .attrs = x86_pmu_attrs, |
---|
2211 | 2397 | }; |
---|
2212 | 2398 | |
---|
.. | .. |
---|
2224 | 2410 | NULL |
---|
2225 | 2411 | }; |
---|
2226 | 2412 | |
---|
2227 | | -static struct attribute_group x86_pmu_caps_group = { |
---|
| 2413 | +static struct attribute_group x86_pmu_caps_group __ro_after_init = { |
---|
2228 | 2414 | .name = "caps", |
---|
2229 | 2415 | .attrs = x86_pmu_caps_attrs, |
---|
2230 | 2416 | }; |
---|
.. | .. |
---|
2239 | 2425 | |
---|
2240 | 2426 | static void x86_pmu_sched_task(struct perf_event_context *ctx, bool sched_in) |
---|
2241 | 2427 | { |
---|
2242 | | - if (x86_pmu.sched_task) |
---|
2243 | | - x86_pmu.sched_task(ctx, sched_in); |
---|
| 2428 | + static_call_cond(x86_pmu_sched_task)(ctx, sched_in); |
---|
| 2429 | +} |
---|
| 2430 | + |
---|
| 2431 | +static void x86_pmu_swap_task_ctx(struct perf_event_context *prev, |
---|
| 2432 | + struct perf_event_context *next) |
---|
| 2433 | +{ |
---|
| 2434 | + static_call_cond(x86_pmu_swap_task_ctx)(prev, next); |
---|
2244 | 2435 | } |
---|
2245 | 2436 | |
---|
2246 | 2437 | void perf_check_microcode(void) |
---|
.. | .. |
---|
2258 | 2449 | if (x86_pmu.limit_period(event, value) > value) |
---|
2259 | 2450 | return -EINVAL; |
---|
2260 | 2451 | } |
---|
| 2452 | + |
---|
| 2453 | + return 0; |
---|
| 2454 | +} |
---|
| 2455 | + |
---|
| 2456 | +static int x86_pmu_aux_output_match(struct perf_event *event) |
---|
| 2457 | +{ |
---|
| 2458 | + if (!(pmu.capabilities & PERF_PMU_CAP_AUX_OUTPUT)) |
---|
| 2459 | + return 0; |
---|
| 2460 | + |
---|
| 2461 | + if (x86_pmu.aux_output_match) |
---|
| 2462 | + return x86_pmu.aux_output_match(event); |
---|
2261 | 2463 | |
---|
2262 | 2464 | return 0; |
---|
2263 | 2465 | } |
---|
.. | .. |
---|
2285 | 2487 | |
---|
2286 | 2488 | .event_idx = x86_pmu_event_idx, |
---|
2287 | 2489 | .sched_task = x86_pmu_sched_task, |
---|
2288 | | - .task_ctx_size = sizeof(struct x86_perf_task_context), |
---|
| 2490 | + .swap_task_ctx = x86_pmu_swap_task_ctx, |
---|
2289 | 2491 | .check_period = x86_pmu_check_period, |
---|
| 2492 | + |
---|
| 2493 | + .aux_output_match = x86_pmu_aux_output_match, |
---|
2290 | 2494 | }; |
---|
2291 | 2495 | |
---|
2292 | 2496 | void arch_perf_update_userpage(struct perf_event *event, |
---|
.. | .. |
---|
2329 | 2533 | cyc2ns_read_end(); |
---|
2330 | 2534 | } |
---|
2331 | 2535 | |
---|
| 2536 | +/* |
---|
| 2537 | + * Determine whether the regs were taken from an irq/exception handler rather |
---|
| 2538 | + * than from perf_arch_fetch_caller_regs(). |
---|
| 2539 | + */ |
---|
| 2540 | +static bool perf_hw_regs(struct pt_regs *regs) |
---|
| 2541 | +{ |
---|
| 2542 | + return regs->flags & X86_EFLAGS_FIXED; |
---|
| 2543 | +} |
---|
| 2544 | + |
---|
2332 | 2545 | void |
---|
2333 | 2546 | perf_callchain_kernel(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) |
---|
2334 | 2547 | { |
---|
| 2548 | + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); |
---|
2335 | 2549 | struct unwind_state state; |
---|
2336 | 2550 | unsigned long addr; |
---|
2337 | 2551 | |
---|
2338 | | - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { |
---|
| 2552 | + if (guest_cbs && guest_cbs->is_in_guest()) { |
---|
2339 | 2553 | /* TODO: We don't support guest os callchain now */ |
---|
2340 | 2554 | return; |
---|
2341 | 2555 | } |
---|
.. | .. |
---|
2343 | 2557 | if (perf_callchain_store(entry, regs->ip)) |
---|
2344 | 2558 | return; |
---|
2345 | 2559 | |
---|
2346 | | - for (unwind_start(&state, current, regs, NULL); !unwind_done(&state); |
---|
2347 | | - unwind_next_frame(&state)) { |
---|
| 2560 | + if (perf_hw_regs(regs)) |
---|
| 2561 | + unwind_start(&state, current, regs, NULL); |
---|
| 2562 | + else |
---|
| 2563 | + unwind_start(&state, current, NULL, (void *)regs->sp); |
---|
| 2564 | + |
---|
| 2565 | + for (; !unwind_done(&state); unwind_next_frame(&state)) { |
---|
2348 | 2566 | addr = unwind_get_return_address(&state); |
---|
2349 | 2567 | if (!addr || perf_callchain_store(entry, addr)) |
---|
2350 | 2568 | return; |
---|
.. | .. |
---|
2395 | 2613 | /* 32-bit process in 64-bit kernel. */ |
---|
2396 | 2614 | unsigned long ss_base, cs_base; |
---|
2397 | 2615 | struct stack_frame_ia32 frame; |
---|
2398 | | - const void __user *fp; |
---|
| 2616 | + const struct stack_frame_ia32 __user *fp; |
---|
2399 | 2617 | |
---|
2400 | 2618 | if (!test_thread_flag(TIF_IA32)) |
---|
2401 | 2619 | return 0; |
---|
.. | .. |
---|
2406 | 2624 | fp = compat_ptr(ss_base + regs->bp); |
---|
2407 | 2625 | pagefault_disable(); |
---|
2408 | 2626 | while (entry->nr < entry->max_stack) { |
---|
2409 | | - unsigned long bytes; |
---|
2410 | | - frame.next_frame = 0; |
---|
2411 | | - frame.return_address = 0; |
---|
2412 | | - |
---|
2413 | 2627 | if (!valid_user_frame(fp, sizeof(frame))) |
---|
2414 | 2628 | break; |
---|
2415 | 2629 | |
---|
2416 | | - bytes = __copy_from_user_nmi(&frame.next_frame, fp, 4); |
---|
2417 | | - if (bytes != 0) |
---|
| 2630 | + if (__get_user(frame.next_frame, &fp->next_frame)) |
---|
2418 | 2631 | break; |
---|
2419 | | - bytes = __copy_from_user_nmi(&frame.return_address, fp+4, 4); |
---|
2420 | | - if (bytes != 0) |
---|
| 2632 | + if (__get_user(frame.return_address, &fp->return_address)) |
---|
2421 | 2633 | break; |
---|
2422 | 2634 | |
---|
2423 | 2635 | perf_callchain_store(entry, cs_base + frame.return_address); |
---|
.. | .. |
---|
2437 | 2649 | void |
---|
2438 | 2650 | perf_callchain_user(struct perf_callchain_entry_ctx *entry, struct pt_regs *regs) |
---|
2439 | 2651 | { |
---|
| 2652 | + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); |
---|
2440 | 2653 | struct stack_frame frame; |
---|
2441 | | - const unsigned long __user *fp; |
---|
| 2654 | + const struct stack_frame __user *fp; |
---|
2442 | 2655 | |
---|
2443 | | - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { |
---|
| 2656 | + if (guest_cbs && guest_cbs->is_in_guest()) { |
---|
2444 | 2657 | /* TODO: We don't support guest os callchain now */ |
---|
2445 | 2658 | return; |
---|
2446 | 2659 | } |
---|
.. | .. |
---|
2451 | 2664 | if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM)) |
---|
2452 | 2665 | return; |
---|
2453 | 2666 | |
---|
2454 | | - fp = (unsigned long __user *)regs->bp; |
---|
| 2667 | + fp = (void __user *)regs->bp; |
---|
2455 | 2668 | |
---|
2456 | 2669 | perf_callchain_store(entry, regs->ip); |
---|
2457 | 2670 | |
---|
.. | .. |
---|
2463 | 2676 | |
---|
2464 | 2677 | pagefault_disable(); |
---|
2465 | 2678 | while (entry->nr < entry->max_stack) { |
---|
2466 | | - unsigned long bytes; |
---|
2467 | | - |
---|
2468 | | - frame.next_frame = NULL; |
---|
2469 | | - frame.return_address = 0; |
---|
2470 | | - |
---|
2471 | 2679 | if (!valid_user_frame(fp, sizeof(frame))) |
---|
2472 | 2680 | break; |
---|
2473 | 2681 | |
---|
2474 | | - bytes = __copy_from_user_nmi(&frame.next_frame, fp, sizeof(*fp)); |
---|
2475 | | - if (bytes != 0) |
---|
| 2682 | + if (__get_user(frame.next_frame, &fp->next_frame)) |
---|
2476 | 2683 | break; |
---|
2477 | | - bytes = __copy_from_user_nmi(&frame.return_address, fp + 1, sizeof(*fp)); |
---|
2478 | | - if (bytes != 0) |
---|
| 2684 | + if (__get_user(frame.return_address, &fp->return_address)) |
---|
2479 | 2685 | break; |
---|
2480 | 2686 | |
---|
2481 | 2687 | perf_callchain_store(entry, frame.return_address); |
---|
.. | .. |
---|
2524 | 2730 | |
---|
2525 | 2731 | unsigned long perf_instruction_pointer(struct pt_regs *regs) |
---|
2526 | 2732 | { |
---|
2527 | | - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) |
---|
2528 | | - return perf_guest_cbs->get_guest_ip(); |
---|
| 2733 | + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); |
---|
| 2734 | + |
---|
| 2735 | + if (guest_cbs && guest_cbs->is_in_guest()) |
---|
| 2736 | + return guest_cbs->get_guest_ip(); |
---|
2529 | 2737 | |
---|
2530 | 2738 | return regs->ip + code_segment_base(regs); |
---|
2531 | 2739 | } |
---|
2532 | 2740 | |
---|
2533 | 2741 | unsigned long perf_misc_flags(struct pt_regs *regs) |
---|
2534 | 2742 | { |
---|
| 2743 | + struct perf_guest_info_callbacks *guest_cbs = perf_get_guest_cbs(); |
---|
2535 | 2744 | int misc = 0; |
---|
2536 | 2745 | |
---|
2537 | | - if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) { |
---|
2538 | | - if (perf_guest_cbs->is_user_mode()) |
---|
| 2746 | + if (guest_cbs && guest_cbs->is_in_guest()) { |
---|
| 2747 | + if (guest_cbs->is_user_mode()) |
---|
2539 | 2748 | misc |= PERF_RECORD_MISC_GUEST_USER; |
---|
2540 | 2749 | else |
---|
2541 | 2750 | misc |= PERF_RECORD_MISC_GUEST_KERNEL; |
---|