All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joakim Zhang <qiangqing.zhang@nxp.com>
To: "will@kernel.org" <will@kernel.org>,
	"mark.rutland@arm.com" <mark.rutland@arm.com>,
	Frank Li <frank.li@nxp.com>
Cc: "linux-arm-kernel@lists.infradead.org"
	<linux-arm-kernel@lists.infradead.org>,
	dl-linux-imx <linux-imx@nxp.com>,
	"kernel@pengutronix.de" <kernel@pengutronix.de>,
	Joakim Zhang <qiangqing.zhang@nxp.com>
Subject: [PATCH] perf: imx8_ddr_perf: calculate ddr bandwidth via virtual event read-bytes/write-bytes
Date: Tue, 9 Jul 2019 05:46:44 +0000	[thread overview]
Message-ID: <20190709054417.11734-1-qiangqing.zhang@nxp.com> (raw)

We can calculate ddr bandwidth via virtual event read-bytes/write-bytes
based on ddr burst width, which actually share event
read-cycles/write-cycles. Burst width is 32 bit on i.MX8 board.

The ddr interface will generate 2 up edges and 2 down edges in an
internal clock cycle, so it can pass 4 beats of data. 4 bytes of each
beat if ddr burst width is 32 bit.

for example:
perf stat -a -e imx8_ddr0/read-bytes/,imx8_ddr0/write-bytes/ ls

Signed-off-by: Joakim Zhang <qiangqing.zhang@nxp.com>
---
 drivers/perf/fsl_imx8_ddr_perf.c | 96 ++++++++++++++++++++------------
 1 file changed, 61 insertions(+), 35 deletions(-)

diff --git a/drivers/perf/fsl_imx8_ddr_perf.c b/drivers/perf/fsl_imx8_ddr_perf.c
index 63fe21600072..e7dbaf4d2387 100644
--- a/drivers/perf/fsl_imx8_ddr_perf.c
+++ b/drivers/perf/fsl_imx8_ddr_perf.c
@@ -88,46 +88,53 @@ ddr_pmu_event_show(struct device *dev, struct device_attribute *attr,
 	struct perf_pmu_events_attr *pmu_attr;
 
 	pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr);
-	return sprintf(page, "event=0x%02llx\n", pmu_attr->id);
+	return sprintf(page, "%s", pmu_attr->event_str);
 }
 
-#define IMX8_DDR_PMU_EVENT_ATTR(_name, _id)				\
+#define IMX8_DDR_PMU_EVENT_ATTR(_name, _str)				\
 	(&((struct perf_pmu_events_attr[]) {				\
 		{ .attr = __ATTR(_name, 0444, ddr_pmu_event_show, NULL),\
-		  .id = _id, }						\
+		  .id = 0,						\
+		  .event_str = _str, }					\
 	})[0].attr.attr)
 
 static struct attribute *ddr_perf_events_attrs[] = {
-	IMX8_DDR_PMU_EVENT_ATTR(cycles, EVENT_CYCLES_ID),
-	IMX8_DDR_PMU_EVENT_ATTR(selfresh, 0x01),
-	IMX8_DDR_PMU_EVENT_ATTR(read-accesses, 0x04),
-	IMX8_DDR_PMU_EVENT_ATTR(write-accesses, 0x05),
-	IMX8_DDR_PMU_EVENT_ATTR(read-queue-depth, 0x08),
-	IMX8_DDR_PMU_EVENT_ATTR(write-queue-depth, 0x09),
-	IMX8_DDR_PMU_EVENT_ATTR(lp-read-credit-cnt, 0x10),
-	IMX8_DDR_PMU_EVENT_ATTR(hp-read-credit-cnt, 0x11),
-	IMX8_DDR_PMU_EVENT_ATTR(write-credit-cnt, 0x12),
-	IMX8_DDR_PMU_EVENT_ATTR(read-command, 0x20),
-	IMX8_DDR_PMU_EVENT_ATTR(write-command, 0x21),
-	IMX8_DDR_PMU_EVENT_ATTR(read-modify-write-command, 0x22),
-	IMX8_DDR_PMU_EVENT_ATTR(hp-read, 0x23),
-	IMX8_DDR_PMU_EVENT_ATTR(hp-req-nocredit, 0x24),
-	IMX8_DDR_PMU_EVENT_ATTR(hp-xact-credit, 0x25),
-	IMX8_DDR_PMU_EVENT_ATTR(lp-req-nocredit, 0x26),
-	IMX8_DDR_PMU_EVENT_ATTR(lp-xact-credit, 0x27),
-	IMX8_DDR_PMU_EVENT_ATTR(wr-xact-credit, 0x29),
-	IMX8_DDR_PMU_EVENT_ATTR(read-cycles, 0x2a),
-	IMX8_DDR_PMU_EVENT_ATTR(write-cycles, 0x2b),
-	IMX8_DDR_PMU_EVENT_ATTR(read-write-transition, 0x30),
-	IMX8_DDR_PMU_EVENT_ATTR(precharge, 0x31),
-	IMX8_DDR_PMU_EVENT_ATTR(activate, 0x32),
-	IMX8_DDR_PMU_EVENT_ATTR(load-mode, 0x33),
-	IMX8_DDR_PMU_EVENT_ATTR(perf-mwr, 0x34),
-	IMX8_DDR_PMU_EVENT_ATTR(read, 0x35),
-	IMX8_DDR_PMU_EVENT_ATTR(read-activate, 0x36),
-	IMX8_DDR_PMU_EVENT_ATTR(refresh, 0x37),
-	IMX8_DDR_PMU_EVENT_ATTR(write, 0x38),
-	IMX8_DDR_PMU_EVENT_ATTR(raw-hazard, 0x39),
+	IMX8_DDR_PMU_EVENT_ATTR(cycles, "event=0x00"),
+	IMX8_DDR_PMU_EVENT_ATTR(selfresh, "event=0x01"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-accesses, "event=0x04"),
+	IMX8_DDR_PMU_EVENT_ATTR(write-accesses, "event=0x05"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-queue-depth, "event=0x08"),
+	IMX8_DDR_PMU_EVENT_ATTR(write-queue-depth, "event=0x09"),
+	IMX8_DDR_PMU_EVENT_ATTR(lp-read-credit-cnt, "event=0x10"),
+	IMX8_DDR_PMU_EVENT_ATTR(hp-read-credit-cnt, "event=0x11"),
+	IMX8_DDR_PMU_EVENT_ATTR(write-credit-cnt, "event=0x12"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-command, "event=0x20"),
+	IMX8_DDR_PMU_EVENT_ATTR(write-command, "event=0x21"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-modify-write-command, "event=0x22"),
+	IMX8_DDR_PMU_EVENT_ATTR(hp-read, "event=0x23"),
+	IMX8_DDR_PMU_EVENT_ATTR(hp-req-nocredit, "event=0x24"),
+	IMX8_DDR_PMU_EVENT_ATTR(hp-xact-credit, "event=0x25"),
+	IMX8_DDR_PMU_EVENT_ATTR(lp-req-nocredit, "event=0x26"),
+	IMX8_DDR_PMU_EVENT_ATTR(lp-xact-credit, "event=0x27"),
+	IMX8_DDR_PMU_EVENT_ATTR(wr-xact-credit, "event=0x29"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-cycles, "event=0x2a"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-bytes, "event=0x12a"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-bytes.unit, "MB"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-bytes.scale, "0.000001"),
+	IMX8_DDR_PMU_EVENT_ATTR(write-cycles, "event=0x2b"),
+	IMX8_DDR_PMU_EVENT_ATTR(write-bytes, "event=0x12b"),
+	IMX8_DDR_PMU_EVENT_ATTR(write-bytes.unit, "MB"),
+	IMX8_DDR_PMU_EVENT_ATTR(write-bytes.scale, "0.000001"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-write-transition, "event=0x30"),
+	IMX8_DDR_PMU_EVENT_ATTR(precharge, "event=0x31"),
+	IMX8_DDR_PMU_EVENT_ATTR(activate, "event=0x32"),
+	IMX8_DDR_PMU_EVENT_ATTR(load-mode, "event=0x33"),
+	IMX8_DDR_PMU_EVENT_ATTR(perf-mwr, "event=0x34"),
+	IMX8_DDR_PMU_EVENT_ATTR(read, "event=0x35"),
+	IMX8_DDR_PMU_EVENT_ATTR(read-activate, "event=0x36"),
+	IMX8_DDR_PMU_EVENT_ATTR(refresh, "event=0x37"),
+	IMX8_DDR_PMU_EVENT_ATTR(write, "event=0x38"),
+	IMX8_DDR_PMU_EVENT_ATTR(raw-hazard, "event=0x39"),
 	NULL,
 };
 
@@ -136,7 +143,7 @@ static struct attribute_group ddr_perf_events_attr_group = {
 	.attrs = ddr_perf_events_attrs,
 };
 
-PMU_FORMAT_ATTR(event, "config:0-7");
+PMU_FORMAT_ATTR(event, "config:0-8");
 
 static struct attribute *ddr_perf_format_attrs[] = {
 	&format_attr_event.attr,
@@ -243,6 +250,17 @@ static void ddr_perf_event_update(struct perf_event *event)
 
 	delta = (new_raw_count - prev_raw_count) & 0xFFFFFFFF;
 
+	/*
+	 * Calculate ddr read/write bandwidth via read-bytes/write-bytes events,
+	 * actually using read-cycles/write-cycles events.
+	 *
+	 * The ddr interface will generate 2 up edges and 2 down edges in an
+	 * internal clock cycle, so it can pass 4 beats of data, and 4 bytes of
+	 * each beat if ddr burst width is 32 bit.
+	 */
+	if (event->attr.config == 0x12a || event->attr.config == 0x12b)
+		delta = delta * 4 * 4;
+
 	local64_add(delta, &event->count);
 }
 
@@ -260,7 +278,15 @@ static void ddr_perf_counter_enable(struct ddr_pmu *pmu, int config,
 		 */
 		writel(0, pmu->base + reg);
 		val = CNTL_EN | CNTL_CLEAR;
-		val |= FIELD_PREP(CNTL_CSV_MASK, config);
+
+		/*
+		 * Virtual events(read-bytes/write-bytes) share real
+		 * events(read-cycles/write-cycles).
+		 */
+		if (config == 0x12a || config == 0x12b)
+			val |= FIELD_PREP(CNTL_CSV_MASK, (config - 0x100));
+		else
+			val |= FIELD_PREP(CNTL_CSV_MASK, config);
 		writel(val, pmu->base + reg);
 	} else {
 		/* Disable counter */
-- 
2.17.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

             reply	other threads:[~2019-07-09  5:46 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-07-09  5:46 Joakim Zhang [this message]
2019-07-09 15:56 ` [PATCH] perf: imx8_ddr_perf: calculate ddr bandwidth via virtual event read-bytes/write-bytes Will Deacon
2019-07-12  7:18   ` Joakim Zhang
2019-07-31 18:01     ` Will Deacon

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=20190709054417.11734-1-qiangqing.zhang@nxp.com \
    --to=qiangqing.zhang@nxp.com \
    --cc=frank.li@nxp.com \
    --cc=kernel@pengutronix.de \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-imx@nxp.com \
    --cc=mark.rutland@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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.