forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 072de836f53be56a70cecf70b43ae43b7ce17376
kernel/arch/powerpc/perf/hv-24x7.c
....@@ -1,13 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Hypervisor supplied "24x7" performance counter support
34 *
45 * Author: Cody P Schafer <cody@linux.vnet.ibm.com>
56 * Copyright 2014 IBM Corporation.
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * as published by the Free Software Foundation; either version
10
- * 2 of the License, or (at your option) any later version.
117 */
128
139 #define pr_fmt(fmt) "hv-24x7: " fmt
....@@ -24,6 +20,7 @@
2420 #include <asm/io.h>
2521 #include <linux/byteorder/generic.h>
2622
23
+#include <asm/rtas.h>
2724 #include "hv-24x7.h"
2825 #include "hv-24x7-catalog.h"
2926 #include "hv-common.h"
....@@ -33,6 +30,8 @@
3330
3431 /* Whether we have to aggregate result data for some domains. */
3532 static bool aggregate_result_elements;
33
+
34
+static cpumask_t hv_24x7_cpumask;
3635
3736 static bool domain_is_valid(unsigned domain)
3837 {
....@@ -59,6 +58,65 @@
5958 default:
6059 return false;
6160 }
61
+}
62
+
63
+/*
64
+ * The Processor Module Information system parameter allows transferring
65
+ * of certain processor module information from the platform to the OS.
66
+ * Refer PAPR+ document to get parameter token value as '43'.
67
+ */
68
+
69
+#define PROCESSOR_MODULE_INFO 43
70
+
71
+static u32 phys_sockets; /* Physical sockets */
72
+static u32 phys_chipspersocket; /* Physical chips per socket*/
73
+static u32 phys_coresperchip; /* Physical cores per chip */
74
+
75
+/*
76
+ * read_24x7_sys_info()
77
+ * Retrieve the number of sockets and chips per socket and cores per
78
+ * chip details through the get-system-parameter rtas call.
79
+ */
80
+void read_24x7_sys_info(void)
81
+{
82
+ int call_status, len, ntypes;
83
+
84
+ spin_lock(&rtas_data_buf_lock);
85
+
86
+ /*
87
+ * Making system parameter: chips and sockets and cores per chip
88
+ * default to 1.
89
+ */
90
+ phys_sockets = 1;
91
+ phys_chipspersocket = 1;
92
+ phys_coresperchip = 1;
93
+
94
+ call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1,
95
+ NULL,
96
+ PROCESSOR_MODULE_INFO,
97
+ __pa(rtas_data_buf),
98
+ RTAS_DATA_BUF_SIZE);
99
+
100
+ if (call_status != 0) {
101
+ pr_err("Error calling get-system-parameter %d\n",
102
+ call_status);
103
+ } else {
104
+ len = be16_to_cpup((__be16 *)&rtas_data_buf[0]);
105
+ if (len < 8)
106
+ goto out;
107
+
108
+ ntypes = be16_to_cpup((__be16 *)&rtas_data_buf[2]);
109
+
110
+ if (!ntypes)
111
+ goto out;
112
+
113
+ phys_sockets = be16_to_cpup((__be16 *)&rtas_data_buf[4]);
114
+ phys_chipspersocket = be16_to_cpup((__be16 *)&rtas_data_buf[6]);
115
+ phys_coresperchip = be16_to_cpup((__be16 *)&rtas_data_buf[8]);
116
+ }
117
+
118
+out:
119
+ spin_unlock(&rtas_data_buf_lock);
62120 }
63121
64122 /* Domains for which more than one result element are returned for each event. */
....@@ -390,6 +448,30 @@
390448 return sprintf(buf, "%s\n", (char *)d->var);
391449 }
392450
451
+static ssize_t cpumask_show(struct device *dev,
452
+ struct device_attribute *attr, char *buf)
453
+{
454
+ return cpumap_print_to_pagebuf(true, buf, &hv_24x7_cpumask);
455
+}
456
+
457
+static ssize_t sockets_show(struct device *dev,
458
+ struct device_attribute *attr, char *buf)
459
+{
460
+ return sprintf(buf, "%d\n", phys_sockets);
461
+}
462
+
463
+static ssize_t chipspersocket_show(struct device *dev,
464
+ struct device_attribute *attr, char *buf)
465
+{
466
+ return sprintf(buf, "%d\n", phys_chipspersocket);
467
+}
468
+
469
+static ssize_t coresperchip_show(struct device *dev,
470
+ struct device_attribute *attr, char *buf)
471
+{
472
+ return sprintf(buf, "%d\n", phys_coresperchip);
473
+}
474
+
393475 static struct attribute *device_str_attr_create_(char *name, char *str)
394476 {
395477 struct dev_ext_attribute *attr = kzalloc(sizeof(*attr), GFP_KERNEL);
....@@ -571,7 +653,7 @@
571653 struct event_uniq *it;
572654 int result;
573655
574
- it = container_of(*new, struct event_uniq, node);
656
+ it = rb_entry(*new, struct event_uniq, node);
575657 result = ev_uniq_ord(name, nl, domain, it->name, it->nl,
576658 it->domain);
577659
....@@ -1036,16 +1118,32 @@
10361118 (unsigned long long)be32_to_cpu(page_0->length) * 4096);
10371119 static BIN_ATTR_RO(catalog, 0/* real length varies */);
10381120 static DEVICE_ATTR_RO(domains);
1121
+static DEVICE_ATTR_RO(sockets);
1122
+static DEVICE_ATTR_RO(chipspersocket);
1123
+static DEVICE_ATTR_RO(coresperchip);
1124
+static DEVICE_ATTR_RO(cpumask);
10391125
10401126 static struct bin_attribute *if_bin_attrs[] = {
10411127 &bin_attr_catalog,
10421128 NULL,
10431129 };
10441130
1131
+static struct attribute *cpumask_attrs[] = {
1132
+ &dev_attr_cpumask.attr,
1133
+ NULL,
1134
+};
1135
+
1136
+static struct attribute_group cpumask_attr_group = {
1137
+ .attrs = cpumask_attrs,
1138
+};
1139
+
10451140 static struct attribute *if_attrs[] = {
10461141 &dev_attr_catalog_len.attr,
10471142 &dev_attr_catalog_version.attr,
10481143 &dev_attr_domains.attr,
1144
+ &dev_attr_sockets.attr,
1145
+ &dev_attr_chipspersocket.attr,
1146
+ &dev_attr_coresperchip.attr,
10491147 NULL,
10501148 };
10511149
....@@ -1061,6 +1159,7 @@
10611159 &event_desc_group,
10621160 &event_long_desc_group,
10631161 &if_group,
1162
+ &cpumask_attr_group,
10641163 NULL,
10651164 };
10661165
....@@ -1305,15 +1404,6 @@
13051404 event_get_reserved3(event));
13061405 return -EINVAL;
13071406 }
1308
-
1309
- /* unsupported modes and filters */
1310
- if (event->attr.exclude_user ||
1311
- event->attr.exclude_kernel ||
1312
- event->attr.exclude_hv ||
1313
- event->attr.exclude_idle ||
1314
- event->attr.exclude_host ||
1315
- event->attr.exclude_guest)
1316
- return -EINVAL;
13171407
13181408 /* no branch sampling */
13191409 if (has_branch_stack(event))
....@@ -1567,7 +1657,47 @@
15671657 .start_txn = h_24x7_event_start_txn,
15681658 .commit_txn = h_24x7_event_commit_txn,
15691659 .cancel_txn = h_24x7_event_cancel_txn,
1660
+ .capabilities = PERF_PMU_CAP_NO_EXCLUDE,
15701661 };
1662
+
1663
+static int ppc_hv_24x7_cpu_online(unsigned int cpu)
1664
+{
1665
+ if (cpumask_empty(&hv_24x7_cpumask))
1666
+ cpumask_set_cpu(cpu, &hv_24x7_cpumask);
1667
+
1668
+ return 0;
1669
+}
1670
+
1671
+static int ppc_hv_24x7_cpu_offline(unsigned int cpu)
1672
+{
1673
+ int target;
1674
+
1675
+ /* Check if exiting cpu is used for collecting 24x7 events */
1676
+ if (!cpumask_test_and_clear_cpu(cpu, &hv_24x7_cpumask))
1677
+ return 0;
1678
+
1679
+ /* Find a new cpu to collect 24x7 events */
1680
+ target = cpumask_last(cpu_active_mask);
1681
+
1682
+ if (target < 0 || target >= nr_cpu_ids) {
1683
+ pr_err("hv_24x7: CPU hotplug init failed\n");
1684
+ return -1;
1685
+ }
1686
+
1687
+ /* Migrate 24x7 events to the new target */
1688
+ cpumask_set_cpu(target, &hv_24x7_cpumask);
1689
+ perf_pmu_migrate_context(&h_24x7_pmu, cpu, target);
1690
+
1691
+ return 0;
1692
+}
1693
+
1694
+static int hv_24x7_cpu_hotplug_init(void)
1695
+{
1696
+ return cpuhp_setup_state(CPUHP_AP_PERF_POWERPC_HV_24x7_ONLINE,
1697
+ "perf/powerpc/hv_24x7:online",
1698
+ ppc_hv_24x7_cpu_online,
1699
+ ppc_hv_24x7_cpu_offline);
1700
+}
15711701
15721702 static int hv_24x7_init(void)
15731703 {
....@@ -1613,10 +1743,17 @@
16131743 if (r)
16141744 return r;
16151745
1746
+ /* init cpuhotplug */
1747
+ r = hv_24x7_cpu_hotplug_init();
1748
+ if (r)
1749
+ return r;
1750
+
16161751 r = perf_pmu_register(&h_24x7_pmu, h_24x7_pmu.name, -1);
16171752 if (r)
16181753 return r;
16191754
1755
+ read_24x7_sys_info();
1756
+
16201757 return 0;
16211758 }
16221759