Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch Support PMCs on multi-processor systems. Still seve...



details:   https://anonhg.NetBSD.org/src/rev/a2973c37dc1c
branches:  trunk
changeset: 821804:a2973c37dc1c
user:      maxv <maxv%NetBSD.org@localhost>
date:      Fri Feb 17 12:10:40 2017 +0000

description:
Support PMCs on multi-processor systems. Still several things to fix, but
at least it works a little. Will be improved and moved into x86/ soon.

diffstat:

 sys/arch/i386/conf/GENERIC     |    5 +-
 sys/arch/i386/conf/files.i386  |    5 +-
 sys/arch/i386/i386/machdep.c   |    7 +-
 sys/arch/i386/i386/pmc.c       |  366 ++++++++++++++++++++++++----------------
 sys/arch/i386/include/pmc.h    |   15 +-
 sys/arch/x86/x86/sys_machdep.c |   16 +-
 6 files changed, 241 insertions(+), 173 deletions(-)

diffs (truncated from 634 to 300 lines):

diff -r 2327c25019a3 -r a2973c37dc1c sys/arch/i386/conf/GENERIC
--- a/sys/arch/i386/conf/GENERIC        Fri Feb 17 11:57:26 2017 +0000
+++ b/sys/arch/i386/conf/GENERIC        Fri Feb 17 12:10:40 2017 +0000
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.1146 2017/01/12 05:24:36 ryo Exp $
+# $NetBSD: GENERIC,v 1.1147 2017/02/17 12:10:40 maxv Exp $
 #
 # GENERIC machine description file
 #
@@ -22,7 +22,7 @@
 
 options        INCLUDE_CONFIG_FILE     # embed config file in kernel binary
 
-#ident         "GENERIC-$Revision: 1.1146 $"
+#ident         "GENERIC-$Revision: 1.1147 $"
 
 maxusers       64              # estimated number of users
 
@@ -42,7 +42,6 @@
 vmt0           at cpu0         # VMware Tools
 
 options        MTRR            # memory-type range register syscall support
-# doesn't work with MP just yet..
 #options       PERFCTRS        # performance-monitoring counters support
 
 options        MULTIBOOT       # Multiboot support (see multiboot(8))
diff -r 2327c25019a3 -r a2973c37dc1c sys/arch/i386/conf/files.i386
--- a/sys/arch/i386/conf/files.i386     Fri Feb 17 11:57:26 2017 +0000
+++ b/sys/arch/i386/conf/files.i386     Fri Feb 17 12:10:40 2017 +0000
@@ -1,4 +1,4 @@
-#      $NetBSD: files.i386,v 1.376 2016/12/15 12:04:18 kamil Exp $
+#      $NetBSD: files.i386,v 1.377 2017/02/17 12:10:40 maxv Exp $
 #
 # new style config file for i386 architecture
 #
@@ -74,6 +74,7 @@
 file   arch/i386/i386/machdep.c
 file   arch/i386/i386/longrun.c
 file   arch/i386/i386/mtrr_k6.c        mtrr
+file   arch/i386/i386/pmc.c
 file   arch/i386/i386/process_machdep.c
 file   arch/x86/x86/convert_xmm_s87.c
 file   arch/i386/i386/trap.c
@@ -83,8 +84,6 @@
 
 file   arch/i386/i386/mptramp.S        multiprocessor
 
-file   arch/i386/i386/pmc.c            perfctrs
-
 file   crypto/des/arch/i386/des_enc.S          des
 file   crypto/des/arch/i386/des_cbc.S          des
 
diff -r 2327c25019a3 -r a2973c37dc1c sys/arch/i386/i386/machdep.c
--- a/sys/arch/i386/i386/machdep.c      Fri Feb 17 11:57:26 2017 +0000
+++ b/sys/arch/i386/i386/machdep.c      Fri Feb 17 12:10:40 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: machdep.c,v 1.778 2017/02/05 10:42:21 maxv Exp $       */
+/*     $NetBSD: machdep.c,v 1.779 2017/02/17 12:10:40 maxv Exp $       */
 
 /*-
  * Copyright (c) 1996, 1997, 1998, 2000, 2004, 2006, 2008, 2009
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.778 2017/02/05 10:42:21 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: machdep.c,v 1.779 2017/02/17 12:10:40 maxv Exp $");
 
 #include "opt_beep.h"
 #include "opt_compat_ibcs2.h"
@@ -135,6 +135,7 @@
 #include <machine/intr.h>
 #include <machine/kcore.h>
 #include <machine/pio.h>
+#include <machine/pmc.h>
 #include <machine/psl.h>
 #include <machine/reg.h>
 #include <machine/specialreg.h>
@@ -1402,6 +1403,8 @@
        }
 
        rw_init(&svr4_fasttrap_lock);
+
+       pmc_init();
 }
 
 #include <dev/ic/mc146818reg.h>                /* for NVRAM POST */
diff -r 2327c25019a3 -r a2973c37dc1c sys/arch/i386/i386/pmc.c
--- a/sys/arch/i386/i386/pmc.c  Fri Feb 17 11:57:26 2017 +0000
+++ b/sys/arch/i386/i386/pmc.c  Fri Feb 17 12:10:40 2017 +0000
@@ -1,6 +1,35 @@
-/*     $NetBSD: pmc.c,v 1.21 2013/11/21 22:04:40 riz Exp $     */
+/*     $NetBSD: pmc.c,v 1.22 2017/02/17 12:10:40 maxv Exp $    */
 
-/*-
+/*
+ * Copyright (c) 2017 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Maxime Villard.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
  * Copyright (c) 2000 Zembu Labs, Inc.
  * All rights reserved.
  *
@@ -38,11 +67,13 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmc.c,v 1.21 2013/11/21 22:04:40 riz Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmc.c,v 1.22 2017/02/17 12:10:40 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/proc.h>
+#include <sys/cpu.h>
+#include <sys/xcall.h>
 
 #include <machine/cpufunc.h>
 #include <machine/cpuvar.h>
@@ -52,37 +83,142 @@
 #include <machine/cpu_counter.h>
 #include <machine/cputypes.h>
 
-static int pmc_initialized;
-static int pmc_ncounters;
-static int pmc_type;
-static int pmc_flags;
+typedef struct {
+       bool running;
+       uint32_t evtmsr;        /* event selector MSR */
+       uint64_t evtval;        /* event selector value */
+       uint32_t ctrmsr;        /* counter MSR */
+       uint64_t ctrval;        /* counter value */
+       uint64_t tsc;
+} pmc_state_t;
+
+static uint64_t pmc_val_cpus[MAXCPUS] __aligned(CACHE_LINE_SIZE);
+static kmutex_t pmc_lock;
+
+static pmc_state_t pmc_state[PMC_NCOUNTERS];
+static int pmc_ncounters __read_mostly;
+static int pmc_type __read_mostly;
+static int pmc_flags __read_mostly;
+
+static void
+pmc_read_cpu(void *arg1, void *arg2)
+{
+       pmc_state_t *pmc = (pmc_state_t *)arg1;
+       struct cpu_info *ci = curcpu();
+
+       pmc_val_cpus[cpu_index(ci)] = rdmsr(pmc->ctrmsr) & 0xffffffffffULL;
+}
 
-static struct pmc_state {
-       uint64_t pmcs_val;
-       uint64_t pmcs_tsc;
-       uint64_t pmcs_control;
-       uint32_t pmcs_ctrmsr;
-} pmc_state[PMC_NCOUNTERS];
+static void
+pmc_read(pmc_state_t *pmc)
+{
+       uint64_t xc;
+       size_t i;
+
+       xc = xc_broadcast(0, pmc_read_cpu, pmc, NULL);
+       xc_wait(xc);
+
+       pmc->ctrval = 0;
+       for (i = 0; i < ncpu; i++) {
+               /* XXX: really shitty */
+               pmc->ctrval += pmc_val_cpus[i];
+       }
+}
 
-static int pmc_running;
+static void
+pmc_apply_cpu(void *arg1, void *arg2)
+{
+       pmc_state_t *pmc = (pmc_state_t *)arg1;
+
+       wrmsr(pmc->ctrmsr, pmc->ctrval);
+       switch (pmc_type) {
+       case PMC_TYPE_I586:
+               wrmsr(MSR_CESR, pmc_state[0].evtval |
+                   (pmc_state[1].evtval << 16));
+               break;
+
+       case PMC_TYPE_I686:
+       case PMC_TYPE_K7:
+               wrmsr(pmc->evtmsr, pmc->evtval);
+               break;
+       }
+}
 
 static void
+pmc_apply(pmc_state_t *pmc)
+{
+       uint64_t xc;
+
+       xc = xc_broadcast(0, pmc_apply_cpu, pmc, NULL);
+       xc_wait(xc);
+}
+
+static void
+pmc_start(pmc_state_t *pmc, struct x86_pmc_startstop_args *args)
+{
+       pmc->running = true;
+
+       /*
+        * Initialize the counter MSR.
+        */
+       pmc->ctrval = args->val;
+
+       /*
+        * Initialize the event MSR.
+        */
+       switch (pmc_type) {
+       case PMC_TYPE_I586:
+               pmc->evtval = args->event |
+                   ((args->flags & PMC_SETUP_KERNEL) ? PMC5_CESR_OS : 0) |
+                   ((args->flags & PMC_SETUP_USER) ? PMC5_CESR_USR : 0) |
+                   ((args->flags & PMC_SETUP_EDGE) ? PMC5_CESR_E : 0);
+               break;
+
+       case PMC_TYPE_I686:
+               pmc->evtval = args->event | PMC6_EVTSEL_EN |
+                   (args->unit << PMC6_EVTSEL_UNIT_SHIFT) |
+                   ((args->flags & PMC_SETUP_KERNEL) ? PMC6_EVTSEL_OS : 0) |
+                   ((args->flags & PMC_SETUP_USER) ? PMC6_EVTSEL_USR : 0) |
+                   ((args->flags & PMC_SETUP_EDGE) ? PMC6_EVTSEL_E : 0) |
+                   ((args->flags & PMC_SETUP_INV) ? PMC6_EVTSEL_INV : 0) |
+                   (args->compare << PMC6_EVTSEL_COUNTER_MASK_SHIFT);
+               break;
+
+       case PMC_TYPE_K7:
+               args->event &= K7_EVTSEL_EVENT;
+               args->unit = (args->unit << K7_EVTSEL_UNIT_SHIFT) &
+                   K7_EVTSEL_UNIT;
+               pmc->evtval = args->event | args->unit | K7_EVTSEL_EN |
+                   ((args->flags & PMC_SETUP_KERNEL) ? K7_EVTSEL_OS : 0) |
+                   ((args->flags & PMC_SETUP_USER) ? K7_EVTSEL_USR : 0) |
+                   ((args->flags & PMC_SETUP_EDGE) ? K7_EVTSEL_E : 0) |
+                   ((args->flags & PMC_SETUP_INV) ? K7_EVTSEL_INV : 0) |
+                   (args->compare << K7_EVTSEL_COUNTER_MASK_SHIFT);
+               break;
+       }
+
+       /*
+        * Apply the changes.
+        */
+       pmc_apply(pmc);
+}
+
+static void
+pmc_stop(pmc_state_t *pmc, struct x86_pmc_startstop_args *args)
+{
+       pmc->running = false;
+       pmc->evtval = 0;
+       pmc_apply(pmc);
+}
+
+void
 pmc_init(void)
 {
        const char *cpu_vendorstr;
        struct cpu_info *ci;
 
-       if (pmc_initialized)
-               return;
-
        pmc_type = PMC_TYPE_NONE;
 
-#ifdef MULTIPROCESSOR
-       /* XXX */
-       if (ncpu > 1)



Home | Main Index | Thread Index | Old Index