-
Notifications
You must be signed in to change notification settings - Fork 7.4k
DNM: arch/arc: Let toolchain select tp-regno #51910
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
DNM: arch/arc: Let toolchain select tp-regno #51910
Conversation
Zephyr cannot unilaterally set the -mtp-regno option as any libraries used from the toolchain must be built with the same option. This means that builds enabling thread local storage will fail when using a toolchain which does not specify a tp-regno value. That is better than potentially using toolchain library code which overwrites the selected register. Signed-off-by: Keith Packard <[email protected]>
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.
There are many compiler settings that need to be consistent for zephyr kernel and libraries, not just the tls one. Don't see why this needs to be handled differently. This change breaks TLS support on ARC.
The idea is that the future releases of Zephyr SDK will automatically use/reserve But, there will be a problem if you are using an ARC toolchain other than the one from Zephyr SDK; for instance, GNU ARC toolchain from Synopsys or even Metaware assuming it also requires the flag? A simpler alternative would be to just leave this flag in and update the Zephyr SDK ARC toolchain to default to The patch for normalising the TLS pointer register from |
Sorry, I still don't understand what's special about this specific option. There are many options that need to be set consistently when building libraries used in Zephyr, we don't rely on toolchain defaults for these either. Probably best to discuss in a toolchain meeting with @abrodkin and @evgeniy-paltsev |
Building the toolchain without defining the TP register number means any code delivered with the toolchain (libc, libstdc++, libgcc) could end up using the register for its own purposes. Most of the time, this isn't an issue as the register will be restored upon return, but if Zephyr code is called while library code is using this register, and that Zephyr code accesses thread-local variables, then that code will fail. I wonder, for instance, whether interrupt handlers might expect this register to reflect the current context? Callbacks (for stdio), overloaded virtual functions (for libstdc++) are also potential sources of adventure here. Linux for Arc V2 sets the thread register to 25 in the toolchain to resolve this issue. Arc V3 reserves r30 for this. Anything which affects ABI must be consistent between libraries delivered with the toolchain and those built in the application; if you have other options in this class, they should either be fixed in the toolchain or configured as multilib options (like -mcpu). |
@keith-packard |
no hurry; @stephanosio suggested we change the toolchain to use r26 so that the existing Zephyr code will 'just work'. This change will enable moving from r26 to r25 in the future, if the Arc community wants to do that. |
@keith-packard , @stephanosio , @ruuddw , @abrodkin Sorry for delay, here is my proposal: For ARCv3 toolchain (arc64-zephyr-elf):Nothing need to be done in both sdk-ng and Zephyr, For ARCv2 toolchain (arc-zephyr-elf):Currently we use So, let's specify default tls registers for ARCv2 toolchain and let's switch to
This won't introduce new compatibility issues for main Zephyr branch as:
This won't introduce new compatibility issues for LTS Zephyr branch (even if de-facto we don't support building LTS branch with latest Zephyr SDKs) as:
This will fix currently existing issue that we build ARCv2 libraries in Zephyr toolchain without reservation register for TLS pointer, so currently Actions:If there is no objections I'll prepare PR's for the rest of the changes. |
I think this is the key patch -- it removes any need for all compilation uses to ensure they set -mtp-regno=25 on the command line. Without this patch, any mis-configured component may silently damage the thread pointer register and lead to unexpected failures. Once this patch is in place, there is only one thing that needs changing to switch from 26 to 25 -- change this value and then ensure that a consistent SDK is used to build all the pieces of the system. As to submitting upstream, I think we could find a way to do that, perhaps by adding another arc-specific GCC configuration value to set this, or plan on making this a part of the switch from arc-zephyr-elf to arc-none-zephyr (or however we want to name the toolchain) as that would allow us to create a zephyr.h file in gcc to include this kind of change. |
Hi @keith-packard,
The initial reason why it wasn't specified for ARC baremetal toolchain is because baremetal targets wouldn't use TLS anyway - so reservation register for TLS is a register waste. The Zephyr is kinda exception here - probably it's not worth to tweak generic baremetal toolchain configuration because of Zephyr only. Ideally we should only build toolchain libraries with Not an expert in crosstool-ng, so not sure if |
Note that RISC-V has made the other choice -- all RISC-V ABIs reserve a register for thread local storage. But, I don't know the ARC ecosystem at all, so perhaps having another register is more useful there? I can see how setting this in every embedded toolchain wouldn't be welcome by all users. Making it a arc-specific GCC configuration option would make a lot of sense though, and aligning the embedded tp register number with the linux choice would also be a good plan.
The alternative is to have targets that do want an extra register to use -mtp-regno=none while building. The only effect of having -mtp-regno=** has is to make that the default when building code. Applications can always override that by turning that feature off.
No, there's nothing taken from crosstool-ng into applications in the way of compiler flags. Note that as far as the toolchain build goes, the only effect of having this set there is that code delivered with the toolchain will use this setting -- that's just libgcc and libc, which aren't generally performance critical bits of code for embedded applications. The problem is that if any code is built without the correct -mtp-regno parameter, then it might cause corruption in subtle ways. So, having the toolchain use a default value is an easy way to avoid that by just removing the command line parameter everywhere, and letting applications not using TLS to use -mtp-regno=none to gain back that extra register. Having the toolchain and Zephyr use matching configurations should work, but I feel it's a bit more fragile as anything which somehow neglects to include this command line parameter could cause weird bugs. |
This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time. |
It seems like the arc team wants to leave this as-is. |
Zephyr cannot unilaterally set the -mtp-regno option as any libraries used from the toolchain must be built with the same option. This means that builds enabling thread local storage will fail when using a toolchain which does not specify a tp-regno value. That is better than potentially using toolchain library code which overwrites the selected register.
Signed-off-by: Keith Packard [email protected]
See also zephyrproject-rtos/gcc#17 which makes the Zephyr SDK use register 25 by default.