svn commit: r295560 - head/sys/dev/hwpmc
Adrian Chadd
adrian.chadd at gmail.com
Fri Feb 12 16:06:54 UTC 2016
Hah great catch! I always wondered about this!
-a
On 11 February 2016 at 23:27, Konstantin Belousov <kib at freebsd.org> wrote:
> 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 at 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.
>
More information about the svn-src-all
mailing list