All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jonathan Cameron <jonathan.cameron@huawei.com>
To: "Clément Le Goffic" <legoffic.clement@gmail.com>
Cc: "Gatien Chevallier" <gatien.chevallier@foss.st.com>,
	"Maxime Coquelin" <mcoquelin.stm32@gmail.com>,
	"Alexandre Torgue" <alexandre.torgue@foss.st.com>,
	"Michael Turquette" <mturquette@baylibre.com>,
	"Stephen Boyd" <sboyd@kernel.org>,
	"Rob Herring" <robh@kernel.org>,
	"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
	"Conor Dooley" <conor+dt@kernel.org>,
	"Gabriel Fernandez" <gabriel.fernandez@foss.st.com>,
	"Krzysztof Kozlowski" <krzk@kernel.org>,
	"Julius Werner" <jwerner@chromium.org>,
	"Will Deacon" <will@kernel.org>,
	"Mark Rutland" <mark.rutland@arm.com>,
	"Philipp Zabel" <p.zabel@pengutronix.de>,
	"Jonathan Corbet" <corbet@lwn.net>,
	linux-stm32@st-md-mailman.stormreply.com,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-clk@vger.kernel.org,
	devicetree@vger.kernel.org, linux-perf-users@vger.kernel.org,
	linux-doc@vger.kernel.org,
	"Clément Le Goffic" <clement.legoffic@foss.st.com>
Subject: Re: [PATCH v6 13/20] perf: stm32: introduce DDRPERFM driver
Date: Wed, 10 Sep 2025 10:26:27 +0100	[thread overview]
Message-ID: <20250910102627.00007a40@huawei.com> (raw)
In-Reply-To: <20250909-b4-ddrperfm-upstream-v6-13-ce082cc801b5@gmail.com>

On Tue, 09 Sep 2025 12:12:20 +0200
Clément Le Goffic <legoffic.clement@gmail.com> wrote:

> From: Clément Le Goffic <clement.legoffic@foss.st.com>
> 
> Introduce the driver for the DDR Performance Monitor available on
> STM32MPU SoC.
> 
> On STM32MP2 platforms, the DDRPERFM allows to monitor up to 8 DDR events
> that come from the DDR Controller such as read or write events.
> 
> On STM32MP1 platforms, the DDRPERFM cannot monitor any event on any
> counter, there is a notion of set of events.
> Events from different sets cannot be monitored at the same time.
> The first chosen event selects the set.
> The set is coded in the first two bytes of the config value which is on 4
> bytes.
> 
> On STM32MP25x series, the DDRPERFM clock is shared with the DDR controller
> and may be secured by bootloaders.
> Access controllers allow to check access to a resource. Use the access
> controller defined in the devicetree to know about the access to the
> DDRPERFM clock.
> 
> Signed-off-by: Clément Le Goffic <clement.legoffic@foss.st.com>
> Signed-off-by: Clément Le Goffic <legoffic.clement@gmail.com>
Hi Clément

A quick drive by review,

J

> diff --git a/drivers/perf/stm32_ddr_pmu.c b/drivers/perf/stm32_ddr_pmu.c
> new file mode 100644
> index 000000000000..38328663d2c5
> --- /dev/null
> +++ b/drivers/perf/stm32_ddr_pmu.c
> @@ -0,0 +1,897 @@

> +
> +#define MP1_CLR_CNT		GENMASK(3, 0)
> +#define MP1_CLR_TIME		BIT(31)
> +#define MP2_CLR_CNT		GENMASK(7, 0)
> +#define MP2_CLR_TIME		BIT(8)
> +
> +/* 4 event counters plus 1 dedicated to time */
> +#define MP1_CNT_NB		(4 + 1)

This is never used so I would drop it and rename the MP2_CNT_NB
to indicate it is the max value for any devices supported.


> +/* Index of the time dedicated counter */
> +#define MP1_TIME_CNT_IDX	4
> +
> +/* 8 event counters plus 1 dedicated to time */
> +#define MP2_CNT_NB		(8 + 1)
...

> +struct stm32_ddr_pmu {
> +	struct pmu pmu;
> +	void __iomem *membase;
> +	struct device *dev;
> +	struct clk *clk;
> +	const struct stm32_ddr_pmu_cfg *cfg;
> +	struct hrtimer hrtimer;
> +	ktime_t poll_period;
> +	int selected_set;
> +	u32 dram_type;
> +	struct list_head counters[];
The absence of a __counted_by() marking made me wonder how
we ensured that this wasn't overrun.  I see below that's because
size is always the same.  So
	struct list_head counters[MP2_CNT_NB];
If you do want to make it dynamic then that is fine but added
a local variable for the size and the __counted_by() marking so
the various analysis tools can check for buffer overruns.

> +};



> +static void stm32_ddr_pmu_event_del(struct perf_event *event, int flags)
> +{
> +	struct stm32_ddr_pmu *pmu = to_stm32_ddr_pmu(event->pmu);
> +	struct stm32_ddr_cnt *counter = event->pmu_private;
> +	bool events = true;

Always set before use, so don't set it here.  I'd move this into the
scope of the for loop to make this more obvious.

> +
> +	stm32_ddr_pmu_event_stop(event, PERF_EF_UPDATE);
> +
> +	stm32_ddr_pmu_free_counter(pmu, counter);
> +
> +	for (int i = 0; i < pmu->cfg->counters_nb; i++) {
> +		events = !list_empty(&pmu->counters[i]);
> +		if (events) /* If there is activity nothing to do */
> +			return;
> +	}
> +
> +	hrtimer_cancel(&pmu->hrtimer);
> +	stm32_ddr_stop_counters(pmu);
> +
> +	pmu->selected_set = -1;
> +
> +	clk_disable(pmu->clk);
> +}

> +
> +#define STM32_DDR_PMU_EVENT_ATTR(_name, _id)			\
> +	PMU_EVENT_ATTR_ID(_name, stm32_ddr_pmu_sysfs_show, _id)
> +
> +static struct attribute *stm32_ddr_pmu_events_attrs_mp[] = {
> +	STM32_DDR_PMU_EVENT_ATTR(perf_op_is_rd, PERF_OP_IS_RD),

Prefixing perf events with perf_ seems unnecessary.

I guess perf_op_is_rd is counting all reads?  Is so why not call it simply 'reads'
or something else short like that?  If it's cycles when a read is going on then
maybe a more complex is needed, but perf_op_is_rd doesn't convey that to me.

> +	STM32_DDR_PMU_EVENT_ATTR(perf_op_is_wr, PERF_OP_IS_WR),
> +	STM32_DDR_PMU_EVENT_ATTR(perf_op_is_activate, PERF_OP_IS_ACTIVATE),
> +	STM32_DDR_PMU_EVENT_ATTR(ctl_idle, CTL_IDLE),
> +	STM32_DDR_PMU_EVENT_ATTR(perf_hpr_req_with_no_credit, PERF_HPR_REQ_WITH_NO_CREDIT),
> +	STM32_DDR_PMU_EVENT_ATTR(perf_lpr_req_with_no_credit, PERF_LPR_REQ_WITH_NO_CREDIT),
> +	STM32_DDR_PMU_EVENT_ATTR(cactive_ddrc, CACTIVE_DDRC),
> +	STM32_DDR_PMU_EVENT_ATTR(perf_op_is_enter_powerdown, PERF_OP_IS_ENTER_POWERDOWN),
> +	STM32_DDR_PMU_EVENT_ATTR(perf_op_is_refresh, PERF_OP_IS_REFRESH),
> +	STM32_DDR_PMU_EVENT_ATTR(perf_selfresh_mode, PERF_SELFRESH_MODE),
> +	STM32_DDR_PMU_EVENT_ATTR(dfi_lp_req, DFI_LP_REQ),
> +	STM32_DDR_PMU_EVENT_ATTR(perf_hpr_xact_when_critical, PERF_HPR_XACT_WHEN_CRITICAL),
> +	STM32_DDR_PMU_EVENT_ATTR(perf_lpr_xact_when_critical, PERF_LPR_XACT_WHEN_CRITICAL),
> +	STM32_DDR_PMU_EVENT_ATTR(perf_wr_xact_when_critical, PERF_WR_XACT_WHEN_CRITICAL),
> +	STM32_DDR_PMU_EVENT_ATTR(dfi_lp_req_cpy, DFI_LP_REQ),  /* Suffixed '_cpy' to allow the
> +								* choice between sets 2 and 3
> +								*/
> +	STM32_DDR_PMU_EVENT_ATTR(time_cnt, TIME_CNT),
> +	NULL
> +};


> +static int stm32_ddr_pmu_device_probe(struct platform_device *pdev)
> +{
> +	struct stm32_firewall firewall;
> +	struct stm32_ddr_pmu *pmu;
> +	struct reset_control *rst;
> +	struct resource *res;
> +	int ret;
> +
> +	pmu = devm_kzalloc(&pdev->dev, struct_size(pmu, counters, MP2_CNT_NB), GFP_KERNEL);

If using a fixed number of counters why not put it in the struct
definition and simplify the code?  I agree it is probably not
worth making this dynamic given small sizes but I don't mind
if you do want to do this.  The only thing that isn't a good idea
is this dynamic, but not really, current situation.


> +	if (!pmu)
> +		return -ENOMEM;



> +static DEFINE_SIMPLE_DEV_PM_OPS(stm32_ddr_pmu_pm_ops, NULL, stm32_ddr_pmu_device_resume);
> +
> +static const struct of_device_id stm32_ddr_pmu_of_match[] = {
> +	{
> +		.compatible = "st,stm32mp131-ddr-pmu",
> +		.data = &stm32_ddr_pmu_cfg_mp1

Trivial but if you are spinning again, normal convention is trailing commas
in cases like this because maybe other fields will get set later.

> +	},
> +	{
> +		.compatible = "st,stm32mp251-ddr-pmu",
> +		.data = &stm32_ddr_pmu_cfg_mp2
> +	},
> +	{ }
> +};
> +MODULE_DEVICE_TABLE(of, stm32_ddr_pmu_of_match);
> +
> +static struct platform_driver stm32_ddr_pmu_driver = {
> +	.driver = {
> +		.name = DRIVER_NAME,
> +		.pm = pm_sleep_ptr(&stm32_ddr_pmu_pm_ops),
> +		.of_match_table = stm32_ddr_pmu_of_match,
> +	},
> +	.probe = stm32_ddr_pmu_device_probe,
> +	.remove = stm32_ddr_pmu_device_remove,
> +};
> +
> +module_platform_driver(stm32_ddr_pmu_driver);
> +
> +MODULE_AUTHOR("Clément Le Goffic");
> +MODULE_DESCRIPTION("STMicroelectronics STM32 DDR performance monitor driver");
> +MODULE_LICENSE("GPL");
> 



  reply	other threads:[~2025-09-10  9:26 UTC|newest]

Thread overview: 36+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-09-09 10:12 [PATCH v6 00/20] Introduce STM32 DDR PMU for STM32MP platforms Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 01/20] bus: firewall: move stm32_firewall header file in include folder Clément Le Goffic
2025-09-09 12:25   ` Gatien CHEVALLIER
2025-09-10  7:47     ` Clément Le Goffic
2025-09-10  8:42       ` Gatien CHEVALLIER
2025-09-10  9:43         ` Clément Le Goffic
2025-09-10  9:52           ` Gatien CHEVALLIER
2025-09-09 10:12 ` [PATCH v6 02/20] dt-bindings: stm32: stm32mp25: add `#access-controller-cells` property Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 03/20] clk: stm32mp25: add firewall grant_access ops Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 04/20] arm64: dts: st: set rcc as an access-controller Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 05/20] dt-bindings: memory: factorise LPDDR props into SDRAM props Clément Le Goffic
2025-09-10  7:54   ` Krzysztof Kozlowski
2025-09-10  8:31     ` Clément Le Goffic
2025-09-10  8:41     ` Clément Le Goffic
2025-09-10  8:52       ` Krzysztof Kozlowski
2025-09-09 10:12 ` [PATCH v6 06/20] dt-bindings: memory: introduce DDR4 Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 07/20] dt-bindings: memory: factorise LPDDR channel binding into SDRAM channel Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 08/20] dt-binding: memory: add DDR4 channel compatible Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 09/20] dt-bindings: memory: SDRAM channel: standardise node name Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 10/20] arm64: dts: st: add LPDDR channel to stm32mp257f-dk board Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 11/20] arm64: dts: st: add DDR channel to stm32mp257f-ev1 board Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 12/20] dt-bindings: perf: stm32: introduce DDRPERFM dt-bindings Clément Le Goffic
2025-09-10  7:57   ` Krzysztof Kozlowski
2025-09-10  8:33     ` Clément Le Goffic
2025-09-10  7:57   ` Krzysztof Kozlowski
2025-09-10  8:34     ` Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 13/20] perf: stm32: introduce DDRPERFM driver Clément Le Goffic
2025-09-10  9:26   ` Jonathan Cameron [this message]
2025-09-11  9:56     ` Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 14/20] Documentation: perf: stm32: add ddrperfm support Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 15/20] MAINTAINERS: add myself as STM32 DDR PMU maintainer Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 16/20] ARM: dts: stm32: add ddrperfm on stm32mp131 Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 17/20] ARM: dts: stm32: add ddrperfm on stm32mp151 Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 18/20] arm64: dts: st: add ddrperfm on stm32mp251 Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 19/20] arm64: dts: st: support ddrperfm on stm32mp257f-dk Clément Le Goffic
2025-09-09 10:12 ` [PATCH v6 20/20] arm64: dts: st: support ddrperfm on stm32mp257f-ev1 Clément Le Goffic

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=20250910102627.00007a40@huawei.com \
    --to=jonathan.cameron@huawei.com \
    --cc=alexandre.torgue@foss.st.com \
    --cc=clement.legoffic@foss.st.com \
    --cc=conor+dt@kernel.org \
    --cc=corbet@lwn.net \
    --cc=devicetree@vger.kernel.org \
    --cc=gabriel.fernandez@foss.st.com \
    --cc=gatien.chevallier@foss.st.com \
    --cc=jwerner@chromium.org \
    --cc=krzk+dt@kernel.org \
    --cc=krzk@kernel.org \
    --cc=legoffic.clement@gmail.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-clk@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-perf-users@vger.kernel.org \
    --cc=linux-stm32@st-md-mailman.stormreply.com \
    --cc=mark.rutland@arm.com \
    --cc=mcoquelin.stm32@gmail.com \
    --cc=mturquette@baylibre.com \
    --cc=p.zabel@pengutronix.de \
    --cc=robh@kernel.org \
    --cc=sboyd@kernel.org \
    --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.