// SPDX-License-Identifier: GPL-2.0 /* * local apic based NMI watchdog for various CPUs. * * This file also handles reservation of performance counters for coordination * with other users. * * Note that these events normally don't tick when the CPU idles. This means * the frequency varies with CPU load. * * Original code for K7/P6 written by Keith Owens *
*/
/* * this number is calculated from Intel's MSR_P4_CRU_ESCR5 register and it's * offset from MSR_P4_BSU_ESCR0. * * It will be the max for all platforms (for now)
*/ #define NMI_MAX_COUNTER_BITS 66
/* * perfctr_nmi_owner tracks the ownership of the perfctr registers: * evtsel_nmi_owner tracks the ownership of the event selection * - different performance counters/ event selection may be reserved for * different subsystems this reservation system just tries to coordinate * things a little
*/ static DECLARE_BITMAP(perfctr_nmi_owner, NMI_MAX_COUNTER_BITS); static DECLARE_BITMAP(evntsel_nmi_owner, NMI_MAX_COUNTER_BITS);
/* converts an msr to an appropriate reservation bit */ staticinlineunsignedint nmi_perfctr_msr_to_bit(unsignedint msr)
{ /* returns the bit offset of the performance counter register */ switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_HYGON: case X86_VENDOR_AMD: if (msr >= MSR_F15H_PERF_CTR) return (msr - MSR_F15H_PERF_CTR) >> 1; return msr - MSR_K7_PERFCTR0; case X86_VENDOR_INTEL: if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) return msr - MSR_ARCH_PERFMON_PERFCTR0;
switch (boot_cpu_data.x86) { case 6: return msr - MSR_P6_PERFCTR0; case 11: return msr - MSR_KNC_PERFCTR0; case 15: return msr - MSR_P4_BPU_PERFCTR0;
} break; case X86_VENDOR_ZHAOXIN: case X86_VENDOR_CENTAUR: return msr - MSR_ARCH_PERFMON_PERFCTR0;
} return 0;
}
/* * converts an msr to an appropriate reservation bit * returns the bit offset of the event selection register
*/ staticinlineunsignedint nmi_evntsel_msr_to_bit(unsignedint msr)
{ /* returns the bit offset of the event selection register */ switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_HYGON: case X86_VENDOR_AMD: if (msr >= MSR_F15H_PERF_CTL) return (msr - MSR_F15H_PERF_CTL) >> 1; return msr - MSR_K7_EVNTSEL0; case X86_VENDOR_INTEL: if (cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) return msr - MSR_ARCH_PERFMON_EVENTSEL0;
switch (boot_cpu_data.x86) { case 6: return msr - MSR_P6_EVNTSEL0; case 11: return msr - MSR_KNC_EVNTSEL0; case 15: return msr - MSR_P4_BSU_ESCR0;
} break; case X86_VENDOR_ZHAOXIN: case X86_VENDOR_CENTAUR: return msr - MSR_ARCH_PERFMON_EVENTSEL0;
} return 0;
}
int reserve_perfctr_nmi(unsignedint msr)
{ unsignedint counter;
counter = nmi_perfctr_msr_to_bit(msr); /* register not managed by the allocator? */ if (counter > NMI_MAX_COUNTER_BITS) return 1;
if (!test_and_set_bit(counter, perfctr_nmi_owner)) return 1; return 0;
}
EXPORT_SYMBOL(reserve_perfctr_nmi);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.