Skip to content
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

kernel: userspace: dynamic thread stack support #59773

Merged
merged 6 commits into from
Jul 17, 2023

Conversation

ceolin
Copy link
Member

@ceolin ceolin commented Jun 26, 2023

Support for dynamic thread stack on userspace.

@cfriedt
Copy link
Member

cfriedt commented Jun 27, 2023

@ceolin - I've applied your fixups and pushed to issue/26999/k-thread-create-dynamic-stack

Flavio Ceolin added 3 commits July 14, 2023 11:36
Test that automatic thread stack allocation works for
both user and kernel threads.

Signed-off-by: Flavio Ceolin <[email protected]>
Add a new API to dynamically allocate kernel objects that allow
passing an arbitrary size. This new API allows to allocate dynamic
thread stack.

Signed-off-by: Flavio Ceolin <[email protected]>
Allocate kernel object for userspace thread stack.

Signed-off-by: Flavio Ceolin <[email protected]>
@ceolin ceolin changed the title kernel: dynamic thread stack support kernel: userspace: dynamic thread stack support Jul 14, 2023
@ceolin ceolin marked this pull request as ready for review July 14, 2023 22:20
@ceolin ceolin requested a review from cfriedt July 14, 2023 22:20
@zephyrbot zephyrbot added area: Kernel area: Base OS Base OS Library (lib/os) area: Userspace Userspace labels Jul 14, 2023
/*
* Linked list of allocated kernel objects, for iteration over all allocated
* objects (and potentially deleting them during iteration).
*/
static sys_dlist_t obj_list = SYS_DLIST_STATIC_INIT(&obj_list);

/*
* TODO: Write some hash table code that will replace both obj_rb_tree
* and obj_list.
* TODO: Write some hash table code that will replace obj_list.
Copy link
Member

@cfriedt cfriedt Jul 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is hash_map_api.h if you are looking for one

cfriedt
cfriedt previously approved these changes Jul 14, 2023
Copy link
Contributor

@andyross andyross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see anything wrong, but that wasted page for every stack creeps me out a bit. Seems like one extra layer of indirection is needed.

struct dyn_obj_base base;

/* The object itself */
uint8_t data[] __aligned(DYN_OBJ_DATA_ALIGN_K_THREAD_STACK);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks suspicious? Aligning the data[] array means that on MMU systems it's going to waste 4096 - sizeof(struct dyn_obj_base) bytes of padding! Tracking the stack as a kobj makes sense, but putting the whole stack inline seems like it's not going to work well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep ... there is this waste of memory indeed, that is probably no longer needed now that I am searching the object linearly. I can now do two allocations and avoid it. Let met try it out.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed this alignment requirement for the object and make a new allocation for the stack data itself (with the proper alignment), this can potentially avoid some memory waste.

@@ -193,6 +227,9 @@ static size_t obj_align_get(enum k_objects otype)
ret = __alignof(struct dyn_obj);
#endif
break;
case K_OBJ_THREAD_STACK_ELEMENT:
ret = __alignof(struct dyn_obj_stack);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar issue, but a nitpick: That struct itself isn't aligned, just a submember. Does this give the right answer on all toolchains? Seems like it might be clearer to return DYN_OBJ_DATA_ALIGN_K_THREAD_STACK specifically.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that function is asking for the object alignment and not the data itself.

Flavio Ceolin added 3 commits July 17, 2023 10:24
Add support for dynamic thread stack objects. A new container
for this kernel object was added to avoid its alignment constraint
to all dynamic objects.

Signed-off-by: Flavio Ceolin <[email protected]>
Fix the preference allocation logic. If pool is preferred but POOL_SIZE
is 0 or pool allocation fails, it fallbacks to heap allocation if it
is enabled.

Signed-off-by: Flavio Ceolin <[email protected]>
Since the rbtree is using as list because we no longer
can assume that the object pointer is the address of the
data field in the dynamic object struct, lets just use
the already existent dlist for tracking dynamic kernel
objects.

Signed-off-by: Flavio Ceolin <[email protected]>
Copy link
Contributor

@andyross andyross left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One more nitpick about the confusingly aliased "data" fields. FWIW I'm seeing now where that alignment padding in the struct came from, it wasn't originally for page padding, it was to get the struct k_thread aligned correctly on x86, which (IIRC) needs that for the x87/SSE context switch field.

No reason not to approve, but if the two uses of data became a proper union with an assert or something to track misuse, I wouldn't cry.

};

struct dyn_obj {
struct dyn_obj_base base;

/* The object itself */
uint8_t data[] __aligned(DYN_OBJ_DATA_ALIGN_K_THREAD);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this item be removed now? The address where it would be is now (in a dyn_obj_stack) the "data" pointer (identically named, but a pointer and not an array!). Trying to use this now would be an aliasing bug.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can make everything work with only one object type now. This was needed to avoid imposing the stack alignment requirement for all objects. I can try it out later.

@cfriedt cfriedt merged commit 2b1106a into zephyrproject-rtos:main Jul 17, 2023
28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Base OS Base OS Library (lib/os) area: Kernel area: Userspace Userspace
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants