From nobody Tue Oct 06 18:49:02 2026 X-Original-To: dev-commits-src-all@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 4hzlfD5JZWz6Z33P for ; Tue, 06 Oct 2026 18:49:08 +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 "YR2" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4hzlfD1cxqz4GnS for ; Tue, 06 Oct 2026 18:49:08 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791312548; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WJCOrpdhMg+kjOHr7IK7eyB9Usx10k7b6S88KXUK1So=; b=Ut8K7XeXQPOGVUyJqFakMBg8YF7PexLARQ1wLxdCLNzYWbs9LtqIfUum/VEUSzu7s4csOY uh7fWVFCDe2f1DeVkYoCzOIdAb6JWuy/42SdYbLds0bWYCk7iJoPG/jMyRx97DOLW8Npf+ 7IS73cOWlAI9em5/A+tViqToYH5MkkgoDXEahBPy7LnUNflO0TZZWSIpkPU7VKz2X/X3k8 Gx0sU6lO2Mng8bSe70TujkBbpSZwkE6b6HHogZUCtyoRzy9sq5F2wQYegTfv/0pioJrGw7 aWtcbpWALRAyFeFAk25ux55QCm0HEgefFVvTE15Om8c4YviLGMP0uKwPFOO3sA== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791312548; b=Yn1Iv8y4Nnt6QwD2VDTNfkK2UZFZP6xCgF4VS6NkarkdwREZnXHBgcwOU+OEKAk8Sa7IGx HrBGd/h7kqvRq97jX9k63GSooL3wWsvdVcIS4AkAREKpFwSikW5F4rdbY1W8RDAscaUBU/ jpElRXsT4CrSDS687qpktdoNYmTIQWAi9Q75Cey1F5trToNF/s/LHOFOApHquziK6xyOvl j4CGgpg3w7Z8CKl+IvLHg1+xraaAknKkezUbfFJ5a9Fy/gwTXQytcA9L1YWWGR3Ph2h5JY 1+B+DTIGd1G7qDjUA5fHmjmx7Z5FaQ0vNfZf8yeiFR0HVsRcnUc7RjE49UT2Gw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791312548; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=WJCOrpdhMg+kjOHr7IK7eyB9Usx10k7b6S88KXUK1So=; b=cYWh7IRyTB79hHdjMVonoIA8xsSQG2MLiLshEixJQ+g4/dlcryp1Vp+5BP1Ta94xBd/++N 4+dW8O7+RWlbP3y9Z/GLc3jlh+FSyls1F7Bc8v1EjISgIVUe9mEkrqnHvKHE56O3Ygo8Pi FFQPhxrBsLgS7D8ybOOUP4hLl5AlPtMn8me1vu1+ePAu2/Gve6iYyw10G83q1UlQWE7Suw /YEpBbR5O20OobtYAt+11dTUjQVRZ4fpF5Na+nqI7hurhAioI00Ese/zsfikD61UTboD2/ SKcSfUI2wm5zhpWooz7ZEAtuW21XjwoAMPGBdj1DUCupx2KFp75hbk+EE++vFg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4hzlfC74ZvzJB4 for ; Tue, 06 Oct 2026 18:49:07 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3ed9c by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 06 Oct 2026 18:49:02 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Cc: Ali Mashtizadeh From: Mitchell Horne Subject: git: 1cc380dbe814 - stable/14 - libpmc: Query hwpmc for caps List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mhorne X-Git-Repository: src X-Git-Refname: refs/heads/stable/14 X-Git-Reftype: branch X-Git-Commit: 1cc380dbe8148d86ba655a92d663da0fd05fb03f Auto-Submitted: auto-generated Date: Tue, 06 Oct 2026 18:49:02 +0000 Message-Id: <6ac5429e.3ed9c.7ac1ff5@gitrepo.freebsd.org> The branch stable/14 has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=1cc380dbe8148d86ba655a92d663da0fd05fb03f commit 1cc380dbe8148d86ba655a92d663da0fd05fb03f Author: Ali Mashtizadeh AuthorDate: 2026-03-01 22:08:30 +0000 Commit: Mitchell Horne CommitDate: 2026-10-06 18:48:37 +0000 libpmc: Query hwpmc for caps This change allows for fine-grained capabilities per counter index. This is particularly useful for AMD where subclasses are not exposed to the general PMC code, but other architectures also have asymmetric behaviors when it comes to specific counter indices. A new PMC_OP_GETCAPS op is added to the hwpmc(4) ioctl interface. Reviewed by: mhorne Sponsored by: Netflix Pull Request: https://github.com/freebsd/freebsd-src/pull/2058 (cherry picked from commit 44a983d249d05d932b6cff333f130baf70febc22) --- lib/libpmc/libpmc.c | 19 +++++++++---------- share/man/man4/hwpmc.4 | 4 ++++ sys/dev/hwpmc/hwpmc_amd.c | 15 +++++++++++++++ sys/dev/hwpmc/hwpmc_mod.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ sys/sys/pmc.h | 15 ++++++++++++++- 5 files changed, 87 insertions(+), 11 deletions(-) diff --git a/lib/libpmc/libpmc.c b/lib/libpmc/libpmc.c index f10a64e28cac..c6aaf5cdec16 100644 --- a/lib/libpmc/libpmc.c +++ b/lib/libpmc/libpmc.c @@ -1169,17 +1169,16 @@ pmc_attach(pmc_id_t pmc, pid_t pid) int pmc_capabilities(pmc_id_t pmcid, uint32_t *caps) { - unsigned int i; - enum pmc_class cl; + struct pmc_op_caps args; + int status; - cl = PMC_ID_TO_CLASS(pmcid); - for (i = 0; i < cpu_info.pm_nclass; i++) - if (cpu_info.pm_classes[i].pm_class == cl) { - *caps = cpu_info.pm_classes[i].pm_caps; - return (0); - } - errno = EINVAL; - return (-1); + args.pm_pmcid = pmcid; + args.pm_caps = 0; + + status = PMC_CALL(PMC_OP_GETCAPS, &args); + *caps = args.pm_caps; + + return (status); } int diff --git a/share/man/man4/hwpmc.4 b/share/man/man4/hwpmc.4 index 54a251dcca76..1ab690e5009c 100644 --- a/share/man/man4/hwpmc.4 +++ b/share/man/man4/hwpmc.4 @@ -325,6 +325,10 @@ This operation returns to the caller after the write operation has returned. The returned error code reflects any pending error state inside .Nm . +.It Dv PMC_OP_GETCAPS +Retrieve the capabilities associated with a specific PMC counter. +Some capabilities may be limited to specific indices (i.e., not available +across all counters within a class). .It Dv PMC_OP_GETCPUINFO Retrieve information about the highest possible CPU number for the system, and the number of hardware performance monitoring counters available per CPU. diff --git a/sys/dev/hwpmc/hwpmc_amd.c b/sys/dev/hwpmc/hwpmc_amd.c index 8e1a6ad25be7..1e8f1421eca2 100644 --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -919,6 +919,20 @@ amd_get_msr(int ri, uint32_t *msr) return (0); } +/* + * Return the capabilities of the given PMC. + */ +static int +amd_get_caps(int ri, uint32_t *caps) +{ + KASSERT(ri >= 0 && ri < amd_npmcs, + ("[amd,%d] ri %d out of range", __LINE__, ri)); + + *caps = amd_pmcdesc[ri].pm_descr.pd_caps; + + return (0); +} + /* * processor dependent initialization. */ @@ -1144,6 +1158,7 @@ pmc_amd_initialize(void) pcd->pcd_start_pmc = amd_start_pmc; pcd->pcd_stop_pmc = amd_stop_pmc; pcd->pcd_write_pmc = amd_write_pmc; + pcd->pcd_get_caps = amd_get_caps; pmc_mdep->pmd_intr = amd_intr; pmc_mdep->pmd_switch_in = amd_switch_in; diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index 216430e3ef5c..0a5ee8c18e13 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -4586,6 +4586,51 @@ pmc_syscall_handler(struct thread *td, void *syscall_args) } break; + /* + * Get the PMC capabilities + */ + + case PMC_OP_GETCAPS: + { + struct pmc_op_caps c; + struct pmc *pm; + struct pmc_classdep *pcd; + pmc_id_t pmcid; + int adjri, ri; + + PMC_DOWNGRADE_SX(); + + if ((error = copyin(arg, &c, sizeof(c))) != 0) + break; + + pmcid = c.pm_pmcid; + + if ((error = pmc_find_pmc(pmcid, &pm)) != 0) + break; + + KASSERT(pmcid == pm->pm_id, + ("[pmc,%d] pmc id %x != pmcid %x", __LINE__, + pm->pm_id, pmcid)); + + ri = PMC_TO_ROWINDEX(pm); + pcd = pmc_ri_to_classdep(md, ri, &adjri); + + /* + * If PMC class has no GETCAPS return the class capabilities + * otherwise get the per counter capabilities. + */ + if (pcd->pcd_get_caps == NULL) { + c.pm_caps = pcd->pcd_caps; + } else { + error = (*pcd->pcd_get_caps)(adjri, &c.pm_caps); + if (error < 0) + break; + } + + if ((error = copyout(&c, arg, sizeof(c))) < 0) + break; + } + break; default: error = EINVAL; diff --git a/sys/sys/pmc.h b/sys/sys/pmc.h index d190632f7a9b..06987e91b942 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -349,7 +349,8 @@ enum pmc_event { __PMC_OP(PMCSTOP, "Stop a PMC") \ __PMC_OP(WRITELOG, "Write a cookie to the log file") \ __PMC_OP(CLOSELOG, "Close log file") \ - __PMC_OP(GETDYNEVENTINFO, "Get dynamic events list") + __PMC_OP(GETDYNEVENTINFO, "Get dynamic events list") \ + __PMC_OP(GETCAPS, "Get capabilities") enum pmc_ops { #undef __PMC_OP @@ -640,6 +641,17 @@ struct pmc_op_getdyneventinfo { struct pmc_dyn_event_descr pm_events[PMC_EV_DYN_COUNT]; }; +/* + * OP GETCAPS + * + * Retrieve the PMC capabilties flags for this type of counter. + */ + +struct pmc_op_caps { + pmc_id_t pm_pmcid; /* allocated pmc id */ + uint32_t pm_caps; /* capabilities */ +}; + #ifdef _KERNEL #include @@ -1030,6 +1042,7 @@ struct pmc_classdep { /* description */ int (*pcd_describe)(int _cpu, int _ri, struct pmc_info *_pi, struct pmc **_ppmc); + int (*pcd_get_caps)(int _ri, uint32_t *_caps); /* class-dependent initialization & finalization */ int (*pcd_pcpu_init)(struct pmc_mdep *_md, int _cpu);