The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Cristian Marussi <cristian.marussi@arm.com>
To: Philip Radford <philip.radford@arm.com>
Cc: linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, arm-scmi@vger.kernel.org,
	linux-pm@vger.kernel.org, sudeep.holla@arm.com,
	james.quinlan@broadcom.com, f.fainelli@gmail.com,
	vincent.guittot@linaro.org, etienne.carriere@st.com,
	peng.fan@oss.nxp.com, michal.simek@amd.com,
	quic_sibis@quicinc.com, dan.carpenter@linaro.org, d-gole@ti.com,
	souvik.chakravarty@arm.com, cristian.marussi@arm.com
Subject: Re: [PATCH v10 01/13] powercap: Add enable disable control-type
Date: Sun, 15 Nov 2026 11:36:28 +0000	[thread overview]
Message-ID: <avmZPMOK8ynHMN0I@pluto> (raw)
In-Reply-To: <20261103231007.537082-2-philip.radford@arm.com>

On Tue, Nov 03, 2026 at 11:09:55PM +0000, Philip Radford wrote:
> Add functionality to disable or enable the Powercap control-type by writing
> directly into sys/class/powercap/arm-scmi/enabled.
> 

Hi Philip,

see a some general remarks down below.

> Signed-off-by: Philip Radford <philip.radford@arm.com>
> ---
> V9->V10
> - changed control-type enable writes to snapshot per-zone state instead of
>   aggregate
> - cancel enable/disable writes if a root child zone is not configurable
> - roll back changed zones on failure
> - changed control-type enable reads to report enabled if any root child zone
>   is enabled
> ---
>  drivers/powercap/arm_scmi_powercap.c | 175 ++++++++++++++++++++++++++-
>  1 file changed, 174 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/powercap/arm_scmi_powercap.c b/drivers/powercap/arm_scmi_powercap.c
> index ab66e9a3b1e2..ba398048bf21 100644
> --- a/drivers/powercap/arm_scmi_powercap.c
> +++ b/drivers/powercap/arm_scmi_powercap.c
> @@ -33,13 +33,171 @@ struct scmi_powercap_zone {
>  
>  struct scmi_powercap_root {
>  	unsigned int num_zones;
> +	bool enabled;
> +	struct list_head node;
>  	struct scmi_powercap_zone *spzones;
>  	struct list_head *registered_zones;
>  	struct list_head scmi_zones;
>  };
>  
> +static LIST_HEAD(scmi_powercap_roots);
> +static DEFINE_MUTEX(scmi_powercap_roots_lock);
> +
>  static struct powercap_control_type *scmi_top_pcntrl;
>  
> +static bool scmi_powercap_is_control_type_child(const struct scmi_powercap_zone *spz)
> +{
> +	return spz->registered && !spz->invalid &&
> +	       spz->info->parent_id == SCMI_POWERCAP_ROOT_ZONE_ID;

Not sure to remember clearly the logic here, but is it possible for a
zone to be registered and invalid ?
I made some recent changes/fixes but the invariant that registered
implied !invalid seemed to apply before and after my fixes...

> +}
> +
> +static int
> +scmi_powercap_read_root_children_enable_state(struct scmi_powercap_root *pr, bool *mode)
> +{
> +	struct scmi_powercap_zone *spz;
> +	bool enabled;
> +	int i, ret;
> +
> +	*mode = false;
> +
> +	for (i = 0; i < pr->num_zones; i++) {

	for (int i = 0 ...

> +		spz = &pr->spzones[i];
> +
> +		if (!scmi_powercap_is_control_type_child(spz))
> +			continue;
> +
> +		ret = powercap_ops->cap_enable_get(spz->ph, spz->info->id, &enabled);
> +		if (ret)
> +			return ret;
> +
> +		if (enabled) {
> +			*mode = true;
> +			return 0;
> +		}
> +	}
> +
> +	return 0;
> +}
> +
> +struct scmi_powercap_zone_state {
> +	struct scmi_powercap_zone *spz;
> +	bool prev_enabled;
> +	bool changed;
> +};
> +
> +static int
> +scmi_powercap_control_type_set_enable(struct powercap_control_type *pct, bool mode)
> +{
> +	struct scmi_powercap_zone_state *states;
> +	struct scmi_powercap_root *pr;
> +	struct scmi_powercap_zone *spz;
> +	int num_zones = 0, nr_states = 0;
> +	int i, ret = 0;

... while looking at some other previous Sashiko reported powercap issue
I had a superficial look at this, and beside the logic that seems to be
fine by itself, the code layout is deadly unreadable, thing which is
pretty normal to happen when there is a mix of allocations mutexes and
various error exit path....please refactor using cleanup handlers to
manage all of this allocations and mutexes, it should allow you to drop
all the gotos and keep a more linear logic across all of this fucntion..
(and NOTE that when using cleanup.h you MUST drop all of the gotos in
this function...all info inside cleanup.h too)
 
> +
> +	mutex_lock(&scmi_powercap_roots_lock);
> +	list_for_each_entry(pr, &scmi_powercap_roots, node) {
> +		for (i = 0; i < pr->num_zones; i++) {
> +			spz = &pr->spzones[i];
> +
> +			if (scmi_powercap_is_control_type_child(spz))
> +				num_zones++;
> +		}
> +	}
> +
> +	states = kcalloc(num_zones, sizeof(*states), GFP_KERNEL);
> +	if (!states) {
> +		ret = -ENOMEM;
> +		goto out_unlock;
> +	}
> +
> +	list_for_each_entry(pr, &scmi_powercap_roots, node)	{
> +		for (i = 0; i < pr->num_zones; i++) {
> +			spz = &pr->spzones[i];
> +
> +			if (!scmi_powercap_is_control_type_child(spz))
> +				continue;
> +
> +			if (!spz->info->powercap_cap_config) {
> +				ret = -EOPNOTSUPP;
> +				goto out_free;
> +			}
> +
> +			states[nr_states].spz = spz;
> +
> +			ret = powercap_ops->cap_enable_get(spz->ph, spz->info->id,
> +				&states[nr_states].prev_enabled);

also...I have not checked this myself, BUT do you use checkpatch --strict that I
can see a few strange indents...

> +
> +			if (ret)
> +				goto out_free;
> +
> +			nr_states++;
> +		}
> +	}
> +
> +	for (i = 0; i < nr_states; i++) {
> +		spz = states[i].spz;
> +
> +		if (states[i].prev_enabled == mode)
> +			continue;
> +
> +		ret = powercap_ops->cap_enable_set(spz->ph, spz->info->id, mode);
> +		if (ret)
> +			goto revert;
> +
> +		states[i].changed = true;
> +	}
> +
> +	goto out_free;
> +
> +revert:
> +	while (i--) {
> +		spz = states[i].spz;
> +
> +		if (!states[i].changed)
> +			continue;
> +
> +		powercap_ops->cap_enable_set(spz->ph, spz->info->id,
> +			states[i].prev_enabled);

ditto...checkpatch

> +	}
> +
> +out_free:
> +			kfree(states);
> +
ditto...checkpatch
> +out_unlock:
> +			mutex_unlock(&scmi_powercap_roots_lock);
ditto...checkpatch
> +
> +			return ret;
> +}
> +
> +static int
> +scmi_powercap_control_type_get_enable(struct powercap_control_type *pct, bool *mode)
> +{
> +	struct scmi_powercap_root *pr;
> +	int ret = 0;
> +

same here...even if it is a smaller function using cleanup guard helps
streamlining the code...

> +	*mode = false;
> +
> +	mutex_lock(&scmi_powercap_roots_lock);
> +	list_for_each_entry(pr, &scmi_powercap_roots, node) {
> +		ret = scmi_powercap_read_root_children_enable_state(pr, &pr->enabled);
> +
> +		if (ret)
> +			break;
> +		if (pr->enabled) {
> +			*mode = true;
> +			break;
> +		}
> +	}
> +	mutex_unlock(&scmi_powercap_roots_lock);
> +
> +	return ret;
> +}
> +

Thanks,
Cristian

  reply	other threads:[~2026-11-15 11:36 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-03 23:09 [PATCH v10 00/13] Add support for SCMIv4.0 Powercap Extensions Philip Radford
2026-11-03 23:09 ` [PATCH v10 01/13] powercap: Add enable disable control-type Philip Radford
2026-11-15 11:36   ` Cristian Marussi [this message]
2026-11-03 23:09 ` [PATCH v10 02/13] firmware: arm_scmi: Add an optional custom parameter to fastchannel helpers Philip Radford
2026-11-03 23:09 ` [PATCH v10 03/13] firmware: arm_scmi: Refactor powercap domain layout Philip Radford
2026-11-03 23:09 ` [PATCH v10 04/13] firmware: arm_scmi: Add SCMIv4.0 Powercap basic support Philip Radford
2026-11-03 23:09 ` [PATCH v10 05/13] firmware: arm_scmi: Add SCMIv4.0 Powercap FCs support Philip Radford
2026-11-03 23:10 ` [PATCH v10 06/13] firmware: arm_scmi: Add SCMIV4.0 Powercap notifications support Philip Radford
2026-11-03 23:10 ` [PATCH v10 07/13] firmware: arm_scmi: Extend powercap report to include MAI Philip Radford
2026-11-03 23:10 ` [PATCH v10 08/13] include: trace: Add new parameter to trace_scmi_fc_call Philip Radford
2026-11-03 23:10 ` [PATCH v10 09/13] powercap: arm_scmi: Enable multiple constraints support Philip Radford
2026-11-03 23:10 ` [PATCH v10 10/13] firmware: arm_scmi: add Powercap MAI get/set support Philip Radford
2026-11-03 23:10 ` [PATCH v10 11/13] powercap: arm_scmi: Create synthetic parent node for multi-instance Philip Radford
2026-11-03 23:10 ` [PATCH v10 12/13] powercap: arm_scmi: Add get_power_uw to synthetic node Philip Radford
2026-11-03 23:10 ` [PATCH v10 13/13] powercap: arm_scmi: Synthetic zone enable/disable Philip Radford

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=avmZPMOK8ynHMN0I@pluto \
    --to=cristian.marussi@arm.com \
    --cc=arm-scmi@vger.kernel.org \
    --cc=d-gole@ti.com \
    --cc=dan.carpenter@linaro.org \
    --cc=etienne.carriere@st.com \
    --cc=f.fainelli@gmail.com \
    --cc=james.quinlan@broadcom.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pm@vger.kernel.org \
    --cc=michal.simek@amd.com \
    --cc=peng.fan@oss.nxp.com \
    --cc=philip.radford@arm.com \
    --cc=quic_sibis@quicinc.com \
    --cc=souvik.chakravarty@arm.com \
    --cc=sudeep.holla@arm.com \
    --cc=vincent.guittot@linaro.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