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 5/7]powerpc/powernv: Add POWER8 specific nest pmu support Date: Wed, 11 Mar 2015 18:37:11 +0530 [thread overview] Message-ID: <1426079233-16720-6-git-send-email-maddy@linux.vnet.ibm.com> (raw) In-Reply-To: <1426079233-16720-1-git-send-email-maddy@linux.vnet.ibm.com> Patch enables POWER8 specific nest pmu support. It defines pmu functions in a generic way that it can be shared across different nest units. Event id is used, to identify the offset in memory to read from. And the offset information is saved in the per-chip data strucutres which are populated at the time of device-tree parsing. Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com> --- arch/powerpc/perf/uncore_pmu.c | 4 + arch/powerpc/perf/uncore_pmu_p8.c | 167 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 arch/powerpc/perf/uncore_pmu_p8.c diff --git a/arch/powerpc/perf/uncore_pmu.c b/arch/powerpc/perf/uncore_pmu.c index 67ab6c0..504c6ac 100644 --- a/arch/powerpc/perf/uncore_pmu.c +++ b/arch/powerpc/perf/uncore_pmu.c @@ -242,6 +242,10 @@ static int __init uncore_init(void) !cpu_has_feature(CPU_FTR_HVMODE)) return ret; + ret = uncore_p8_init(); + if (ret) + return ret; + ret = uncore_types_init(ppc64_uncore); if (ret) return ret; diff --git a/arch/powerpc/perf/uncore_pmu_p8.c b/arch/powerpc/perf/uncore_pmu_p8.c new file mode 100644 index 0000000..411c077 --- /dev/null +++ b/arch/powerpc/perf/uncore_pmu_p8.c @@ -0,0 +1,167 @@ +/* + * Uncore Performance Monitor counter support for POWER8 processors. + * + * Copyright 2015, 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; version + * 2 of the License + */ + +#include "uncore_pmu.h" + +#define P8_UNCORE_EVENT_MASK 0xFF +#define P8_UNCORE_ENGINE_START 0x1 +#define P8_UNCORE_ENGINE_STOP 0 + +extern struct ppc64_uncore_type **ppc64_uncore; +static struct ppc64_uncore_unit uncore_per_chip[P8_MAX_CHIP]; + +struct attribute *p8_uncore_event_attrs[MAX_TYPE_EVENTS]; +struct ppc64_uncore_type *p8_uncore[MAX_UNITS_SUPPORTED]; + +/* + * percpu variable for refcount for uncore events. + */ +DEFINE_PER_CPU(uint32_t, uncore_refcnt); + +PMU_FORMAT_ATTR(event, "config:0-7"); + +static struct attribute *p8_uncore_format_attrs[] = { + &format_attr_event.attr, + NULL, +}; + +static struct attribute_group p8_uncore_format_group = { + .name = "format", + .attrs = p8_uncore_format_attrs, +}; + +int p8_uncore_event_init(struct perf_event *event) +{ + struct ppc64_uncore_pmu *pmu; + struct ppc64_uncore_type *type; + int chip_id, cfg; + + if (event->attr.type != event->pmu->type) + return -ENOENT; + + /* Sampling not supported yet */ + if (event->hw.sample_period) + return -EINVAL; + + /* unsupported modes and filters */ + if (event->attr.exclude_user || + event->attr.exclude_kernel || + event->attr.exclude_hv || + event->attr.exclude_idle || + event->attr.exclude_host || + event->attr.exclude_guest || + event->attr.sample_period) /* no sampling */ + return -EINVAL; + + if (event->cpu < 0) + return -EINVAL; + + pmu = uncore_event_to_pmu(event); + if (!pmu) + return -EINVAL; + + if (event->attr.config & ~P8_UNCORE_EVENT_MASK) + return -EINVAL; + + /* Event to look for in the offset strucutre */ + cfg = event->attr.config & P8_UNCORE_EVENT_MASK; + + type = pmu->type; + chip_id = topology_physical_package_id(event->cpu); + + /* Mem access address calculation for this event */ + event->hw.event_base = uncore_per_chip[chip_id].vreg_base; + event->hw.event_base += type->event_arry[pmu->pmu_idx].ev_offset[(cfg - 1)]; + + return 0; +} + +void p8_uncore_read_counter(struct perf_event *event) +{ + uint64_t *ptr; + + ptr = (uint64_t *)event->hw.event_base; + local64_set(&event->hw.prev_count, __be64_to_cpu((uint64_t)*ptr)); +} + +void p8_uncore_perf_event_update(struct perf_event *event) +{ + u64 counter_prev, counter_new, final_count; + uint64_t *ptr; + + ptr = (uint64_t *)event->hw.event_base; + counter_prev = cpu_to_be64(local64_read(&event->hw.prev_count)); + counter_new = __be64_to_cpu((uint64_t)*ptr); + final_count = counter_new - counter_prev; + + local64_set(&event->hw.prev_count, counter_new); + local64_add(final_count, &event->count); +} + +void p8_uncore_event_start(struct perf_event *event, int flags) +{ + uint32_t *refcnt = &get_cpu_var(uncore_refcnt); + + event->hw.state = 0; + *refcnt += 1; + + if (*refcnt == 1) + opal_uncore_control(P8_UNCORE_ENGINE_START); + + p8_uncore_read_counter(event); + put_cpu_var(uncore_refcnt); +} + +void p8_uncore_event_stop(struct perf_event *event, int flags) +{ + uint32_t *refcnt = &get_cpu_var(uncore_refcnt); + + *refcnt -= 1; + if (*refcnt == 0) + opal_uncore_control(P8_UNCORE_ENGINE_STOP); + + p8_uncore_perf_event_update(event); + put_cpu_var(uncore_refcnt); +} + +int p8_uncore_event_add(struct perf_event *event, int flags) +{ + p8_uncore_event_start(event, flags); + return 0; +} + +void p8_uncore_event_del(struct perf_event *event, int flags) +{ + p8_uncore_event_stop(event, flags); +} + +struct pmu p8_uncore_pmu = { + .task_ctx_nr = perf_invalid_context, + .event_init = p8_uncore_event_init, + .add = p8_uncore_event_add, + .del = p8_uncore_event_del, + .start = p8_uncore_event_start, + .stop = p8_uncore_event_stop, + .read = p8_uncore_perf_event_update, +}; + +static int uncore_init(void) +{ + return 0; +} + +int uncore_p8_init(void) +{ + ppc64_uncore = p8_uncore; + return uncore_init(); +} + + -- 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 ` [RFC PATCH 3/7] powerpc/powernv: uncore cpumask and CPU hotplug Madhavan Srinivasan 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 ` Madhavan Srinivasan [this message] 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-6-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).