-
Notifications
You must be signed in to change notification settings - Fork 26
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
Initialize main thread pthread structure #59
Conversation
It seems some steps were missing in pthread structure initialization. This patch does the following: - zeroes pthread memory (previously potentially contained garbage after uk_mem_align allocation) - initializes tsd - sets detach_state to joinable Signed-off-by: Aleksandr Iashchenko <Aleksandr.Iashchenko@opensynergy.com>
previously discussed here unikraft/unikraft#961 (review) regarding joinable for main thread please grep here https://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html |
@@ -84,6 +84,7 @@ | |||
* map + size ---------------------------------------------------------- | |||
*/ | |||
|
|||
static const size_t __uk_tsd_size = sizeof(void *) * PTHREAD_KEYS_MAX; |
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.
This could be also provided as a macro, no symbol is effectively required.
#define UK_TSD_SIZE (sizeof(void *) * PTHREAD_KEYS_MAX)
I did not check the whole musl code yet, sorry for these questions:
- Is
sizeof(void *)
big enough to hold a TSD entry? - Isn't somewhere else a size definition that we should use instead (to avoid code-out-of-sync type of errors in the future)?
- Do we need to allocate TSD here already? The dangerous part is, because
__uk_copy_tls()
is called on every TLS memory allocation that we crash at any TLS creation (which happens at any thread creation) if we run out of memory instead of returningENOMEM
.
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.
Hi @skuenzer . Thank you for the comment.
This could be also provided as a macro, no symbol is effectively required.
Is sizeof(void *) big enough to hold a TSD entry?
Isn't somewhere else a size definition that we should use instead (to avoid code-out-of-sync type of errors in the future)?
Actually, I have not introduced this, that was before me, I just moved this line from below. That is how TSD was created for other threads. If we are not sure if that logic is correct, maybe we should target a different PR to fix this? The macro I can do of course if needed, but again I have not invented this.
Do we need to allocate TSD here already? The dangerous part is, because __uk_copy_tls() is called on every TLS memory allocation that we crash at any TLS creation (which happens at any thread creation) if we run out of memory instead of returning ENOMEM.
Sorry, I don't understand how __uk_copy_tls() relates to this. It is in __uk_init_tp()
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.
Re: macro vs static const: I think it hardly matters; in general I'd go for the option of least change.
Re: __uk_copy_tls
indeed it's not relevant; all the changed code is in __uk_init_tp
which gets called only for the main thread.
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.
Actually, I have not introduced this, that was before me, I just moved this line from below. That is how TSD was created for other threads. If we are not sure if that logic is correct, maybe we should target a different PR to fix this? The macro I can do of course if needed, but again I have not invented this.
True, sorry, it is a pure style preference. I usually do not like introducing a static const
variable where a macro achieves the same. But it is true, you just moved it up. I leave it up to you if you want to change it or leave it. I am just less hesitant for changes here (but normally I agree with @andreittr) because this file is purely our code.
Do we need to allocate TSD here already? The dangerous part is, because __uk_copy_tls() is called on every TLS memory allocation that we crash at any TLS creation (which happens at any thread creation) if we run out of memory instead of returning ENOMEM.
Sorry, I don't understand how __uk_copy_tls() relates to this. It is in __uk_init_tp()
In fact, my fault. It seems I was in a rush last time. Forget this comment. Btw, is there a way to return and propagate an error out of __uk_init_tp()
instead of crashing?
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.
Btw, is there a way to return and propagate an error out of __uk_init_tp() instead of crashing?
If we propagate this error up, it will end up in ukarch_tls_tcb_init
, which then requires changes to both lib-musl and the Unikraft code that calls it. I am also not sure what the calling code could do to fix this, other then crash in Unikraft.
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.
Btw, is there a way to return and propagate an error out of __uk_init_tp() instead of crashing?
We can propagate, but it is not clear for what purpose. If we can't allocate tsd even for init thread, then it is a fatal error and we can't recover from that.
I usually do not like introducing a static const variable where a macro achieves the same. But it is true, you just moved it up. I leave it up to you if you want to change it or leave it.
I prefer to leave as is.
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.
Yes, this makes sense, and I think we should change the return type of __uk_init_tp
from int
to void
.
@alexhoppus , @kubanrob , could you please ensure this PR is updated in the next days to have it part of the 0.14 release? |
@razvand To be honest I am not sure what exactly needs to be changed given @alexhoppus and @andreittr answers. @skuenzer Please review again given the answers. To me it seems like the requested three changes are not really needed / desired. macro
TSD
|
No changes per se, but there are some pending questions in the latest comment from @skuenzer and in my review above. |
@andreittr I answered about error propagation and macro vs static const questions. I don't see any other questions. Please let me know if I missed something. Thank you. |
* - information about stack | ||
* - canary | ||
*/ | ||
memset(td, 0, sizeof(*td)); |
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.
- Is a complete zeroing out of memory ok here? The init function called for other threads (
uk_thread_uktcb_init
) seems to set a few important fields (stack & self pointer); are these set somewhere else for the main thread? - In the interest of not repeating oneself, we shouldn't duplicate the tcb/tsd init code here; we likely can't piggyback on top of
uk_thread_uktcb_init
and call it directly, but can we factor out the tcb/td init code into a subroutine called by both?
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.
The init function called for other threads (uk_thread_uktcb_init) seems to set a few important fields (stack & self pointer)
Yes, there are several things which are not initialized, that is specified in the FIXME block above memset. self pointer is set here. The stack is not set, I have not found an easy way to propagate this information to __uk_init_tp and that will affect related pthread api which retrieves stack information, however that also didn't work before. There is a way to do that, and that relates to your second question.
we likely can't piggyback on top of uk_thread_uktcb_init
I think that is exactly what we should do, but to do that properly, I assume we should also propagate / initialize earlier uk_thread for main thread Ideally, the mechanic for creating init thread & native threads should be the same and that might be the target for the refactoring. The other approaches like creating some subroutine unifying parts of uk_thread_uktcb_init and __uk_init_tp I don't like. My suggestion is to merge this and then to target a separate pr for refactoring. But in case if you insist, I can do that in this PR, however, as I said I don't see it as a small change,so I'm not sure that will be in line with the purpose of PR (bugfix).
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.
Hum... it sounds like that we probably should brainstorm and discuss the initialization unification. I am not sure what you have in mind for unifying it for the init thread with a refactoring of uk_thread_uktcb_init
but I am curious. I agree with you that this would be beyond the purpose of this PR. On the other hand, I think, @andreittr just commented about a smaller deduplication work within this file for improving the code readability without changing the model right now which also sounds okay to me. Maybe you can explain a bit more why you don't like it.
For full transparency of my opinion: I rather accept and merge the PR "as is" before not having any fix as part of the upcoming release. If some changes need bigger discussions and brainstorming, I am all for a meeting after the release to discuss a solution. On the other hand, minor things that are clear to do, we should try to fix with this PR.
What do you think @alexhoppus , @andreittr , @eduardvintila ?
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.
On the other hand, I think, @andreittr just commented about a smaller deduplication work within this file for improving the code readability without changing the model right now which also sounds okay to me. Maybe you can explain a bit more why you don't like it.
There should be possible to make common API (unified function) which could be used for all native threads tcb initialization (including init thread). Maybe that will be just uk_thread_uktcb_init or some other function it is not clear to me yet. Also it makes sense to check what else could we unify on the paths of native threads/init thread initialization. However, that requires some work with external code also, so can't be done in isolated manner. Unifying parts of uk_thread_uktcb_init and __uk_init_tp now looks like a half-measure to me. Anyway, as I said, if you or @andreittr think differently I will do. I don't have particular plan, all above just generic thoughts.
Thank you.
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.
Okay, from my side I think it makes sense to investigate more time after the release for finding a solution. You have my okay for this PR. @andreittr would you prefer restructuring the functions with this PR or we also move this to be discussed as part of the brainstorming as @alexhoppus suggested?
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'm ok with merging this fix as-is, seeing that it doesn't break anything, and revisit refactoring later.
Oops, my bad, I had left my review in draft form and it wouldn't show to others; fixed now, my 2 questions should now be visible. |
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.
As discussed, let's revisit this code base after a brainstorming discussion about TLS initialization. I am okay with integrating it "as is".
Reviewed-by: Simon Kuenzer simon@unikraft.io
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.
As discussed, approved as-is, will pursue refactoring later.
Reviewed-by: Andrei Tatar andrei@unikraft.io
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.
Thank you @alexhoppus
Reviewed-by: Robert Kuban robert.kuban@opensynergy.com
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.
Approved-by: Razvan Deaconescu razvand@unikraft.io
It seems some steps were missing in pthread structure initialization. This patch does the following: