Thread (8 messages) 8 messages, 2 authors, 2026-02-26

Re: [PATCH 0/4] firmware: arm_scmi: Drop fake 'const' on scmi_handle

From: Krzysztof Kozlowski <hidden>
Date: 2026-02-25 11:42:12
Also in: arm-scmi, imx, linux-clk, lkml, stable

On 24/02/2026 13:31, Cristian Marussi wrote:
On Tue, Feb 24, 2026 at 11:43:38AM +0100, Krzysztof Kozlowski wrote:
quoted
Severale functions operating on the 'handle' pointer, like
Hi Krzysztof,
quoted
scmi_handle_put() or scmi_xfer_raw_get(), are claiming it is a pointer
to const thus they should not modify the handle.  In fact that's a false
statement, because first thing these functions do is drop the cast to
const with container_of:
Thanks for this first of all...

...but :D

... the SCMI stack attempts to follow a sort of layered design, so roughly
we have transport, core, protocols and finally SCMI Drivers.

Each of these layers has its own responsabilities and the aim was to
enforce some sort of isolation between these layers, OR even between
different disjoint features within the same layer, if it made sense,
like with the notification subsystem within the core...

Now, given that all of the above must be attained using our beloved C
language, such attempt to enforce isolation between such 'islands' with
different responsibilities is based on:

 - fully opaque pointers/handles...like the ph protocol handels within
   SCMI drivers...best way to do it..if you cannot even peek into an
   object you certainly cannot mess with it...

 - some 'constification' when passing around some nonm-opaque references
   across such boundaries

So, when you say that some of these functions sports a fake const
reference, is certainly true to some extent, BUT you miss the fact that
usually the const is meant to stop the CALLER from messing freely with
the handle and instead enforce the usage of a dedicated helper that sits
in another layer...
The caller can mess with the handle, because of container_of() cast, so
there is nothing stopping it. I understand you want to express that
handle is somehow unchangeable but then as you mentioned - it should be
opaque pointer.
As an example, when you say that the scmi_protocol_handle *ph is indeed
manipulated by scmi_protocol_set_priv() and so it is NOT const, you are
certainly right, BUT the above function and the protocol handle itself
lives in the core, a different layer from the protocols, and indeed the
protocol_init function cannot change directly the protocol priv value
but instead has to pass through the helper ph->set_priv() which is the
only helper that can touch the ph content...
...IOW you are forced to respect the isolation boundary (as much as
possible) by the constification of ph...if you drop the const in the
protocol_init protoypes you end opening the stack to all sort of
cross-boundary manipulations annd hacks: helpers like set_priv were
added to be able to manipulate the bits that needed to be modifiable
while maintaining separation of resposibilities between latyers.

Similarly for notifications, they are kept isolated as much as possible
from the core.
I understand the goal this code tried to achieve. And it did achieve
it... plus another goal of having "const" like functions modifying
memory. This is not a readable code. Function which receives only
arguments as values and pointers to const is expected to not modify
state of received pointed data. But all the functions here, because of
the cast, can or even do modify.

I understand we do not write here C++ const methods, obviously. But all
these functions look re-entrant from the interface point of view but in
fact are not re-entrant.

So, I still have definitely to properly go through all of your
series, but while the usage of container_of_const() is certainly a
welcome addition, because it raises the isolation factor, dropping the
'fake' const seems to me a step back in the enforcement of isolation
boundaries between different layers or different subsystems within the
same layer.

IOW, the last that we want is to be able to freely change the content
of such const handles from outside the 'island' they live in...
If I understood correctly the composition here:

The handle should be in such case be not contained in the upper
structure, but be a pointer to const like:

struct scmi_protocol_instance {
	...
-	struct scmi_protocol_handle     ph;
+	const struct scmi_protocol_handle     *ph;
}

And since this is 1-to-1 relationship, the scmi_protocol_handle should
have a pointer to scmi_protocol_instance. This way you keep passing
pointer to const handle without ever needing to cast it.

The current solution would be much nicer than above, if the code was not
dropping const, IMO.
Any improvement on such isolation with more modern C tricks, if
possible, is pretty much welcome, i.e. I am not saying that the current
system is perfect and not improvable...but just dropping all of this in
name of some better possible compilation optimization seems not worth in
terms of maintainability...

Does any of the above blabbing of mine makes sense :P ?
Best regards,
Krzysztof
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help