-
Notifications
You must be signed in to change notification settings - Fork 6.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
scripts: Dynamically add driver subsystems to subsystems list #23183
scripts: Dynamically add driver subsystems to subsystems list #23183
Conversation
This change extends the parse_syscalls.py script to scan for a __subsystem sentinal added to driver api declarations. It thens generates a list that is passed into gen_kobject_list.py to extend the subsystems list. This allows subsystems to be declared in the code instead of a separate python list and provides a mechanism for defining out-of-tree subsystems. Signed-off-by: Corey Wharton <coreyw7@fb.com>
Hi, can you please explain what the "subsystem list" is. Does it exist already, or is it introduced in this PR? If it is introduced in this PR please, in detail, explain what it is for. Also, AFAIK it is possible to define out-of-tree subystems already, if it is not, then please elaborate |
@SebastianBoe Certainly, the list exists already inside the gen_kobject_list.py script and is currently defined as: subsystems = [
"adc_driver_api",
"aio_cmp_driver_api",
"counter_driver_api",
"crypto_driver_api",
"dma_driver_api",
"flash_driver_api",
"gpio_driver_api",
"i2c_driver_api",
"i2s_driver_api",
"ipm_driver_api",
"led_driver_api",
"pinmux_driver_api",
"pwm_driver_api",
"entropy_driver_api",
"sensor_driver_api",
"spi_driver_api",
"uart_driver_api",
"can_driver_api",
"ptp_clock_driver_api",
"eeprom_driver_api",
"wdt_driver_api",
# Fake 'sample driver' subsystem, used by tests/samples
"sample_driver_api"
] While it is possible to define custom drivers and interfaces, these don't get the special handling done in this script (see comments in file header) unless the driver api struct name is added to this list. This change allows that through the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this! I think we should just go ahead and tag all the existing subsystems and remove the hard-coded subsystems list to make everything clean and consistent.
I defer the build system stuff to @SebastianBoe opinion.
@SebastianBoe this is for memory protection. All driver APIs take a |
I was not aware of this hardcoded list. We do indeed need to support out-of-tree subsystem But we should populate this list through CMake instead of by parsing C code because this is significantly faster, simpler, and less prone to obscure issues (e.g. subsystem declarations using preprocessor constructs). We don't do this for syscalls because there are hundreds of syscalls, but for a few dozen subsystems this is the better approach. The way it would work is that we would in CMake populate a list that is stored in a target property. Storing it in a target property means that we can read it out at generation-time, and therefore not have a read-after-write dependency on the code declaring the gen_kobject_list.py command, and the code populating the list. See 6538c28 for a demonstration on how it can be done. |
No no no I don't agree at all, I understand doing this in CMake is simpler from a build system perspective, but I think this is far less intuitive to the end user, and splits information between the C code and the build system files. It is dead simple, from an end user perspective, if they declare a subsystem api, to tag the struct declaration with __subsystem. That is all they need to do, and it is co-located with the API struct declaration. No dual maintenance between separate files, which was the whole point of this patch.
No offense, but yuck. You're just moving the list of subsystems out of the python code and into some CMakelists.txt. What's the point? Might as well leave it in the Python.
This has nothing to do with the number of system calls. We need to know the type information for the system call. Moving this to CMake would require that we effectively duplicate the function prototype, and have to update both if it changes. And from an end user perspective, its simple and intuitive to just tag an API that needs to be a system call with |
@SebastianBoe would an acceptable compromise be to simply have the same script that does the __syscall scanning also look for __subsystem? I think this would eliminate most of the build system changes. |
That is how it is implemented, no? |
I disagree that it is simpler to regex parse all the C code in the codebase than to maintain a list in CMake. Note that the point of this PR was to support out-of-tree declarations of subsystems. There are a myriad of limitations, e.g. the __subsystem keyword must be put at a very specific place in the declaration, and it can not be expanded through a macro. |
@SebastianBoe I acknowledge your proposed solution is simpler in both the size of the change and complexity, and it's not that much different from my first approach. However, I do agree with @andrewboie that using the Ultimately, my team has a need for defining new subsystems without maintaining a separate Zephyr tree, and I'm willing to implement whatever solution the greater community thinks is the best approach. |
We're fundamentally not looking at this the same way. This is simpler for the end user developer experience, which is what I care about, to a very intense degree. |
I disagree that this is simpler for the end user developer experience. The user When considering what is the simplest for the user I like to look at how much documentation is necessary to read.
versus
That being said, since you are the maintainer of this API, I will If we do regex parsing I would like to see some numbers for the |
I wrote some benchmarking code in the parse_syscalls.py script: Build command:west build -p always -b stm32f4_disco samples/userspace/prod_consumer/ Build system:Intel(R) Xeon(R) W-2135 CPU @ 3.70GHz Results
Times are in milliseconds so the average impact per file is roughly 4 microseconds and the total impact should be around 1.8ms total. Not bad for a technology first defined in the 50s! The runtime for entire python script:
I'm guessing much of that is file I/O and python overhead. |
I pushed a commit removing the names in the hard-coded list as mentioned earlier. In the process of creating the change I've found the follow interesting issues. I may need a sanity check to make sure I'm not missing something:
|
@xodus7 Note that the eSPI subsystem so far is only used on MEC15xx boards, which has no CONFIG_USERSPACE not enabled (No MPU). Nevertheless, I'm planning to add espi handlers for v2.3. |
This change removes the hardcoded subsystem list in gen_kobject_list.py favor of marking the relevant driver API structs with the _subsystem sentinel. Signed-off-by: Corey Wharton <coreyw7@fb.com>
091c4d1
to
495773e
Compare
The regex parsing overhead is ok. Thank you for benchmarking. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
@andrewboie Is there anything else I need to do here before final approval? |
Merge window needs to open up for 2.3 and then we can push this. |
It's probably the case that this stuff isn't being built by tests, we will need to address that. |
This change extends the parse_syscalls.py script to scan for a
__subsystem sentinal added to driver api declarations. It thens
generates a list that is passed into gen_kobject_list.py to extend
the subsystems list. This allows subsystems to be declared in the
code instead of a separate python list and provides a mechanism for
defining out-of-tree subsystems.
Signed-off-by: Corey Wharton coreyw7@fb.com