Date: Fri, 12 Feb 2016 07:27:24 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r295560 - head/sys/dev/hwpmc Message-ID: <201602120727.u1C7ROYF090987@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Fri Feb 12 07:27:24 2016 New Revision: 295560 URL: https://svnweb.freebsd.org/changeset/base/295560 Log: If full width writes to the performance monitoring counters are supported, use full-width aliases MSRs for writes. This fixes the "[pmc,X] negative increment" assertion on the context switch when clipped counter value is sign-extended. Add definitions for the MSR IA32_PERF_CAPABILITIES needed to detect the feature. PR: 207068 Submitted by: joss.upton@yahoo.com MFC after: 2 weeks Modified: head/sys/dev/hwpmc/hwpmc_core.c head/sys/dev/hwpmc/hwpmc_core.h Modified: head/sys/dev/hwpmc/hwpmc_core.c ============================================================================== --- head/sys/dev/hwpmc/hwpmc_core.c Fri Feb 12 07:20:27 2016 (r295559) +++ head/sys/dev/hwpmc/hwpmc_core.c Fri Feb 12 07:27:24 2016 (r295560) @@ -103,6 +103,7 @@ static int core_iaf_npmc; static int core_iap_width; static int core_iap_npmc; +static int core_iap_wroffset; static int core_pcpu_noop(struct pmc_mdep *md, int cpu) @@ -2473,7 +2474,7 @@ iap_read_pmc(int cpu, int ri, pmc_value_ *v = tmp & ((1ULL << core_iap_width) - 1); PMCDBG4(MDP,REA,1, "iap-read cpu=%d ri=%d msr=0x%x -> v=%jx", cpu, ri, - ri, *v); + IAP_PMC0 + ri, *v); return (0); } @@ -2605,19 +2606,20 @@ iap_write_pmc(int cpu, int ri, pmc_value ("[core,%d] cpu%d ri%d no configured PMC to stop", __LINE__, cpu, ri)); - PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, - IAP_PMC0 + ri, v); - if (PMC_IS_SAMPLING_MODE(PMC_TO_MODE(pm))) v = iap_reload_count_to_perfctr_value(v); - /* - * Write the new value to the counter. The counter will be in - * a stopped state when the pcd_write() entry point is called. - */ + v &= (1ULL << core_iap_width) - 1; - wrmsr(IAP_PMC0 + ri, v & ((1ULL << core_iap_width) - 1)); + PMCDBG4(MDP,WRI,1, "iap-write cpu=%d ri=%d msr=0x%x v=%jx", cpu, ri, + IAP_PMC0 + ri, v); + /* + * Write the new value to the counter (or it's alias). The + * counter will be in a stopped state when the pcd_write() + * entry point is called. + */ + wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v); return (0); } @@ -2700,7 +2702,7 @@ core_intr(int cpu, struct trapframe *tf) */ msr = rdmsr(IAP_EVSEL0 + ri) & ~IAP_EVSEL_MASK; wrmsr(IAP_EVSEL0 + ri, msr); - wrmsr(IAP_PMC0 + ri, v); + wrmsr(core_iap_wroffset + IAP_PMC0 + ri, v); if (error) continue; @@ -2814,7 +2816,7 @@ core2_intr(int cpu, struct trapframe *tf (uintmax_t) v); /* Reload sampling count. */ - wrmsr(IAP_PMC0 + n, v); + wrmsr(core_iap_wroffset + IAP_PMC0 + n, v); } /* @@ -2865,6 +2867,18 @@ pmc_core_initialize(struct pmc_mdep *md, return (EPROGMISMATCH); } + core_iap_wroffset = 0; + if (cpu_feature2 & CPUID2_PDCM) { + if (rdmsr(IA32_PERF_CAPABILITIES) & PERFCAP_FW_WRITE) { + PMCDBG0(MDP, INI, 1, + "core-init full-width write supported"); + core_iap_wroffset = IAP_A_PMC0 - IAP_PMC0; + } else + PMCDBG0(MDP, INI, 1, + "core-init full-width write NOT supported"); + } else + PMCDBG0(MDP, INI, 1, "core-init pdcm not supported"); + core_pmcmask = 0; /* Modified: head/sys/dev/hwpmc/hwpmc_core.h ============================================================================== --- head/sys/dev/hwpmc/hwpmc_core.h Fri Feb 12 07:20:27 2016 (r295559) +++ head/sys/dev/hwpmc/hwpmc_core.h Fri Feb 12 07:27:24 2016 (r295560) @@ -29,6 +29,14 @@ #ifndef _DEV_HWPMC_CORE_H_ #define _DEV_HWPMC_CORE_H_ 1 +#define IA32_PERF_CAPABILITIES 0x345 +#define PERFCAP_LBR_FORMAT 0x003f +#define PERFCAP_PEBS_TRAP 0x0040 +#define PERFCAP_PEBS_SAVEARCH 0x0080 +#define PERFCAP_PEBS_RECFORMAT 0x0f00 +#define PERFCAP_SMM_FREEZE 0x1000 +#define PERFCAP_FW_WRITE 0x2000 /* full width write aliases */ + /* * Fixed-function PMCs. */ @@ -101,6 +109,7 @@ struct pmc_md_iap_op_pmcallocate { */ #define IAP_PMC0 0x0C1 +#define IAP_A_PMC0 0x4C1 /* * IAP_EVSEL(n) is laid out in the following way.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201602120727.u1C7ROYF090987>