Source-Changes-HG archive

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

[src/trunk]: src Switch to per-CPU PMC results, and completely rewrite the pm...



details:   https://anonhg.NetBSD.org/src/rev/6ec946443dab
branches:  trunk
changeset: 352010:6ec946443dab
user:      maxv <maxv%NetBSD.org@localhost>
date:      Fri Mar 10 13:09:11 2017 +0000

description:
Switch to per-CPU PMC results, and completely rewrite the pmc(1) tool. Now
the PMCs are system-wide, fine-grained and more tunable by the user.

We don't do application tracking, since it would require to store the PMC
values in mdproc and starting/stopping the counters on each context switch.
While this doesn't seem to be particularly difficult to achieve, I don't
think it is really interesting; and if someone really wants to measure
the performance of an application, they can simply schedctl it to a cpu
and look at the PMC results for this cpu.

Note that several options are implemented but not yet used.

diffstat:

 sys/arch/i386/i386/pmc.c       |   49 ++--
 sys/arch/x86/include/sysarch.h |   15 +-
 usr.bin/pmc/pmc.1              |  133 +++++++++-----
 usr.bin/pmc/pmc.c              |  383 ++++++++++++++++++++++++----------------
 4 files changed, 352 insertions(+), 228 deletions(-)

diffs (truncated from 832 to 300 lines):

diff -r ca6249ee1fd0 -r 6ec946443dab sys/arch/i386/i386/pmc.c
--- a/sys/arch/i386/i386/pmc.c  Fri Mar 10 09:13:49 2017 +0000
+++ b/sys/arch/i386/i386/pmc.c  Fri Mar 10 13:09:11 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pmc.c,v 1.24 2017/03/08 16:42:27 maxv Exp $    */
+/*     $NetBSD: pmc.c,v 1.25 2017/03/10 13:09:11 maxv Exp $    */
 
 /*
  * Copyright (c) 2017 The NetBSD Foundation, Inc.
@@ -67,7 +67,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pmc.c,v 1.24 2017/03/08 16:42:27 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pmc.c,v 1.25 2017/03/10 13:09:11 maxv Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -88,17 +88,15 @@
        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;
+       uint64_t ctrval;        /* initial counter value */
 } pmc_state_t;
 
-static uint64_t pmc_val_cpus[MAXCPUS] __aligned(CACHE_LINE_SIZE);
+static x86_pmc_cpuval_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)
@@ -106,29 +104,25 @@
        pmc_state_t *pmc = (pmc_state_t *)arg1;
        struct cpu_info *ci = curcpu();
 
-       pmc_val_cpus[cpu_index(ci)] = rdmsr(pmc->ctrmsr) & 0xffffffffffULL;
+       pmc_val_cpus[cpu_index(ci)].ctrval =
+           rdmsr(pmc->ctrmsr) & 0xffffffffffULL;
+       pmc_val_cpus[cpu_index(ci)].overfl = 0;
 }
 
 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 void
 pmc_apply_cpu(void *arg1, void *arg2)
 {
        pmc_state_t *pmc = (pmc_state_t *)arg1;
+       struct cpu_info *ci = curcpu();
 
        wrmsr(pmc->ctrmsr, pmc->ctrval);
        switch (pmc_type) {
@@ -142,6 +136,9 @@
                wrmsr(pmc->evtmsr, pmc->evtval);
                break;
        }
+
+       pmc_val_cpus[cpu_index(ci)].ctrval = 0;
+       pmc_val_cpus[cpu_index(ci)].overfl = 0;
 }
 
 static void
@@ -210,6 +207,7 @@
 {
        pmc->running = false;
        pmc->evtval = 0;
+       pmc->ctrval = 0;
        pmc_apply(pmc);
 }
 
@@ -262,9 +260,6 @@
                break;
        }
 
-       if (pmc_type != PMC_TYPE_NONE && cpu_hascounter())
-               pmc_flags |= PMC_INFO_HASTSC;
-
        mutex_init(&pmc_lock, MUTEX_DEFAULT, IPL_NONE);
 }
 
@@ -277,7 +272,7 @@
 
        rv.vers = PMC_VERSION;
        rv.type = pmc_type;
-       rv.flags = pmc_flags;
+       rv.nctrs = pmc_ncounters;
 
        return copyout(&rv, uargs, sizeof(rv));
 }
@@ -330,6 +325,7 @@
 {
        struct x86_pmc_read_args args;
        pmc_state_t *pmc;
+       size_t nval;
        int error;
 
        if (pmc_type == PMC_TYPE_NONE)
@@ -341,20 +337,27 @@
 
        if (args.counter >= pmc_ncounters)
                return EINVAL;
+       if (args.values == NULL)
+               return EINVAL;
+       nval = MIN(ncpu, args.nval);
+
        pmc = &pmc_state[args.counter];
 
        mutex_enter(&pmc_lock);
 
        if (pmc->running) {
                pmc_read(pmc);
-               if (pmc_flags & PMC_INFO_HASTSC)
-                       pmc->tsc = cpu_counter();
+               error = copyout(&pmc_val_cpus, args.values,
+                   nval * sizeof(x86_pmc_cpuval_t));
+               args.nval = nval;
+       } else {
+               error = ENOENT;
        }
 
-       args.val = pmc->ctrval;
-       args.time = pmc->tsc;
-
        mutex_exit(&pmc_lock);
 
+       if (error)
+               return error;
+
        return copyout(&args, uargs, sizeof(args));
 }
diff -r ca6249ee1fd0 -r 6ec946443dab sys/arch/x86/include/sysarch.h
--- a/sys/arch/x86/include/sysarch.h    Fri Mar 10 09:13:49 2017 +0000
+++ b/sys/arch/x86/include/sysarch.h    Fri Mar 10 13:09:11 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: sysarch.h,v 1.10 2017/03/08 16:42:27 maxv Exp $        */
+/*     $NetBSD: sysarch.h,v 1.11 2017/03/10 13:09:11 maxv Exp $        */
 
 /*-
  * Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -133,7 +133,7 @@
 struct _X86_SYSARCH_L(pmc_info_args) {
        int vers;
        int type;
-       int flags;
+       uint32_t nctrs;
 };
 
 #define        PMC_VERSION             1
@@ -162,10 +162,15 @@
 #define        PMC_SETUP_EDGE          0x04
 #define        PMC_SETUP_INV           0x08
 
+typedef struct {
+       uint64_t ctrval;
+       uint32_t overfl;
+} x86_pmc_cpuval_t;
+
 struct _X86_SYSARCH_L(pmc_read_args) {
-       int counter;
-       uint64_t val;
-       uint64_t time;
+       uint32_t counter;
+       x86_pmc_cpuval_t *values;
+       uint32_t nval;
 };
 
 struct mtrr;
diff -r ca6249ee1fd0 -r 6ec946443dab usr.bin/pmc/pmc.1
--- a/usr.bin/pmc/pmc.1 Fri Mar 10 09:13:49 2017 +0000
+++ b/usr.bin/pmc/pmc.1 Fri Mar 10 13:09:11 2017 +0000
@@ -1,4 +1,31 @@
-.\"    $NetBSD: pmc.1,v 1.9 2014/03/18 18:20:45 riastradh Exp $
+.\"    $NetBSD: pmc.1,v 1.10 2017/03/10 13:09:11 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.
@@ -31,77 +58,87 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd October 24, 2000
+.Dd March 10, 2017
 .Dt PMC 1
 .Os
 .Sh NAME
 .Nm pmc
-.Nd performance-monitoring counter interface for command execution
+.Nd performance-monitoring counter interface
 .Sh SYNOPSIS
-.Nm
-.Fl h
-.Nm
-.Fl C
-.Nm
-.Fl c
-.Ar event
+.Nm pmc
 .Ar command
-.Oo
-.Ar options
-.Ar ...
-.Oc
+.Op Ar arguments
 .Sh DESCRIPTION
+The
 .Nm
-is a means of using a processor's performance-monitoring counter (PMC)
-facility to measure various aspects of a program's execution.
-It is
-meant to be used in a fashion similar to
-.Xr time 1 .
+command can be used to control and inspect the state of CPUs in the system.
 .Pp
-The arguments are as follows:
-.Bl -tag -width indent
-.It Fl h
-Display a list of performance counter events available on
-the system.
-.It Fl C
-Cancel any performance counters that are currently running.
-.It Fl c Ar event
-Count the event specified by
-.Ar event
-while running the command.
+The first argument,
+.Ar command ,
+specifies the action to take.
+Valid commands are:
+.Bl -tag -width offline
+.It list
+Display a list of performance counter events available on the system.
+.It start Ar name:option Op Ar name:option ...
+Start one or several counters.
+.Ar name
+specifies the name of the event to count; it must be taken from the list of
+available events.
+.Ar option
+specifies the source of the event; it must be a combination of
+.Ar u
+(userland) and
+.Ar k
+(kernel).
+.It stop
+Stop any performance counters that are currently running, and display the
+values of these counters.
 .El
+.Sh EXAMPLES
+.Pp
+The following command prints the available counters.
+.Dl $ pmc list
+.Pp
+The following command starts two counters.
+The former will count the 'l2cache-access' events that are triggered from



Home | Main Index | Thread Index | Old Index