Lines Matching +full:core +full:- +full:domain
1 // SPDX-License-Identifier: GPL-2.0-or-later
9 #define pr_fmt(fmt) "hv-24x7: " fmt
24 #include "hv-24x7.h"
25 #include "hv-24x7-catalog.h"
26 #include "hv-common.h"
36 static bool domain_is_valid(unsigned domain) in domain_is_valid() argument
38 switch (domain) { in domain_is_valid()
39 #define DOMAIN(n, v, x, c) \ in domain_is_valid() macro
42 #include "hv-24x7-domains.h" in domain_is_valid()
43 #undef DOMAIN in domain_is_valid()
50 static bool is_physical_domain(unsigned domain) in is_physical_domain() argument
52 switch (domain) { in is_physical_domain()
53 #define DOMAIN(n, v, x, c) \ in is_physical_domain() macro
56 #include "hv-24x7-domains.h" in is_physical_domain()
57 #undef DOMAIN in is_physical_domain()
78 * chip details through the get-system-parameter rtas call.
94 call_status = rtas_call(rtas_token("ibm,get-system-parameter"), 3, 1, in read_24x7_sys_info()
101 pr_err("Error calling get-system-parameter %d\n", in read_24x7_sys_info()
123 static bool domain_needs_aggregation(unsigned int domain) in domain_needs_aggregation() argument
126 (domain == HV_PERF_DOMAIN_PHYS_CORE || in domain_needs_aggregation()
127 (domain >= HV_PERF_DOMAIN_VCPU_HOME_CORE && in domain_needs_aggregation()
128 domain <= HV_PERF_DOMAIN_VCPU_REMOTE_NODE)); in domain_needs_aggregation()
131 static const char *domain_name(unsigned domain) in domain_name() argument
133 if (!domain_is_valid(domain)) in domain_name()
136 switch (domain) { in domain_name()
138 case HV_PERF_DOMAIN_PHYS_CORE: return "Physical Core"; in domain_name()
139 case HV_PERF_DOMAIN_VCPU_HOME_CORE: return "VCPU Home Core"; in domain_name()
145 WARN_ON_ONCE(domain); in domain_name()
149 static bool catalog_entry_domain_is_valid(unsigned domain) in catalog_entry_domain_is_valid() argument
153 return is_physical_domain(domain); in catalog_entry_domain_is_valid()
155 return domain_is_valid(domain); in catalog_entry_domain_is_valid()
160 * - Think of the hcall as an interface to a 4d array of counters:
161 * - x = domains
162 * - y = indexes in the domain (core, chip, vcpu, node, etc)
163 * - z = offset into the counter space
164 * - w = lpars (guest vms, "logical partitions")
165 * - A single request is: x,y,y_last,z,z_last,w,w_last
166 * - this means we can retrieve a rectangle of counters in y,z for a single x.
168 * - Things to consider (ignoring w):
169 * - input cost_per_request = 16
170 * - output cost_per_result(ys,zs) = 8 + 8 * ys + ys * zs
171 * - limited number of requests per hcall (must fit into 4K bytes)
172 * - 4k = 16 [buffer header] - 16 [request size] * request_count
173 * - 255 requests per hcall
174 * - sometimes it will be more efficient to read extra data and discard
179 * perf stat -e 'hv_24x7/domain=2,offset=8,vcpu=0,lpar=0xffffffff/'
182 /* u3 0-6, one of HV_24X7_PERF_DOMAIN */
183 EVENT_DEFINE_RANGE_FORMAT(domain, config, 0, 3);
185 EVENT_DEFINE_RANGE_FORMAT(core, config, 16, 31);
249 return (H24x7_DATA_BUFFER_SIZE - sizeof(struct hv_24x7_request_buffer)) in max_num_requests()
255 *len = be16_to_cpu(ev->event_name_len) - 2; in event_name()
256 return (char *)ev->remainder; in event_name()
261 unsigned nl = be16_to_cpu(ev->event_name_len); in event_desc()
262 __be16 *desc_len = (__be16 *)(ev->remainder + nl - 2); in event_desc()
264 *len = be16_to_cpu(*desc_len) - 2; in event_desc()
265 return (char *)ev->remainder + nl; in event_desc()
270 unsigned nl = be16_to_cpu(ev->event_name_len); in event_long_desc()
271 __be16 *desc_len_ = (__be16 *)(ev->remainder + nl - 2); in event_long_desc()
273 __be16 *long_desc_len = (__be16 *)(ev->remainder + nl + desc_len - 2); in event_long_desc()
275 *len = be16_to_cpu(*long_desc_len) - 2; in event_long_desc()
276 return (char *)ev->remainder + nl + desc_len; in event_long_desc()
289 * - padding for desc, name, and long/detailed desc is required to be '\0'
300 unsigned nl = be16_to_cpu(ev->event_name_len); in event_end()
313 dl_ = (__be16 *)(ev->remainder + nl - 2); in event_end()
328 ldl_ = (__be16 *)(ev->remainder + nl + dl - 2); in event_end()
367 * data for this sysfs entry based on the event's domain.
369 * Events belonging to the Chip domain can only be monitored in that domain.
370 * i.e the domain for these events is a fixed/knwon value.
372 * Events belonging to the Core domain can be monitored either in the physical
373 * core or in one of the virtual CPU domains. So the domain value for these
375 * the Core events with 'domain=?' so the perf-tool can error check required
378 * NOTE: For the Core domain events, rather than making domain a required
380 * override the domain to one of the VCPU domains.
384 * If we set domain=2 (PHYS_CHIP) and allow user to override this field
389 * perf stat -e hv_24x7/HPM_PCYC,offset=0x20/
393 * By not assigning a default value to the domain for the Core events,
396 * - Specifying values for parameters with "=?" is required.
398 * - Specifying (i.e overriding) values for other parameters
401 static char *event_fmt(struct hv_24x7_event_data *event, unsigned domain) in event_fmt() argument
408 switch (domain) { in event_fmt()
410 snprintf(buf, sizeof(buf), "%d", domain); in event_fmt()
418 sindex = "core"; in event_fmt()
427 "domain=%s,offset=0x%x,%s=?,lpar=%s", in event_fmt()
429 be16_to_cpu(event->event_counter_offs) + in event_fmt()
430 be16_to_cpu(event->event_group_record_offs), in event_fmt()
448 return sprintf(buf, "%s\n", (char *)d->var); in device_show_string()
482 sysfs_attr_init(&attr->attr.attr); in device_str_attr_create_()
484 attr->var = str; in device_str_attr_create_()
485 attr->attr.attr.name = name; in device_str_attr_create_()
486 attr->attr.attr.mode = 0444; in device_str_attr_create_()
487 attr->attr.show = device_show_string; in device_str_attr_create_()
489 return &attr->attr.attr; in device_str_attr_create_()
534 unsigned domain, in event_to_attr() argument
541 if (!domain_is_valid(domain)) { in event_to_attr()
542 pr_warn("catalog event %u has invalid domain %u\n", in event_to_attr()
543 ix, domain); in event_to_attr()
547 val = event_fmt(event, domain); in event_to_attr()
605 *attrs = event_to_attr(ix, event, event->domain, nonce); in event_data_to_attrs()
607 return -1; in event_data_to_attrs()
618 unsigned domain; member
626 return -1; in memord()
641 return -1; in ev_uniq_ord()
646 unsigned domain) in event_uniq_add() argument
648 struct rb_node **new = &(root->rb_node), *parent = NULL; in event_uniq_add()
657 result = ev_uniq_ord(name, nl, domain, it->name, it->nl, in event_uniq_add()
658 it->domain); in event_uniq_add()
662 new = &((*new)->rb_left); in event_uniq_add()
664 new = &((*new)->rb_right); in event_uniq_add()
666 it->ct++; in event_uniq_add()
668 name, it->ct); in event_uniq_add()
669 return it->ct; in event_uniq_add()
675 return -ENOMEM; in event_uniq_add()
681 .domain = domain, in event_uniq_add()
685 rb_link_node(&data->node, parent, new); in event_uniq_add()
686 rb_insert_color(&data->node, root); in event_uniq_add()
688 /* data->ct */ in event_uniq_add()
710 * Otherwise, return -1 (and print as appropriate).
722 return -1; in catalog_event_len_validate()
726 event_data_bytes - offset); in catalog_event_len_validate()
727 return -1; in catalog_event_len_validate()
733 return -1; in catalog_event_len_validate()
736 ev_len = be16_to_cpu(event->length); in catalog_event_len_validate()
747 return -1; in catalog_event_len_validate()
755 return -1; in catalog_event_len_validate()
761 return -1; in catalog_event_len_validate()
798 ret = -ENOMEM; in create_events_from_catalog()
804 ret = -EIO; in create_events_from_catalog()
808 catalog_version_num = be64_to_cpu(page_0->version); in create_events_from_catalog()
809 catalog_page_len = be32_to_cpu(page_0->length); in create_events_from_catalog()
813 ret = -EIO; in create_events_from_catalog()
819 event_entry_count = be16_to_cpu(page_0->event_entry_count); in create_events_from_catalog()
820 event_data_offs = be16_to_cpu(page_0->event_data_offs); in create_events_from_catalog()
821 event_data_len = be16_to_cpu(page_0->event_data_len); in create_events_from_catalog()
829 || (MAX_4K - event_data_offs < event_data_len)) { in create_events_from_catalog()
832 ret = -EIO; in create_events_from_catalog()
837 pr_err("event data %zu-%zu does not fit inside catalog 0-%zu\n", in create_events_from_catalog()
841 ret = -EIO; in create_events_from_catalog()
845 if (SIZE_MAX - 1 < event_entry_count) { in create_events_from_catalog()
847 ret = -EIO; in create_events_from_catalog()
860 ret = -ENOMEM; in create_events_from_catalog()
880 ret = -EIO; in create_events_from_catalog()
892 size_t offset = (void *)event - (void *)event_data; in create_events_from_catalog()
909 if (event->event_group_record_len == 0) { in create_events_from_catalog()
916 if (!catalog_entry_domain_is_valid(event->domain)) { in create_events_from_catalog()
917 pr_info("event %zu (%.*s) has invalid domain %d\n", in create_events_from_catalog()
918 event_idx, nl, name, event->domain); in create_events_from_catalog()
933 ret = -ENOMEM; in create_events_from_catalog()
940 ret = -ENOMEM; in create_events_from_catalog()
947 ret = -ENOMEM; in create_events_from_catalog()
955 event_idx++, ev_len = be16_to_cpu(event->length), in create_events_from_catalog()
964 if (event->event_group_record_len == 0) in create_events_from_catalog()
966 if (!catalog_entry_domain_is_valid(event->domain)) in create_events_from_catalog()
973 nonce = event_uniq_add(&ev_uniq, name, nl, event->domain); in create_events_from_catalog()
1038 return -ENOMEM; in catalog_read()
1042 ret = -EIO; in catalog_read()
1046 catalog_version_num = be64_to_cpu(page_0->version); in catalog_read()
1047 catalog_page_len = be32_to_cpu(page_0->length); in catalog_read()
1060 ret = -EIO; in catalog_read()
1065 copy_len = 4096 - offset_in_page; in catalog_read()
1117 return -ENOMEM; \
1120 ret = -EIO; \
1131 (unsigned long long)be64_to_cpu(page_0->version));
1133 (unsigned long long)be32_to_cpu(page_0->length) * 4096);
1191 request_buffer->interface_version = interface_version; in init_24x7_request()
1192 /* memset above set request_buffer->num_requests to 0 */ in init_24x7_request()
1216 req = request_buffer->requests; in make_24x7_request()
1218 req->performance_domain, req->data_offset, in make_24x7_request()
1219 req->starting_ix, req->starting_lpar_ix, in make_24x7_request()
1220 ret, ret, result_buffer->detailed_rc, in make_24x7_request()
1221 result_buffer->failing_request_ix); in make_24x7_request()
1222 return -EIO; in make_24x7_request()
1243 if (request_buffer->num_requests >= in add_event_to_24x7_request()
1244 max_num_requests(request_buffer->interface_version)) { in add_event_to_24x7_request()
1246 request_buffer->num_requests); in add_event_to_24x7_request()
1247 return -EINVAL; in add_event_to_24x7_request()
1261 req_size = H24x7_REQUEST_SIZE(request_buffer->interface_version); in add_event_to_24x7_request()
1263 i = request_buffer->num_requests++; in add_event_to_24x7_request()
1264 req = (void *) request_buffer->requests + i * req_size; in add_event_to_24x7_request()
1266 req->performance_domain = event_get_domain(event); in add_event_to_24x7_request()
1267 req->data_size = cpu_to_be16(8); in add_event_to_24x7_request()
1268 req->data_offset = cpu_to_be32(event_get_offset(event)); in add_event_to_24x7_request()
1269 req->starting_lpar_ix = cpu_to_be16(event_get_lpar(event)); in add_event_to_24x7_request()
1270 req->max_num_lpars = cpu_to_be16(1); in add_event_to_24x7_request()
1271 req->starting_ix = cpu_to_be16(idx); in add_event_to_24x7_request()
1272 req->max_ix = cpu_to_be16(1); in add_event_to_24x7_request()
1274 if (request_buffer->interface_version > 1) { in add_event_to_24x7_request()
1275 if (domain_needs_aggregation(req->performance_domain)) in add_event_to_24x7_request()
1276 req->max_num_thread_groups = -1; in add_event_to_24x7_request()
1277 else if (req->performance_domain != HV_PERF_DOMAIN_PHYS_CHIP) { in add_event_to_24x7_request()
1278 req->starting_thread_group_ix = idx % 2; in add_event_to_24x7_request()
1279 req->max_num_thread_groups = 1; in add_event_to_24x7_request()
1287 * get_count_from_result - get event count from all result elements in result
1303 u16 num_elements = be16_to_cpu(res->num_elements_returned); in get_count_from_result()
1304 u16 data_size = be16_to_cpu(res->result_element_data_size); in get_count_from_result()
1315 res->result_ix); in get_count_from_result()
1318 *next = (struct hv_24x7_result *) res->elements; in get_count_from_result()
1320 return -ENODATA; in get_count_from_result()
1331 res->result_ix, num_elements); in get_count_from_result()
1333 return -EIO; in get_count_from_result()
1338 res->result_ix, data_size); in get_count_from_result()
1340 return -ENOTSUPP; in get_count_from_result()
1343 if (resb->interface_version == 1) in get_count_from_result()
1351 for (i = count = 0, element_data = res->elements + data_offset; in get_count_from_result()
1360 *next = element_data - data_offset; in get_count_from_result()
1389 result_buffer->results, count, NULL); in single_24x7_request()
1401 unsigned domain; in h_24x7_event_init() local
1406 if (event->attr.type != event->pmu->type) in h_24x7_event_init()
1407 return -ENOENT; in h_24x7_event_init()
1414 event->attr.config, in h_24x7_event_init()
1416 event->attr.config1, in h_24x7_event_init()
1418 event->attr.config2, in h_24x7_event_init()
1420 return -EINVAL; in h_24x7_event_init()
1425 return -EOPNOTSUPP; in h_24x7_event_init()
1430 return -EINVAL; in h_24x7_event_init()
1433 domain = event_get_domain(event); in h_24x7_event_init()
1434 if (domain >= HV_PERF_DOMAIN_MAX) { in h_24x7_event_init()
1435 pr_devel("invalid domain %d\n", domain); in h_24x7_event_init()
1436 return -EINVAL; in h_24x7_event_init()
1442 return -EIO; in h_24x7_event_init()
1446 if (!caps.collect_privileged && (is_physical_domain(domain) || in h_24x7_event_init()
1449 is_physical_domain(domain), in h_24x7_event_init()
1451 return -EACCES; in h_24x7_event_init()
1457 return -EIO; in h_24x7_event_init()
1459 (void)local64_xchg(&event->hw.prev_count, ct); in h_24x7_event_init()
1479 prev = local64_xchg(&event->hw.prev_count, now); in update_event_count()
1480 local64_add(now - prev, &event->count); in update_event_count()
1514 * so ->commit_txn() can quickly find/update count. in h_24x7_event_read()
1516 i = request_buffer->num_requests - 1; in h_24x7_event_read()
1519 h24x7hw->events[i] = event; in h_24x7_event_read()
1533 local64_set(&event->hw.prev_count, h_24x7_get_value(event)); in h_24x7_event_start()
1590 * and dont need/support ADD transactions. Clear ->txn_flags but otherwise
1627 for (i = 0, res = result_buffer->results; in h_24x7_event_commit_txn()
1628 i < result_buffer->num_results; i++, res = next_res) { in h_24x7_event_commit_txn()
1629 struct perf_event *event = h24x7hw->events[res->result_ix]; in h_24x7_event_commit_txn()
1699 return -1; in ppc_hv_24x7_cpu_offline()
1725 return -ENODEV; in hv_24x7_init()
1726 } else if (!cur_cpu_spec->oprofile_cpu_type) in hv_24x7_init()
1727 return -ENODEV; in hv_24x7_init()
1730 if (!strcmp(cur_cpu_spec->oprofile_cpu_type, "ppc64/power8")) in hv_24x7_init()
1744 return -ENODEV; in hv_24x7_init()
1747 hv_page_cache = kmem_cache_create("hv-page-4096", 4096, 4096, 0, NULL); in hv_24x7_init()
1749 return -ENOMEM; in hv_24x7_init()
1766 r = perf_pmu_register(&h_24x7_pmu, h_24x7_pmu.name, -1); in hv_24x7_init()