Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.2:Rings:1-MinimalX
pcp
0008-pmdas-perf-Add-support-for-hv_24x7-nest-ev...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0008-pmdas-perf-Add-support-for-hv_24x7-nest-events-on-mu.patch of Package pcp
From 2251fbdda3b270fa1b1c5f59c83d1e156ff8ea36 Mon Sep 17 00:00:00 2001 From: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Date: Wed, 16 Oct 2019 16:09:04 +0530 Subject: [PATCH] pmdas/perf: Add support for hv_24x7 nest events on mutlinode system Patch-mainline: 5.0.1 Git-commit: 2251fbdda3b270fa1b1c5f59c83d1e156ff8ea36 For dynamic perf events like hv_24x7 nest event, `chip_id` is also an event parameter. So for multinode systems, same event can be defined for different nodes(/chips) in the system. Add support for hv_24x7 nest events in mutinode systems. Eg: ---> perfevent.conf [dynamic] hv_24x7.PM_PB_CYC 4 chip:0 hv_24x7.PM_PB_CYC 13 chip:1 hv_24x7.PM_MBA0_CLK_CYC 4 chip:0 hv_24x7.PM_MBA0_CLK_CYC 14 chip:1 # pminfo | grep PM_PB_CYC perfevent.hwcounters.hv_24x7.PM_PB_CYC_chip_1.dutycycle perfevent.hwcounters.hv_24x7.PM_PB_CYC_chip_1.value perfevent.hwcounters.hv_24x7.PM_PB_CYC_chip_0.dutycycle perfevent.hwcounters.hv_24x7.PM_PB_CYC_chip_0.value # pmval perfevent.hwcounters.hv_24x7.PM_PB_CYC_chip_0.value metric: perfevent.hwcounters.hv_24x7.PM_PB_CYC_chip_0.value host: #### semantics: cumulative counter (converting to rate) units: count (converting to count / sec) samples: all cpu4 7.805E+06 # pmval perfevent.hwcounters.hv_24x7.PM_PB_CYC_chip_1.value metric: perfevent.hwcounters.hv_24x7.PM_PB_CYC_chip_1.value host: #### semantics: cumulative counter (converting to rate) units: count (converting to count / sec) samples: all cpu13 7.805E+06 7.805E+06 Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com> --- src/pmdas/perfevent/parse_events.c | 221 ++++++++++++++++++----------- 1 file changed, 138 insertions(+), 83 deletions(-) diff --git a/src/pmdas/perfevent/parse_events.c b/src/pmdas/perfevent/parse_events.c index 1632f09b1f32..27fb37df3fb7 100644 --- a/src/pmdas/perfevent/parse_events.c +++ b/src/pmdas/perfevent/parse_events.c @@ -412,89 +412,138 @@ static void cleanup_property_info(struct property_info *pi) */ static int parse_event_string(char *buf, struct pmu_event *event, struct pmu *pmu, struct pmcsetting *dynamicpmc, - char *pmu_name) + char *pmu_name, int *new_events) { struct property_info *pi, *head = NULL, *tmp; - char *start, *ptr, *nptr, **endptr, *str, eventname[BUF_SIZE]; + char *start, *ptr, *nptr, **endptr, *str, eventname[BUF_SIZE], ev_str[BUF_SIZE], pmc_str[BUF_SIZE], *tmp_buf_str; struct pmcsetting *pmctmp; + int i, ret, sub_ev_cnt = 0; + struct pmu_event *sub_event = NULL, *ev_tmp= NULL, *ev_head = NULL; + + pmsprintf(ev_str, sizeof(ev_str), "%s.%s", pmu_name, event->name); + for (pmctmp = dynamicpmc; pmctmp; pmctmp = pmctmp->next) + if (!strncmp(ev_str, pmctmp->name, strlen(ev_str))) + sub_ev_cnt++; + + if (sub_ev_cnt > 1) + *new_events = sub_ev_cnt; + + for (i = 0; i < (sub_ev_cnt - 1); i++) { + ev_tmp = calloc(1, sizeof(*ev_tmp)); + if (!ev_tmp) { + sub_ev_cnt = 0; + break; + } + + if (!sub_event) { + sub_event = ev_tmp; + ev_head = sub_event; + event->next = ev_head; + sub_event->name = strdup(event->name); + } else { + sub_event->next = ev_tmp; + sub_event = sub_event->next; + sub_event->name = strdup(event->name); + } + } - start = buf; - - while (1) { - ptr = strchr(start, '='); - if (!ptr) - break; - - /* Found a property */ - *ptr = '\0'; - ptr++; /* ptr now points to the value */ - pi = calloc(1, sizeof(*pi)); - if (!pi) { - cleanup_property_info(head); - return -E_PERFEVENT_REALLOC; - } - pi->next = NULL; - - pi->name = strdup(start); - if (!pi->name) { - free(pi); - cleanup_property_info(head); - return -E_PERFEVENT_REALLOC; - } - - pmsprintf(eventname, sizeof(eventname), "%s.%s", pmu_name, event->name); - - /* Find next property */ - start = strchr(ptr, ','); - if (!start) { - str = buf + strlen(buf) - 1; - endptr = &str; - nptr = ptr; - if ((!strcmp(nptr, "?")) && (!strcmp(pi->name, "chip"))) { - for (pmctmp = dynamicpmc; pmctmp; pmctmp = pmctmp->next) { - if (!strncmp(eventname, pmctmp->name, strlen(eventname))) + ev_head = event; + + for (i=0; i < sub_ev_cnt; i++) { + head = NULL; + tmp_buf_str = strdup(buf); + start = tmp_buf_str; + + while (1) { + ptr = strchr(start, '='); + if (!ptr) + break; + + /* Found a property */ + *ptr = '\0'; + ptr++; /* ptr now points to the value */ + pi = calloc(1, sizeof(*pi)); + if (!pi) { + cleanup_property_info(head); + return -E_PERFEVENT_REALLOC; + } + + pi->next = NULL; + pi->name = strdup(start); + if (!pi->name) { + free(pi); + cleanup_property_info(head); + return -E_PERFEVENT_REALLOC; + } + + pmsprintf(eventname, sizeof(eventname), "%s.%s", pmu_name, event->name); + + /* Find next property */ + start = strchr(ptr, ','); + if (!start) { + str = buf + strlen(buf) - 1; + endptr = &str; + nptr = ptr; + if ((!strcmp(nptr, "?")) && (!strcmp(pi->name, "chip"))) { + for (pmctmp = dynamicpmc; pmctmp; pmctmp = pmctmp->next) { + if (!strncmp(eventname, pmctmp->name, strlen(pmctmp->name))) { - pi->value = pmctmp->chip; + pmsprintf(ev_str, sizeof(ev_str), "%s_chip_%d", event->name,pmctmp->chip); + event->name = strdup(ev_str); + pmsprintf(pmc_str, sizeof(pmc_str), "%s_chip_%d", pmctmp->name,pmctmp->chip); + pmctmp->name = strdup(pmc_str); + pi->value = pmctmp->chip; + break; } + } + } else + pi->value = strtoull(nptr, endptr, 16); + if (!head) { + head = pi; + pi = pi->next; + } else { + tmp->next = pi; + tmp = tmp->next; } - } else - pi->value = strtoull(nptr, endptr, 16); - if (!head) { - head = pi; - pi = pi->next; - } else { - tmp->next = pi; - tmp = tmp->next; - } - break; - } else { - /* We found the next property */ - *start = '\0'; - str = buf + strlen(buf) - 1; - endptr = &str; - start++; - nptr = ptr; - if ((!strcmp(nptr, "?")) && (!strcmp(pi->name, "chip"))) { - for (pmctmp = dynamicpmc; pmctmp; pmctmp = pmctmp->next) { - if (!strncmp(eventname, pmctmp->name, strlen(eventname))) + break; + } else { + /* We found the next property */ + *start = '\0'; + str = buf + strlen(buf) - 1; + endptr = &str; + start++; + nptr = ptr; + if ((!strcmp(nptr, "?")) && (!strcmp(pi->name, "chip"))) { + for (pmctmp = dynamicpmc; pmctmp; pmctmp = pmctmp->next) { + if (!strncmp(eventname, pmctmp->name, strlen(pmctmp->name))) { - pi->value = pmctmp->chip; + pmsprintf(ev_str, sizeof(ev_str), "%s_chip_%d", event->name,pmctmp->chip); + event->name = strdup(ev_str); + pmsprintf(pmc_str, sizeof(pmc_str), "%s_chip_%d", pmctmp->name,pmctmp->chip); + pmctmp->name = strdup(pmc_str); + pi->value = pmctmp->chip; + break; } - } - } else - pi->value = strtoul(nptr, endptr, 16); - } - - if (!head) { - head = pi; - tmp = head; - } else { - tmp->next = pi; - tmp = tmp->next; - } + } + } else + pi->value = strtoul(nptr, endptr, 16); + } + if (!head) { + head = pi; + tmp = head; + } else { + tmp->next = pi; + tmp = tmp->next; + } + } + ret = fetch_event_config(head, event, pmu); + if (ret) + return ret; + + event->pmu = pmu; + event = event->next; } - - return fetch_event_config(head, event, pmu); + return 0; } /* @@ -509,7 +558,7 @@ static int fetch_events(DIR *events_dir, struct pmu_event **events, struct dirent *dir; struct pmu_event *ev = NULL, *tmp, *head = NULL; char event_path[PATH_MAX], *buf; - int ret = 0; + int ret = 0, sub_events, i; if (!events_dir) return -1; @@ -551,21 +600,27 @@ static int fetch_events(DIR *events_dir, struct pmu_event **events, goto free_buf; } - ret = parse_event_string(buf, tmp, pmu, dynamicpmc, pmu_name); + ret = parse_event_string(buf, tmp, pmu, dynamicpmc, pmu_name, &sub_events); if (ret) { ret = -E_PERFEVENT_RUNTIME; goto free_buf; } - tmp->pmu = pmu; + i = 0; + do { + tmp->pmu = pmu; + if (!ev) { + ev = tmp; + head = ev; + } else { + ev->next = tmp; + ev = ev->next; + } + tmp = tmp->next; + i++; + } while(i < sub_events); - if (!ev) { - ev = tmp; - head = ev; - } else { - ev->next = tmp; - ev = ev->next; - } + sub_events = 0; } *events = head; -- 2.23.0
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor