File 0007-pmdas-perf-Add-cpunumber-option-for-dynamic-perf-eve.patch of Package pcp.18196

From 7392ce0cd29e3364989cde2a2342973c7540b72d Mon Sep 17 00:00:00 2001
From: Anju T Sudhakar <anju@linux.vnet.ibm.com>
Date: Tue, 15 Oct 2019 15:39:11 +0530
Subject: [PATCH] pmdas/perf: Add cpunumber option for dynamic perf events

Patch-mainline: 5.0.1
Git-commit: 7392ce0cd29e3364989cde2a2342973c7540b72d

For perf events defined under [dynamic] section, perf_event_open() is invoked
for the cpumask specified in /sysfs for that event. If no cpumask is
defined, then by default perf_event_open() is called for all cpus
in the system.

For dynamic events like, hv_24x7 nest events, we need perf-event_open()
to be invoked on a single cpu on each node to get the counter data.

Add support to have the cpu number in the perfevent.conf file for
dynamic events, and to use this as the cpumask for perf_event_open() call.

Eg:
---> perfevent.conf

[dynamic]
cpu.branch-misses 3
cpu.cache-references
software.page-faults
software.context-switches
hv_24x7.PM_PB_CYC 13    chip:1

# pmval perfevent.hwcounters.cpu.branch_misses.value

metric:    perfevent.hwcounters.cpu.branch_misses.value
host:      ####
semantics: cumulative counter (converting to rate)
units:     count (converting to count / sec)
samples:   all

              cpu3
               0.0
               0.0

Signed-off-by: Anju T Sudhakar <anju@linux.vnet.ibm.com>
---
 src/pmdas/perfevent/configparser.l  | 19 +++++++++++++--
 src/pmdas/perfevent/perfevent.conf  | 11 +++++++++
 src/pmdas/perfevent/perfinterface.c | 38 ++++++++++++++++++++---------
 3 files changed, 55 insertions(+), 13 deletions(-)

diff --git a/src/pmdas/perfevent/configparser.l b/src/pmdas/perfevent/configparser.l
index 29a322480eb1..83ff8c520786 100644
--- a/src/pmdas/perfevent/configparser.l
+++ b/src/pmdas/perfevent/configparser.l
@@ -195,7 +195,7 @@ static void add_pmc_setting_name_dynamic(configuration_t *config, char *name)
     }
     newpmcdynamicsetting = calloc(1, sizeof *newpmcdynamicsetting);
     newpmcdynamicsetting->name = strdup(name);
-    newpmcdynamicsetting->cpuConfig = 0;
+    newpmcdynamicsetting->cpuConfig = -1;
     newpmcdynamicsetting->scale = 1.0;
     newpmcdynamicsetting->need_perf_scale = 0;
     newpmcdynamicsetting->chip = -1;
@@ -315,7 +315,7 @@ static void set_pmcsetting_derived_scale(configuration_t *config,  double scale,
 
 static void set_pmcsetting_cpuconfig(configuration_t *config, int cpuconfig)
 {
-    pmcsetting_t *pmcsetting;
+    pmcsetting_t *pmcsetting, *list;
     pmcSettingLists_t *setting_lists;
 
     if( (NULL == config) || (0 == config->nConfigEntries) )
@@ -340,6 +340,21 @@ static void set_pmcsetting_cpuconfig(configuration_t *config, int cpuconfig)
             pmcsetting = pmcsetting->next;
         }
     }
+
+    else if (context_dynamic)
+    {
+        list = config->dynamicpmc->dynamicSettingList;
+        if (NULL == list)
+        {
+          return;
+        }
+        while (list->next)
+        {
+          list = list->next;
+        }
+        pmcsetting = list;
+    }
+
     else
     {
         pmcsetting = config->configArr[config->nConfigEntries-1].pmcSettingList;
diff --git a/src/pmdas/perfevent/perfevent.conf b/src/pmdas/perfevent/perfevent.conf
index 12d876f2b7d0..c8ca683ae380 100644
--- a/src/pmdas/perfevent/perfevent.conf
+++ b/src/pmdas/perfevent/perfevent.conf
@@ -25,6 +25,17 @@
 # If not specified like above, a user will continue to see the event but
 # will not be able to monitor it.
 #
+# For events, specified under dynamic section, the cpuconfig can also
+# be specified along with the event.
+# For eg:
+# [dynamic]
+# foo.bar [CPU NUMBER]
+#
+# If no cpu number is specified for events under [dynamic], then the cpumask
+# specified in /sys/bus/event_source/devices/ for that event is considered.
+# Suppose if cpumask is also not mentioned in /sys/ then the event is monitored
+# for all cpus in the system.
+#
 #
 # For derived events :
 # [event:derived]
diff --git a/src/pmdas/perfevent/perfinterface.c b/src/pmdas/perfevent/perfinterface.c
index 161e3fa102c8..e8b8fe490c84 100644
--- a/src/pmdas/perfevent/perfinterface.c
+++ b/src/pmdas/perfevent/perfinterface.c
@@ -699,20 +699,23 @@ static int perf_setup_dynamic_events(perfdata_t *inst,
     struct pmu_event *event_ptr;
     char eventname[BUF_SIZE];
     pmcsetting_t *ptr;
-    int disable_event;
+    int disable_event, cpusetting;
 
     for (pmu_ptr = pmu_list; pmu_ptr; pmu_ptr = pmu_ptr->next) {
         for (event_ptr = pmu_ptr->ev; event_ptr;
              event_ptr = event_ptr->next) {
             ncpus = 0;
             disable_event = 1;
+	    cpusetting = -1;
             /* Setup the event name */
             pmsprintf(eventname, BUF_SIZE, "%s.%s", pmu_ptr->name,
                      event_ptr->name);
             for (ptr = dynamic_setting; ptr; ptr = ptr->next) {
                 if (!strncmp(eventname, ptr->name,
-                             strlen(eventname)))
+                             strlen(eventname))) {
                     disable_event = 0;
+		    cpusetting = ptr->cpuConfig;
+		}
             }
 
             /* Increase the size of event array */
@@ -726,15 +729,28 @@ static int perf_setup_dynamic_events(perfdata_t *inst,
             }
 	    events = evp;
 
-            setup_cpu_config(pmu_ptr, &ncpus, &cpumask);
-
-            if (ncpus <= 0) { /* Assume default cpu set */
-                cpuarr = archinfo->cpus.index;
-                ncpus = archinfo->cpus.count;
-            } else {
-                cpuarr = cpumask;
-            }
-
+	    /*
+	     * If dynamic events have a cpuconfig defined in the
+	     * perfevent.conf, consider that
+	     */
+	    if(!(cpusetting < 0)) {
+	        if (cpusetting < archinfo->cpus.count) {
+		    cpuarr = &archinfo->cpus.index[cpusetting];
+		    ncpus = 1;
+		}
+	    } else {
+		/*
+		 * If no cpuconfig specified in perfevent.conf
+		 * setup the cpu config for this event
+		 */
+	        setup_cpu_config(pmu_ptr, &ncpus, &cpumask);
+		if (ncpus <= 0) { /* Assume default cpu set */
+		    cpuarr = archinfo->cpus.index;
+		    ncpus = archinfo->cpus.count;
+		} else {
+		    cpuarr = cpumask;
+		}
+	    }
             event_t *curr = events + nevents;
             curr->name = strdup(eventname);
 
-- 
2.23.0

openSUSE Build Service is sponsored by