From: Joakim Zhang <qiangqing.zhang@nxp.com>
To: will@kernel.org, mark.rutland@arm.com, robin.murphy@arm.com
Cc: linux-imx@nxp.com, linux-arm-kernel@lists.infradead.org
Subject: [PATCH 2/2] perf/imx_ddr: Add stop counter support for i.MX8MP
Date: Tue, 25 Feb 2020 20:56:44 +0800 [thread overview]
Message-ID: <20200225125644.18853-2-qiangqing.zhang@nxp.com> (raw)
In-Reply-To: <20200225125644.18853-1-qiangqing.zhang@nxp.com>
DDR perf driver now only supports free-running event counters
(counter1/2/3), which means that event counters will continue counting
even they are overflow.
However, the situation is changed on i.MX8MP, event counters are not
free-running any more. Event counters would stop counting if they are
overflow. So we need clear event counters when cycle counter overflow.
The patch adds stop counter support which would be compatible to
free-running counter.
Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
---
drivers/perf/fsl_imx8_ddr_perf.c | 37 ++++++++++++++++++++++++++------
1 file changed, 31 insertions(+), 6 deletions(-)
diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index 90884d14f95f..5713f0631f79 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -14,6 +14,7 @@
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/perf_event.h>
+#include <linux/spinlock.h>
#include <linux/slab.h>
#define COUNTER_CNTL 0x0
@@ -82,6 +83,7 @@ struct ddr_pmu {
const struct fsl_ddr_devtype_data *devtype_data;
int irq;
int id;
+ spinlock_t lock;
};
enum ddr_perf_filter_capabilities {
@@ -368,16 +370,19 @@ static void ddr_perf_event_update(struct perf_event *event)
struct hw_perf_event *hwc = &event->hw;
u64 delta, prev_raw_count, new_raw_count;
int counter = hwc->idx;
+ unsigned long flags;
- do {
- prev_raw_count = local64_read(&hwc->prev_count);
- new_raw_count = ddr_perf_read_counter(pmu, counter);
- } while (local64_cmpxchg(&hwc->prev_count, prev_raw_count,
- new_raw_count) != prev_raw_count);
+ spin_lock_irqsave(&pmu->lock, flags);
+
+ prev_raw_count = local64_read(&hwc->prev_count);
+ new_raw_count = ddr_perf_read_counter(pmu, counter);
delta = (new_raw_count - prev_raw_count) & 0xFFFFFFFF;
local64_add(delta, &event->count);
+ local64_set(&hwc->prev_count, new_raw_count);
+
+ spin_unlock_irqrestore(&pmu->lock, flags);
}
static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config,
@@ -546,7 +551,7 @@ static irqreturn_t ddr_perf_irq_handler(int irq, void *p)
/*
* When the cycle counter overflows, all counters are stopped,
* and an IRQ is raised. If any other counter overflows, it
- * continues counting, and no IRQ is raised.
+ * stop counting, and no IRQ is raised.
*
* Cycles occur at least 4 times as often as other events, so we
* can update all events on a cycle counter overflow and not
@@ -566,6 +571,25 @@ static irqreturn_t ddr_perf_irq_handler(int irq, void *p)
cycle_event = event;
}
+ spin_lock(&pmu->lock);
+
+ for (i = 0; i < NUM_COUNTERS; i++) {
+ if (!pmu->events[i])
+ continue;
+
+ event = pmu->events[i];
+
+ if (event->hw.idx == EVENT_CYCLES_COUNTER)
+ continue;
+
+ /* clear non-cycle counters */
+ ddr_perf_counter_enable(pmu, event->attr.config, event->hw.idx, true);
+
+ local64_set(&event->hw.prev_count, 0);
+ }
+
+ spin_unlock(&pmu->lock);
+
ddr_perf_counter_enable(pmu,
EVENT_CYCLES_ID,
EVENT_CYCLES_COUNTER,
@@ -619,6 +643,7 @@ static int ddr_perf_probe(struct platform_device *pdev)
num = ddr_perf_init(pmu, base, &pdev->dev);
platform_set_drvdata(pdev, pmu);
+ spin_lock_init(&pmu->lock);
name = devm_kasprintf(&pdev->dev, GFP_KERNEL, DDR_PERF_DEV_NAME "%d",
num);
--
2.17.1
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-02-25 13:00 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-02-25 12:56 [PATCH 1/2] perf/imx_ddr: Correct the CLEAR bit definition Joakim Zhang
2020-02-25 12:56 ` Joakim Zhang [this message]
2020-03-02 11:24 ` [PATCH 2/2] perf/imx_ddr: Add stop counter support for i.MX8MP Will Deacon
2020-03-03 5:34 ` Joakim Zhang
2020-04-16 9:51 ` Joakim Zhang
2020-05-20 7:51 ` Will Deacon
2020-05-21 4:57 ` Joakim Zhang
2020-03-02 11:25 ` [PATCH 1/2] perf/imx_ddr: Correct the CLEAR bit definition Will Deacon
2020-03-03 5:34 ` Joakim Zhang
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=20200225125644.18853-2-qiangqing.zhang@nxp.com \
--to=qiangqing.zhang@nxp.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-imx@nxp.com \
--cc=mark.rutland@arm.com \
--cc=robin.murphy@arm.com \
--cc=will@kernel.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