Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Jul 2021 15:25:34 GMT
From:      Mitchell Horne <mhorne@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 83166f871407 - stable/13 - arm64 support for pmu-events
Message-ID:  <202107291525.16TFPYEe010038@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by mhorne:

URL: https://cgit.FreeBSD.org/src/commit/?id=83166f87140764c36d7c6bdfab0433aceada66a9

commit 83166f87140764c36d7c6bdfab0433aceada66a9
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2021-05-19 16:11:33 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2021-07-29 15:02:05 +0000

    arm64 support for pmu-events
    
    8cc3815f:
    hwpmc_arm64: accept raw event codes for PMC_OP_PMCALLOCATE
    
    Make it possible to specify event codes without an offset of
    PMC_EV_ARMV8_FIRST, by setting a machine-dependent flag. This is
    required to make use of event definitions from pmu-events.
    
    Reviewed by:    ray (slightly earlier version)
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D30602
    
    28dd6730:
    libpmc: enable pmu_utils on arm64
    
    This allows supported libpmc to query/select from the pmu-events table,
    which may have a more complete set of events than what we define
    manually. A future update to these definitions should greatly improve
    this support. The alias table is empty for now, until this future import
    is complete.
    
    Add the Foundation's copyright for recent work on this file.
    
    Reviewed by:    ray (slightly earlier version)
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D30603
    
    27ea55fc:
    libpmc/hwpmc: fix issues with arm64 pmu-events support
    
    Due to a mis-merge, the changes committed to libpmc never called
    pmu_parse_event(), or set pm->pm_ev. However, this field shouldn't be
    used to carry the actual pmc event code anyway, as it is expected to
    contain the index into the pmu event array (otherwise, it breaks event
    name lookup in pmclog_get_event()). Add a new MD field,
    pm_md.pm_md_config, to pass the raw event code to arm64_allocate_pmc().
    
    Additionally, the change made to pmc_md_op_pmcallocate was incorrect, as
    this is a union, not a struct. Restore the proper padding size.
    
    Reviewed by:    luporl, ray, andrew
    Fixes:          28dd6730a5d6 ("libpmc: enable pmu_utils on arm64")
    Fixes:          8cc3815f02be ("hwpmc_arm64: accept raw event codes...")
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D31221
    
    (cherry picked from commit 8cc3815f02be9fa2a96e47713ad989e6d787e12a)
    (cherry picked from commit 28dd6730a5d6bc73aca4c015c0ff875a9def25ac)
    (cherry picked from commit 27ea55fc655b0081f760a34ff5dd5526ba02a0fb)
---
 lib/libpmc/libpmc_pmu_util.c | 49 ++++++++++++++++++++++++++++++++++++++++++++
 sys/arm64/include/pmc_mdep.h |  5 +++++
 sys/dev/hwpmc/hwpmc_arm64.c  | 11 ++++++----
 3 files changed, 61 insertions(+), 4 deletions(-)

diff --git a/lib/libpmc/libpmc_pmu_util.c b/lib/libpmc/libpmc_pmu_util.c
index 81320a3dc954..e6f74e6abe81 100644
--- a/lib/libpmc/libpmc_pmu_util.c
+++ b/lib/libpmc/libpmc_pmu_util.c
@@ -2,6 +2,10 @@
  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
  *
  * Copyright (c) 2018, Matthew Macy
+ * Copyright (c) 2021, The FreeBSD Foundation
+ *
+ * Portions of this software were developed by Mitchell Horne
+ * under sponsorship from the FreeBSD Foundation.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -139,6 +143,24 @@ pmu_alias_get(const char *name)
 	return (name);
 }
 
+#elif defined(__aarch64__)
+
+static struct pmu_alias pmu_armv8_alias_table[] = {
+	{NULL, NULL},
+};
+
+static const char *
+pmu_alias_get(const char *name)
+{
+	struct pmu_alias *pa;
+
+	for (pa = pmu_armv8_alias_table; pa->pa_alias != NULL; pa++)
+		if (strcasecmp(name, pa->pa_alias) == 0)
+			return (pa->pa_name);
+
+	return (name);
+}
+
 #else
 
 static const char *
@@ -549,6 +571,33 @@ pmc_pmu_pmcallocate(const char *event_name, struct pmc_op_pmcallocate *pm)
 		return (pmc_pmu_amd_pmcallocate(event_name, pm, &ped));
 }
 
+#elif defined(__aarch64__)
+
+int
+pmc_pmu_pmcallocate(const char *event_name, struct pmc_op_pmcallocate *pm)
+{
+	const struct pmu_event *pe;
+	struct pmu_event_desc ped;
+	int idx = -1;
+
+	event_name = pmu_alias_get(event_name);
+	if ((pe = pmu_event_get(NULL, event_name, &idx)) == NULL)
+		return (ENOENT);
+	if (pe->event == NULL)
+		return (ENOENT);
+	if (pmu_parse_event(&ped, pe->event))
+		return (ENOENT);
+
+	assert(idx >= 0);
+	pm->pm_ev = idx;
+	pm->pm_md.pm_md_config = ped.ped_event;
+	pm->pm_md.pm_md_flags |= PM_MD_RAW_EVENT;
+	pm->pm_class = PMC_CLASS_ARMV8;
+	pm->pm_caps |= (PMC_CAP_READ | PMC_CAP_WRITE);
+
+	return (0);
+}
+
 #else
 
 int
diff --git a/sys/arm64/include/pmc_mdep.h b/sys/arm64/include/pmc_mdep.h
index bcf08a7f9551..dec90b386b13 100644
--- a/sys/arm64/include/pmc_mdep.h
+++ b/sys/arm64/include/pmc_mdep.h
@@ -38,6 +38,11 @@
 #include <dev/hwpmc/hwpmc_arm64.h>
 
 union pmc_md_op_pmcallocate {
+	struct {
+		uint32_t	pm_md_config;
+		uint32_t	pm_md_flags;
+#define	PM_MD_RAW_EVENT		0x1
+	};
 	uint64_t		__pad[4];
 };
 
diff --git a/sys/dev/hwpmc/hwpmc_arm64.c b/sys/dev/hwpmc/hwpmc_arm64.c
index be26605bad51..06e2e66c7fda 100644
--- a/sys/dev/hwpmc/hwpmc_arm64.c
+++ b/sys/dev/hwpmc/hwpmc_arm64.c
@@ -181,11 +181,14 @@ arm64_allocate_pmc(int cpu, int ri, struct pmc *pm,
 	}
 	pe = a->pm_ev;
 
-	config = (uint32_t)pe - PMC_EV_ARMV8_FIRST;
-	if (config > (PMC_EV_ARMV8_LAST - PMC_EV_ARMV8_FIRST))
-		return (EINVAL);
+	/* Adjust the config value if needed. */
+	config = a->pm_md.pm_md_config;
+	if ((a->pm_md.pm_md_flags & PM_MD_RAW_EVENT) == 0) {
+		config = (uint32_t)pe - PMC_EV_ARMV8_FIRST;
+		if (config > (PMC_EV_ARMV8_LAST - PMC_EV_ARMV8_FIRST))
+			return (EINVAL);
+	}
 	pm->pm_md.pm_arm64.pm_arm64_evsel = config;
-
 	PMCDBG2(MDP, ALL, 2, "arm64-allocate ri=%d -> config=0x%x", ri, config);
 
 	return (0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202107291525.16TFPYEe010038>