powerpc/hv-gpci: Fix hv_gpci event list
authorKajol Jain <kjain@linux.ibm.com>
Wed, 30 Nov 2022 17:45:13 +0000 (23:15 +0530)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 31 Dec 2022 12:32:51 +0000 (13:32 +0100)
[ Upstream commit 03f7c1d2a49acd30e38789cd809d3300721e9b0e ]

Based on getPerfCountInfo v1.018 documentation, some of the
hv_gpci events were deprecated for platform firmware that
supports counter_info_version 0x8 or above.

Fix the hv_gpci event list by adding a new attribute group
called "hv_gpci_event_attrs_v6" and a "ENABLE_EVENTS_COUNTERINFO_V6"
macro to enable these events for platform firmware
that supports counter_info_version 0x6 or below. And assigning
the hv_gpci event list based on output counter info version
of underlying plaform.

Fixes: 97bf2640184f ("powerpc/perf/hv-gpci: add the remaining gpci requests")
Signed-off-by: Kajol Jain <kjain@linux.ibm.com>
Reviewed-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Reviewed-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20221130174513.87501-1-kjain@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
arch/powerpc/perf/hv-gpci-requests.h
arch/powerpc/perf/hv-gpci.c
arch/powerpc/perf/hv-gpci.h
arch/powerpc/perf/req-gen/perf.h

index 8965b44..5e86371 100644 (file)
@@ -79,6 +79,7 @@ REQUEST(__field(0,    8,      partition_id)
 )
 #include I(REQUEST_END)
 
+#ifdef ENABLE_EVENTS_COUNTERINFO_V6
 /*
  * Not available for counter_info_version >= 0x8, use
  * run_instruction_cycles_by_partition(0x100) instead.
@@ -92,6 +93,7 @@ REQUEST(__field(0,    8,      partition_id)
        __count(0x10,   8,      cycles)
 )
 #include I(REQUEST_END)
+#endif
 
 #define REQUEST_NAME system_performance_capabilities
 #define REQUEST_NUM 0x40
@@ -103,6 +105,7 @@ REQUEST(__field(0,  1,      perf_collect_privileged)
 )
 #include I(REQUEST_END)
 
+#ifdef ENABLE_EVENTS_COUNTERINFO_V6
 #define REQUEST_NAME processor_bus_utilization_abc_links
 #define REQUEST_NUM 0x50
 #define REQUEST_IDX_KIND "hw_chip_id=?"
@@ -194,6 +197,7 @@ REQUEST(__field(0,  4,      phys_processor_idx)
        __count(0x28,   8,      instructions_completed)
 )
 #include I(REQUEST_END)
+#endif
 
 /* Processor_core_power_mode (0x95) skipped, no counters */
 /* Affinity_domain_information_by_virtual_processor (0xA0) skipped,
index 5eb60ed..7ff8ff3 100644 (file)
@@ -70,9 +70,9 @@ static const struct attribute_group format_group = {
        .attrs = format_attrs,
 };
 
-static const struct attribute_group event_group = {
+static struct attribute_group event_group = {
        .name  = "events",
-       .attrs = hv_gpci_event_attrs,
+       /* .attrs is set in init */
 };
 
 #define HV_CAPS_ATTR(_name, _format)                           \
@@ -330,6 +330,7 @@ static int hv_gpci_init(void)
        int r;
        unsigned long hret;
        struct hv_perf_caps caps;
+       struct hv_gpci_request_buffer *arg;
 
        hv_gpci_assert_offsets_correct();
 
@@ -353,6 +354,36 @@ static int hv_gpci_init(void)
        /* sampling not supported */
        h_gpci_pmu.capabilities |= PERF_PMU_CAP_NO_INTERRUPT;
 
+       arg = (void *)get_cpu_var(hv_gpci_reqb);
+       memset(arg, 0, HGPCI_REQ_BUFFER_SIZE);
+
+       /*
+        * hcall H_GET_PERF_COUNTER_INFO populates the output
+        * counter_info_version value based on the system hypervisor.
+        * Pass the counter request 0x10 corresponds to request type
+        * 'Dispatch_timebase_by_processor', to get the supported
+        * counter_info_version.
+        */
+       arg->params.counter_request = cpu_to_be32(0x10);
+
+       r = plpar_hcall_norets(H_GET_PERF_COUNTER_INFO,
+                       virt_to_phys(arg), HGPCI_REQ_BUFFER_SIZE);
+       if (r) {
+               pr_devel("hcall failed, can't get supported counter_info_version: 0x%x\n", r);
+               arg->params.counter_info_version_out = 0x8;
+       }
+
+       /*
+        * Use counter_info_version_out value to assign
+        * required hv-gpci event list.
+        */
+       if (arg->params.counter_info_version_out >= 0x8)
+               event_group.attrs = hv_gpci_event_attrs;
+       else
+               event_group.attrs = hv_gpci_event_attrs_v6;
+
+       put_cpu_var(hv_gpci_reqb);
+
        r = perf_pmu_register(&h_gpci_pmu, h_gpci_pmu.name, -1);
        if (r)
                return r;
index 4d10826..c720209 100644 (file)
@@ -26,6 +26,7 @@ enum {
 #define REQUEST_FILE "../hv-gpci-requests.h"
 #define NAME_LOWER hv_gpci
 #define NAME_UPPER HV_GPCI
+#define ENABLE_EVENTS_COUNTERINFO_V6
 #include "req-gen/perf.h"
 #undef REQUEST_FILE
 #undef NAME_LOWER
index fa9bc80..6b2a59f 100644 (file)
@@ -139,6 +139,26 @@ PMU_EVENT_ATTR_STRING(                                                     \
 #define REQUEST_(r_name, r_value, r_idx_1, r_fields)                   \
        r_fields
 
+/* Generate event list for platforms with counter_info_version 0x6 or below */
+static __maybe_unused struct attribute *hv_gpci_event_attrs_v6[] = {
+#include REQUEST_FILE
+       NULL
+};
+
+/*
+ * Based on getPerfCountInfo v1.018 documentation, some of the hv-gpci
+ * events were deprecated for platform firmware that supports
+ * counter_info_version 0x8 or above.
+ * Those deprecated events are still part of platform firmware that
+ * support counter_info_version 0x6 and below. As per the getPerfCountInfo
+ * v1.018 documentation there is no counter_info_version 0x7.
+ * Undefining macro ENABLE_EVENTS_COUNTERINFO_V6, to disable the addition of
+ * deprecated events in "hv_gpci_event_attrs" attribute group, for platforms
+ * that supports counter_info_version 0x8 or above.
+ */
+#undef ENABLE_EVENTS_COUNTERINFO_V6
+
+/* Generate event list for platforms with counter_info_version 0x8 or above*/
 static __maybe_unused struct attribute *hv_gpci_event_attrs[] = {
 #include REQUEST_FILE
        NULL