* [PATCH v5 0/2] perf/x86/amd/uncore: Add Hygon uncore PMU and JSON events
@ 2026-08-18 10:01 Qi Liu
2026-08-18 10:01 ` [PATCH v5 1/2] perf/x86/amd/uncore: Add Hygon uncore PMU support Qi Liu
2026-08-18 10:01 ` [PATCH v5 2/2] perf vendor events hygon: Add Hygon Data Fabric PMU events and metrics Qi Liu
0 siblings, 2 replies; 7+ messages in thread
From: Qi Liu @ 2026-08-18 10:01 UTC (permalink / raw)
To: peterz, mingo, namhyung, alexander.shishkin, jolsa, sandipan.das,
ravi.bangoria, irogers, x86
Cc: linux-perf-users, linux-kernel, lijing, liuqi
This series adds initial uncore PMU support for Hygon Family 18h
processors.
Hygon uncore PMUs use a programming model similar to AMD's, but
differ in MSR base addresses, event encodings, and counter allocation
semantics. Rather than embedding Hygon support in the AMD uncore
driver with vendor checks, a dedicated driver is introduced to keep
both drivers clean and independently maintainable.
The new driver provides hygon_df and hygon_df_iod PMUs covering the
Data Fabric on both the CPU die and the IO Die, together with perf
JSON events and metrics for three processor models. A per-context
hrtimer handles counter reads, and CPU hotplug callbacks manage
context lifecycle.
Changes since RFC:
- Address sashiko bot review.
Changes since v1:
- Rename the helper namespace to amd_uncore_common_* to avoid
an generic uncore_common_* prefix, and to keep it distinct
from the existing amd_uncore_* names.
Changes since v2:
- Drop the common helpers refactoring. Keep the Hygon driver
self-contained instead, avoiding unnecessary changes in the AMD
uncore driver.
Changes since v3:
- Address sashiko bot review.
Changes since v4:
- Improve Hygon Data Fabric PMU event naming, descriptions, and scaling.
Qi Liu (2):
perf/x86/amd/uncore: Add Hygon uncore PMU support
perf vendor events hygon: Add Hygon Data Fabric PMU events and metrics
arch/x86/events/Kconfig | 11 +
arch/x86/events/amd/Makefile | 2 +
arch/x86/events/amd/hygon_uncore.c | 872 ++++++++++++++++++
arch/x86/events/amd/uncore.c | 11 +-
arch/x86/include/asm/msr-index.h | 2 +
arch/x86/include/asm/perf_event.h | 20 +
include/linux/cpuhotplug.h | 3 +
tools/perf/pmu-events/Build | 2 +-
.../arch/x86/hygonm1/data-fabric.json | 95 ++
.../arch/x86/hygonm4/data-fabric.json | 134 +++
.../arch/x86/hygonm6/data-fabric.json | 170 ++++
tools/perf/pmu-events/arch/x86/mapfile.csv | 3 +
tools/perf/pmu-events/jevents.py | 2 +
13 files changed, 1318 insertions(+), 9 deletions(-)
create mode 100644 arch/x86/events/amd/hygon_uncore.c
create mode 100644 tools/perf/pmu-events/arch/x86/hygonm1/data-fabric.json
create mode 100644 tools/perf/pmu-events/arch/x86/hygonm4/data-fabric.json
create mode 100644 tools/perf/pmu-events/arch/x86/hygonm6/data-fabric.json
--
2.34.1
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v5 1/2] perf/x86/amd/uncore: Add Hygon uncore PMU support
2026-08-18 10:01 [PATCH v5 0/2] perf/x86/amd/uncore: Add Hygon uncore PMU and JSON events Qi Liu
@ 2026-08-18 10:01 ` Qi Liu
2026-08-18 10:16 ` sashiko-bot
2026-08-18 10:01 ` [PATCH v5 2/2] perf vendor events hygon: Add Hygon Data Fabric PMU events and metrics Qi Liu
1 sibling, 1 reply; 7+ messages in thread
From: Qi Liu @ 2026-08-18 10:01 UTC (permalink / raw)
To: peterz, mingo, namhyung, alexander.shishkin, jolsa, sandipan.das,
ravi.bangoria, irogers, x86
Cc: linux-perf-users, linux-kernel, lijing, liuqi, Zhenglang Hu
Add uncore PMU driver for Hygon Family 18h processors, supporting two
PMU types:
- hygon_df: Data Fabric counters shared across CPUs within the
same DF instance, identified via Node ID.
- hygon_df_iod: Data Fabric counters on the IO Die (IOD) for
monitoring memory access metrics.
A per-context hrtimer periodically reads the counters since uncore
PMUs do not generate interrupts. CPU hotplug callbacks handle context
creation, migration, and teardown.
Keeping Hygon support in a separate driver avoids accumulating vendor
checks in uncore.c as more Hygon-specific features are introduced.
Remove the now-unnecessary Hygon checks from the AMD uncore driver.
Signed-off-by: Qi Liu <liuqi@hygon.cn>
Tested-by: Zhenglang Hu <huzhenglang@hygon.cn>
---
arch/x86/events/Kconfig | 11 +
arch/x86/events/amd/Makefile | 2 +
arch/x86/events/amd/hygon_uncore.c | 872 +++++++++++++++++++++++++++++
arch/x86/events/amd/uncore.c | 11 +-
arch/x86/include/asm/msr-index.h | 2 +
arch/x86/include/asm/perf_event.h | 20 +
include/linux/cpuhotplug.h | 3 +
7 files changed, 913 insertions(+), 8 deletions(-)
create mode 100644 arch/x86/events/amd/hygon_uncore.c
diff --git a/arch/x86/events/Kconfig b/arch/x86/events/Kconfig
index dabdf3d7bf84..cc8387236b95 100644
--- a/arch/x86/events/Kconfig
+++ b/arch/x86/events/Kconfig
@@ -45,6 +45,17 @@ config PERF_EVENTS_AMD_UNCORE
To compile this driver as a module, choose M here: the
module will be called 'amd-uncore'.
+config PERF_EVENTS_HYGON_UNCORE
+ tristate "Hygon Uncore performance events"
+ depends on PERF_EVENTS && CPU_SUP_HYGON
+ default y
+ help
+ Include support for Hygon uncore performance events for use with
+ e.g., perf stat -e hygon_df/.../.
+
+ To compile this driver as a module, choose M here: the
+ module will be called 'hygon-uncore'.
+
config PERF_EVENTS_AMD_BRS
depends on PERF_EVENTS && CPU_SUP_AMD
bool "AMD Zen3 Branch Sampling support"
diff --git a/arch/x86/events/amd/Makefile b/arch/x86/events/amd/Makefile
index 527d947eb76b..c373fd1d1525 100644
--- a/arch/x86/events/amd/Makefile
+++ b/arch/x86/events/amd/Makefile
@@ -5,6 +5,8 @@ obj-$(CONFIG_PERF_EVENTS_AMD_POWER) += power.o
obj-$(CONFIG_X86_LOCAL_APIC) += ibs.o
obj-$(CONFIG_PERF_EVENTS_AMD_UNCORE) += amd-uncore.o
amd-uncore-objs := uncore.o
+obj-$(CONFIG_PERF_EVENTS_HYGON_UNCORE) += hygon-uncore.o
+hygon-uncore-objs := hygon_uncore.o
ifdef CONFIG_AMD_IOMMU
obj-$(CONFIG_CPU_SUP_AMD) += iommu.o
endif
diff --git a/arch/x86/events/amd/hygon_uncore.c b/arch/x86/events/amd/hygon_uncore.c
new file mode 100644
index 000000000000..471955d6fc28
--- /dev/null
+++ b/arch/x86/events/amd/hygon_uncore.c
@@ -0,0 +1,872 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2026 Chengdu Haiguang IC Design Co., Ltd.
+ *
+ */
+
+#include <linux/cpu.h>
+#include <linux/cpumask.h>
+#include <linux/cpufeature.h>
+#include <linux/hrtimer.h>
+#include <linux/init.h>
+#include <linux/perf_event.h>
+#include <linux/percpu.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/types.h>
+
+#include <asm/amd/nb.h>
+#include <asm/cpuid/api.h>
+#include <asm/perf_event.h>
+#include <asm/msr.h>
+
+#define HYGON_UNCORE_NUM_COUNTERS_DF 4
+#define HYGON_UNCORE_NUM_COUNTERS_MAX 8
+
+#define HYGON_UNCORE_NAME_LEN 16
+#define HYGON_UNCORE_COUNTER_SHIFT 16
+
+#undef pr_fmt
+#define pr_fmt(fmt) "hygon_uncore: " fmt
+
+struct hygon_uncore_ctx {
+ int refcnt;
+ int cpu;
+ struct perf_event **events;
+ unsigned long active_mask[BITS_TO_LONGS(HYGON_UNCORE_NUM_COUNTERS_MAX)];
+ int nr_active;
+ struct hrtimer hrtimer;
+ u64 hrtimer_duration;
+};
+
+struct hygon_uncore_pmu {
+ char name[HYGON_UNCORE_NAME_LEN];
+ int type;
+ int num_counters;
+ u32 msr_base;
+ cpumask_t active_mask;
+ struct pmu pmu;
+ struct hygon_uncore_ctx * __percpu *ctx;
+};
+
+enum {
+ HYGON_UNCORE_TYPE_DF,
+ HYGON_UNCORE_TYPE_DF_IOD,
+ HYGON_UNCORE_TYPE_MAX
+};
+
+union hygon_uncore_info {
+ struct {
+ u64 num_iods:8; /* number of iods of each package */
+ u64 num_pmcs:8; /* number of counters */
+ u64 cid:8; /* context id */
+ } split;
+ u64 full;
+};
+
+struct hygon_uncore {
+ union hygon_uncore_info __percpu *info;
+ struct hygon_uncore_pmu pmu;
+ bool pmu_registered;
+ bool init_done;
+ void (*scan)(struct hygon_uncore *uncore, unsigned int cpu);
+ int (*init)(struct hygon_uncore *uncore, unsigned int cpu);
+ void (*move)(struct hygon_uncore *uncore, unsigned int cpu);
+ void (*free)(struct hygon_uncore *uncore, unsigned int cpu);
+};
+static struct hygon_uncore uncores[];
+
+static unsigned int update_interval = 60 * MSEC_PER_SEC;
+module_param(update_interval, uint, 0444);
+
+static struct hygon_uncore_pmu *event_to_hygon_uncore_pmu(struct perf_event *event)
+{
+ return container_of(event->pmu, struct hygon_uncore_pmu, pmu);
+}
+
+static __always_inline bool is_uncore_df_iod_event(struct hygon_uncore_pmu *pmu)
+{
+ return pmu->type == HYGON_UNCORE_TYPE_DF_IOD;
+}
+
+static __always_inline int hygon_uncore_ctx_num_pmcs(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ union hygon_uncore_info *info = per_cpu_ptr(uncore->info, cpu);
+
+ return info->split.num_pmcs;
+}
+
+static __always_inline int hygon_uncore_ctx_cid(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ union hygon_uncore_info *info = per_cpu_ptr(uncore->info, cpu);
+
+ return info->split.cid;
+}
+
+static __always_inline int hygon_uncore_ctx_num_iods(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ union hygon_uncore_info *info = per_cpu_ptr(uncore->info, cpu);
+
+ return info->split.num_iods;
+}
+
+static enum hrtimer_restart hygon_uncore_hrtimer(struct hrtimer *hrtimer)
+{
+ struct hygon_uncore_ctx *ctx;
+ struct perf_event *event;
+ int bit;
+
+ ctx = container_of(hrtimer, struct hygon_uncore_ctx, hrtimer);
+
+ if (!ctx->nr_active || ctx->cpu != smp_processor_id())
+ return HRTIMER_NORESTART;
+
+ for_each_set_bit(bit, ctx->active_mask, HYGON_UNCORE_NUM_COUNTERS_MAX) {
+ event = ctx->events[bit];
+ event->pmu->read(event);
+ }
+
+ hrtimer_forward_now(hrtimer, ns_to_ktime(ctx->hrtimer_duration));
+ return HRTIMER_RESTART;
+}
+
+static void hygon_uncore_start_hrtimer(struct hygon_uncore_ctx *ctx)
+{
+ hrtimer_start(&ctx->hrtimer, ns_to_ktime(ctx->hrtimer_duration),
+ HRTIMER_MODE_REL_PINNED_HARD);
+}
+
+static void hygon_uncore_cancel_hrtimer(struct hygon_uncore_ctx *ctx)
+{
+ hrtimer_cancel(&ctx->hrtimer);
+}
+
+static void hygon_uncore_init_hrtimer(struct hygon_uncore_ctx *ctx)
+{
+ hrtimer_setup(&ctx->hrtimer, hygon_uncore_hrtimer, CLOCK_MONOTONIC,
+ HRTIMER_MODE_REL_HARD);
+}
+
+static void hygon_uncore_read(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ u64 prev, cur;
+ s64 delta;
+
+ do {
+ prev = local64_read(&hwc->prev_count);
+ rdmsrq(hwc->event_base, cur);
+ } while (local64_cmpxchg(&hwc->prev_count, prev, cur) != prev);
+ delta = (cur << HYGON_UNCORE_COUNTER_SHIFT) -
+ (prev << HYGON_UNCORE_COUNTER_SHIFT);
+ delta >>= HYGON_UNCORE_COUNTER_SHIFT;
+ local64_add(delta, &event->count);
+}
+
+static void hygon_uncore_start(struct perf_event *event, int flags)
+{
+ struct hygon_uncore_pmu *pmu = event_to_hygon_uncore_pmu(event);
+ struct hygon_uncore_ctx *ctx = *per_cpu_ptr(pmu->ctx, event->cpu);
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (!ctx->nr_active++)
+ hygon_uncore_start_hrtimer(ctx);
+
+ if (flags & PERF_EF_RELOAD)
+ wrmsrq(hwc->event_base, (u64)local64_read(&hwc->prev_count));
+
+ hwc->state = 0;
+ __set_bit(hwc->idx, ctx->active_mask);
+ wrmsrq(hwc->config_base, (hwc->config | ARCH_PERFMON_EVENTSEL_ENABLE));
+ perf_event_update_userpage(event);
+}
+
+static void hygon_uncore_stop(struct perf_event *event, int flags)
+{
+ struct hygon_uncore_pmu *pmu = event_to_hygon_uncore_pmu(event);
+ struct hygon_uncore_ctx *ctx = *per_cpu_ptr(pmu->ctx, event->cpu);
+ struct hw_perf_event *hwc = &event->hw;
+
+ wrmsrq(hwc->config_base, hwc->config);
+ hwc->state |= PERF_HES_STOPPED;
+
+ if ((flags & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) {
+ event->pmu->read(event);
+ hwc->state |= PERF_HES_UPTODATE;
+ }
+
+ if (!--ctx->nr_active)
+ hygon_uncore_cancel_hrtimer(ctx);
+
+ __clear_bit(hwc->idx, ctx->active_mask);
+}
+
+static int hygon_uncore_add(struct perf_event *event, int flags)
+{
+ struct hygon_uncore_pmu *pmu = event_to_hygon_uncore_pmu(event);
+ struct hygon_uncore_ctx *ctx = *per_cpu_ptr(pmu->ctx, event->cpu);
+ struct hw_perf_event *hwc = &event->hw;
+ int i, iod_idx;
+
+ if (!ctx)
+ return -ENODEV;
+
+ if (hwc->idx != -1 && ctx->events[hwc->idx] == event)
+ goto out;
+
+ for (i = 0; i < pmu->num_counters; i++) {
+ if (ctx->events[i] == event) {
+ hwc->idx = i;
+ goto out;
+ }
+ }
+
+ hwc->idx = -1;
+ if (is_uncore_df_iod_event(pmu)) {
+ iod_idx = event->attr.config1;
+ for (i = iod_idx * HYGON_UNCORE_NUM_COUNTERS_DF;
+ i < (iod_idx + 1) * HYGON_UNCORE_NUM_COUNTERS_DF;
+ i++) {
+ struct perf_event *tmp = NULL;
+
+ if (try_cmpxchg(&ctx->events[i], &tmp, event)) {
+ hwc->idx = i;
+ break;
+ }
+ }
+ } else {
+ for (i = 0; i < pmu->num_counters; i++) {
+ struct perf_event *tmp = NULL;
+
+ if (try_cmpxchg(&ctx->events[i], &tmp, event)) {
+ hwc->idx = i;
+ break;
+ }
+ }
+ }
+out:
+ if (hwc->idx == -1)
+ return -EBUSY;
+
+ hwc->config_base = pmu->msr_base + (2 * hwc->idx);
+ hwc->event_base = pmu->msr_base + 1 + (2 * hwc->idx);
+ hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED;
+ if (flags & PERF_EF_START)
+ event->pmu->start(event, PERF_EF_RELOAD);
+
+ return 0;
+}
+
+static void hygon_uncore_del(struct perf_event *event, int flags)
+{
+ struct hygon_uncore_pmu *pmu = event_to_hygon_uncore_pmu(event);
+ struct hygon_uncore_ctx *ctx = *per_cpu_ptr(pmu->ctx, event->cpu);
+ struct hw_perf_event *hwc = &event->hw;
+ int i;
+
+ if (!ctx)
+ return;
+
+ event->pmu->stop(event, PERF_EF_UPDATE);
+ for (i = 0; i < pmu->num_counters; i++) {
+ struct perf_event *tmp = event;
+
+ if (try_cmpxchg(&ctx->events[i], &tmp, NULL))
+ break;
+ }
+
+ hwc->idx = -1;
+}
+
+static int hygon_uncore_event_init(struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hygon_uncore_pmu *pmu;
+ struct hygon_uncore_ctx *ctx;
+
+ if (event->attr.type != event->pmu->type)
+ return -ENOENT;
+
+ if (event->cpu < 0)
+ return -EINVAL;
+
+ pmu = event_to_hygon_uncore_pmu(event);
+ ctx = *per_cpu_ptr(pmu->ctx, event->cpu);
+ if (!ctx)
+ return -ENODEV;
+
+ event->cpu = ctx->cpu;
+ hwc->config = event->attr.config;
+ hwc->idx = -1;
+
+ return 0;
+}
+
+static int hygon_uncore_df_event_init(struct perf_event *event)
+{
+ int ret = hygon_uncore_event_init(event);
+ struct hw_perf_event *hwc = &event->hw;
+ struct hygon_uncore_pmu *pmu;
+ struct hygon_uncore *uncore;
+ u64 event_mask = HYGON_F18H_RAW_EVENT_MASK_DF;
+
+ if (ret)
+ return ret;
+
+ pmu = event_to_hygon_uncore_pmu(event);
+ uncore = &uncores[pmu->type];
+ if (is_uncore_df_iod_event(pmu) &&
+ (event->attr.config1 >= hygon_uncore_ctx_num_iods(uncore, event->cpu)))
+ return -EINVAL;
+
+ if (boot_cpu_data.x86_model == 0x4 ||
+ boot_cpu_data.x86_model == 0x5)
+ event_mask = HYGON_F18H_M4H_RAW_EVENT_MASK_DF;
+ else if (boot_cpu_data.x86_model >= 0x6 &&
+ boot_cpu_data.x86_model <= 0x18)
+ event_mask = HYGON_F18H_M6H_RAW_EVENT_MASK_DF;
+
+ hwc->config = event->attr.config & event_mask;
+ return 0;
+}
+
+static ssize_t cpumask_show(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct pmu *ptr = dev_get_drvdata(dev);
+ struct hygon_uncore_pmu *pmu = container_of(ptr, struct hygon_uncore_pmu, pmu);
+
+ return cpumap_print_to_pagebuf(true, buf, &pmu->active_mask);
+}
+static DEVICE_ATTR_RO(cpumask);
+
+static struct attribute *hygon_uncore_attrs[] = {
+ &dev_attr_cpumask.attr,
+ NULL,
+};
+
+static struct attribute_group hygon_uncore_attr_group = {
+ .attrs = hygon_uncore_attrs,
+};
+
+#define DEFINE_UNCORE_FORMAT_ATTR(_var, _name, _format) \
+static ssize_t __uncore_##_var##_show(struct device *dev, \
+ struct device_attribute *attr, \
+ char *page) \
+{ \
+ BUILD_BUG_ON(sizeof(_format) >= PAGE_SIZE); \
+ return sprintf(page, _format "\n"); \
+} \
+static struct device_attribute format_attr_##_var = \
+ __ATTR(_name, 0444, __uncore_##_var##_show, NULL)
+
+DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-5");
+DEFINE_UNCORE_FORMAT_ATTR(umask8, umask, "config:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(umask10, umask, "config:8-17"); /* F18h M4h DF */
+DEFINE_UNCORE_FORMAT_ATTR(umask12, umask, "config:8-19"); /* F18h M6h DF */
+DEFINE_UNCORE_FORMAT_ATTR(compid, compid, "config:6-7,32-35,61-62");
+DEFINE_UNCORE_FORMAT_ATTR(iod, iod, "config1:0-1");
+
+static struct attribute *hygon_uncore_df_umask_attr(void)
+{
+ if (boot_cpu_data.x86_model == 0x4 ||
+ boot_cpu_data.x86_model == 0x5)
+ return &format_attr_umask10.attr;
+
+ if (boot_cpu_data.x86_model >= 0x6 &&
+ boot_cpu_data.x86_model <= 0x18)
+ return &format_attr_umask12.attr;
+
+ return &format_attr_umask8.attr;
+}
+
+static struct attribute *hygon_uncore_df_format_attr[] = {
+ &format_attr_event.attr, /* event */
+ &format_attr_umask8.attr, /* umask */
+ &format_attr_compid.attr, /* compid */
+ NULL,
+};
+
+static struct attribute_group hygon_uncore_df_format_group = {
+ .name = "format",
+ .attrs = hygon_uncore_df_format_attr,
+};
+
+static const struct attribute_group *hygon_uncore_df_attr_groups[] = {
+ &hygon_uncore_attr_group,
+ &hygon_uncore_df_format_group,
+ NULL,
+};
+
+static struct attribute *hygon_uncore_df_iod_format_attr[] = {
+ &format_attr_event.attr, /* event */
+ &format_attr_umask10.attr, /* umask */
+ &format_attr_compid.attr, /* compid */
+ &format_attr_iod.attr, /* iod */
+ NULL,
+};
+
+static struct attribute_group hygon_uncore_df_iod_format_group = {
+ .name = "format",
+ .attrs = hygon_uncore_df_iod_format_attr,
+};
+
+static const struct attribute_group *hygon_uncore_df_iod_attr_groups[] = {
+ &hygon_uncore_attr_group,
+ &hygon_uncore_df_iod_format_group,
+ NULL,
+};
+
+static int hygon_uncore_cpu_starting(unsigned int cpu)
+{
+ struct hygon_uncore *uncore;
+ int i;
+
+ for (i = 0; i < HYGON_UNCORE_TYPE_MAX; i++) {
+ uncore = &uncores[i];
+ uncore->scan(uncore, cpu);
+ }
+
+ return 0;
+}
+
+static int hygon_uncore_cpu_dead(unsigned int cpu)
+{
+ struct hygon_uncore *uncore;
+ int i;
+
+ for (i = 0; i < HYGON_UNCORE_TYPE_MAX; i++) {
+ uncore = &uncores[i];
+ uncore->free(uncore, cpu);
+ }
+
+ return 0;
+}
+
+static int hygon_uncore_cpu_online(unsigned int cpu)
+{
+ struct hygon_uncore *uncore;
+ int i;
+
+ for (i = 0; i < HYGON_UNCORE_TYPE_MAX; i++) {
+ uncore = &uncores[i];
+ if (uncore->init(uncore, cpu))
+ continue;
+ }
+
+ return 0;
+}
+
+static int hygon_uncore_cpu_down_prepare(unsigned int cpu)
+{
+ struct hygon_uncore *uncore;
+ int i;
+
+ for (i = 0; i < HYGON_UNCORE_TYPE_MAX; i++) {
+ uncore = &uncores[i];
+ uncore->move(uncore, cpu);
+ }
+
+ return 0;
+}
+
+static void hygon_uncore_ctx_free(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ struct hygon_uncore_pmu *pmu = &uncore->pmu;
+ struct hygon_uncore_ctx *ctx;
+
+ if (!uncore->init_done || !uncore->pmu_registered)
+ return;
+
+ if (!pmu->ctx)
+ return;
+
+ ctx = *per_cpu_ptr(pmu->ctx, cpu);
+ if (!ctx)
+ return;
+
+ if (cpu == ctx->cpu)
+ cpumask_clear_cpu(cpu, &pmu->active_mask);
+
+ if (!--ctx->refcnt) {
+ hygon_uncore_cancel_hrtimer(ctx);
+ kfree(ctx->events);
+ kfree(ctx);
+ }
+
+ *per_cpu_ptr(pmu->ctx, cpu) = NULL;
+}
+
+static void hygon_uncore_ctx_move(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ struct hygon_uncore_pmu *pmu = &uncore->pmu;
+ struct hygon_uncore_ctx *curr, *next;
+ int i;
+
+ if (!uncore->init_done || !uncore->pmu_registered)
+ return;
+
+ if (!pmu->ctx)
+ return;
+
+ curr = *per_cpu_ptr(pmu->ctx, cpu);
+ if (!curr)
+ return;
+
+ for_each_online_cpu(i) {
+ next = *per_cpu_ptr(pmu->ctx, i);
+ if (!next || cpu == i)
+ continue;
+
+ if (curr == next) {
+ perf_pmu_migrate_context(&pmu->pmu, cpu, i);
+ cpumask_clear_cpu(cpu, &pmu->active_mask);
+ cpumask_set_cpu(i, &pmu->active_mask);
+ next->cpu = i;
+ break;
+ }
+ }
+}
+
+static int hygon_uncore_ctx_init(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ struct hygon_uncore_ctx *curr, *prev;
+ struct hygon_uncore_pmu *pmu = &uncore->pmu;
+ int node, cid, i;
+
+ if (!uncore->init_done || !uncore->pmu_registered)
+ return 0;
+
+ if (!pmu->ctx)
+ return 0;
+
+ cid = hygon_uncore_ctx_cid(uncore, cpu);
+ *per_cpu_ptr(pmu->ctx, cpu) = NULL;
+ curr = NULL;
+
+ for_each_online_cpu(i) {
+ if (cpu == i)
+ continue;
+
+ prev = *per_cpu_ptr(pmu->ctx, i);
+ if (!prev)
+ continue;
+ if (cid == hygon_uncore_ctx_cid(uncore, i)) {
+ curr = prev;
+ break;
+ }
+ }
+
+ if (!curr) {
+ node = cpu_to_node(cpu);
+ curr = kzalloc_node(sizeof(*curr), GFP_KERNEL, node);
+ if (!curr)
+ goto fail;
+
+ curr->cpu = cpu;
+ curr->events = kzalloc_node(sizeof(*curr->events) *
+ pmu->num_counters,
+ GFP_KERNEL, node);
+ if (!curr->events) {
+ kfree(curr);
+ goto fail;
+ }
+
+ cpumask_set_cpu(cpu, &pmu->active_mask);
+
+ hygon_uncore_init_hrtimer(curr);
+ curr->hrtimer_duration = (u64)update_interval * NSEC_PER_MSEC;
+ }
+
+ curr->refcnt++;
+ *per_cpu_ptr(pmu->ctx, cpu) = curr;
+
+ return 0;
+
+fail:
+ hygon_uncore_ctx_free(uncore, cpu);
+
+ return -ENOMEM;
+}
+
+static void hygon_uncore_df_ctx_scan(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ union hygon_uncore_info info = {};
+
+ if (!boot_cpu_has(X86_FEATURE_PERFCTR_NB))
+ return;
+
+ info.split.num_iods = 0;
+ info.split.num_pmcs = HYGON_UNCORE_NUM_COUNTERS_DF;
+ info.split.cid = topology_amd_node_id(cpu);
+
+ *per_cpu_ptr(uncore->info, cpu) = info;
+}
+
+static
+int hygon_uncore_df_ctx_init(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ struct hygon_uncore_pmu *pmu = &uncore->pmu;
+ int num_counters;
+
+ if (uncore->init_done)
+ return hygon_uncore_ctx_init(uncore, cpu);
+
+ num_counters = hygon_uncore_ctx_num_pmcs(uncore, cpu);
+ if (!num_counters)
+ goto done;
+
+ strscpy(pmu->name, "hygon_df", sizeof(pmu->name));
+ pmu->num_counters = num_counters;
+ pmu->msr_base = MSR_HYGON_F18H_DF_CTL;
+ pmu->type = HYGON_UNCORE_TYPE_DF;
+
+ hygon_uncore_df_format_attr[1] = hygon_uncore_df_umask_attr();
+
+ pmu->ctx = alloc_percpu(struct hygon_uncore_ctx *);
+ if (!pmu->ctx)
+ goto done;
+
+ pmu->pmu = (struct pmu) {
+ .task_ctx_nr = perf_invalid_context,
+ .attr_groups = hygon_uncore_df_attr_groups,
+ .name = pmu->name,
+ .event_init = hygon_uncore_df_event_init,
+ .add = hygon_uncore_add,
+ .del = hygon_uncore_del,
+ .start = hygon_uncore_start,
+ .stop = hygon_uncore_stop,
+ .read = hygon_uncore_read,
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
+ .module = THIS_MODULE,
+ };
+
+ if (perf_pmu_register(&pmu->pmu, pmu->pmu.name, -1)) {
+ free_percpu(pmu->ctx);
+ pmu->ctx = NULL;
+ goto done;
+ }
+ uncore->pmu_registered = true;
+
+done:
+ uncore->init_done = true;
+ return hygon_uncore_ctx_init(uncore, cpu);
+}
+
+static
+void hygon_uncore_df_iod_ctx_scan(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ union hygon_uncore_info info = {};
+ int num_packages, num_cdds, iods_per_package;
+
+ if (!boot_cpu_has(X86_FEATURE_PERFCTR_NB))
+ return;
+
+ if (boot_cpu_data.x86_model < 0x4 || boot_cpu_data.x86_model == 0x6)
+ return;
+
+ num_packages = topology_max_packages();
+ num_cdds = topology_max_dies_per_package() * num_packages;
+ iods_per_package = (amd_nb_num() - num_cdds) / num_packages;
+
+ /* Hardware does not support more than 2 IODs per package. */
+ if (iods_per_package <= 0 || iods_per_package > 2)
+ return;
+
+ info.split.cid = topology_physical_package_id(cpu);
+ info.split.num_iods = iods_per_package;
+ info.split.num_pmcs = HYGON_UNCORE_NUM_COUNTERS_DF * iods_per_package;
+
+ *per_cpu_ptr(uncore->info, cpu) = info;
+}
+
+static
+int hygon_uncore_df_iod_ctx_init(struct hygon_uncore *uncore, unsigned int cpu)
+{
+ struct hygon_uncore_pmu *pmu = &uncore->pmu;
+ int num_counters;
+
+ if (uncore->init_done)
+ return hygon_uncore_ctx_init(uncore, cpu);
+
+ num_counters = hygon_uncore_ctx_num_pmcs(uncore, cpu);
+ if (!num_counters)
+ goto done;
+
+ strscpy(pmu->name, "hygon_df_iod", sizeof(pmu->name));
+ pmu->num_counters = num_counters;
+ pmu->msr_base = MSR_HYGON_F18H_DF_IOD_CTL;
+ pmu->type = HYGON_UNCORE_TYPE_DF_IOD;
+
+ hygon_uncore_df_iod_format_attr[1] = hygon_uncore_df_umask_attr();
+
+ pmu->ctx = alloc_percpu(struct hygon_uncore_ctx *);
+ if (!pmu->ctx)
+ goto done;
+
+ pmu->pmu = (struct pmu) {
+ .task_ctx_nr = perf_invalid_context,
+ .attr_groups = hygon_uncore_df_iod_attr_groups,
+ .name = pmu->name,
+ .event_init = hygon_uncore_df_event_init,
+ .add = hygon_uncore_add,
+ .del = hygon_uncore_del,
+ .start = hygon_uncore_start,
+ .stop = hygon_uncore_stop,
+ .read = hygon_uncore_read,
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE | PERF_PMU_CAP_NO_INTERRUPT,
+ .module = THIS_MODULE,
+ };
+
+ if (perf_pmu_register(&pmu->pmu, pmu->pmu.name, -1)) {
+ free_percpu(pmu->ctx);
+ pmu->ctx = NULL;
+ goto done;
+ }
+ uncore->pmu_registered = true;
+done:
+ uncore->init_done = true;
+ return hygon_uncore_ctx_init(uncore, cpu);
+}
+
+static struct hygon_uncore uncores[HYGON_UNCORE_TYPE_MAX] = {
+ /* HYGON DF */
+ {
+ .scan = hygon_uncore_df_ctx_scan,
+ .init = hygon_uncore_df_ctx_init,
+ .move = hygon_uncore_ctx_move,
+ .free = hygon_uncore_ctx_free,
+ },
+ /* HYGON DF IOD */
+ {
+ .scan = hygon_uncore_df_iod_ctx_scan,
+ .init = hygon_uncore_df_iod_ctx_init,
+ .move = hygon_uncore_ctx_move,
+ .free = hygon_uncore_ctx_free,
+ }
+};
+
+static void hygon_uncore_pmu_cleanup(void)
+{
+ struct hygon_uncore_ctx *ctx;
+ struct hygon_uncore *uncore;
+ int i, cpu;
+
+ for (i = 0; i < HYGON_UNCORE_TYPE_MAX; i++) {
+ uncore = &uncores[i];
+
+ /* Unregister PMU before freeing its contexts. */
+ if (uncore->pmu_registered) {
+ perf_pmu_unregister(&uncore->pmu.pmu);
+ uncore->pmu_registered = false;
+ }
+
+ if (!uncore->pmu.ctx)
+ continue;
+
+ /* Shared ctx objects are released through their refcnt. */
+ for_each_possible_cpu(cpu) {
+ ctx = *per_cpu_ptr(uncore->pmu.ctx, cpu);
+ if (!ctx)
+ continue;
+
+ if (!--ctx->refcnt) {
+ hygon_uncore_cancel_hrtimer(ctx);
+ kfree(ctx->events);
+ kfree(ctx);
+ }
+ *per_cpu_ptr(uncore->pmu.ctx, cpu) = NULL;
+ }
+
+ free_percpu(uncore->pmu.ctx);
+ uncore->pmu.ctx = NULL;
+ }
+}
+
+static void hygon_uncore_info_cleanup(void)
+{
+ struct hygon_uncore *uncore;
+ int i;
+
+ for (i = 0; i < HYGON_UNCORE_TYPE_MAX; i++) {
+ uncore = &uncores[i];
+ if (uncore->info) {
+ free_percpu(uncore->info);
+ uncore->info = NULL;
+ }
+ }
+}
+
+static int __init hygon_uncore_init(void)
+{
+ struct hygon_uncore *uncore;
+ int ret = -ENODEV;
+ int i;
+
+
+ if (!update_interval) {
+ pr_err("update_interval must be greater than 0 ms\n");
+ return -EINVAL;
+ }
+
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+ return -ENODEV;
+
+ if (!boot_cpu_has(X86_FEATURE_TOPOEXT))
+ return -ENODEV;
+
+ for (i = 0; i < HYGON_UNCORE_TYPE_MAX; i++) {
+ uncore = &uncores[i];
+
+ uncore->info = alloc_percpu(union hygon_uncore_info);
+ if (!uncore->info) {
+ ret = -ENOMEM;
+ goto fail;
+ }
+ }
+
+ ret = cpuhp_setup_state(CPUHP_PERF_X86_HYGON_UNCORE_PREP,
+ "perf/x86/hygon/uncore:prepare",
+ NULL, hygon_uncore_cpu_dead);
+ if (ret)
+ goto fail;
+
+ ret = cpuhp_setup_state(CPUHP_AP_PERF_X86_HYGON_UNCORE_STARTING,
+ "perf/x86/hygon/uncore:starting",
+ hygon_uncore_cpu_starting, NULL);
+ if (ret)
+ goto fail_prep;
+
+ ret = cpuhp_setup_state(CPUHP_AP_PERF_X86_HYGON_UNCORE_ONLINE,
+ "perf/x86/hygon/uncore:online",
+ hygon_uncore_cpu_online,
+ hygon_uncore_cpu_down_prepare);
+ if (ret)
+ goto fail_start;
+
+ return 0;
+
+fail_start:
+ cpuhp_remove_state(CPUHP_AP_PERF_X86_HYGON_UNCORE_STARTING);
+fail_prep:
+ cpuhp_remove_state(CPUHP_PERF_X86_HYGON_UNCORE_PREP);
+fail:
+ hygon_uncore_info_cleanup();
+ return ret;
+}
+
+static void __exit hygon_uncore_exit(void)
+{
+ cpuhp_remove_state(CPUHP_AP_PERF_X86_HYGON_UNCORE_ONLINE);
+ cpuhp_remove_state(CPUHP_AP_PERF_X86_HYGON_UNCORE_STARTING);
+ cpuhp_remove_state(CPUHP_PERF_X86_HYGON_UNCORE_PREP);
+
+ hygon_uncore_pmu_cleanup();
+ hygon_uncore_info_cleanup();
+}
+module_init(hygon_uncore_init);
+module_exit(hygon_uncore_exit);
+
+MODULE_DESCRIPTION("Hygon Uncore Driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
index dbc00b6dd69e..6c486e1ab001 100644
--- a/arch/x86/events/amd/uncore.c
+++ b/arch/x86/events/amd/uncore.c
@@ -775,9 +775,7 @@ int amd_uncore_df_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
goto done;
}
- pr_info("%d %s%s counters detected\n", pmu->num_counters,
- boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ? "HYGON " : "",
- pmu->pmu.name);
+ pr_info("%d %s counters detected\n", pmu->num_counters, pmu->pmu.name);
uncore->num_pmus = 1;
@@ -911,9 +909,7 @@ int amd_uncore_l3_ctx_init(struct amd_uncore *uncore, unsigned int cpu)
goto done;
}
- pr_info("%d %s%s counters detected\n", pmu->num_counters,
- boot_cpu_data.x86_vendor == X86_VENDOR_HYGON ? "HYGON " : "",
- pmu->pmu.name);
+ pr_info("%d %s counters detected\n", pmu->num_counters, pmu->pmu.name);
uncore->num_pmus = 1;
@@ -1120,8 +1116,7 @@ static int __init amd_uncore_init(void)
int ret = -ENODEV;
int i;
- if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
- boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
+ if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
return -ENODEV;
if (!boot_cpu_has(X86_FEATURE_TOPOEXT))
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 18c4be75e927..d20338f0b2b2 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -851,6 +851,8 @@
#define MSR_F15H_PTSC 0xc0010280
#define MSR_F15H_IC_CFG 0xc0011021
#define MSR_F15H_EX_CFG 0xc001102c
+#define MSR_HYGON_F18H_DF_CTL 0xc0010240
+#define MSR_HYGON_F18H_DF_IOD_CTL 0xc0010250
/* Fam 10h MSRs */
#define MSR_FAM10H_MMIO_CONF_BASE 0xc0010058
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index 1eb13673e889..7c8c00ad56e9 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -124,6 +124,26 @@
(AMD64_PERFMON_V2_EVENTSEL_EVENT_NB | \
AMD64_PERFMON_V2_EVENTSEL_UMASK_NB)
+#define HYGON_F18H_EVENTSEL_EVENT_DF 0x0000003FULL
+#define HYGON_F18H_EVENTSEL_UMASK_DF 0x0000FF00ULL
+#define HYGON_F18H_M4H_EVENTSEL_UMASK_DF 0x0003FF00ULL
+#define HYGON_F18H_M6H_EVENTSEL_UMASK_DF 0x000FFF00ULL
+#define HYGON_F18H_EVENTSEL_CONSTID_DF \
+ (0x000000C0ULL | GENMASK_ULL(35, 32) | GENMASK_ULL(62, 61))
+
+#define HYGON_F18H_RAW_EVENT_MASK_DF \
+ (HYGON_F18H_EVENTSEL_EVENT_DF | \
+ HYGON_F18H_EVENTSEL_UMASK_DF | \
+ HYGON_F18H_EVENTSEL_CONSTID_DF)
+#define HYGON_F18H_M4H_RAW_EVENT_MASK_DF \
+ (HYGON_F18H_EVENTSEL_EVENT_DF | \
+ HYGON_F18H_M4H_EVENTSEL_UMASK_DF | \
+ HYGON_F18H_EVENTSEL_CONSTID_DF)
+#define HYGON_F18H_M6H_RAW_EVENT_MASK_DF \
+ (HYGON_F18H_EVENTSEL_EVENT_DF | \
+ HYGON_F18H_M6H_EVENTSEL_UMASK_DF | \
+ HYGON_F18H_EVENTSEL_CONSTID_DF)
+
#define AMD64_PERFMON_V2_ENABLE_UMC BIT_ULL(31)
#define AMD64_PERFMON_V2_EVENTSEL_EVENT_UMC GENMASK_ULL(7, 0)
#define AMD64_PERFMON_V2_EVENTSEL_RDWRMASK_UMC GENMASK_ULL(9, 8)
diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h
index 0fb3a2a62eb0..bccdb87a0c05 100644
--- a/include/linux/cpuhotplug.h
+++ b/include/linux/cpuhotplug.h
@@ -62,6 +62,7 @@ enum cpuhp_state {
CPUHP_CREATE_THREADS,
CPUHP_PERF_X86_PREPARE,
CPUHP_PERF_X86_AMD_UNCORE_PREP,
+ CPUHP_PERF_X86_HYGON_UNCORE_PREP,
CPUHP_PERF_POWER,
CPUHP_PERF_SUPERH,
CPUHP_X86_HPET_DEAD,
@@ -148,6 +149,7 @@ enum cpuhp_state {
CPUHP_AP_IRQ_RISCV_SBI_IPI_STARTING,
CPUHP_AP_ARM_MVEBU_COHERENCY,
CPUHP_AP_PERF_X86_AMD_UNCORE_STARTING,
+ CPUHP_AP_PERF_X86_HYGON_UNCORE_STARTING,
CPUHP_AP_PERF_X86_STARTING,
CPUHP_AP_PERF_X86_AMD_IBS_STARTING,
CPUHP_AP_PERF_XTENSA_STARTING,
@@ -205,6 +207,7 @@ enum cpuhp_state {
CPUHP_AP_PERF_X86_ONLINE,
CPUHP_AP_PERF_X86_UNCORE_ONLINE,
CPUHP_AP_PERF_X86_AMD_UNCORE_ONLINE,
+ CPUHP_AP_PERF_X86_HYGON_UNCORE_ONLINE,
CPUHP_AP_PERF_X86_AMD_POWER_ONLINE,
CPUHP_AP_PERF_S390_CF_ONLINE,
CPUHP_AP_PERF_S390_SF_ONLINE,
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v5 2/2] perf vendor events hygon: Add Hygon Data Fabric PMU events and metrics
2026-08-18 10:01 [PATCH v5 0/2] perf/x86/amd/uncore: Add Hygon uncore PMU and JSON events Qi Liu
2026-08-18 10:01 ` [PATCH v5 1/2] perf/x86/amd/uncore: Add Hygon uncore PMU support Qi Liu
@ 2026-08-18 10:01 ` Qi Liu
2026-08-18 10:12 ` sashiko-bot
2026-08-19 5:11 ` Sandipan Das
1 sibling, 2 replies; 7+ messages in thread
From: Qi Liu @ 2026-08-18 10:01 UTC (permalink / raw)
To: peterz, mingo, namhyung, alexander.shishkin, jolsa, sandipan.das,
ravi.bangoria, irogers, x86
Cc: linux-perf-users, linux-kernel, lijing, liuqi
Add perf JSON event definitions and metrics for the Hygon Data Fabric (DF)
uncore PMU.
Signed-off-by: Qi Liu <liuqi@hygon.cn>
---
tools/perf/pmu-events/Build | 2 +-
.../arch/x86/hygonm1/data-fabric.json | 95 ++++++++++
.../arch/x86/hygonm4/data-fabric.json | 134 ++++++++++++++
.../arch/x86/hygonm6/data-fabric.json | 170 ++++++++++++++++++
tools/perf/pmu-events/arch/x86/mapfile.csv | 3 +
tools/perf/pmu-events/jevents.py | 2 +
6 files changed, 405 insertions(+), 1 deletion(-)
create mode 100644 tools/perf/pmu-events/arch/x86/hygonm1/data-fabric.json
create mode 100644 tools/perf/pmu-events/arch/x86/hygonm4/data-fabric.json
create mode 100644 tools/perf/pmu-events/arch/x86/hygonm6/data-fabric.json
diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
index 372773b998e4..79a9b4cad202 100644
--- a/tools/perf/pmu-events/Build
+++ b/tools/perf/pmu-events/Build
@@ -95,7 +95,7 @@ endif
ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),x86 all))
# Generate Intel Json
-INTELS := $(shell ls -d pmu-events/arch/x86/*|grep -v amdzen|grep -v mapfile.csv)
+INTELS := $(shell ls -d pmu-events/arch/x86/*|grep -v amdzen|grep -v hygon|grep -v mapfile.csv)
INTEL_METRICS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metrics.json)
INTEL_METRICGROUPS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metricgroups.json)
GEN_JSON += $(INTEL_METRICS) $(INTEL_METRICGROUPS)
diff --git a/tools/perf/pmu-events/arch/x86/hygonm1/data-fabric.json b/tools/perf/pmu-events/arch/x86/hygonm1/data-fabric.json
new file mode 100644
index 000000000000..8c6a8e9ba9a5
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/hygonm1/data-fabric.json
@@ -0,0 +1,95 @@
+[
+ {
+ "EventName": "cpu_read_requests_cs_0",
+ "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
+ "EventCode": "0x2",
+ "UMask": "0x07",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_read_requests_cs_1",
+ "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
+ "EventCode": "0x2",
+ "UMask": "0x07",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_write_requests_cs_0",
+ "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
+ "EventCode": "0x2",
+ "UMask": "0x08",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_write_requests_cs_1",
+ "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
+ "EventCode": "0x2",
+ "UMask": "0x08",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_read_requests_cs_0",
+ "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x0F",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_read_requests_cs_1",
+ "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x0F",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_write_requests_cs_0",
+ "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x70",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_write_requests_cs_1",
+ "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x70",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "MetricName": "cpu_memory_bandwidth",
+ "MetricExpr": "(cpu_read_requests_cs_0 + cpu_read_requests_cs_1 + cpu_write_requests_cs_0 + cpu_write_requests_cs_1) * 64 / (duration_time * 1e6)",
+ "BriefDescription": "Total CPU memory access bandwidth",
+ "MetricGroup": "DF_Memory_BW",
+ "ScaleUnit": "1MB/s"
+ },
+ {
+ "MetricName": "io_memory_max_bandwidth",
+ "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_write_requests_cs_0 + io_write_requests_cs_1) * 64 / (duration_time * 1e6)",
+ "BriefDescription": "Maximum inbound I/O memory access bandwidth (upper bound, assuming 64B per request. Actual inbound I/O requests may be 32B or 64B)",
+ "MetricGroup": "DF_Memory_BW",
+ "ScaleUnit": "1MB/s"
+ },
+ {
+ "MetricName": "io_memory_min_bandwidth",
+ "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_write_requests_cs_0 + io_write_requests_cs_1) * 32 / (duration_time * 1e6)",
+ "BriefDescription": "Minimum inbound I/O memory access bandwidth (lower bound, assuming 32B per request. Actual inbound I/O requests may be 32B or 64B)",
+ "MetricGroup": "DF_Memory_BW",
+ "ScaleUnit": "1MB/s"
+ }
+]
diff --git a/tools/perf/pmu-events/arch/x86/hygonm4/data-fabric.json b/tools/perf/pmu-events/arch/x86/hygonm4/data-fabric.json
new file mode 100644
index 000000000000..41932a1a3d6d
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/hygonm4/data-fabric.json
@@ -0,0 +1,134 @@
+[
+ {
+ "EventName": "cpu_read_requests_cs_0",
+ "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
+ "EventCode": "0x2",
+ "UMask": "0x07",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_read_requests_cs_1",
+ "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
+ "EventCode": "0x2",
+ "UMask": "0x07",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_read_requests_cs_2",
+ "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 2 (CS2).",
+ "EventCode": "0x2",
+ "UMask": "0x07",
+ "CompId": "0x2",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_write_requests_cs_0",
+ "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
+ "EventCode": "0x2",
+ "UMask": "0x08",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_write_requests_cs_1",
+ "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
+ "EventCode": "0x2",
+ "UMask": "0x08",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_write_requests_cs_2",
+ "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 2 (CS2).",
+ "EventCode": "0x2",
+ "UMask": "0x08",
+ "CompId": "0x2",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_read_requests_cs_0",
+ "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x0F",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_read_requests_cs_1",
+ "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x0F",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_read_requests_cs_2",
+ "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 2 (CS2). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x0F",
+ "CompId": "0x2",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_write_requests_cs_0",
+ "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x70",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_write_requests_cs_1",
+ "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x70",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_write_requests_cs_2",
+ "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 2 (CS2). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x70",
+ "CompId": "0x2",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "MetricName": "cpu_memory_bandwidth",
+ "MetricExpr": "(cpu_read_requests_cs_0 + cpu_read_requests_cs_1 + cpu_read_requests_cs_2 + cpu_write_requests_cs_0 + cpu_write_requests_cs_1 + cpu_write_requests_cs_2) * 64 / (duration_time * 1e6)",
+ "MetricConstraint": "NO_GROUP_EVENTS",
+ "BriefDescription": "Total CPU memory access bandwidth",
+ "MetricGroup": "DF_Memory_BW",
+ "ScaleUnit": "1MB/s"
+ },
+ {
+ "MetricName": "io_memory_max_bandwidth",
+ "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_read_requests_cs_2 + io_write_requests_cs_0 + io_write_requests_cs_1 + io_write_requests_cs_2) * 64 / (duration_time * 1e6)",
+ "MetricConstraint": "NO_GROUP_EVENTS",
+ "BriefDescription": "Maximum inbound I/O memory access bandwidth (upper bound, assuming 64B per request. Actual inbound I/O requests may be 32B or 64B)",
+ "MetricGroup": "DF_Memory_BW",
+ "ScaleUnit": "1MB/s"
+ },
+ {
+ "MetricName": "io_memory_min_bandwidth",
+ "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_read_requests_cs_2 + io_write_requests_cs_0 + io_write_requests_cs_1 + io_write_requests_cs_2) * 32 / (duration_time * 1e6)",
+ "MetricConstraint": "NO_GROUP_EVENTS",
+ "BriefDescription": "Minimum inbound I/O memory access bandwidth (lower bound, assuming 32B per request. Actual inbound I/O requests may be 32B or 64B)",
+ "MetricGroup": "DF_Memory_BW",
+ "ScaleUnit": "1MB/s"
+ }
+]
diff --git a/tools/perf/pmu-events/arch/x86/hygonm6/data-fabric.json b/tools/perf/pmu-events/arch/x86/hygonm6/data-fabric.json
new file mode 100644
index 000000000000..ee81e35dc6f3
--- /dev/null
+++ b/tools/perf/pmu-events/arch/x86/hygonm6/data-fabric.json
@@ -0,0 +1,170 @@
+[
+ {
+ "EventName": "cpu_read_requests_cs_0",
+ "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
+ "EventCode": "0x2",
+ "UMask": "0x07",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_read_requests_cs_1",
+ "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
+ "EventCode": "0x2",
+ "UMask": "0x07",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_read_requests_cs_2",
+ "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 2 (CS2).",
+ "EventCode": "0x2",
+ "UMask": "0x07",
+ "CompId": "0x2",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_read_requests_cs_3",
+ "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 3 (CS3).",
+ "EventCode": "0x2",
+ "UMask": "0x07",
+ "CompId": "0x3",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_write_requests_cs_0",
+ "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
+ "EventCode": "0x2",
+ "UMask": "0x08",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_write_requests_cs_1",
+ "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
+ "EventCode": "0x2",
+ "UMask": "0x08",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_write_requests_cs_2",
+ "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 2 (CS2).",
+ "EventCode": "0x2",
+ "UMask": "0x08",
+ "CompId": "0x2",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "cpu_write_requests_cs_3",
+ "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 3 (CS3).",
+ "EventCode": "0x2",
+ "UMask": "0x08",
+ "CompId": "0x3",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_read_requests_cs_0",
+ "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x0F",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_read_requests_cs_1",
+ "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x0F",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_read_requests_cs_2",
+ "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 2 (CS2). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x0F",
+ "CompId": "0x2",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_read_requests_cs_3",
+ "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 3 (CS3). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x0F",
+ "CompId": "0x3",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_write_requests_cs_0",
+ "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x70",
+ "CompId": "0x0",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_write_requests_cs_1",
+ "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x70",
+ "CompId": "0x1",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_write_requests_cs_2",
+ "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 2 (CS2). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x70",
+ "CompId": "0x2",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "EventName": "io_write_requests_cs_3",
+ "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 3 (CS3). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
+ "EventCode": "0x3",
+ "UMask": "0x70",
+ "CompId": "0x3",
+ "Unit": "HYGON_DF",
+ "ScaleUnit": "64Bytes"
+ },
+ {
+ "MetricName": "cpu_memory_bandwidth",
+ "MetricExpr": "(cpu_read_requests_cs_0 + cpu_read_requests_cs_1 + cpu_read_requests_cs_2 + cpu_read_requests_cs_3 + cpu_write_requests_cs_0 + cpu_write_requests_cs_1 + cpu_write_requests_cs_2 + cpu_write_requests_cs_3) * 64 / (duration_time * 1e6)",
+ "MetricConstraint": "NO_GROUP_EVENTS",
+ "BriefDescription": "Total CPU memory access bandwidth",
+ "MetricGroup": "DF_Memory_BW",
+ "ScaleUnit": "1MB/s"
+ },
+ {
+ "MetricName": "io_memory_max_bandwidth",
+ "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_read_requests_cs_2 + io_read_requests_cs_3 + io_write_requests_cs_0 + io_write_requests_cs_1 + io_write_requests_cs_2 + io_write_requests_cs_3) * 64 / (duration_time * 1e6)",
+ "MetricConstraint": "NO_GROUP_EVENTS",
+ "BriefDescription": "Maximum inbound I/O memory access bandwidth (upper bound, assuming 64B per request. Actual inbound I/O requests may be 32B or 64B)",
+ "MetricGroup": "DF_Memory_BW",
+ "ScaleUnit": "1MB/s"
+ },
+ {
+ "MetricName": "io_memory_min_bandwidth",
+ "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_read_requests_cs_2 + io_read_requests_cs_3 + io_write_requests_cs_0 + io_write_requests_cs_1 + io_write_requests_cs_2 + io_write_requests_cs_3) * 32 / (duration_time * 1e6)",
+ "MetricConstraint": "NO_GROUP_EVENTS",
+ "BriefDescription": "Minimum inbound I/O memory access bandwidth (lower bound, assuming 32B per request. Actual inbound I/O requests may be 32B or 64B)",
+ "MetricGroup": "DF_Memory_BW",
+ "ScaleUnit": "1MB/s"
+ }
+]
diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv
index 50a403b429b1..ba17117245d1 100644
--- a/tools/perf/pmu-events/arch/x86/mapfile.csv
+++ b/tools/perf/pmu-events/arch/x86/mapfile.csv
@@ -45,3 +45,6 @@ AuthenticAMD-25-([245][[:xdigit:]]|[[:xdigit:]]),v1,amdzen3,core
AuthenticAMD-25-[[:xdigit:]]+,v1,amdzen4,core
AuthenticAMD-26-([12467][[:xdigit:]]|[[:xdigit:]]),v1,amdzen5,core
AuthenticAMD-26-[[:xdigit:]]+,v1,amdzen6,core
+HygonGenuine-24-[0123],v1,hygonm1,core
+HygonGenuine-24-[45],v1,hygonm4,core
+HygonGenuine-24-(1[012345678]|[6789ABCDEF]),v1,hygonm6,core
diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
index 376dc2d24162..07a843d92483 100755
--- a/tools/perf/pmu-events/jevents.py
+++ b/tools/perf/pmu-events/jevents.py
@@ -294,6 +294,7 @@ class JsonEvent:
'L3PMC': 'amd_l3',
'DFPMC': 'amd_df',
'UMCPMC': 'amd_umc',
+ 'HYGON_DF': 'hygon_df',
'cpu_core': 'cpu_core',
'cpu_atom': 'cpu_atom',
'ali_drw': 'ali_drw',
@@ -390,6 +391,7 @@ class JsonEvent:
('Invert', 'inv='),
('SampleAfterValue', 'period='),
('UMask', 'umask='),
+ ('CompId', 'compid='),
('NodeType', 'type='),
('RdWrMask', 'rdwrmask='),
('EnAllCores', 'enallcores='),
--
2.34.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v5 2/2] perf vendor events hygon: Add Hygon Data Fabric PMU events and metrics
2026-08-18 10:01 ` [PATCH v5 2/2] perf vendor events hygon: Add Hygon Data Fabric PMU events and metrics Qi Liu
@ 2026-08-18 10:12 ` sashiko-bot
2026-08-19 5:11 ` Sandipan Das
1 sibling, 0 replies; 7+ messages in thread
From: sashiko-bot @ 2026-08-18 10:12 UTC (permalink / raw)
To: Qi Liu; +Cc: linux-perf-users
> Add perf JSON event definitions and metrics for the Hygon Data Fabric (DF)
> uncore PMU.
>
> Signed-off-by: Qi Liu <liuqi@hygon.cn>
Sashiko has reviewed this patch and found no issues. It looks great!
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260818100118.12944-1-liuqi@hygon.cn?part=2
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 1/2] perf/x86/amd/uncore: Add Hygon uncore PMU support
2026-08-18 10:01 ` [PATCH v5 1/2] perf/x86/amd/uncore: Add Hygon uncore PMU support Qi Liu
@ 2026-08-18 10:16 ` sashiko-bot
2026-08-18 11:32 ` Qi Liu
0 siblings, 1 reply; 7+ messages in thread
From: sashiko-bot @ 2026-08-18 10:16 UTC (permalink / raw)
To: Qi Liu; +Cc: linux-perf-users
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [Medium] Removal of Hygon L3 Uncore PMU support without a replacement in the new driver.
--
--- Patch [1]: [PATCH v5 1/2] perf/x86/amd/uncore: Add Hygon uncore PMU support ---
commit 1b6dd18387bea20f9f548951bf79cae006705b47
Author: Qi Liu <liuqi@hygon.cn>
perf/x86/amd/uncore: Add Hygon uncore PMU support
This commit introduces a separate uncore PMU driver for Hygon processors to
support Data Fabric (DF) and Data Fabric IO Die (DF_IOD) counters. It also
removes the Hygon vendor checks from the AMD uncore driver to keep the
vendor-specific features separated.
> diff --git a/arch/x86/events/amd/hygon_uncore.c b/arch/x86/events/amd/hygon_uncore.c
> new file mode 100644
> index 0000000000000..471955d6fc282
> --- /dev/null
> +++ b/arch/x86/events/amd/hygon_uncore.c
[ ... ]
> +static struct hygon_uncore uncores[HYGON_UNCORE_TYPE_MAX] = {
> + /* HYGON DF */
> + {
> + .scan = hygon_uncore_df_ctx_scan,
> + .init = hygon_uncore_df_ctx_init,
> + .move = hygon_uncore_ctx_move,
> + .free = hygon_uncore_ctx_free,
> + },
> + /* HYGON DF IOD */
> + {
> + .scan = hygon_uncore_df_iod_ctx_scan,
> + .init = hygon_uncore_df_iod_ctx_init,
> + .move = hygon_uncore_ctx_move,
> + .free = hygon_uncore_ctx_free,
> + }
> +};
[ ... ]
> diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
> index dbc00b6dd69ee..6c486e1ab001a 100644
> --- a/arch/x86/events/amd/uncore.c
> +++ b/arch/x86/events/amd/uncore.c
[ ... ]
> @@ -1120,8 +1116,7 @@ static int __init amd_uncore_init(void)
> int ret = -ENODEV;
> int i;
>
> - if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
> - boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
> + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
> return -ENODEV;
>
> if (!boot_cpu_has(X86_FEATURE_TOPOEXT))
[Severity: Medium]
Does this inadvertently remove L3 uncore PMU support for Hygon systems?
Removing the Hygon vendor check in amd_uncore_init() prevents the AMD uncore
driver from initializing on Hygon CPUs, which previously provided L3 cache PMU
support.
Looking at the new driver in hygon_uncore.c, the uncores[] array only
implements the DF and DF_IOD components. It does not appear to provide a
replacement for the L3 cache PMU that was previously available.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260818100118.12944-1-liuqi@hygon.cn?part=1
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 1/2] perf/x86/amd/uncore: Add Hygon uncore PMU support
2026-08-18 10:16 ` sashiko-bot
@ 2026-08-18 11:32 ` Qi Liu
0 siblings, 0 replies; 7+ messages in thread
From: Qi Liu @ 2026-08-18 11:32 UTC (permalink / raw)
To: sashiko-reviews; +Cc: linux-perf-users
Hi
On 8/18/2026 6:16 PM, sashiko-bot@kernel.org wrote:
> Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
> - [Medium] Removal of Hygon L3 Uncore PMU support without a replacement in the new driver.
> --
>
> --- Patch [1]: [PATCH v5 1/2] perf/x86/amd/uncore: Add Hygon uncore PMU support ---
> commit 1b6dd18387bea20f9f548951bf79cae006705b47
> Author: Qi Liu <liuqi@hygon.cn>
>
> perf/x86/amd/uncore: Add Hygon uncore PMU support
>
> This commit introduces a separate uncore PMU driver for Hygon processors to
> support Data Fabric (DF) and Data Fabric IO Die (DF_IOD) counters. It also
> removes the Hygon vendor checks from the AMD uncore driver to keep the
> vendor-specific features separated.
>
>> diff --git a/arch/x86/events/amd/hygon_uncore.c b/arch/x86/events/amd/hygon_uncore.c
>> new file mode 100644
>> index 0000000000000..471955d6fc282
>> --- /dev/null
>> +++ b/arch/x86/events/amd/hygon_uncore.c
>
> [ ... ]
>
>> +static struct hygon_uncore uncores[HYGON_UNCORE_TYPE_MAX] = {
>> + /* HYGON DF */
>> + {
>> + .scan = hygon_uncore_df_ctx_scan,
>> + .init = hygon_uncore_df_ctx_init,
>> + .move = hygon_uncore_ctx_move,
>> + .free = hygon_uncore_ctx_free,
>> + },
>> + /* HYGON DF IOD */
>> + {
>> + .scan = hygon_uncore_df_iod_ctx_scan,
>> + .init = hygon_uncore_df_iod_ctx_init,
>> + .move = hygon_uncore_ctx_move,
>> + .free = hygon_uncore_ctx_free,
>> + }
>> +};
>
> [ ... ]
>
>> diff --git a/arch/x86/events/amd/uncore.c b/arch/x86/events/amd/uncore.c
>> index dbc00b6dd69ee..6c486e1ab001a 100644
>> --- a/arch/x86/events/amd/uncore.c
>> +++ b/arch/x86/events/amd/uncore.c
>
> [ ... ]
>
>> @@ -1120,8 +1116,7 @@ static int __init amd_uncore_init(void)
>> int ret = -ENODEV;
>> int i;
>>
>> - if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD &&
>> - boot_cpu_data.x86_vendor != X86_VENDOR_HYGON)
>> + if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD)
>> return -ENODEV;
>>
>> if (!boot_cpu_has(X86_FEATURE_TOPOEXT))
>
> [Severity: Medium]
> Does this inadvertently remove L3 uncore PMU support for Hygon systems?
>
> Removing the Hygon vendor check in amd_uncore_init() prevents the AMD uncore
> driver from initializing on Hygon CPUs, which previously provided L3 cache PMU
> support.
>
> Looking at the new driver in hygon_uncore.c, the uncores[] array only
> implements the DF and DF_IOD components. It does not appear to provide a
> replacement for the L3 cache PMU that was previously available.
>
L3 and UMC PMU support for Hygon will be added in follow-up series. This series
focuses specifically on Data Fabric uncore PMU support as the initial step.
Thanks,
Qi
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v5 2/2] perf vendor events hygon: Add Hygon Data Fabric PMU events and metrics
2026-08-18 10:01 ` [PATCH v5 2/2] perf vendor events hygon: Add Hygon Data Fabric PMU events and metrics Qi Liu
2026-08-18 10:12 ` sashiko-bot
@ 2026-08-19 5:11 ` Sandipan Das
1 sibling, 0 replies; 7+ messages in thread
From: Sandipan Das @ 2026-08-19 5:11 UTC (permalink / raw)
To: Qi Liu, peterz, mingo, namhyung, alexander.shishkin, jolsa,
ravi.bangoria, irogers, x86
Cc: linux-perf-users, linux-kernel, lijing
On 18-08-2026 15:31, Qi Liu wrote:
> Add perf JSON event definitions and metrics for the Hygon Data Fabric (DF)
> uncore PMU.
>
> Signed-off-by: Qi Liu <liuqi@hygon.cn>
> ---
> tools/perf/pmu-events/Build | 2 +-
> .../arch/x86/hygonm1/data-fabric.json | 95 ++++++++++
> .../arch/x86/hygonm4/data-fabric.json | 134 ++++++++++++++
> .../arch/x86/hygonm6/data-fabric.json | 170 ++++++++++++++++++
> tools/perf/pmu-events/arch/x86/mapfile.csv | 3 +
> tools/perf/pmu-events/jevents.py | 2 +
> 6 files changed, 405 insertions(+), 1 deletion(-)
> create mode 100644 tools/perf/pmu-events/arch/x86/hygonm1/data-fabric.json
> create mode 100644 tools/perf/pmu-events/arch/x86/hygonm4/data-fabric.json
> create mode 100644 tools/perf/pmu-events/arch/x86/hygonm6/data-fabric.json
>
> diff --git a/tools/perf/pmu-events/Build b/tools/perf/pmu-events/Build
> index 372773b998e4..79a9b4cad202 100644
> --- a/tools/perf/pmu-events/Build
> +++ b/tools/perf/pmu-events/Build
> @@ -95,7 +95,7 @@ endif
>
> ifeq ($(JEVENTS_ARCH),$(filter $(JEVENTS_ARCH),x86 all))
> # Generate Intel Json
> -INTELS := $(shell ls -d pmu-events/arch/x86/*|grep -v amdzen|grep -v mapfile.csv)
> +INTELS := $(shell ls -d pmu-events/arch/x86/*|grep -v amdzen|grep -v hygon|grep -v mapfile.csv)
> INTEL_METRICS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metrics.json)
> INTEL_METRICGROUPS = $(foreach x,$(INTELS),$(OUTPUT)$(x)/extra-metricgroups.json)
> GEN_JSON += $(INTEL_METRICS) $(INTEL_METRICGROUPS)
> diff --git a/tools/perf/pmu-events/arch/x86/hygonm1/data-fabric.json b/tools/perf/pmu-events/arch/x86/hygonm1/data-fabric.json
> new file mode 100644
> index 000000000000..8c6a8e9ba9a5
> --- /dev/null
> +++ b/tools/perf/pmu-events/arch/x86/hygonm1/data-fabric.json
> @@ -0,0 +1,95 @@
> +[
> + {
> + "EventName": "cpu_read_requests_cs_0",
> + "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
Coherent Station is the correct term, if you go by the terminology in AMD
PPRs. Since CSes are the interfaces between the data fabric and the memory
controllers (UMCs), it may be better to rephrase the descriptions as read
or write requests to DRAM channel 0..N which are backed by UMC 0..N and
CS 0..N.
> + "EventCode": "0x2",
> + "UMask": "0x07",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
As the naming suggests, my understanding is that these events count the
number of requests and each request carries a 64-byte payload. Perhaps
the ScaleUnit needs to be factored into the bandwidth metrics instead of
the individual events.
> + },
> + {
> + "EventName": "cpu_read_requests_cs_1",
> + "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
> + "EventCode": "0x2",
> + "UMask": "0x07",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_write_requests_cs_0",
> + "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
> + "EventCode": "0x2",
> + "UMask": "0x08",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_write_requests_cs_1",
> + "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
> + "EventCode": "0x2",
> + "UMask": "0x08",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_read_requests_cs_0",
> + "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x0F",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_read_requests_cs_1",
> + "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x0F",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_write_requests_cs_0",
> + "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x70",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_write_requests_cs_1",
> + "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x70",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "MetricName": "cpu_memory_bandwidth",
> + "MetricExpr": "(cpu_read_requests_cs_0 + cpu_read_requests_cs_1 + cpu_write_requests_cs_0 + cpu_write_requests_cs_1) * 64 / (duration_time * 1e6)",
> + "BriefDescription": "Total CPU memory access bandwidth",
> + "MetricGroup": "DF_Memory_BW",
> + "ScaleUnit": "1MB/s"
> + },
> + {
> + "MetricName": "io_memory_max_bandwidth",
> + "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_write_requests_cs_0 + io_write_requests_cs_1) * 64 / (duration_time * 1e6)",
> + "BriefDescription": "Maximum inbound I/O memory access bandwidth (upper bound, assuming 64B per request. Actual inbound I/O requests may be 32B or 64B)",
> + "MetricGroup": "DF_Memory_BW",
> + "ScaleUnit": "1MB/s"
> + },
> + {
> + "MetricName": "io_memory_min_bandwidth",
> + "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_write_requests_cs_0 + io_write_requests_cs_1) * 32 / (duration_time * 1e6)",
> + "BriefDescription": "Minimum inbound I/O memory access bandwidth (lower bound, assuming 32B per request. Actual inbound I/O requests may be 32B or 64B)",
> + "MetricGroup": "DF_Memory_BW",
> + "ScaleUnit": "1MB/s"
> + }
> +]
> diff --git a/tools/perf/pmu-events/arch/x86/hygonm4/data-fabric.json b/tools/perf/pmu-events/arch/x86/hygonm4/data-fabric.json
> new file mode 100644
> index 000000000000..41932a1a3d6d
> --- /dev/null
> +++ b/tools/perf/pmu-events/arch/x86/hygonm4/data-fabric.json
> @@ -0,0 +1,134 @@
> +[
> + {
> + "EventName": "cpu_read_requests_cs_0",
> + "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
> + "EventCode": "0x2",
> + "UMask": "0x07",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_read_requests_cs_1",
> + "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
> + "EventCode": "0x2",
> + "UMask": "0x07",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_read_requests_cs_2",
> + "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 2 (CS2).",
> + "EventCode": "0x2",
> + "UMask": "0x07",
> + "CompId": "0x2",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_write_requests_cs_0",
> + "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
> + "EventCode": "0x2",
> + "UMask": "0x08",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_write_requests_cs_1",
> + "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
> + "EventCode": "0x2",
> + "UMask": "0x08",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_write_requests_cs_2",
> + "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 2 (CS2).",
> + "EventCode": "0x2",
> + "UMask": "0x08",
> + "CompId": "0x2",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_read_requests_cs_0",
> + "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x0F",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_read_requests_cs_1",
> + "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x0F",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_read_requests_cs_2",
> + "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 2 (CS2). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x0F",
> + "CompId": "0x2",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_write_requests_cs_0",
> + "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x70",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_write_requests_cs_1",
> + "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x70",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_write_requests_cs_2",
> + "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 2 (CS2). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x70",
> + "CompId": "0x2",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "MetricName": "cpu_memory_bandwidth",
> + "MetricExpr": "(cpu_read_requests_cs_0 + cpu_read_requests_cs_1 + cpu_read_requests_cs_2 + cpu_write_requests_cs_0 + cpu_write_requests_cs_1 + cpu_write_requests_cs_2) * 64 / (duration_time * 1e6)",
> + "MetricConstraint": "NO_GROUP_EVENTS",
> + "BriefDescription": "Total CPU memory access bandwidth",
> + "MetricGroup": "DF_Memory_BW",
> + "ScaleUnit": "1MB/s"
> + },
> + {
> + "MetricName": "io_memory_max_bandwidth",
> + "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_read_requests_cs_2 + io_write_requests_cs_0 + io_write_requests_cs_1 + io_write_requests_cs_2) * 64 / (duration_time * 1e6)",
> + "MetricConstraint": "NO_GROUP_EVENTS",
> + "BriefDescription": "Maximum inbound I/O memory access bandwidth (upper bound, assuming 64B per request. Actual inbound I/O requests may be 32B or 64B)",
> + "MetricGroup": "DF_Memory_BW",
> + "ScaleUnit": "1MB/s"
> + },
> + {
> + "MetricName": "io_memory_min_bandwidth",
> + "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_read_requests_cs_2 + io_write_requests_cs_0 + io_write_requests_cs_1 + io_write_requests_cs_2) * 32 / (duration_time * 1e6)",
> + "MetricConstraint": "NO_GROUP_EVENTS",
> + "BriefDescription": "Minimum inbound I/O memory access bandwidth (lower bound, assuming 32B per request. Actual inbound I/O requests may be 32B or 64B)",
> + "MetricGroup": "DF_Memory_BW",
> + "ScaleUnit": "1MB/s"
> + }
> +]
> diff --git a/tools/perf/pmu-events/arch/x86/hygonm6/data-fabric.json b/tools/perf/pmu-events/arch/x86/hygonm6/data-fabric.json
> new file mode 100644
> index 000000000000..ee81e35dc6f3
> --- /dev/null
> +++ b/tools/perf/pmu-events/arch/x86/hygonm6/data-fabric.json
> @@ -0,0 +1,170 @@
> +[
> + {
> + "EventName": "cpu_read_requests_cs_0",
> + "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
> + "EventCode": "0x2",
> + "UMask": "0x07",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_read_requests_cs_1",
> + "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
> + "EventCode": "0x2",
> + "UMask": "0x07",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_read_requests_cs_2",
> + "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 2 (CS2).",
> + "EventCode": "0x2",
> + "UMask": "0x07",
> + "CompId": "0x2",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_read_requests_cs_3",
> + "BriefDescription": "Number of CPU read requests to memory in 64-byte units for Coherent Subordinate 3 (CS3).",
> + "EventCode": "0x2",
> + "UMask": "0x07",
> + "CompId": "0x3",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_write_requests_cs_0",
> + "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0).",
> + "EventCode": "0x2",
> + "UMask": "0x08",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_write_requests_cs_1",
> + "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1).",
> + "EventCode": "0x2",
> + "UMask": "0x08",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_write_requests_cs_2",
> + "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 2 (CS2).",
> + "EventCode": "0x2",
> + "UMask": "0x08",
> + "CompId": "0x2",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "cpu_write_requests_cs_3",
> + "BriefDescription": "Number of CPU write requests to memory in 64-byte units for Coherent Subordinate 3 (CS3).",
> + "EventCode": "0x2",
> + "UMask": "0x08",
> + "CompId": "0x3",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_read_requests_cs_0",
> + "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x0F",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_read_requests_cs_1",
> + "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x0F",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_read_requests_cs_2",
> + "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 2 (CS2). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x0F",
> + "CompId": "0x2",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_read_requests_cs_3",
> + "BriefDescription": "Number of inbound I/O read requests to memory in 64-byte units for Coherent Subordinate 3 (CS3). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x0F",
> + "CompId": "0x3",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_write_requests_cs_0",
> + "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 0 (CS0). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x70",
> + "CompId": "0x0",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_write_requests_cs_1",
> + "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 1 (CS1). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x70",
> + "CompId": "0x1",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_write_requests_cs_2",
> + "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 2 (CS2). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x70",
> + "CompId": "0x2",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "EventName": "io_write_requests_cs_3",
> + "BriefDescription": "Number of inbound I/O write requests to memory in 64-byte units for Coherent Subordinate 3 (CS3). Some requests may be 32B, so the reported byte count may overestimate the actual data.",
> + "EventCode": "0x3",
> + "UMask": "0x70",
> + "CompId": "0x3",
> + "Unit": "HYGON_DF",
> + "ScaleUnit": "64Bytes"
> + },
> + {
> + "MetricName": "cpu_memory_bandwidth",
> + "MetricExpr": "(cpu_read_requests_cs_0 + cpu_read_requests_cs_1 + cpu_read_requests_cs_2 + cpu_read_requests_cs_3 + cpu_write_requests_cs_0 + cpu_write_requests_cs_1 + cpu_write_requests_cs_2 + cpu_write_requests_cs_3) * 64 / (duration_time * 1e6)",
> + "MetricConstraint": "NO_GROUP_EVENTS",
> + "BriefDescription": "Total CPU memory access bandwidth",
> + "MetricGroup": "DF_Memory_BW",
> + "ScaleUnit": "1MB/s"
> + },
> + {
> + "MetricName": "io_memory_max_bandwidth",
> + "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_read_requests_cs_2 + io_read_requests_cs_3 + io_write_requests_cs_0 + io_write_requests_cs_1 + io_write_requests_cs_2 + io_write_requests_cs_3) * 64 / (duration_time * 1e6)",
> + "MetricConstraint": "NO_GROUP_EVENTS",
> + "BriefDescription": "Maximum inbound I/O memory access bandwidth (upper bound, assuming 64B per request. Actual inbound I/O requests may be 32B or 64B)",
> + "MetricGroup": "DF_Memory_BW",
> + "ScaleUnit": "1MB/s"
> + },
> + {
> + "MetricName": "io_memory_min_bandwidth",
> + "MetricExpr": "(io_read_requests_cs_0 + io_read_requests_cs_1 + io_read_requests_cs_2 + io_read_requests_cs_3 + io_write_requests_cs_0 + io_write_requests_cs_1 + io_write_requests_cs_2 + io_write_requests_cs_3) * 32 / (duration_time * 1e6)",
> + "MetricConstraint": "NO_GROUP_EVENTS",
> + "BriefDescription": "Minimum inbound I/O memory access bandwidth (lower bound, assuming 32B per request. Actual inbound I/O requests may be 32B or 64B)",
> + "MetricGroup": "DF_Memory_BW",
> + "ScaleUnit": "1MB/s"
> + }
> +]
> diff --git a/tools/perf/pmu-events/arch/x86/mapfile.csv b/tools/perf/pmu-events/arch/x86/mapfile.csv
> index 50a403b429b1..ba17117245d1 100644
> --- a/tools/perf/pmu-events/arch/x86/mapfile.csv
> +++ b/tools/perf/pmu-events/arch/x86/mapfile.csv
> @@ -45,3 +45,6 @@ AuthenticAMD-25-([245][[:xdigit:]]|[[:xdigit:]]),v1,amdzen3,core
> AuthenticAMD-25-[[:xdigit:]]+,v1,amdzen4,core
> AuthenticAMD-26-([12467][[:xdigit:]]|[[:xdigit:]]),v1,amdzen5,core
> AuthenticAMD-26-[[:xdigit:]]+,v1,amdzen6,core
> +HygonGenuine-24-[0123],v1,hygonm1,core
> +HygonGenuine-24-[45],v1,hygonm4,core
> +HygonGenuine-24-(1[012345678]|[6789ABCDEF]),v1,hygonm6,core
> diff --git a/tools/perf/pmu-events/jevents.py b/tools/perf/pmu-events/jevents.py
> index 376dc2d24162..07a843d92483 100755
> --- a/tools/perf/pmu-events/jevents.py
> +++ b/tools/perf/pmu-events/jevents.py
> @@ -294,6 +294,7 @@ class JsonEvent:
> 'L3PMC': 'amd_l3',
> 'DFPMC': 'amd_df',
> 'UMCPMC': 'amd_umc',
> + 'HYGON_DF': 'hygon_df',
> 'cpu_core': 'cpu_core',
> 'cpu_atom': 'cpu_atom',
> 'ali_drw': 'ali_drw',
> @@ -390,6 +391,7 @@ class JsonEvent:
> ('Invert', 'inv='),
> ('SampleAfterValue', 'period='),
> ('UMask', 'umask='),
> + ('CompId', 'compid='),
> ('NodeType', 'type='),
> ('RdWrMask', 'rdwrmask='),
> ('EnAllCores', 'enallcores='),
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2026-08-19 5:12 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-18 10:01 [PATCH v5 0/2] perf/x86/amd/uncore: Add Hygon uncore PMU and JSON events Qi Liu
2026-08-18 10:01 ` [PATCH v5 1/2] perf/x86/amd/uncore: Add Hygon uncore PMU support Qi Liu
2026-08-18 10:16 ` sashiko-bot
2026-08-18 11:32 ` Qi Liu
2026-08-18 10:01 ` [PATCH v5 2/2] perf vendor events hygon: Add Hygon Data Fabric PMU events and metrics Qi Liu
2026-08-18 10:12 ` sashiko-bot
2026-08-19 5:11 ` Sandipan Das
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).