Re: [PATCH v13 3/5] powerpc/perf: Add nest imc pmu support

2017-07-22 Thread Madhavan Srinivasan

my bad, missed to change the authership of this patch.

From: Anju T Sudhakar 

On Wednesday 19 July 2017 03:06 AM, Madhavan Srinivasan wrote:

Add support to register Nest In-Memory Collection pmu counters.
Patch adds a new device file called "imc-pmu.c" under powerpc/perf
folder to contain all the device pmu functions.

Device tree parser code added to parse the pmu events information
and create sysfs event attributes for the pmu.

Cpumask attribute added along with Cpu hotplug online/offline functions
specific for nest pmu. A new state "CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE"
added for the cpu hotplug callbacks. Error handle path frees the memory
and unregisters the cpuhotplug callbacks.

Signed-off-by: Anju T Sudhakar 
Signed-off-by: Hemant Kumar 
Signed-off-by: Madhavan Srinivasan 
---
  arch/powerpc/perf/Makefile|   1 +
  arch/powerpc/perf/imc-pmu.c   | 748 ++
  arch/powerpc/platforms/powernv/opal-imc.c |   5 +
  include/linux/cpuhotplug.h|   1 +
  4 files changed, 755 insertions(+)
  create mode 100644 arch/powerpc/perf/imc-pmu.c

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 4d606b99a5cb..3f3a5ce66495 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -8,6 +8,7 @@ obj64-$(CONFIG_PPC_PERF_CTRS)   += power4-pmu.o ppc970-pmu.o 
power5-pmu.o \
   isa207-common.o power8-pmu.o power9-pmu.o
  obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o

+obj-$(CONFIG_PPC_POWERNV)  += imc-pmu.o
  obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
  obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o

diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
new file mode 100644
index ..6e00ea7358a2
--- /dev/null
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -0,0 +1,748 @@
+/*
+ * In-Memory Collection (IMC) Performance Monitor counter support.
+ *
+ * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation.
+ *   (C) 2017 Anju T Sudhakar, IBM Corporation.
+ *   (C) 2017 Hemant K Shaw, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or later version.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+//Nest imc data structures and variable
+/*
+ * Used to avoid races in counting the nest-pmu units during hotplug
+ * register and unregister
+ */
+static DEFINE_MUTEX(nest_init_lock);
+static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc);
+static struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS];
+static cpumask_t nest_imc_cpumask;
+struct imc_pmu_ref *nest_imc_refc;
+static int nest_pmus;
+
+struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
+{
+   return container_of(event->pmu, struct imc_pmu, pmu);
+}
+
+PMU_FORMAT_ATTR(event, "config:0-40");
+PMU_FORMAT_ATTR(offset, "config:0-31");
+PMU_FORMAT_ATTR(rvalue, "config:32");
+PMU_FORMAT_ATTR(mode, "config:33-40");
+static struct attribute *imc_format_attrs[] = {
+   _attr_event.attr,
+   _attr_offset.attr,
+   _attr_rvalue.attr,
+   _attr_mode.attr,
+   NULL,
+};
+
+static struct attribute_group imc_format_group = {
+   .name = "format",
+   .attrs = imc_format_attrs,
+};
+
+/* Get the cpumask printed to a buffer "buf" */
+static ssize_t imc_pmu_cpumask_get_attr(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct pmu *pmu = dev_get_drvdata(dev);
+   struct imc_pmu *imc_pmu = container_of(pmu, struct imc_pmu, pmu);
+   cpumask_t *active_mask;
+
+   /* Subsequenct patch will add more pmu types here */
+   switch(imc_pmu->domain){
+   case IMC_DOMAIN_NEST:
+   active_mask = _imc_cpumask;
+   break;
+   default:
+   return 0;
+   }
+
+   return cpumap_print_to_pagebuf(true, buf, active_mask);
+}
+
+static DEVICE_ATTR(cpumask, S_IRUGO, imc_pmu_cpumask_get_attr, NULL);
+
+static struct attribute *imc_pmu_cpumask_attrs[] = {
+   _attr_cpumask.attr,
+   NULL,
+};
+
+static struct attribute_group imc_pmu_cpumask_attr_group = {
+   .attrs = imc_pmu_cpumask_attrs,
+};
+
+/* device_str_attr_create : Populate event "name" and string "str" in 
attribute */
+static struct attribute *device_str_attr_create(const char *name, const char 
*str)
+{
+   struct perf_pmu_events_attr *attr;
+
+   attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+   if (!attr)
+   return NULL;
+   sysfs_attr_init(>attr.attr);
+
+   attr->event_str = str;
+   attr->attr.attr.name = name;
+   attr->attr.attr.mode = 0444;
+   

Re: [PATCH v13 3/5] powerpc/perf: Add nest imc pmu support

2017-07-22 Thread Madhavan Srinivasan

my bad, missed to change the authership of this patch.

From: Anju T Sudhakar 

On Wednesday 19 July 2017 03:06 AM, Madhavan Srinivasan wrote:

Add support to register Nest In-Memory Collection pmu counters.
Patch adds a new device file called "imc-pmu.c" under powerpc/perf
folder to contain all the device pmu functions.

Device tree parser code added to parse the pmu events information
and create sysfs event attributes for the pmu.

Cpumask attribute added along with Cpu hotplug online/offline functions
specific for nest pmu. A new state "CPUHP_AP_PERF_POWERPC_NEST_IMC_ONLINE"
added for the cpu hotplug callbacks. Error handle path frees the memory
and unregisters the cpuhotplug callbacks.

Signed-off-by: Anju T Sudhakar 
Signed-off-by: Hemant Kumar 
Signed-off-by: Madhavan Srinivasan 
---
  arch/powerpc/perf/Makefile|   1 +
  arch/powerpc/perf/imc-pmu.c   | 748 ++
  arch/powerpc/platforms/powernv/opal-imc.c |   5 +
  include/linux/cpuhotplug.h|   1 +
  4 files changed, 755 insertions(+)
  create mode 100644 arch/powerpc/perf/imc-pmu.c

diff --git a/arch/powerpc/perf/Makefile b/arch/powerpc/perf/Makefile
index 4d606b99a5cb..3f3a5ce66495 100644
--- a/arch/powerpc/perf/Makefile
+++ b/arch/powerpc/perf/Makefile
@@ -8,6 +8,7 @@ obj64-$(CONFIG_PPC_PERF_CTRS)   += power4-pmu.o ppc970-pmu.o 
power5-pmu.o \
   isa207-common.o power8-pmu.o power9-pmu.o
  obj32-$(CONFIG_PPC_PERF_CTRS) += mpc7450-pmu.o

+obj-$(CONFIG_PPC_POWERNV)  += imc-pmu.o
  obj-$(CONFIG_FSL_EMB_PERF_EVENT) += core-fsl-emb.o
  obj-$(CONFIG_FSL_EMB_PERF_EVENT_E500) += e500-pmu.o e6500-pmu.o

diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c
new file mode 100644
index ..6e00ea7358a2
--- /dev/null
+++ b/arch/powerpc/perf/imc-pmu.c
@@ -0,0 +1,748 @@
+/*
+ * In-Memory Collection (IMC) Performance Monitor counter support.
+ *
+ * Copyright (C) 2017 Madhavan Srinivasan, IBM Corporation.
+ *   (C) 2017 Anju T Sudhakar, IBM Corporation.
+ *   (C) 2017 Hemant K Shaw, IBM Corporation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or later version.
+ */
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+//Nest imc data structures and variable
+/*
+ * Used to avoid races in counting the nest-pmu units during hotplug
+ * register and unregister
+ */
+static DEFINE_MUTEX(nest_init_lock);
+static DEFINE_PER_CPU(struct imc_pmu_ref *, local_nest_imc_refc);
+static struct imc_pmu *per_nest_pmu_arr[IMC_MAX_PMUS];
+static cpumask_t nest_imc_cpumask;
+struct imc_pmu_ref *nest_imc_refc;
+static int nest_pmus;
+
+struct imc_pmu *imc_event_to_pmu(struct perf_event *event)
+{
+   return container_of(event->pmu, struct imc_pmu, pmu);
+}
+
+PMU_FORMAT_ATTR(event, "config:0-40");
+PMU_FORMAT_ATTR(offset, "config:0-31");
+PMU_FORMAT_ATTR(rvalue, "config:32");
+PMU_FORMAT_ATTR(mode, "config:33-40");
+static struct attribute *imc_format_attrs[] = {
+   _attr_event.attr,
+   _attr_offset.attr,
+   _attr_rvalue.attr,
+   _attr_mode.attr,
+   NULL,
+};
+
+static struct attribute_group imc_format_group = {
+   .name = "format",
+   .attrs = imc_format_attrs,
+};
+
+/* Get the cpumask printed to a buffer "buf" */
+static ssize_t imc_pmu_cpumask_get_attr(struct device *dev,
+   struct device_attribute *attr,
+   char *buf)
+{
+   struct pmu *pmu = dev_get_drvdata(dev);
+   struct imc_pmu *imc_pmu = container_of(pmu, struct imc_pmu, pmu);
+   cpumask_t *active_mask;
+
+   /* Subsequenct patch will add more pmu types here */
+   switch(imc_pmu->domain){
+   case IMC_DOMAIN_NEST:
+   active_mask = _imc_cpumask;
+   break;
+   default:
+   return 0;
+   }
+
+   return cpumap_print_to_pagebuf(true, buf, active_mask);
+}
+
+static DEVICE_ATTR(cpumask, S_IRUGO, imc_pmu_cpumask_get_attr, NULL);
+
+static struct attribute *imc_pmu_cpumask_attrs[] = {
+   _attr_cpumask.attr,
+   NULL,
+};
+
+static struct attribute_group imc_pmu_cpumask_attr_group = {
+   .attrs = imc_pmu_cpumask_attrs,
+};
+
+/* device_str_attr_create : Populate event "name" and string "str" in 
attribute */
+static struct attribute *device_str_attr_create(const char *name, const char 
*str)
+{
+   struct perf_pmu_events_attr *attr;
+
+   attr = kzalloc(sizeof(*attr), GFP_KERNEL);
+   if (!attr)
+   return NULL;
+   sysfs_attr_init(>attr.attr);
+
+   attr->event_str = str;
+   attr->attr.attr.name = name;
+   attr->attr.attr.mode = 0444;
+   attr->attr.show = perf_event_sysfs_show;
+
+   return >attr.attr;
+}
+
+struct imc_events