ipc: replace enum fields with uint32_t in some IPC structures#9379
Conversation
| struct sof_ipc_cmd_hdr hdr; | ||
| uint32_t id; | ||
| enum sof_comp_type type; | ||
| uint32_t type; |
There was a problem hiding this comment.
I'm for this change - IPC structures are one of few locations where fixed-size types must be used, unlike in multiple other locations, where proper C types should be used instead. But just one proposal - would be good to add a comment with enum X to these fields to help prevent future mistakes
There was a problem hiding this comment.
ok, this is fine - its good we can get more coverage with different ISAs, the ARM compiler throwing this up means we should make this change.
One thing, can we inline comment each change to say that the new uint32_t type uses enum X
There was a problem hiding this comment.
fixed, also added reference to #9378. Should make it easier for ppl to find why the change was done w/o having to look at commit msg.
|
|
||
| struct ipc4_pin_props { | ||
| /* type of the connected stream. */ | ||
| enum ipc4_stream_type stream_type; |
There was a problem hiding this comment.
About this structure: my initial thought was that this is used in IPC4 communication between Linux and SOF, but after looking a bit more carefully it doesn't seem to be the case.
From this comment:
This file contains structures that are exact copies of an existing ABI used
by IOT middleware. They are Intel specific and will be used by one middleware.
Some of the structures may contain programming implementations that makes them
unsuitable for generic use and general usage.
This code is mostly copied "as-is" from existing C++ interface files hence the use of
different style in places. The intention is to keep the interface as close as possible to
original so it's easier to track changes with IPC host code.
My guess is this is being used by some other entity (?) and it would seem like this is Intel specific.
Since this is also included in files used by IPC3 platforms we get the compilation warning mentioned in #9378 (i.e: warning: 'format' offset 1 in 'struct ipc4_pin_props' isn't aligned to 4) (caused by the size of enum ipc4_stream_type).
With this in mind, I'm not sure the replacement with the uint32_t type is right as I don't fully understand how these IPC4 structures are used. Can someone from Intel comment on this, please?
CC: @RanderWang @ranj063
EDIT: alternatively, since this is not actually used we can file a bug report on this and just go with the "struct sof_ipc_comp" change. The main issue with this is that the many warnings this generates make it hard to spot other, new warnings.
There was a problem hiding this comment.
I think this is OK now, we were doing a lot of work at that time to ensure compatibility, but that good now.
There was a problem hiding this comment.
alright, I'm still somewhat skeptical of the IPC4-related change but if ppl from Intel are fine with it then that's fine with me
|
Adding |
OK, CI results are good so no impact - all ISAs are aligned. |
32e81a5 to
9baaee8
Compare
Normally, the type of enums is "unsigned int" or "int". GCC has the "-fshort-enums" option, which instructs the compiler to use the smallest data type that can hold all the values in the enum (i.e: char, short, int or their unsigned variants). According to the GCC documentation, "-fshort-enums" may be default on some targets. This seems to be the case for "arm-zephyr-eabi-gcc", which is used to build Zephyr on ARM platforms. On Linux, this is not the case (tested with "aarch64-linux-gnu-gcc"), which means enums such as "enum sof_comp_type" will end up having different sizes on Linux and SOF. Since "enum sof_comp_type" is used in IPC-related structures such as "struct sof_ipc_comp", this means the fields of the structures will end up being placed at different offsets. This, in turn, leads to SOF not being able to properly interpret data passed from Linux. With this in mind, replace "enum sof_comp_type" from "struct sof_ipc_comp" and "enum ipc4_stream_type" from "struct ipc4_pin_props" with "uint32_t". Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
|
Dropping [DNM] tag. I've also built the following Zephyr sample to emphasize the idea that the size of enums may differ from arch to arch (or toolchain to toolchain): on 3 different architectures (using 3 dif. toolchains). Leaving the results here in case people might be interested:
CC: @marc-hb you might find this discussion interesting |
|
Interesting! I got curious and traced this back to... 2017! When this code was originally added by commit 425aa5e That commit had a good few other "packed enums" (searched for "packed"). I don't know whether they still exist today. |
Normally, the type of enums is "unsigned int" or "int". GCC has the "-fshort-enums" option, which instructs the compiler to use the smallest data type that can hold all the values in the enum (i.e: char, short, int or their unsigned variants).
According to the GCC documentation, "-fshort-enums" may be default on some targets. This seems to be the case for "arm-zephyr-eabi-gcc", which is used to build Zephyr on ARM platforms.
On Linux, this is not the case (tested with "aarch64-linux-gnu-gcc"), which means enums such as "enum sof_comp_type" will end up having different sizes on Linux and SOF. Since "enum sof_comp_type" is used in IPC-related structures such as "struct sof_ipc_comp", this means the fields of the structures will end up being placed at different offsets. This, in turn, leads to SOF not being able to properly interpret data passed from Linux.
With this in mind, replace "enum sof_comp_type" from "struct sof_ipc_comp" and "enum ipc4_stream_type" from "struct ipc4_pin_props" with "uint32_t".
Fixes #9378.
Kernel-side change: thesofproject/linux#5148