LKML Archive on lore.kernel.org help / color / mirror / Atom feed
From: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> To: mpe@ellerman.id.au, benh@kernel.crashing.org, paulus@samba.org Cc: linux-kernel@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, linuxppc-dev@ozlabs.org, eranian@google.com, ak@linux.intel.com, srivatsa@mit.edu, Madhavan Srinivasan <maddy@linux.vnet.ibm.com> Subject: [RFC PATCH 3/7] powerpc/powernv: uncore cpumask and CPU hotplug Date: Wed, 11 Mar 2015 18:37:09 +0530 [thread overview] Message-ID: <1426079233-16720-4-git-send-email-maddy@linux.vnet.ibm.com> (raw) In-Reply-To: <1426079233-16720-1-git-send-email-maddy@linux.vnet.ibm.com> Patch to add cpumask attribute for the Nest pmu to control per-chip counter values to be read by cpus. Also adds support of cpu hotplug. Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> --- arch/powerpc/perf/uncore_pmu.c | 152 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) diff --git a/arch/powerpc/perf/uncore_pmu.c b/arch/powerpc/perf/uncore_pmu.c index cc544d3..67ab6c0 100644 --- a/arch/powerpc/perf/uncore_pmu.c +++ b/arch/powerpc/perf/uncore_pmu.c @@ -19,6 +19,32 @@ struct ppc64_uncore_type *empty_uncore[] = { NULL, }; struct ppc64_uncore_type **ppc64_uncore = empty_uncore; +/* mask of cpus that collect uncore events */ +static cpumask_t uncore_cpu_mask; + +static ssize_t uncore_get_attr_cpumask(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return cpumap_print_to_pagebuf(true, buf, &uncore_cpu_mask); +} + +/* + * cpumask attr used by perf userspace to pick the cpus to execute + * in case of -a option. User can still specify -C option to override. + * Since these Nest Counters are per-chip, make only one cpu from chip + * to read. + */ +static DEVICE_ATTR(cpumask, S_IRUGO, uncore_get_attr_cpumask, NULL); + +static struct attribute *uncore_pmu_attrs[] = { + &dev_attr_cpumask.attr, + NULL, +}; + +static struct attribute_group uncore_pmu_attr_group = { + .attrs = uncore_pmu_attrs, +}; + struct ppc64_uncore_pmu *uncore_event_to_pmu(struct perf_event *event) { return container_of(event->pmu, struct ppc64_uncore_pmu, pmu); @@ -43,6 +69,7 @@ int __init uncore_type_init(struct ppc64_uncore_type *type) type->name, (int)i); } + type->pmu_group = &uncore_pmu_attr_group; return 0; } @@ -82,6 +109,130 @@ static int __init uncore_pmus_register(void) return 0; } +static void +uncore_change_context(struct ppc64_uncore_type **uncores, + int old_cpu, int new_cpu) +{ + struct ppc64_uncore_type *type; + struct ppc64_uncore_pmu *pmu; + int i, j; + + for (i = 0; uncores[i]; i++) { + type = uncores[i]; + for (j = 0; j < type->num_boxes; j++) { + pmu = &type->pmus[j]; + if (old_cpu < 0) + continue; + if (new_cpu >= 0) { + perf_pmu_migrate_context(&pmu->pmu, + old_cpu, new_cpu); + } + } + } +} + +static void uncore_event_init_cpu(int cpu) +{ + int i, phys_id; + + phys_id = topology_physical_package_id(cpu); + for_each_cpu(i, &uncore_cpu_mask) { + if (phys_id == topology_physical_package_id(i)) + return; + } + + cpumask_set_cpu(cpu, &uncore_cpu_mask); + + uncore_change_context(ppc64_uncore, -1, cpu); +} + +static void uncore_event_exit_cpu(int cpu) +{ + int i, phys_id, target; + + /* if exiting cpu is used for collecting uncore events */ + if (!cpumask_test_and_clear_cpu(cpu, &uncore_cpu_mask)) + return; + + /* find a new cpu to collect uncore events */ + phys_id = topology_physical_package_id(cpu); + target = -1; + for_each_online_cpu(i) { + if (i == cpu) + continue; + if (phys_id == topology_physical_package_id(i)) { + target = i; + break; + } + } + + /* migrate uncore events to the new cpu */ + if (target >= 0) + cpumask_set_cpu(target, &uncore_cpu_mask); + + uncore_change_context(ppc64_uncore, cpu, target); +} + +static int uncore_cpu_notifier(struct notifier_block *self, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (long)hcpu; + + /* select the cpu that collects uncore events */ + switch (action & ~CPU_TASKS_FROZEN) { + case CPU_DOWN_FAILED: + case CPU_STARTING: + uncore_event_init_cpu(cpu); + break; + case CPU_DOWN_PREPARE: + uncore_event_exit_cpu(cpu); + break; + default: + break; + } + + return NOTIFY_OK; +} + +static struct notifier_block uncore_cpu_nb = { + .notifier_call = uncore_cpu_notifier, + /* + * to migrate uncore events, our notifier should be executed + * before perf core's notifier. + */ + .priority = CPU_PRI_PERF + 1, +}; + +static void __init cpumask_per_chip_init(void) +{ + int cpu; + + if (!cpumask_empty(&uncore_cpu_mask)) + return; + + cpu_notifier_register_begin(); + + for_each_online_cpu(cpu) { + int i, phys_id = topology_physical_package_id(cpu); + + for_each_cpu(i, &uncore_cpu_mask) { + if (phys_id == topology_physical_package_id(i)) { + phys_id = -1; + break; + } + } + if (phys_id < 0) + continue; + + uncore_event_init_cpu(cpu); + } + + __register_cpu_notifier(&uncore_cpu_nb); + + cpu_notifier_register_done(); +} + + static int __init uncore_init(void) { int ret = 0; @@ -95,6 +246,7 @@ static int __init uncore_init(void) if (ret) return ret; + cpumask_per_chip_init(); uncore_pmus_register(); return ret; -- 1.9.1
next prev parent reply other threads:[~2015-03-11 13:08 UTC|newest] Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top 2015-03-11 13:07 [RFC PATCH 0/7] powerpc/powernv: Nest Instrumentation support Madhavan Srinivasan 2015-03-11 13:07 ` [RFC PATCH 1/7] powerpc/powernv: Data structure and macros definition Madhavan Srinivasan 2015-03-11 13:07 ` [RFC PATCH 2/7] powerpc/powernv: uncore foundation code Madhavan Srinivasan 2015-03-11 13:07 ` Madhavan Srinivasan [this message] 2015-03-11 13:07 ` [RFC PATCH 4/7]powerpc/powernv: Add OPAL support for Nest pmu Madhavan Srinivasan 2015-03-11 22:57 ` Stewart Smith 2015-03-12 8:47 ` maddy 2015-03-11 13:07 ` [RFC PATCH 5/7]powerpc/powernv: Add POWER8 specific nest pmu support Madhavan Srinivasan 2015-03-11 13:07 ` [RFC PATCH 6/7]powerpc/powernv: add support to parse dt for nest pmu Madhavan Srinivasan 2015-03-11 13:07 ` [RFC PATCH 7/7]powerpc/powernv: enable nest pmu related file in Makefile Madhavan Srinivasan
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1426079233-16720-4-git-send-email-maddy@linux.vnet.ibm.com \ --to=maddy@linux.vnet.ibm.com \ --cc=ak@linux.intel.com \ --cc=benh@kernel.crashing.org \ --cc=eranian@google.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linuxppc-dev@lists.ozlabs.org \ --cc=linuxppc-dev@ozlabs.org \ --cc=mpe@ellerman.id.au \ --cc=paulus@samba.org \ --cc=srivatsa@mit.edu \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).