From nobody Tue Oct 06 18:43:32 2026 X-Original-To: dev-commits-src-branches@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 4hzlWt05jjz6Z1tl for ; Tue, 06 Oct 2026 18:43:38 +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 4hzlWs4vxVz4FNs for ; Tue, 06 Oct 2026 18:43:37 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791312217; 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=ZXJLV0Sj7DxfQz7dBxdmLsMNDFzdV+E7T1O4ZD4G51Y=; b=PX2kBFV3AyxXi7f7NI7f2OkuXeiKsaVdemX9ZS8CcbTWpzGV4Xt6PEP+OWmAxd/Zj8tWKN xTsUWW7z6eALcQytn/CCITAhtfLiTF/gW8GijzRgb/Bh2Refrkr83sHM+SFvD4HWKlTNIg r57Ru7oaBa1swy8Hh88bovgd/tbajQRX3iJSnMSnZoGmF7gFGLBoX///GsTwzv5+tYAMUt Y2FoLVcgcVei1Q2U7g3FaoAolY9tuZ8RiMGFwxDj3IRyg0fm/qaq1roDBSjksfQcn59cPw KYpaMNUPOuQhpQsnu014qvhADoytQSZtEdRW4WdkF8quS+F2ye1cgBpoe9Vktw== ARC-Seal: i=1; a=rsa-sha256; d=freebsd.org; s=dkim; cv=none; t=1791312217; b=M+WRHxo+lMWqiu8hrQIwAy0RsvDSVU1zr6cFvTbjWFa+5oAWkXLNr94blN5INX1UY1A4Hs o5HsYC2yqx3fjIexBEIW/VzEqQmRkSKw3ZrJzX7xyhLfyH6z2k/EGkW6R1JEC/wPeSSloR eGrciq6MuonpfS2/PGou08rJU/638S5IiKyVbhKZ8QCdWlqfYzOa7/DEYDMOmHyBFoxqnd 8I85phPSp8LWbH3PyiwN4y+MnFdSP0rzg7+e6/+OnQF84mDNBOb5Iszt0uR1RV+4NU5E7H thWl1GU54R5qalw/4gA7WckC9ZJuogPM09dEQj2pRxnlSS4mp2UOVozwB9Q4YA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1791312217; 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=ZXJLV0Sj7DxfQz7dBxdmLsMNDFzdV+E7T1O4ZD4G51Y=; b=X5hMWQ82CK6+Zpc2FVaeBrOn9XTVv4HAPEMnQMsuc6118VLuo9gju94A90skqogkNVP21n rLKozBRcE5p9ClTyV0WmDt8IbJ7mFrc0jxOGqDPy83ufMUx1FDEu+WgZVdu5BrgrSvaGDU XkweXWbVqXT8l4Z+CAN3zWmVnQVMLFb9ZxJxPenopUW/tGkvL1B6CoOMOs7/RP/VMhthDO t28FBb7LlpKfZJh0FH865RL82592SvextruWxMIQVmKkKcOTs5iqcJaxcTTg0Cymt1Ixmw 8b0jlLBZRK1abhZE9LYSfH+YJDoNLFCpQAxkbbNBc+Qaiq6Fm6NsJkC8w2sJ0Q== 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 4hzlWs3fBszJ6f for ; Tue, 06 Oct 2026 18:43:37 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 3fb1f by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Tue, 06 Oct 2026 18:43:32 +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: 7c5caf70b6e9 - stable/15 - libpmc: Query hwpmc for caps List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-branches@freebsd.org Sender: owner-dev-commits-src-branches@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/15 X-Git-Reftype: branch X-Git-Commit: 7c5caf70b6e9ec9de608480b841fb1d091f1d3ff Auto-Submitted: auto-generated Date: Tue, 06 Oct 2026 18:43:32 +0000 Message-Id: <6ac54154.3fb1f.25850f91@gitrepo.freebsd.org> The branch stable/15 has been updated by mhorne: URL: https://cgit.FreeBSD.org/src/commit/?id=7c5caf70b6e9ec9de608480b841fb1d091f1d3ff commit 7c5caf70b6e9ec9de608480b841fb1d091f1d3ff Author: Ali Mashtizadeh AuthorDate: 2026-03-01 22:08:30 +0000 Commit: Mitchell Horne CommitDate: 2026-10-06 18:27:57 +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 10e357f55935..aad9c2dff737 100644 --- a/lib/libpmc/libpmc.c +++ b/lib/libpmc/libpmc.c @@ -1168,17 +1168,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 8bb1cb96f694..5b3e9a195b8c 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 82d1a4c6180c..1ecea9dd28d0 100644 --- a/sys/dev/hwpmc/hwpmc_amd.c +++ b/sys/dev/hwpmc/hwpmc_amd.c @@ -695,6 +695,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. */ @@ -1022,6 +1036,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_cputype = cputype; pmc_mdep->pmd_intr = amd_intr; diff --git a/sys/dev/hwpmc/hwpmc_mod.c b/sys/dev/hwpmc/hwpmc_mod.c index 342b600276b0..de6beb165c66 100644 --- a/sys/dev/hwpmc/hwpmc_mod.c +++ b/sys/dev/hwpmc/hwpmc_mod.c @@ -4583,6 +4583,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 726a03c35502..7ac6eafdac4d 100644 --- a/sys/sys/pmc.h +++ b/sys/sys/pmc.h @@ -348,7 +348,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 @@ -639,6 +640,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 @@ -1031,6 +1043,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);