From: pawel.moll@arm.com (Pawel Moll)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH 5/5] bus: arm-ccn: Allocate event when it is being added, not initialised
Date: Fri, 1 May 2015 18:36:30 +0100 [thread overview]
Message-ID: <1430501790-26918-6-git-send-email-pawel.moll@arm.com> (raw)
In-Reply-To: <1430501790-26918-1-git-send-email-pawel.moll@arm.com>
To make events rotation possible, they should be allocated when event
is being ->added(), not during initialisation. This patch moves the
respective code.
Signed-off-by: Pawel Moll <pawel.moll@arm.com>
---
drivers/bus/arm-ccn.c | 114 +++++++++++++++++++++++++++++---------------------
1 file changed, 67 insertions(+), 47 deletions(-)
diff --git a/drivers/bus/arm-ccn.c b/drivers/bus/arm-ccn.c
index fb589d4..df5f307 100644
--- a/drivers/bus/arm-ccn.c
+++ b/drivers/bus/arm-ccn.c
@@ -628,7 +628,65 @@ static int arm_ccn_pmu_type_eq(u32 a, u32 b)
return 0;
}
-static void arm_ccn_pmu_event_destroy(struct perf_event *event)
+static int arm_ccn_pmu_event_alloc(struct perf_event *event)
+{
+ struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
+ struct hw_perf_event *hw = &event->hw;
+ u32 node_xp, type, event_id;
+ struct arm_ccn_component *source;
+ int bit;
+
+ node_xp = CCN_CONFIG_NODE(event->attr.config);
+ type = CCN_CONFIG_TYPE(event->attr.config);
+ event_id = CCN_CONFIG_EVENT(event->attr.config);
+
+ /* Allocate the cycle counter */
+ if (type == CCN_TYPE_CYCLES) {
+ if (test_and_set_bit(CCN_IDX_PMU_CYCLE_COUNTER,
+ ccn->dt.pmu_counters_mask))
+ return -EAGAIN;
+
+ hw->idx = CCN_IDX_PMU_CYCLE_COUNTER;
+ ccn->dt.pmu_counters[CCN_IDX_PMU_CYCLE_COUNTER].event = event;
+
+ return 0;
+ }
+
+ /* Allocate an event counter */
+ hw->idx = arm_ccn_pmu_alloc_bit(ccn->dt.pmu_counters_mask,
+ CCN_NUM_PMU_EVENT_COUNTERS);
+ if (hw->idx < 0) {
+ dev_dbg(ccn->dev, "No more counters available!\n");
+ return -EAGAIN;
+ }
+
+ if (type == CCN_TYPE_XP)
+ source = &ccn->xp[node_xp];
+ else
+ source = &ccn->node[node_xp];
+ ccn->dt.pmu_counters[hw->idx].source = source;
+
+ /* Allocate an event source or a watchpoint */
+ if (type == CCN_TYPE_XP && event_id == CCN_EVENT_WATCHPOINT)
+ bit = arm_ccn_pmu_alloc_bit(source->xp.dt_cmp_mask,
+ CCN_NUM_XP_WATCHPOINTS);
+ else
+ bit = arm_ccn_pmu_alloc_bit(source->pmu_events_mask,
+ CCN_NUM_PMU_EVENTS);
+ if (bit < 0) {
+ dev_dbg(ccn->dev, "No more event sources/watchpoints on node/XP %d!\n",
+ node_xp);
+ clear_bit(hw->idx, ccn->dt.pmu_counters_mask);
+ return -EAGAIN;
+ }
+ hw->config_base = bit;
+
+ ccn->dt.pmu_counters[hw->idx].event = event;
+
+ return 0;
+}
+
+static void arm_ccn_pmu_event_release(struct perf_event *event)
{
struct arm_ccn *ccn = pmu_to_arm_ccn(event->pmu);
struct hw_perf_event *hw = &event->hw;
@@ -657,8 +715,7 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
struct arm_ccn *ccn;
struct hw_perf_event *hw = &event->hw;
u32 node_xp, type, event_id;
- int valid, bit;
- struct arm_ccn_component *source;
+ int valid;
int i;
struct perf_event *sibling;
@@ -666,7 +723,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
return -ENOENT;
ccn = pmu_to_arm_ccn(event->pmu);
- event->destroy = arm_ccn_pmu_event_destroy;
if (hw->sample_period) {
dev_warn(ccn->dev, "Sampling not supported!\n");
@@ -778,49 +834,6 @@ static int arm_ccn_pmu_event_init(struct perf_event *event)
!is_software_event(sibling))
return -EINVAL;
- /* Allocate the cycle counter */
- if (type == CCN_TYPE_CYCLES) {
- if (test_and_set_bit(CCN_IDX_PMU_CYCLE_COUNTER,
- ccn->dt.pmu_counters_mask))
- return -EAGAIN;
-
- hw->idx = CCN_IDX_PMU_CYCLE_COUNTER;
- ccn->dt.pmu_counters[CCN_IDX_PMU_CYCLE_COUNTER].event = event;
-
- return 0;
- }
-
- /* Allocate an event counter */
- hw->idx = arm_ccn_pmu_alloc_bit(ccn->dt.pmu_counters_mask,
- CCN_NUM_PMU_EVENT_COUNTERS);
- if (hw->idx < 0) {
- dev_warn(ccn->dev, "No more counters available!\n");
- return -EAGAIN;
- }
-
- if (type == CCN_TYPE_XP)
- source = &ccn->xp[node_xp];
- else
- source = &ccn->node[node_xp];
- ccn->dt.pmu_counters[hw->idx].source = source;
-
- /* Allocate an event source or a watchpoint */
- if (type == CCN_TYPE_XP && event_id == CCN_EVENT_WATCHPOINT)
- bit = arm_ccn_pmu_alloc_bit(source->xp.dt_cmp_mask,
- CCN_NUM_XP_WATCHPOINTS);
- else
- bit = arm_ccn_pmu_alloc_bit(source->pmu_events_mask,
- CCN_NUM_PMU_EVENTS);
- if (bit < 0) {
- dev_warn(ccn->dev, "No more event sources/watchpoints on node/XP %d!\n",
- node_xp);
- clear_bit(hw->idx, ccn->dt.pmu_counters_mask);
- return -EAGAIN;
- }
- hw->config_base = bit;
-
- ccn->dt.pmu_counters[hw->idx].event = event;
-
return 0;
}
@@ -1087,8 +1100,13 @@ static void arm_ccn_pmu_event_config(struct perf_event *event)
static int arm_ccn_pmu_event_add(struct perf_event *event, int flags)
{
+ int err;
struct hw_perf_event *hw = &event->hw;
+ err = arm_ccn_pmu_event_alloc(event);
+ if (err)
+ return err;
+
arm_ccn_pmu_event_config(event);
hw->state = PERF_HES_STOPPED;
@@ -1102,6 +1120,8 @@ static int arm_ccn_pmu_event_add(struct perf_event *event, int flags)
static void arm_ccn_pmu_event_del(struct perf_event *event, int flags)
{
arm_ccn_pmu_event_stop(event, PERF_EF_UPDATE);
+
+ arm_ccn_pmu_event_release(event);
}
static void arm_ccn_pmu_event_read(struct perf_event *event)
--
2.1.0
next prev parent reply other threads:[~2015-05-01 17:36 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-05-01 17:36 [PATCH 0/5] ARM CCN driver updates Pawel Moll
2015-05-01 17:36 ` [PATCH 1/5] bus: arm-ccn: Fix node->XP config conversion Pawel Moll
2015-05-01 17:36 ` [PATCH 2/5] bus: arm-ccn: cpumask attribute Pawel Moll
2015-05-01 17:36 ` [PATCH 3/5] bus: arm-ccn: Provide required event arguments Pawel Moll
2015-05-01 17:36 ` [PATCH 4/5] bus: arm-ccn: Do not group CCN events with other PMUs Pawel Moll
2015-05-01 17:36 ` Pawel Moll [this message]
2015-05-12 14:48 ` [PATCH 0/5] ARM CCN driver updates Arnd Bergmann
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=1430501790-26918-6-git-send-email-pawel.moll@arm.com \
--to=pawel.moll@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
/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: link
Be 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).