From nobody Sun Jun 26 09:12:04 2022 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 00977877DD0; Sun, 26 Jun 2022 09:12:05 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4LW4qm4p2fz4mGV; Sun, 26 Jun 2022 09:12:04 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1656234724; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Ps6JmPjVEQXNq0eNZ4psKPYcZ3aFXn0biWcleC6FaiE=; b=wLZkMINA5y5+En/Y604Yv8m/vb6ADNb3F++vsvVPiOZvudJz1uY3dY1cx0yKovKy/zrUgO 5820MqUZVbB8e84iD3c+u0YS1/QAhI9A5C+RA6m1XO7nw8V5LBZhRKPtmw9hUiGkvPdHOi SNUlV+uFeWbNyrySvJrB1nWyIjhFyCK3NMGh7u5zoPUgiAL475jHcN+2JgS9w2QjJixTbO fVud5qlGYD5J1WnhM1PiXZg7K2A6nlv9VjhGtuhdzxf/YIszmJtAtQ3yV4KNHlWeJkfZ2W /g/qQCVQzUa2Bnzt4QPwOXdv8bdKnoTnNXOyRAUGwoPQuUUuVJBfhEljTeeh3g== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 8650613F4E; Sun, 26 Jun 2022 09:12:04 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 25Q9C4OI042664; Sun, 26 Jun 2022 09:12:04 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 25Q9C4tA042663; Sun, 26 Jun 2022 09:12:04 GMT (envelope-from git) Date: Sun, 26 Jun 2022 09:12:04 GMT Message-Id: <202206260912.25Q9C4tA042663@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Toomas Soome Subject: git: b6e28991bf3a - main - System wide and NUMA domain wide counters support. PMC classes for ARM DMC-620 and CMN-600. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: tsoome X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: b6e28991bf3aadb74c54c7e6dfc2992b29abae5a Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1656234724; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Ps6JmPjVEQXNq0eNZ4psKPYcZ3aFXn0biWcleC6FaiE=; b=vtj1HMC0XpH04IvFwZPYSHcmCtQkzFJWSzN2KxoSdIS77+bn1ruhcnHIUcDmihchEzDlcg U8xcYlACKgiC6DbKJg6eDtwZFJXBHSD4SFo1+UjzRO+bqqN38AnRS4zSl0C2oV3b5vjEYV mSd/OjUoI0mzD9sll8RvGQM2Z2HutwnZIzW6bRVhv9ZdtJsPeuSUn9r/HLkDMmGoYOiIY3 udj5k9JgKC+4qowK2LpgAnq/0fV8XKSulUXCH9lXPDRemaF5Mhlj+MwrygdBHb2fwxExk+ uY3GiIlr7MXj/a+7+ZSUfL80ZfA8v8is40lkzBzcmBUWqRMX/UuokyUHqPVy+A== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1656234724; a=rsa-sha256; cv=none; b=tkIiVALtQbuuq1Fk0ULP9zFSkrxsLFxtgtppniWDXsHVP6k2+WorTopt+B252TGKjAmM/B GX52rGKcb/SaDNnKyrqtwBu1NlyYPwJ7X93NjVv8d1SYOnX26PpGDe5gSJ8PYI7mrZvUZj j/tRQYJChztYj3Y1W21IgNH/GsCqW/izY+ngFhq8sAIzSGP3+yoJOVZfNJWarjQCR0tCJ+ sgOVAU2K9DvJMgwM19dtJDuXpoxZuERFzDo3yTzlNNbNSN/K0fwIa0C0ehUDhgTeXR0is5 hDhO9cbp+goZmiNTothtzQpag+FUf4JJaQek0Z6xoBZtGRK/bBFFEr9mkdz5Lw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by tsoome: URL: https://cgit.FreeBSD.org/src/commit/?id=b6e28991bf3aadb74c54c7e6dfc2992b29abae5a commit b6e28991bf3aadb74c54c7e6dfc2992b29abae5a Author: Aleksandr Rybalko AuthorDate: 2022-02-16 00:17:02 +0000 Commit: Toomas Soome CommitDate: 2022-06-26 05:31:03 +0000 System wide and NUMA domain wide counters support. PMC classes for ARM DMC-620 and CMN-600. Add support for system wide and NUMA domain wide counters support. Add 3 new PMC classes for ARM DMC-620 and CMN-600 controllers PMU. Reviewed by: mhorne Sponsored By: ARM Sponsored By: Ampere Computing Differential Revision: https://reviews.freebsd.org/D35342 --- lib/libpmc/pmc.3 | 6 +++- sys/sys/pmc.h | 13 ++++--- usr.sbin/pmcstat/pmcstat.c | 84 +++++++++++++++++++++++++++++++++++++--------- 3 files changed, 83 insertions(+), 20 deletions(-) diff --git a/lib/libpmc/pmc.3 b/lib/libpmc/pmc.3 index 3325cb1e3d40..abe9f3208030 100644 --- a/lib/libpmc/pmc.3 +++ b/lib/libpmc/pmc.3 @@ -23,7 +23,7 @@ .\" .\" $FreeBSD$ .\" -.Dd August 10, 2021 +.Dd May 28, 2022 .Dt PMC 3 .Os .Sh NAME @@ -200,6 +200,8 @@ Supported capabilities include: .Bl -tag -width "Li PMC_CAP_INTERRUPT" -compact .It Li PMC_CAP_CASCADE The ability to cascade counters. +.It Li PMC_CAP_DOMWIDE +Separate counters tied to each NUMA domain. .It Li PMC_CAP_EDGE The ability to count negated to asserted transitions of the hardware conditions being probed for. @@ -218,6 +220,8 @@ The ability to read from performance counters. .It Li PMC_CAP_SYSTEM The ability to restrict counting of hardware events to when the CPU is running privileged code. +.It Li PMC_CAP_SYSWIDE +A single counter aggregating events for the whole system. .It Li PMC_CAP_THRESHOLD The ability to ignore simultaneous hardware events below a programmable threshold. diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h index 18c38ca36659..5465d0532a2a 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -171,7 +171,10 @@ enum pmc_cputype { __PMC_CLASS(MIPS74K, 0x12, "MIPS 74K") \ __PMC_CLASS(E500, 0x13, "Freescale e500 class") \ __PMC_CLASS(BERI, 0x14, "MIPS BERI") \ - __PMC_CLASS(POWER8, 0x15, "IBM POWER8 class") + __PMC_CLASS(POWER8, 0x15, "IBM POWER8 class") \ + __PMC_CLASS(DMC620_PMU_CD2, 0x16, "ARM DMC620 Memory Controller PMU CLKDIV2") \ + __PMC_CLASS(DMC620_PMU_C, 0x17, "ARM DMC620 Memory Controller PMU CLK") \ + __PMC_CLASS(CMN600_PMU, 0x18, "Arm CoreLink CMN600 Coherent Mesh Network PMU") enum pmc_class { #undef __PMC_CLASS @@ -180,7 +183,7 @@ enum pmc_class { }; #define PMC_CLASS_FIRST PMC_CLASS_TSC -#define PMC_CLASS_LAST PMC_CLASS_POWER8 +#define PMC_CLASS_LAST PMC_CLASS_CMN600_PMU /* * A PMC can be in the following states: @@ -308,7 +311,9 @@ enum pmc_disp { __PMC_CAP(QUALIFIER, 8, "further qualify monitored events") \ __PMC_CAP(PRECISE, 9, "perform precise sampling") \ __PMC_CAP(TAGGING, 10, "tag upstream events") \ - __PMC_CAP(CASCADE, 11, "cascade counters") + __PMC_CAP(CASCADE, 11, "cascade counters") \ + __PMC_CAP(SYSWIDE, 12, "system wide counter") \ + __PMC_CAP(DOMWIDE, 13, "NUMA domain wide counter") enum pmc_caps { @@ -318,7 +323,7 @@ enum pmc_caps }; #define PMC_CAP_FIRST PMC_CAP_INTERRUPT -#define PMC_CAP_LAST PMC_CAP_CASCADE +#define PMC_CAP_LAST PMC_CAP_DOMWIDE /* * PMC Event Numbers diff --git a/usr.sbin/pmcstat/pmcstat.c b/usr.sbin/pmcstat/pmcstat.c index 3e2d101ab113..08e43d5d446a 100644 --- a/usr.sbin/pmcstat/pmcstat.c +++ b/usr.sbin/pmcstat/pmcstat.c @@ -59,6 +59,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include @@ -116,6 +117,7 @@ static int pmcstat_kq; static kvm_t *pmcstat_kvm; static struct kinfo_proc *pmcstat_plist; struct pmcstat_args args; +static bool libpmc_initialized = false; static void pmcstat_get_cpumask(const char *cpuspec, cpuset_t *cpumask) @@ -419,6 +421,22 @@ pmcstat_topexit(void) endwin(); } +static inline void +libpmc_initialize(int *npmc) +{ + + if (libpmc_initialized) + return; + if (pmc_init() < 0) + err(EX_UNAVAILABLE, "ERROR: Initialization of the pmc(3)" + " library failed"); + + /* assume all CPUs are identical */ + if ((*npmc = pmc_npmc(0)) < 0) + err(EX_OSERR, "ERROR: Cannot determine the number of PMCs on " + "CPU %d", 0); + libpmc_initialized = true; +} /* * Main */ @@ -426,14 +444,14 @@ pmcstat_topexit(void) int main(int argc, char **argv) { - cpuset_t cpumask, rootmask; + cpuset_t cpumask, dommask, rootmask; double interval; double duration; int option, npmc; int c, check_driver_stats; int do_callchain, do_descendants, do_logproccsw, do_logprocexit; - int do_print, do_read, do_listcounters, do_descr; - int do_userspace; + int do_print, do_read, do_listcounters, do_descr, domains; + int do_userspace, i; size_t len; int graphdepth; int pipefd[2], rfd; @@ -450,6 +468,7 @@ main(int argc, char **argv) struct winsize ws; struct stat sb; char buffer[PATH_MAX]; + uint32_t caps; check_driver_stats = 0; current_sampling_count = 0; @@ -460,6 +479,7 @@ main(int argc, char **argv) do_logproccsw = 0; do_logprocexit = 0; do_listcounters = 0; + domains = 0; use_cumulative_counts = 0; graphfilename = "-"; args.pa_required = 0; @@ -489,8 +509,10 @@ main(int argc, char **argv) bzero(&ds_end, sizeof(ds_end)); ev = NULL; event = NULL; + caps = 0; CPU_ZERO(&cpumask); + /* Default to using the running system kernel. */ len = 0; if (sysctlbyname("kern.bootfile", NULL, &len, NULL, 0) == -1) @@ -500,6 +522,9 @@ main(int argc, char **argv) errx(EX_SOFTWARE, "ERROR: Out of memory."); if (sysctlbyname("kern.bootfile", args.pa_kernel, &len, NULL, 0) == -1) err(EX_OSERR, "ERROR: Cannot determine path of running kernel"); + len = sizeof(domains); + if (sysctlbyname("vm.ndomains", &domains, &len, NULL, 0) == -1) + err(EX_OSERR, "ERROR: Cannot get number of domains"); /* * The initial CPU mask specifies the root mask of this process @@ -640,6 +665,7 @@ main(int argc, char **argv) case 's': /* system-wide counting PMC */ case 'P': /* process virtual sampling PMC */ case 'S': /* system-wide sampling PMC */ + caps = 0; if ((ev = malloc(sizeof(*ev))) == NULL) errx(EX_SOFTWARE, "ERROR: Out of memory."); @@ -707,12 +733,48 @@ main(int argc, char **argv) errx(EX_SOFTWARE, "ERROR: Out of memory."); (void) strncpy(ev->ev_name, optarg, c); *(ev->ev_name + c) = '\0'; + libpmc_initialize(&npmc); + if (args.pa_flags & FLAG_HAS_SYSTEM_PMCS) { + if (pmc_allocate(ev->ev_spec, ev->ev_mode, + ev->ev_flags, ev->ev_cpu, &ev->ev_pmcid, + ev->ev_count) < 0) + err(EX_OSERR, "ERROR: Cannot allocate " + "system-mode pmc with specification" + " \"%s\"", ev->ev_spec); + if (pmc_capabilities(ev->ev_pmcid, &caps)) { + pmc_release(ev->ev_pmcid); + err(EX_OSERR, "ERROR: Cannot get pmc " + "capabilities"); + } + } + STAILQ_INSERT_TAIL(&args.pa_events, ev, ev_next); + if ((caps & PMC_CAP_SYSWIDE) == PMC_CAP_SYSWIDE) + break; + if ((caps & PMC_CAP_DOMWIDE) == PMC_CAP_DOMWIDE) { + CPU_ZERO(&cpumask); + /* + * Get number of domains and allocate one + * counter in each. + * First already allocated. + */ + for (i = 1; i < domains; i++) { + CPU_ZERO(&dommask); + cpuset_getaffinity(CPU_LEVEL_WHICH, + CPU_WHICH_DOMAIN, i, sizeof(dommask), + &dommask); + CPU_SET(CPU_FFS(&dommask) - 1, &cpumask); + } + args.pa_flags |= FLAGS_HAS_CPUMASK; + } if (option == 's' || option == 'S') { CPU_CLR(ev->ev_cpu, &cpumask); + pmc_id_t saved_pmcid = ev->ev_pmcid; + ev->ev_pmcid = PMC_ID_INVALID; pmcstat_clone_event_descriptor(ev, &cpumask, &args); + ev->ev_pmcid = saved_pmcid; CPU_SET(ev->ev_cpu, &cpumask); } @@ -1050,17 +1112,8 @@ main(int argc, char **argv) } /* if we've been asked to process a log file, skip init */ - if ((args.pa_flags & FLAG_READ_LOGFILE) == 0) { - if (pmc_init() < 0) - err(EX_UNAVAILABLE, - "ERROR: Initialization of the pmc(3) library failed" - ); - - if ((npmc = pmc_npmc(0)) < 0) /* assume all CPUs are identical */ - err(EX_OSERR, -"ERROR: Cannot determine the number of PMCs on CPU %d", - 0); - } + if ((args.pa_flags & FLAG_READ_LOGFILE) == 0) + libpmc_initialize(&npmc); /* Allocate a kqueue */ if ((pmcstat_kq = kqueue()) < 0) @@ -1134,7 +1187,8 @@ main(int argc, char **argv) */ STAILQ_FOREACH(ev, &args.pa_events, ev_next) { - if (pmc_allocate(ev->ev_spec, ev->ev_mode, + if (ev->ev_pmcid == PMC_ID_INVALID && + pmc_allocate(ev->ev_spec, ev->ev_mode, ev->ev_flags, ev->ev_cpu, &ev->ev_pmcid, ev->ev_count) < 0) err(EX_OSERR,