Page MenuHomeFreeBSD

hwpmc: add PMU assigner and AMD Zen constraint provider
Needs ReviewPublic

Authored by afscoelho_gmail.com on Jun 18 2026, 7:06 AM.
Tags
None
Referenced Files
Unknown Object (File)
Mon, Sep 7, 11:15 PM
Unknown Object (File)
Fri, Sep 4, 11:11 AM
Unknown Object (File)
Thu, Sep 3, 3:46 PM
Unknown Object (File)
Tue, Sep 1, 11:41 AM
Unknown Object (File)
Fri, Aug 28, 8:33 PM
Unknown Object (File)
Thu, Aug 27, 7:46 PM
Unknown Object (File)
Wed, Aug 26, 6:46 PM
Unknown Object (File)
Sat, Aug 22, 10:00 AM
Subscribers
None

Details

Summary

Two pieces:

(1) sys/dev/hwpmc/hwpmc_assign.c

Most-constrained-first greedy assigner.  pmu_count_core_hw_slots
enumerates global rows that are class-compatible with the leader and
pass amd_can_assign_pmc; pmu_assign_group sorts events by weight and
binds them all-or-none.  Critical detail: the assigner operates in
per-class adjri space for pe_cons.pc_allowed_rows / *used_mask /
pc_fixed_row, but the framework numbers PMC rows globally.  The code
converts adjri <-> ri via hwpmc_ri_to_classdep() and pcd->pcd_ri so
that amd_can_assign_pmc and pcd_allocate_pmc are always called with
the class-relative index they expect.  Without this conversion AMD
trips its own KASSERT (illegal row index >= amd_npmcs) on Zen, where
K8 rows start at global ri=17.

(2) sys/dev/hwpmc/hwpmc_amd.c

Add amd_can_assign_pmc() (factored out of amd_allocate_pmc) and
amd_get_sched_constraint() that emits a pmc_sched_constraint_t
covering every Zen sub-class (CORE / L3_CACHE / DATA_FABRIC).
pc_allowed_rows is built in the per-class adjri namespace as
documented in hwpmc_pmu.h.  The two new functions are prototyped in
hwpmc_pmu.h (alongside the rest of the PMU layer interface) so
hwpmc_amd.h needs no change.  Other backends (Intel/ARM) continue to
return EOPNOTSUPP so legacy non-grouped allocation is unaffected.

Sponsored by: AMD
Signed-off-by: Raghavendra K T <raghavendra.kt@amd.com>

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 76444
Build 73327: arc lint + arc unit

Event Timeline

In the existing code we have to allocate counters into specific indexes in an order to check that they meet our constraints. Either:

  1. Keep this approach and you can just save and restore the counter to specific indices, which is nice because it checks that the group of counters can be satisfied. It's not a great approach for multiplexing.
  2. Expose the constraint checking to userspace so we can validate the counters without allocation.

https://reviews.freebsd.org/D57637 line pmcstat.c:1171

sys/dev/hwpmc/hwpmc_amd.c
673

Leave the comments in here and below that this is older support below this line. Hopefully @mhorne can land his diff to just remove this code.

I think my higher level comment in the previous diff still holds that you can just expose the amd functions through the pmc_classdep struct to make it platform agnostic and then remove the #ifdefs and amd specific checks throughout the code. Everyone zero's out that structure so we depend on a NULL pointer meaning that the call isn't implemented. Just have your wrapper function return EOPNOTSUPP if it's a null pointer.

sys/dev/hwpmc/hwpmc_amd.c
46

Should move down below machine headers.

654

Maintain the largest to smallest sorting of local variables (see style manpage)

sys/dev/hwpmc/hwpmc_assign.c
92

In here you have the pcd struct if you just expose the functions through the structure you can make this platform agnostic.

170

Local variable definitions always go at the top of the function.

This revision now requires changes to proceed.Jun 30 2026, 3:58 PM
afscoelho_gmail.com updated this revision to Diff 185747.

Update to the rebuilt PerfMonV2 grouping and multiplexing stack.