Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1340218 > unrolled thread

[PATCH v8 7/7] powerpc/perf: nest pmu cpumask and cpu hotplug support

Started byMadhavan Srinivasan <maddy@linux.vnet.ibm.com>
First post2016-02-23 04:50 +0100
Last post2016-02-29 21:20 +0100
Articles 2 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  [PATCH v8 7/7] powerpc/perf: nest pmu cpumask and cpu hotplug support Madhavan Srinivasan <maddy@linux.vnet.ibm.com> - 2016-02-23 04:50 +0100
    Re: [PATCH v8 7/7] powerpc/perf: nest pmu cpumask and cpu hotplug  support kbuild test robot <lkp@intel.com> - 2016-02-29 21:20 +0100

#1340218 — [PATCH v8 7/7] powerpc/perf: nest pmu cpumask and cpu hotplug support

FromMadhavan Srinivasan <maddy@linux.vnet.ibm.com>
Date2016-02-23 04:50 +0100
Subject[PATCH v8 7/7] powerpc/perf: nest pmu cpumask and cpu hotplug support
Message-ID<r5c95-7TE-31@gated-at.bofh.it>
Adds cpumask attribute to be used by each nest pmu since nest
units are per-chip. Only one cpu (first online cpu) from each chip
is designated to read counters.

On cpu hotplug, dying cpu is checked to see whether it is one of the
designated cpus, if yes, next online cpu from the same chip is
designated as new cpu to read counters.

Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Anton Blanchard <anton@samba.org>
Cc: Daniel Axtens <dja@axtens.net>
Cc: Stephane Eranian <eranian@google.com>
Cc: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com>
Cc: Preeti U Murthy <preetium@andrew.cmu.edu>
Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
---
 arch/powerpc/perf/nest-pmu.c | 171 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 171 insertions(+)

diff --git a/arch/powerpc/perf/nest-pmu.c b/arch/powerpc/perf/nest-pmu.c
index 772e4d2d7a04..4550de859f36 100644
--- a/arch/powerpc/perf/nest-pmu.c
+++ b/arch/powerpc/perf/nest-pmu.c
@@ -12,6 +12,7 @@
 
 struct perchip_nest_info nest_perchip_info[NEST_MAX_CHIPS];
 struct nest_pmu *per_nest_pmu_arr[NEST_MAX_PMUS];
+static cpumask_t nest_pmu_cpu_mask;
 
 PMU_FORMAT_ATTR(event, "config:0-20");
 static struct attribute *nest_format_attrs[] = {
@@ -24,6 +25,171 @@ static struct attribute_group nest_format_group = {
 	.attrs = nest_format_attrs,
 };
 
+static ssize_t nest_pmu_cpumask_get_attr(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	return cpumap_print_to_pagebuf(true, buf, &nest_pmu_cpu_mask);
+}
+
+static DEVICE_ATTR(cpumask, S_IRUGO, nest_pmu_cpumask_get_attr, NULL);
+
+static struct attribute *nest_pmu_cpumask_attrs[] = {
+	&dev_attr_cpumask.attr,
+	NULL,
+};
+
+static struct attribute_group nest_pmu_cpumask_attr_group = {
+	.attrs = nest_pmu_cpumask_attrs,
+};
+
+static void nest_init(int *loc)
+{
+	int rc;
+
+	rc = opal_nest_counters_control(
+				NEST_MODE_PRODUCTION, NEST_ENGINE_START, 0, 0);
+	if (rc)
+		loc[smp_processor_id()] = 1;
+}
+
+static void nest_change_cpu_context(int old_cpu, int new_cpu)
+{
+	int i;
+
+	for (i = 0;
+		(per_nest_pmu_arr[i] != NULL) && (i < NEST_MAX_PMUS); i++)
+		perf_pmu_migrate_context(&per_nest_pmu_arr[i]->pmu,
+							old_cpu, new_cpu);
+}
+
+static void nest_exit_cpu(int cpu)
+{
+	int nid, target = -1;
+	struct cpumask *l_cpumask;
+
+	/*
+	 * Check in the designated list for this cpu. Dont bother
+	 * if not one of them.
+	 */
+	if (!cpumask_test_and_clear_cpu(cpu, &nest_pmu_cpu_mask))
+		return;
+
+	/*
+	 * Now that this cpu is one of the designated,
+	 * find a next cpu a) which is online and b) in same chip.
+	 */
+	nid = cpu_to_node(cpu);
+	l_cpumask = cpumask_of_node(nid);
+	target = cpumask_next(cpu, l_cpumask);
+
+	/*
+	 * Update the cpumask with the target cpu and
+	 * migrate the context if needed
+	 */
+	if (target >= 0 && target <= nr_cpu_ids) {
+		cpumask_set_cpu(target, &nest_pmu_cpu_mask);
+		nest_change_cpu_context(cpu, target);
+	}
+}
+
+static void nest_init_cpu(int cpu)
+{
+	int nid, fcpu, ncpu;
+	struct cpumask *l_cpumask, tmp_mask;
+
+	nid = cpu_to_node(cpu);
+	l_cpumask = cpumask_of_node(nid);
+
+	if (!cpumask_and(&tmp_mask, l_cpumask, &nest_pmu_cpu_mask)) {
+		cpumask_set_cpu(cpu, &nest_pmu_cpu_mask);
+		return;
+	}
+
+	fcpu = cpumask_first(l_cpumask);
+	ncpu = cpumask_next(cpu, l_cpumask);
+	if (cpu == fcpu) {
+		if (cpumask_test_and_clear_cpu(ncpu, &nest_pmu_cpu_mask)) {
+			cpumask_set_cpu(cpu, &nest_pmu_cpu_mask);
+			nest_change_cpu_context(ncpu, cpu);
+		}
+	}
+}
+
+static int nest_pmu_cpu_notifier(struct notifier_block *self,
+					unsigned long action, void *hcpu)
+{
+	long cpu = (long)hcpu;
+
+	switch (action & ~CPU_TASKS_FROZEN) {
+	case CPU_ONLINE:
+		nest_init_cpu(cpu);
+		break;
+	case CPU_DOWN_PREPARE:
+		nest_exit_cpu(cpu);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_OK;
+}
+
+static struct notifier_block nest_pmu_cpu_nb = {
+	.notifier_call  = nest_pmu_cpu_notifier,
+	.priority       = CPU_PRI_PERF + 1,
+};
+
+static int nest_pmu_cpumask_init(void)
+{
+	const struct cpumask *l_cpumask;
+	int cpu, nid;
+	int *cpus_opal_rc;
+
+	if (!cpumask_empty(&nest_pmu_cpu_mask))
+		return 0;
+
+	cpu_notifier_register_begin();
+
+	/*
+	 * Nest PMUs are per-chip counters. So designate a cpu
+	 * from each chip for counter collection.
+	 */
+	for_each_online_node(nid) {
+		l_cpumask = cpumask_of_node(nid);
+
+		/* designate first online cpu in this node */
+		cpu = cpumask_first(l_cpumask);
+		cpumask_set_cpu(cpu, &nest_pmu_cpu_mask);
+	}
+
+	/*
+	 * Memory for OPAL call return value.
+	 */
+	cpus_opal_rc = kzalloc((sizeof(int) * nr_cpu_ids), GFP_KERNEL);
+	if (!cpus_opal_rc)
+		goto fail;
+
+	/* Initialize Nest PMUs in each node using designated cpus */
+	on_each_cpu_mask(&nest_pmu_cpu_mask, (smp_call_func_t)nest_init,
+						(void *)cpus_opal_rc, 1);
+
+	/* Check return value array for any OPAL call failure */
+	for_each_cpu(cpu, &nest_pmu_cpu_mask) {
+		if (cpus_opal_rc[cpu])
+			goto fail;
+	}
+
+
+	__register_cpu_notifier(&nest_pmu_cpu_nb);
+
+	cpu_notifier_register_done();
+	return 0;
+
+fail:
+	cpu_notifier_register_done();
+	return -ENODEV;
+}
+
 static int nest_event_init(struct perf_event *event)
 {
 	int chip_id;
@@ -114,6 +280,7 @@ static int update_pmu_ops(struct nest_pmu *pmu)
 	pmu->pmu.stop = nest_event_stop;
 	pmu->pmu.read = nest_perf_event_update;
 	pmu->attr_groups[1] = &nest_format_group;
+	pmu->attr_groups[2] = &nest_pmu_cpumask_attr_group;
 	pmu->pmu.attr_groups = pmu->attr_groups;
 
 	return 0;
@@ -169,6 +336,10 @@ int init_nest_pmu(struct nest_ima_events *nest_events,
 {
 	int ret = -ENODEV;
 
+	/* Add cpumask and register for hotplug notification */
+	if (nest_pmu_cpumask_init())
+		return ret;
+
 	update_events_in_group(nest_events, idx, pmu_ptr);
 	update_pmu_ops(pmu_ptr);
 
-- 
1.9.1

[toc] | [next] | [standalone]


#1346137 — Re: [PATCH v8 7/7] powerpc/perf: nest pmu cpumask and cpu hotplug support

Fromkbuild test robot <lkp@intel.com>
Date2016-02-29 21:20 +0100
SubjectRe: [PATCH v8 7/7] powerpc/perf: nest pmu cpumask and cpu hotplug support
Message-ID<r7Csq-7Ke-9@gated-at.bofh.it>
In reply to#1340218

[Multipart message — attachments visible in raw view] — view raw

Hi Madhavan,

[auto build test ERROR on v4.5-rc5]
[also build test ERROR on next-20160229]
[cannot apply to powerpc/next]
[if your patch is applied to the wrong git tree, please drop us a note to help improving the system]

url:    https://github.com/0day-ci/linux/commits/Madhavan-Srinivasan/powerpc-powernv-Nest-Instrumentation-support/20160223-120036
config: powerpc-maple_defconfig (attached as .config)
reproduce:
        wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        make.cross ARCH=powerpc 

All errors (new ones prefixed by >>):

   arch/powerpc/perf/nest-pmu.c: In function 'nest_exit_cpu':
>> arch/powerpc/perf/nest-pmu.c:82:12: error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
     l_cpumask = cpumask_of_node(nid);
               ^
   arch/powerpc/perf/nest-pmu.c: In function 'nest_init_cpu':
   arch/powerpc/perf/nest-pmu.c:101:12: error: assignment discards 'const' qualifier from pointer target type [-Werror=discarded-qualifiers]
     l_cpumask = cpumask_of_node(nid);
               ^
   cc1: all warnings being treated as errors

vim +/const +82 arch/powerpc/perf/nest-pmu.c

    76	
    77		/*
    78		 * Now that this cpu is one of the designated,
    79		 * find a next cpu a) which is online and b) in same chip.
    80		 */
    81		nid = cpu_to_node(cpu);
  > 82		l_cpumask = cpumask_of_node(nid);
    83		target = cpumask_next(cpu, l_cpumask);
    84	
    85		/*

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web