diff options
| author | Ali Mashtizadeh <ali@mashtizadeh.com> | 2026-04-20 22:06:30 +0000 |
|---|---|---|
| committer | Warner Losh <imp@FreeBSD.org> | 2026-04-24 16:23:05 +0000 |
| commit | 70ae0c4524d2c5d0aae3339e95f6bd4f3c480b6e (patch) | |
| tree | f341673e612b18b5103446e61530bc27bcd59e65 | |
| parent | 576c6e9620dff3e92f3c5d1e5be4d92c9eb29828 (diff) | |
i386: Remove perfmon performance monitoring facility
Remove the perfmon performance monitoring facility that was for Intel
Pentium and Pentium Pro processors.
Reviewed by: imp,mhorne,emaste
Pull Request: https://github.com/freebsd/freebsd-src/pull/2155
| -rw-r--r-- | ObsoleteFiles.inc | 8 | ||||
| -rw-r--r-- | etc/mtree/BSD.usr.dist | 2 | ||||
| -rw-r--r-- | share/examples/Makefile | 7 | ||||
| -rw-r--r-- | share/examples/perfmon/Makefile | 8 | ||||
| -rw-r--r-- | share/examples/perfmon/README | 23 | ||||
| -rw-r--r-- | share/examples/perfmon/perfmon.c | 191 | ||||
| -rw-r--r-- | share/man/man4/man4.i386/Makefile | 1 | ||||
| -rw-r--r-- | share/man/man4/man4.i386/perfmon.4 | 211 | ||||
| -rw-r--r-- | share/man/man7/clocks.7 | 4 | ||||
| -rw-r--r-- | sys/conf/files.i386 | 1 | ||||
| -rw-r--r-- | sys/i386/conf/NOTES | 6 | ||||
| -rw-r--r-- | sys/i386/i386/machdep.c | 7 | ||||
| -rw-r--r-- | sys/i386/i386/perfmon.c | 402 | ||||
| -rw-r--r-- | sys/i386/include/perfmon.h | 253 | ||||
| -rw-r--r-- | tools/build/mk/OptionalObsoleteFiles.inc | 4 |
15 files changed, 8 insertions, 1120 deletions
diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index a4fdac95bf5a..465508bf40a3 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -51,6 +51,14 @@ # xargs -n1 | sort | uniq -d; # done +# 20260420: remove perfmon +OLD_FILES+=boot/kernel/perfmon.ko +OLD_FILES+=usr/share/man/man4/perfmon.4.gz +OLD_FILES+=usr/share/examples/perfmon/Makefile +OLD_FILES+=usr/share/examples/perfmon/README +OLD_FILES+=usr/share/examples/perfmon/perfmon.c +OLD_DIRS+=usr/share/examples/perfmon + # 20260402: posix_spawn_file_actions_addchdir lost _np suffix OLD_FILES+=usr/share/man/man3/posix_spawn_file_actions_addchdir_np.3.gz OLD_FILES+=usr/share/man/man3/posix_spawn_file_actions_addfchdir_np.3.gz diff --git a/etc/mtree/BSD.usr.dist b/etc/mtree/BSD.usr.dist index b281a368861d..120b961d230c 100644 --- a/etc/mtree/BSD.usr.dist +++ b/etc/mtree/BSD.usr.dist @@ -346,8 +346,6 @@ .. netgraph .. - perfmon - .. pf .. ppi diff --git a/share/examples/Makefile b/share/examples/Makefile index d977f2e5a0da..dae84f27d9dc 100644 --- a/share/examples/Makefile +++ b/share/examples/Makefile @@ -22,7 +22,6 @@ LDIRS= BSD_daemon \ mdoc \ netgraph \ oci \ - perfmon \ ppi \ ppp \ ses \ @@ -202,12 +201,6 @@ SE_OCI= \ README \ Containerfile.pkg -SE_DIRS+= perfmon -SE_PERFMON= \ - Makefile \ - README \ - perfmon.c \ - .if ${MK_PF} != "no" SE_DIRS+= pf .if ${MK_STAGING} == "no" diff --git a/share/examples/perfmon/Makefile b/share/examples/perfmon/Makefile deleted file mode 100644 index 96712dee88e3..000000000000 --- a/share/examples/perfmon/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -PACKAGE=examples -FILESDIR=${SHAREDIR}/examples/${PROG} -PROG= perfmon -MAN= - -install: - -.include <bsd.prog.mk> diff --git a/share/examples/perfmon/README b/share/examples/perfmon/README deleted file mode 100644 index 25452813f3db..000000000000 --- a/share/examples/perfmon/README +++ /dev/null @@ -1,23 +0,0 @@ -`perfmon' is a sample program to access the performance-monitoring -counters on Pentium and Pentium Pro CPUs. See perfmon(4) for a -description of this facility. - -The program takes the following options: - - -u count events in user mode - -o count events in kernel mode - (these two can be combined) - - -e count events, not duration - -l n run `n' loops (default 50) - -s n sleep `n' seconds between loop iterations (default 0) - -The following options are not implemented on Pentium CPUs: - - -m n use count mask `n' - -i invert sense of count mask comparison - -U n use unit mask `n' - -There is one mandatory argument, which is the event number to be -monitored, defined in <machine/perfmon.h>. All numbers can be -specified in any format acceptable to strtol(3). diff --git a/share/examples/perfmon/perfmon.c b/share/examples/perfmon/perfmon.c deleted file mode 100644 index 1b7afad9d69e..000000000000 --- a/share/examples/perfmon/perfmon.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright 1996 Massachusetts Institute of Technology - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby - * granted, provided that both the above copyright notice and this - * permission notice appear in all copies, that both the above - * copyright notice and this permission notice appear in all - * supporting documentation, and that the name of M.I.T. not be used - * in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. M.I.T. makes - * no representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS - * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT - * SHALL M.I.T. 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. - */ - -#include <sys/types.h> -#include <sys/ioctl.h> - -#include <machine/cpu.h> -#include <machine/perfmon.h> - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <err.h> -#include <unistd.h> -#include <fcntl.h> -#include <limits.h> -#include <errno.h> - -static int getnum(const char *, int, int); -static void usage(const char *) __dead2; - -int -main(int argc, char **argv) -{ - int c, fd, num; - int loops, i, sleeptime; - char *cmd; - struct pmc pmc; - struct pmc_tstamp then, now; - struct pmc_data value; - quad_t *buf; - double total; - - pmc.pmc_num = 0; - pmc.pmc_event = 0; - pmc.pmc_unit = 0; - pmc.pmc_flags = 0; - pmc.pmc_mask = 0; - cmd = NULL; - loops = 50; - sleeptime = 0; - - while ((c = getopt(argc, argv, "s:l:uoeiU:m:c:")) != -1) { - switch(c) { - case 'u': - pmc.pmc_flags |= PMCF_USR; - break; - case 'o': - pmc.pmc_flags |= PMCF_OS; - break; - case 'e': - pmc.pmc_flags |= PMCF_E; - break; - case 'i': - pmc.pmc_flags |= PMCF_INV; - break; - case 'U': - pmc.pmc_unit = getnum(optarg, 0, 256); - break; - case 'm': - pmc.pmc_mask = getnum(optarg, 0, 256); - break; - case 'l': - loops = getnum(optarg, 1, INT_MAX - 1); - break; - case 's': - sleeptime = getnum(optarg, 0, INT_MAX - 1); - break; - case 'c': - cmd = optarg; - break; - default: - usage(argv[0]); - } - } - - if (argc - optind != 1) - usage(argv[0]); - - pmc.pmc_event = getnum(argv[optind], 0, 255); - - buf = malloc((loops + 1) * sizeof *buf); - if (!buf) - err(1, "malloc(%lu)", (unsigned long)(loops +1) * sizeof *buf); - - fd = open(_PATH_PERFMON, O_RDWR, 0); - if (fd < 0) - err(1, "open: " _PATH_PERFMON); - - if (ioctl(fd, PMIOSETUP, &pmc) < 0) - err(1, "ioctl(PMIOSETUP)"); - - if (ioctl(fd, PMIOTSTAMP, &then) < 0) - err(1, "ioctl(PMIOTSTAMP)"); - - num = 0; - if (ioctl(fd, PMIOSTART, &num) < 0) - err(1, "ioctl(PMIOSTART)"); - - value.pmcd_num = 0; - for (i = 0; i < loops; i++) { - if (ioctl(fd, PMIOSTOP, &num) < 0) - err(1, "ioctl(PMIOSTOP)"); - if (ioctl(fd, PMIOREAD, &value) < 0) - err(1, "ioctl(PMIOREAD)"); - buf[i] = value.pmcd_value; - if (ioctl(fd, PMIORESET, &value.pmcd_num) < 0) - err(1, "ioctl(PMIORESET)"); - if (ioctl(fd, PMIOSTART, &num) < 0) - err(1, "ioctl(PMIOSTART)"); - if (sleeptime) - sleep(sleeptime); - if (cmd) - system(cmd); - } - - if (ioctl(fd, PMIOSTOP, &num) < 0) - err(1, "ioctl(PMIOSTOP)"); - if (ioctl(fd, PMIOREAD, &value) < 0) - err(1, "ioctl(PMIOREAD)"); - buf[i] = value.pmcd_value; - if (ioctl(fd, PMIOTSTAMP, &now) < 0) - err(1, "ioctl(PMIOTSTAMP)"); - - total = 0; - for (i = 1; i <= loops; i++) { - printf("%d: %qd\n", i, buf[i]); - total += buf[i]; - } - printf("total: %f\nmean: %f\n", total, total / loops); - - printf("clocks (at %d-MHz): %qd\n", now.pmct_rate, - now.pmct_value - then.pmct_value); - - return 0; -} - -static int -getnum(const char *buf, int min, int max) -{ - char *ep; - long l; - - errno = 0; - l = strtol(buf, &ep, 0); - if (*buf && !*ep && !errno) { - if (l < min || l > max) { - errx(1, "%s: must be between %d and %d", - buf, min, max); - } - return (int)l; - } - - errx(1, "%s: parameter must be an integer", buf); -} - -static void -usage(const char *pname) -{ - fprintf(stderr, - "usage: %s [-eiou] [-c command] [-l nloops] [-m mask] [-s sleeptime]\n" - " [-U unit] counter\n", - pname); - exit(1); -} diff --git a/share/man/man4/man4.i386/Makefile b/share/man/man4/man4.i386/Makefile index ad9b3a01828c..1136de341947 100644 --- a/share/man/man4/man4.i386/Makefile +++ b/share/man/man4/man4.i386/Makefile @@ -6,7 +6,6 @@ MAN= apm.4 \ npx.4 \ pae.4 \ pbio.4 \ - perfmon.4 \ pnp.4 \ pnpbios.4 \ sbni.4 \ diff --git a/share/man/man4/man4.i386/perfmon.4 b/share/man/man4/man4.i386/perfmon.4 deleted file mode 100644 index 7a899e863f1b..000000000000 --- a/share/man/man4/man4.i386/perfmon.4 +++ /dev/null @@ -1,211 +0,0 @@ -.\" -.\" Copyright 1996 Massachusetts Institute of Technology -.\" -.\" Permission to use, copy, modify, and distribute this software and -.\" its documentation for any purpose and without fee is hereby -.\" granted, provided that both the above copyright notice and this -.\" permission notice appear in all copies, that both the above -.\" copyright notice and this permission notice appear in all -.\" supporting documentation, and that the name of M.I.T. not be used -.\" in advertising or publicity pertaining to distribution of the -.\" software without specific, written prior permission. M.I.T. makes -.\" no representations about the suitability of this software for any -.\" purpose. It is provided "as is" without express or implied -.\" warranty. -.\" -.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS -.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, -.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT -.\" SHALL M.I.T. 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. -.Dd March 26, 1996 -.Dt PERFMON 4 i386 -.Os -.Sh NAME -.Nm perfmon -.Nd CPU performance-monitoring interface -.Sh SYNOPSIS -.Cd cpu I586_CPU -.Cd cpu I686_CPU -.Cd options PERFMON -.Sh DESCRIPTION -The -.Nm -driver provides access to the internal performance-monitoring -capabilities of the -.Tn Intel -.Tn Pentium -and -.Tn "Pentium Pro" -CPUs. -These processors implement two internal counters which can be -configured to measure a variety of events for either count or duration -(in CPU cycles), as well as a cycle counter which counts clock cycles. -The -.Nm -driver provides a device-style interface to these capabilities. -.Pp -All access to the performance-monitoring counters is performed through -the special device file -.Dq Pa /dev/perfmon . -This device supports a number of -.Xr ioctl 2 -requests, defined in -.In machine/perfmon.h -along with the definitions of the various counters for both -.Tn Pentium -and -.Tn "Pentium Pro" -processors. -.Pp -.Sy NOTA BENE : -The set of available events differs from processor to processor. -It -is the responsibility of the programmer to ensure that the event -numbers used are the correct ones for the CPU type being measured. -.Pp -The following -.Xr ioctl 2 -requests are defined: -.Bl -tag -width PMIOTSTAMP -.It Dv PMIOSETUP -.Pq Li "struct pmc" -Set up a counter with parameters and flags defined in the structure. -The following fields are defined in -.Li struct pmc : -.Bl -tag -width "u_char pmc_eventx" -.It Li "int pmc_num" -the number of the counter in question; must be less than -.Dv NPMC -(currently 2). -.It Li "u_char pmc_event" -the particular event number to be monitored, as defined in -.In machine/perfmon.h . -.It Li "u_char pmc_unit" -the unit mask value, specific to the event type (see the -.Tn Intel -documentation). -.It Li "u_char pmc_flags" -flags modifying the operation of the counter (see below). -.It Li "u_char pmc_mask" -the counter mask value; essentially, this is a threshold used to -restrict the count to events lasting more (or less) than the specified -number of clocks. -.El -.Pp -The following -.Li pmc_flags -values are defined: -.Bl -tag -compact -width PMCF_USRxx -.It Dv PMCF_USR -count events in user mode -.It Dv PMCF_OS -count events in kernel mode -.It Dv PMCF_E -count number of events rather than their duration -.It Dv PMCF_INV -invert the sense of the counter mask comparison -.El -.It Dv PMIOGET -.Pq Li "struct pmc" -returns the current configuration of the specified counter. -.It Dv PMIOSTART -.It Dv PMIOSTOP -.Pq Li int -starts (stops) the specified counter. -Due to hardware deficiencies, -counters must be started and stopped in numerical order. -(That is to -say, counter 0 can never be stopped without first stopping counter 1.) -The driver will -.Em not -enforce this restriction (since it may not be present in future CPUs). -.It Dv PMIORESET -.Pq Li int -reset the specified counter to zero. -The counter should be stopped -with -.Dv PMIOSTOP -before it is reset. -All counters are automatically reset by -.Dv PMIOSETUP . -.It Dv PMIOREAD -.Pq Li "struct pmc_data" -get the current value of the counter. -The -.Li pmc_data -structure defines two fields: -.Pp -.Bl -tag -compact -width "quad_t pmcd_value" -.It Li "int pmcd_num" -the number of the counter to read -.It Li "quad_t pmcd_value" -the resulting value as a 64-bit signed integer -.El -.Pp -In the future, it may be possible to use the -.Li RDPMC -instruction on -.Tn "Pentium Pro" -processors to read the counters directly. -.It Dv PMIOTSTAMP -.Pq Li "struct pmc_tstamp" -read the time stamp counter. -The -.Li pmc_tstamp -structure defines two fields: -.Pp -.Bl -tag -compact -width "quad_t pmct_value" -.It Li "int pmct_rate" -the approximate rate of the counter, in MHz -.It Li "quad_t pmct_value" -the current value of the counter as a 64-bit integer -.El -.Pp -It is important to note that the counter rate, as provided in the -.Li pmct_rate -field, is often incorrect because of calibration difficulties and -non-integral clock rates. -This field should be considered more of a -hint or sanity-check than an actual representation of the rate of -clock ticks. -.El -.Sh FILES -.Bl -tag -compact -width "/usr/include/machine/perfmon.h" -.It Pa /dev/perfmon -character device interface to counters -.It Pa /usr/include/machine/perfmon.h -include file with definitions of structures and event types -.It Pa /usr/share/examples/perfmon -sample source code demonstrating use of all the -.Fn ioctl -commands -.El -.Sh SEE ALSO -.Xr ioctl 2 , -.Xr hwpmc 4 -.Rs -.%A Intel Corporation -.%B Pentium Pro Family Developer's Manual -.%D January 1996 -.%V vol. 3 -.%O Operating System Writer's Manual -.Re -.Sh HISTORY -The -.Nm -device first appeared in -.Fx 2.2 . -.Sh AUTHORS -The -.Nm -driver was written by -.An Garrett A. Wollman , -MIT Laboratory for Computer Science. diff --git a/share/man/man7/clocks.7 b/share/man/man7/clocks.7 index 3a218f844450..26283909f06d 100644 --- a/share/man/man7/clocks.7 +++ b/share/man/man7/clocks.7 @@ -141,10 +141,6 @@ Its frequency can be found using the .Va machdep.tsc_freq sysctl, if it is available. It is used to interpolate between values of the scheduling clock. -It can be accessed using the -.Dv PMIOTSTAMP -request of -.Xr perfmon 4 . .It The ACPI clock. This is a real clock/timer with a nominal frequency of 3579545. diff --git a/sys/conf/files.i386 b/sys/conf/files.i386 index e6c2089e2c1e..0e7a1f24be7e 100644 --- a/sys/conf/files.i386 +++ b/sys/conf/files.i386 @@ -91,7 +91,6 @@ i386/i386/mp_clock.c optional smp i386/i386/mp_machdep.c optional smp i386/i386/mpboot.S optional smp i386/i386/npx.c standard -i386/i386/perfmon.c optional perfmon i386/i386/pmap_base.c standard i386/i386/pmap_nopae.c standard i386/i386/pmap_pae.c standard diff --git a/sys/i386/conf/NOTES b/sys/i386/conf/NOTES index fbcea76527db..25bfb99c1fef 100644 --- a/sys/i386/conf/NOTES +++ b/sys/i386/conf/NOTES @@ -178,12 +178,6 @@ options CYRIX_CACHE_REALLY_WORKS options NPX_DEBUG # enable npx debugging # -# PERFMON causes the driver for Pentium/Pentium Pro performance counters -# to be compiled. See perfmon(4) for more information. -# -options PERFMON - -# # Hints for the non-optional Numeric Processing eXtension driver. envvar hint.npx.0.flags="0x0" envvar hint.npx.0.irq="13" diff --git a/sys/i386/i386/machdep.c b/sys/i386/i386/machdep.c index 7dbaded419e6..f9afb9afe45f 100644 --- a/sys/i386/i386/machdep.c +++ b/sys/i386/i386/machdep.c @@ -50,7 +50,6 @@ #include "opt_isa.h" #include "opt_kstack_pages.h" #include "opt_maxmem.h" -#include "opt_perfmon.h" #include "opt_platform.h" #include <sys/param.h> @@ -133,9 +132,6 @@ #include <x86/ucode.h> #include <machine/vm86.h> #include <x86/init.h> -#ifdef PERFMON -#include <machine/perfmon.h> -#endif #ifdef SMP #include <machine/smp.h> #endif @@ -245,9 +241,6 @@ cpu_startup(void *dummy) startrtclock(); printcpuinfo(); panicifcpuunsupported(); -#ifdef PERFMON - perfmon_init(); -#endif /* * Display physical memory if SMBIOS reports reasonable amount. diff --git a/sys/i386/i386/perfmon.c b/sys/i386/i386/perfmon.c deleted file mode 100644 index 5e6d37d7f5ed..000000000000 --- a/sys/i386/i386/perfmon.c +++ /dev/null @@ -1,402 +0,0 @@ -/*- - * Copyright 1996 Massachusetts Institute of Technology - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby - * granted, provided that both the above copyright notice and this - * permission notice appear in all copies, that both the above - * copyright notice and this permission notice appear in all - * supporting documentation, and that the name of M.I.T. not be used - * in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. M.I.T. makes - * no representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS - * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT - * SHALL M.I.T. 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. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/conf.h> -#include <sys/fcntl.h> -#include <sys/kernel.h> - -#ifndef SMP -#include <machine/cputypes.h> -#endif -#include <machine/clock.h> -#include <machine/perfmon.h> -#include <machine/specialreg.h> - -static int perfmon_inuse; -static int perfmon_cpuok; -#ifndef SMP -static int msr_ctl[NPMC]; -#endif -static int msr_pmc[NPMC]; -static unsigned int ctl_shadow[NPMC]; -static quad_t pmc_shadow[NPMC]; /* used when ctr is stopped on P5 */ -static int (*writectl)(int); -#ifndef SMP -static int writectl5(int); -static int writectl6(int); -#endif - -static d_close_t perfmon_close; -static d_open_t perfmon_open; -static d_ioctl_t perfmon_ioctl; - -/* - * XXX perfmon_init_dev(void *) is a split from the perfmon_init() function. - * This solves a problem for DEVFS users. It loads the "perfmon" driver after - * the DEVFS subsystem has been kicked into action. The SI_ORDER_ANY is to - * assure that it is the most lowest priority task which, guarantees the - * above. - */ -static void perfmon_init_dev(void *); -SYSINIT(cpu, SI_SUB_DRIVERS, SI_ORDER_ANY, perfmon_init_dev, NULL); - -static struct cdevsw perfmon_cdevsw = { - .d_version = D_VERSION, - .d_flags = D_NEEDGIANT, - .d_open = perfmon_open, - .d_close = perfmon_close, - .d_ioctl = perfmon_ioctl, - .d_name = "perfmon", -}; - -/* - * Must be called after cpu_class is set up. - */ -void -perfmon_init(void) -{ -#ifndef SMP - switch(cpu_class) { - case CPUCLASS_586: - perfmon_cpuok = 1; - msr_ctl[0] = MSR_P5_CESR; - msr_ctl[1] = MSR_P5_CESR; - msr_pmc[0] = MSR_P5_CTR0; - msr_pmc[1] = MSR_P5_CTR1; - writectl = writectl5; - break; - case CPUCLASS_686: - perfmon_cpuok = 1; - msr_ctl[0] = MSR_EVNTSEL0; - msr_ctl[1] = MSR_EVNTSEL1; - msr_pmc[0] = MSR_PERFCTR0; - msr_pmc[1] = MSR_PERFCTR1; - writectl = writectl6; - break; - - default: - perfmon_cpuok = 0; - break; - } -#endif /* SMP */ -} - -static void -perfmon_init_dev(void *dummy) -{ - make_dev(&perfmon_cdevsw, 32, UID_ROOT, GID_KMEM, 0640, "perfmon"); -} - -int -perfmon_avail(void) -{ - return perfmon_cpuok; -} - -int -perfmon_setup(int pmc, unsigned int control) -{ - register_t saveintr; - - if (pmc < 0 || pmc >= NPMC) - return EINVAL; - - perfmon_inuse |= (1 << pmc); - control &= ~(PMCF_SYS_FLAGS << 16); - saveintr = intr_disable(); - ctl_shadow[pmc] = control; - writectl(pmc); - wrmsr(msr_pmc[pmc], pmc_shadow[pmc] = 0); - intr_restore(saveintr); - return 0; -} - -int -perfmon_get(int pmc, unsigned int *control) -{ - if (pmc < 0 || pmc >= NPMC) - return EINVAL; - - if (perfmon_inuse & (1 << pmc)) { - *control = ctl_shadow[pmc]; - return 0; - } - return EBUSY; /* XXX reversed sense */ -} - -int -perfmon_fini(int pmc) -{ - if (pmc < 0 || pmc >= NPMC) - return EINVAL; - - if (perfmon_inuse & (1 << pmc)) { - perfmon_stop(pmc); - ctl_shadow[pmc] = 0; - perfmon_inuse &= ~(1 << pmc); - return 0; - } - return EBUSY; /* XXX reversed sense */ -} - -int -perfmon_start(int pmc) -{ - register_t saveintr; - - if (pmc < 0 || pmc >= NPMC) - return EINVAL; - - if (perfmon_inuse & (1 << pmc)) { - saveintr = intr_disable(); - ctl_shadow[pmc] |= (PMCF_EN << 16); - wrmsr(msr_pmc[pmc], pmc_shadow[pmc]); - writectl(pmc); - intr_restore(saveintr); - return 0; - } - return EBUSY; -} - -int -perfmon_stop(int pmc) -{ - register_t saveintr; - - if (pmc < 0 || pmc >= NPMC) - return EINVAL; - - if (perfmon_inuse & (1 << pmc)) { - saveintr = intr_disable(); - pmc_shadow[pmc] = rdmsr(msr_pmc[pmc]) & 0xffffffffffULL; - ctl_shadow[pmc] &= ~(PMCF_EN << 16); - writectl(pmc); - intr_restore(saveintr); - return 0; - } - return EBUSY; -} - -int -perfmon_read(int pmc, quad_t *val) -{ - if (pmc < 0 || pmc >= NPMC) - return EINVAL; - - if (perfmon_inuse & (1 << pmc)) { - if (ctl_shadow[pmc] & (PMCF_EN << 16)) - *val = rdmsr(msr_pmc[pmc]) & 0xffffffffffULL; - else - *val = pmc_shadow[pmc]; - return 0; - } - - return EBUSY; -} - -int -perfmon_reset(int pmc) -{ - if (pmc < 0 || pmc >= NPMC) - return EINVAL; - - if (perfmon_inuse & (1 << pmc)) { - wrmsr(msr_pmc[pmc], pmc_shadow[pmc] = 0); - return 0; - } - return EBUSY; -} - -#ifndef SMP -/* - * Unfortunately, the performance-monitoring registers are laid out - * differently in the P5 and P6. We keep everything in P6 format - * internally (except for the event code), and convert to P5 - * format as needed on those CPUs. The writectl function pointer - * is set up to point to one of these functions by perfmon_init(). - */ -int -writectl6(int pmc) -{ - if (pmc > 0 && !(ctl_shadow[pmc] & (PMCF_EN << 16))) { - wrmsr(msr_ctl[pmc], 0); - } else { - wrmsr(msr_ctl[pmc], ctl_shadow[pmc]); - } - return 0; -} - -#define P5FLAG_P 0x200 -#define P5FLAG_E 0x100 -#define P5FLAG_USR 0x80 -#define P5FLAG_OS 0x40 - -int -writectl5(int pmc) -{ - quad_t newval = 0; - - if (ctl_shadow[1] & (PMCF_EN << 16)) { - if (ctl_shadow[1] & (PMCF_USR << 16)) - newval |= P5FLAG_USR << 16; - if (ctl_shadow[1] & (PMCF_OS << 16)) - newval |= P5FLAG_OS << 16; - if (!(ctl_shadow[1] & (PMCF_E << 16))) - newval |= P5FLAG_E << 16; - newval |= (ctl_shadow[1] & 0x3f) << 16; - } - if (ctl_shadow[0] & (PMCF_EN << 16)) { - if (ctl_shadow[0] & (PMCF_USR << 16)) - newval |= P5FLAG_USR; - if (ctl_shadow[0] & (PMCF_OS << 16)) - newval |= P5FLAG_OS; - if (!(ctl_shadow[0] & (PMCF_E << 16))) - newval |= P5FLAG_E; - newval |= ctl_shadow[0] & 0x3f; - } - - wrmsr(msr_ctl[0], newval); - return 0; /* XXX should check for unimplemented bits */ -} -#endif /* !SMP */ - -/* - * Now the user-mode interface, called from a subdevice of mem.c. - */ -static int writer; -static int writerpmc; - -static int -perfmon_open(struct cdev *dev, int flags, int fmt, struct thread *td) -{ - if (!perfmon_cpuok) - return ENXIO; - - if (flags & FWRITE) { - if (writer) { - return EBUSY; - } else { - writer = 1; - writerpmc = 0; - } - } - return 0; -} - -static int -perfmon_close(struct cdev *dev, int flags, int fmt, struct thread *td) -{ - if (flags & FWRITE) { - int i; - - for (i = 0; i < NPMC; i++) { - if (writerpmc & (1 << i)) - perfmon_fini(i); - } - writer = 0; - } - return 0; -} - -static int -perfmon_ioctl(struct cdev *dev, u_long cmd, caddr_t param, int flags, struct thread *td) -{ - struct pmc *pmc; - struct pmc_data *pmcd; - struct pmc_tstamp *pmct; - uint64_t freq; - int *ip; - int rv; - - switch(cmd) { - case PMIOSETUP: - if (!(flags & FWRITE)) - return EPERM; - pmc = (struct pmc *)param; - - rv = perfmon_setup(pmc->pmc_num, pmc->pmc_val); - if (!rv) { - writerpmc |= (1 << pmc->pmc_num); - } - break; - - case PMIOGET: - pmc = (struct pmc *)param; - rv = perfmon_get(pmc->pmc_num, &pmc->pmc_val); - break; - - case PMIOSTART: - if (!(flags & FWRITE)) - return EPERM; - - ip = (int *)param; - rv = perfmon_start(*ip); - break; - - case PMIOSTOP: - if (!(flags & FWRITE)) - return EPERM; - - ip = (int *)param; - rv = perfmon_stop(*ip); - break; - - case PMIORESET: - if (!(flags & FWRITE)) - return EPERM; - - ip = (int *)param; - rv = perfmon_reset(*ip); - break; - - case PMIOREAD: - pmcd = (struct pmc_data *)param; - rv = perfmon_read(pmcd->pmcd_num, &pmcd->pmcd_value); - break; - - case PMIOTSTAMP: - freq = atomic_load_acq_64(&tsc_freq); - if (freq == 0) { - rv = ENOTTY; - break; - } - pmct = (struct pmc_tstamp *)param; - /* XXX interface loses precision. */ - pmct->pmct_rate = freq / 1000000; - pmct->pmct_value = rdtsc(); - rv = 0; - break; - default: - rv = ENOTTY; - } - - return rv; -} diff --git a/sys/i386/include/perfmon.h b/sys/i386/include/perfmon.h deleted file mode 100644 index c23498aeace4..000000000000 --- a/sys/i386/include/perfmon.h +++ /dev/null @@ -1,253 +0,0 @@ -/*- - * Copyright 1996 Massachusetts Institute of Technology - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby - * granted, provided that both the above copyright notice and this - * permission notice appear in all copies, that both the above - * copyright notice and this permission notice appear in all - * supporting documentation, and that the name of M.I.T. not be used - * in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. M.I.T. makes - * no representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS - * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT - * SHALL M.I.T. 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. - */ - -/* - * Interface to performance-monitoring counters for Intel Pentium and - * Pentium Pro CPUs. - */ - -#ifndef _MACHINE_PERFMON_H_ -#define _MACHINE_PERFMON_H_ - -#ifndef _KERNEL -#include <sys/types.h> -#endif -#include <sys/ioccom.h> - -#define NPMC 2 - -#define PMIOSETUP _IOW('5', 1, struct pmc) -#define PMIOGET _IOWR('5', 7, struct pmc) -#define PMIOSTART _IOW('5', 2, int) -#define PMIOSTOP _IOW('5', 3, int) -#define PMIOREAD _IOWR('5', 4, struct pmc_data) -#define PMIORESET _IOW('5', 5, int) -#define PMIOTSTAMP _IOR('5', 6, struct pmc_tstamp) - -struct pmc { - int pmc_num; - union { - struct { - unsigned char pmcus_event; - unsigned char pmcus_unit; - unsigned char pmcus_flags; - unsigned char pmcus_mask; - } pmcu_s; - unsigned int pmcu_val; - } pmc_pmcu; -}; - -#define PMC_ALL (-1) - -#define pmc_event pmc_pmcu.pmcu_s.pmcus_event -#define pmc_unit pmc_pmcu.pmcu_s.pmcus_unit -#define pmc_flags pmc_pmcu.pmcu_s.pmcus_flags -#define pmc_mask pmc_pmcu.pmcu_s.pmcus_mask -#define pmc_val pmc_pmcu.pmcu_val - -#define PMCF_USR 0x01 /* count events in user mode */ -#define PMCF_OS 0x02 /* count events in kernel mode */ -#define PMCF_E 0x04 /* use edge-detection mode */ -#define PMCF_PC 0x08 /* PMx output pin control */ -#define PMCF_INT 0x10 /* APIC interrupt enable (do not use) */ -#define PMCF_EN 0x40 /* enable counters */ -#define PMCF_INV 0x80 /* invert counter mask comparison */ - -#define PMCF_SYS_FLAGS (PMCF_INT | PMCF_EN) /* user cannot set */ - -struct pmc_data { - int pmcd_num; - quad_t pmcd_value; -}; - -struct pmc_tstamp { - int pmct_rate; - quad_t pmct_value; -}; - -#ifndef _KERNEL - -#define _PATH_PERFMON "/dev/perfmon" - -#else - -/* - * Intra-kernel interface to performance monitoring counters - */ -void perfmon_init(void); -int perfmon_avail(void); -int perfmon_setup(int, unsigned int); -int perfmon_get(int, unsigned int *); -int perfmon_fini(int); -int perfmon_start(int); -int perfmon_stop(int); -int perfmon_read(int, quad_t *); -int perfmon_reset(int); - -#endif /* _KERNEL */ - -/* - * Pentium Pro performance counters, from Appendix B. - */ -/* Data Cache Unit */ -#define PMC6_DATA_MEM_REFS 0x43 -#define PMC6_DCU_LINES_IN 0x45 -#define PMC6_DCU_M_LINES_IN 0x46 -#define PMC6_DCU_M_LINES_OUT 0x47 -#define PMC6_DCU_MISS_OUTSTANDING 0x48 - -/* Instruction Fetch Unit */ -#define PMC6_IFU_IFETCH 0x80 -#define PMC6_IFU_IFETCH_MISS 0x81 -#define PMC6_ITLB_MISS 0x85 -#define PMC6_IFU_MEM_STALL 0x86 -#define PMC6_ILD_STALL 0x87 - -/* L2 Cache */ -#define PMC6_L2_IFETCH 0x28 /* MESI */ -#define PMC6_L2_LD 0x29 /* MESI */ -#define PMC6_L2_ST 0x2a /* MESI */ -#define PMC6_L2_LINES_IN 0x24 -#define PMC6_L2_LINES_OUT 0x26 -#define PMC6_L2_M_LINES_INM 0x25 -#define PMC6_L2_M_LINES_OUTM 0x27 -#define PMC6_L2_RQSTS 0x2e /* MESI */ -#define PMC6_L2_ADS 0x21 -#define PMC6_L2_DBUS_BUSY 0x22 -#define PMC6_L2_DBUS_BUSY_RD 0x23 - -/* External Bus Logic */ -#define PMC6_BUS_DRDY_CLOCKS 0x62 -#define PMC6_BUS_LOCK_CLOCKS 0x63 -#define PMC6_BUS_REQ_OUTSTANDING 0x60 -#define PMC6_BUS_TRAN_BRD 0x65 -#define PMC6_BUS_TRAN_RFO 0x66 -#define PMC6_BUS_TRAN_WB 0x67 -#define PMC6_BUS_TRAN_IFETCH 0x68 -#define PMC6_BUS_TRAN_INVAL 0x69 -#define PMC6_BUS_TRAN_PWR 0x6a -#define PMC6_BUS_TRAN_P 0x6b -#define PMC6_BUS_TRAN_IO 0x6c -#define PMC6_BUS_TRAN_DEF 0x6d -#define PMC6_BUS_TRAN_BURST 0x6e -#define PMC6_BUS_TRAN_ANY 0x70 -#define PMC6_BUS_TRAN_MEM 0x6f -#define PMC6_BUS_DATA_RCV 0x64 -#define PMC6_BUS_BNR_DRV 0x61 -#define PMC6_BUS_HIT_DRV 0x7a -#define PMC6_BUS_HITM_DRV 0x7b -#define PMC6_BUS_SNOOP_STALL 0x7e - -/* Floating Point Unit */ -#define PMC6_FLOPS 0xc1 /* counter 0 only */ -#define PMC6_FP_COMP_OPS_EXE 0x10 /* counter 0 only */ -#define PMC6_FP_ASSIST 0x11 /* counter 1 only */ -#define PMC6_MUL 0x12 /* counter 1 only */ -#define PMC6_DIV 0x13 /* counter 1 only */ -#define PMC6_CYCLES_DIV_BUSY 0x14 /* counter 0 only */ - -/* Memory Ordering */ -#define PMC6_LD_BLOCKS 0x03 -#define PMC6_SB_DRAINS 0x04 -#define PMC6_MISALIGN_MEM_REF 0x05 - -/* Instruction Decoding and Retirement */ -#define PMC6_INST_RETIRED 0xc0 -#define PMC6_UOPS_RETIRED 0xc2 -#define PMC6_INST_DECODER 0xd0 /* (sic) */ - -/* Interrupts */ -#define PMC6_HW_INT_RX 0xc8 -#define PMC6_CYCLES_INT_MASKED 0xc6 -#define PMC6_CYCLES_INT_PENDING_AND_MASKED 0xc7 - -/* Branches */ -#define PMC6_BR_INST_RETIRED 0xc4 -#define PMC6_BR_MISS_PRED_RETIRED 0xc5 -#define PMC6_BR_TAKEN_RETIRED 0xc9 -#define PMC6_BR_MISS_PRED_TAKEN_RET 0xca -#define PMC6_BR_INST_DECODED 0xe0 -#define PMC6_BTB_MISSES 0xe2 -#define PMC6_BR_BOGUS 0xe4 -#define PMC6_BACLEARS 0xe6 - -/* Stalls */ -#define PMC6_RESOURCE_STALLS 0xa2 -#define PMC6_PARTIAL_RAT_STALLS 0xd2 - -/* Segment Register Loads */ -#define PMC6_SEGMENT_REG_LOADS 0x06 - -/* Clocks */ -#define PMC6_CPU_CLK_UNHALTED 0x79 - -/* - * Pentium Performance Counters - * This list comes from the Harvard people, not Intel. - */ -#define PMC5_DATA_READ 0 -#define PMC5_DATA_WRITE 1 -#define PMC5_DATA_TLB_MISS 2 -#define PMC5_DATA_READ_MISS 3 -#define PMC5_DATA_WRITE_MISS 4 -#define PMC5_WRITE_M_E 5 -#define PMC5_DATA_LINES_WBACK 6 -#define PMC5_DATA_CACHE_SNOOP 7 -#define PMC5_DATA_CACHE_SNOOP_HIT 8 -#define PMC5_MEM_ACCESS_BOTH 9 -#define PMC5_BANK_CONFLICTS 10 -#define PMC5_MISALIGNED_DATA 11 -#define PMC5_INST_READ 12 -#define PMC5_INST_TLB_MISS 13 -#define PMC5_INST_CACHE_MISS 14 -#define PMC5_SEGMENT_REG_LOAD 15 -#define PMC5_BRANCHES 18 -#define PMC5_BTB_HITS 19 -#define PMC5_BRANCH_TAKEN 20 -#define PMC5_PIPELINE_FLUSH 21 -#define PMC5_INST_EXECUTED 22 -#define PMC5_INST_EXECUTED_V 23 -#define PMC5_BUS_UTILIZATION 24 -#define PMC5_WRITE_BACKUP_STALL 25 -#define PMC5_DATA_READ_STALL 26 -#define PMC5_WRITE_E_M_STALL 27 -#define PMC5_LOCKED_BUS 28 -#define PMC5_IO_CYCLE 29 -#define PMC5_NONCACHE_MEMORY 30 -#define PMC5_ADDR_GEN_INTERLOCK 31 -#define PMC5_FLOPS 34 -#define PMC5_BP0_MATCH 35 -#define PMC5_BP1_MATCH 36 -#define PMC5_BP2_MATCH 37 -#define PMC5_BP3_MATCH 38 -#define PMC5_HW_INTR 39 -#define PMC5_DATA_RW 40 -#define PMC5_DATA_RW_MISS 41 - -#endif /* !_MACHINE_PERFMON_H_ */ diff --git a/tools/build/mk/OptionalObsoleteFiles.inc b/tools/build/mk/OptionalObsoleteFiles.inc index a4ddf8dbf51f..35ee7d094240 100644 --- a/tools/build/mk/OptionalObsoleteFiles.inc +++ b/tools/build/mk/OptionalObsoleteFiles.inc @@ -1822,9 +1822,6 @@ OLD_FILES+=usr/share/examples/netgraph/virtual.chain OLD_FILES+=usr/share/examples/netgraph/virtual.lan OLD_FILES+=usr/share/examples/oci/Containerfile.pkg OLD_FILES+=usr/share/examples/oci/README -OLD_FILES+=usr/share/examples/perfmon/Makefile -OLD_FILES+=usr/share/examples/perfmon/README -OLD_FILES+=usr/share/examples/perfmon/perfmon.c OLD_FILES+=usr/share/examples/pf/ackpri OLD_FILES+=usr/share/examples/pf/faq-example1 OLD_FILES+=usr/share/examples/pf/faq-example2 @@ -1991,7 +1988,6 @@ OLD_DIRS+=usr/share/examples/libvgl OLD_DIRS+=usr/share/examples/mdoc OLD_DIRS+=usr/share/examples/netgraph OLD_DIRS+=usr/share/examples/oci -OLD_DIRS+=usr/share/examples/perfmon OLD_DIRS+=usr/share/examples/pf OLD_DIRS+=usr/share/examples/ppi OLD_DIRS+=usr/share/examples/ppp |
