-
Notifications
You must be signed in to change notification settings - Fork 349
fast-get: fix a recent regression #10639
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -201,10 +201,8 @@ struct processing_module { | |
| enum module_processing_type proc_type; | ||
| #if CONFIG_USERSPACE | ||
| struct userspace_context *user_ctx; | ||
| #endif /* CONFIG_USERSPACE */ | ||
| #if CONFIG_SOF_USERSPACE_APPLICATION | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this change is unnecessary, because the proxy already stores the memory domain in its context. |
||
| struct k_mem_domain *mdom; | ||
| #endif | ||
| #endif /* CONFIG_USERSPACE */ | ||
| #endif /* SOF_MODULE_PRIVATE */ | ||
| }; | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,7 +29,7 @@ struct sof_fast_get_entry { | |
| const void *dram_ptr; | ||
| void *sram_ptr; | ||
| #if CONFIG_USERSPACE | ||
| struct k_thread *thread; | ||
| struct k_mem_domain *mdom; | ||
| #endif | ||
| size_t size; | ||
| unsigned int refcount; | ||
|
|
@@ -103,7 +103,7 @@ static struct sof_fast_get_entry *fast_get_find_entry(struct sof_fast_get_data * | |
| #endif | ||
|
|
||
| #if CONFIG_USERSPACE | ||
| static bool fast_get_domain_exists(struct k_thread *thread, void *start, size_t size) | ||
| static bool fast_get_partition_exists(struct k_thread *thread, void *start, size_t size) | ||
| { | ||
| struct k_mem_domain *domain = thread->mem_domain_info.mem_domain; | ||
|
|
||
|
|
@@ -117,7 +117,7 @@ static bool fast_get_domain_exists(struct k_thread *thread, void *start, size_t | |
| return false; | ||
| } | ||
|
|
||
| static int fast_get_access_grant(k_tid_t thread, void *addr, size_t size) | ||
| static int fast_get_access_grant(struct k_mem_domain *mdom, void *addr, size_t size) | ||
| { | ||
| struct k_mem_partition part = { | ||
| .start = (uintptr_t)addr, | ||
|
|
@@ -126,7 +126,7 @@ static int fast_get_access_grant(k_tid_t thread, void *addr, size_t size) | |
| }; | ||
|
|
||
| LOG_DBG("add %#zx @ %p", part.size, addr); | ||
| return k_mem_domain_add_partition(thread->mem_domain_info.mem_domain, &part); | ||
| return k_mem_domain_add_partition(mdom, &part); | ||
| } | ||
| #endif /* CONFIG_USERSPACE */ | ||
|
|
||
|
|
@@ -183,15 +183,21 @@ const void *fast_get(struct k_heap *heap, const void *dram_ptr, size_t size) | |
| ret = entry->sram_ptr; | ||
|
|
||
| #if CONFIG_USERSPACE | ||
| /* We only get there for large buffers */ | ||
| if (k_current_get()->mem_domain_info.mem_domain->num_partitions > 1) { | ||
| struct k_mem_domain *mdom = k_current_get()->mem_domain_info.mem_domain; | ||
|
|
||
| /* | ||
| * We only get there for large buffers, since small buffers with | ||
| * enabled userspace don't create fast-get entries | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just to clarify, I think this part is well understood (you can deduce this info just by examining fast_get function itself). No need to further explain it. mdom->num_partitions > 1 I am not sure if this comment is even related. I am guessing the related comment is below: /* A userspace thread makes the request */ Am I right? If yes, maybe you could just change it to: /* if num_partitions > 0, the request comes form a userspace thread */ Or you can combine both comments like this: /* We only get there for large buffers.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @wjablon1 yes, that test is related to the "userspace thread" comment. @softwarecki wanted to replace that test with a
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok, if we already have a plan for this, forget about my comment and remove unnecessary clarification |
||
| */ | ||
| if (mdom->num_partitions > 1) { | ||
| /* A userspace thread makes the request */ | ||
| if (k_current_get() != entry->thread && | ||
| !fast_get_domain_exists(k_current_get(), ret, | ||
| ALIGN_UP(size, CONFIG_MM_DRV_PAGE_SIZE))) { | ||
| LOG_DBG("grant access to thread %p first was %p", k_current_get(), | ||
| entry->thread); | ||
| int err = fast_get_access_grant(k_current_get(), ret, size); | ||
| if (mdom != entry->mdom && | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't really understand the purpose of this check. The entry allocation together with the If the same module instance calls
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe just checking for "partition exists" would be enough, but this would be an optimisation, we can optimise it later. |
||
| !fast_get_partition_exists(k_current_get(), ret, | ||
| ALIGN_UP(size, CONFIG_MM_DRV_PAGE_SIZE))) { | ||
| LOG_DBG("grant access to domain %p first was %p", mdom, | ||
| entry->mdom); | ||
|
|
||
| int err = fast_get_access_grant(mdom, ret, size); | ||
|
|
||
| if (err < 0) { | ||
| LOG_ERR("failed to grant additional access err=%d", err); | ||
|
|
@@ -228,10 +234,10 @@ const void *fast_get(struct k_heap *heap, const void *dram_ptr, size_t size) | |
| dcache_writeback_region((__sparse_force void __sparse_cache *)entry->sram_ptr, size); | ||
|
|
||
| #if CONFIG_USERSPACE | ||
| entry->thread = k_current_get(); | ||
| entry->mdom = k_current_get()->mem_domain_info.mem_domain; | ||
| if (size > FAST_GET_MAX_COPY_SIZE) { | ||
| /* Otherwise we've allocated on thread's heap, so it already has access */ | ||
| int err = fast_get_access_grant(entry->thread, ret, size); | ||
| int err = fast_get_access_grant(entry->mdom, ret, size); | ||
|
|
||
| if (err < 0) { | ||
| LOG_ERR("failed to grant access err=%d", err); | ||
|
|
@@ -265,7 +271,7 @@ static struct sof_fast_get_entry *fast_put_find_entry(struct sof_fast_get_data * | |
| return NULL; | ||
| } | ||
|
|
||
| void fast_put(struct k_heap *heap, const void *sram_ptr) | ||
| void fast_put(struct k_heap *heap, struct k_mem_domain *mdom, const void *sram_ptr) | ||
| { | ||
| struct sof_fast_get_data *data = &fast_get_data; | ||
| struct sof_fast_get_entry *entry; | ||
|
|
@@ -281,7 +287,7 @@ void fast_put(struct k_heap *heap, const void *sram_ptr) | |
| entry->refcount--; | ||
|
|
||
| if (!entry->refcount) { | ||
| LOG_DBG("freeing buffer %p", entry->sram_ptr); | ||
| LOG_DBG("freeing buffer %p", sram_ptr); | ||
| sof_heap_free(heap, entry->sram_ptr); | ||
| } | ||
|
|
||
|
|
@@ -294,17 +300,16 @@ void fast_put(struct k_heap *heap, const void *sram_ptr) | |
| * Order matters: free buffer first (needs partition for cache access), | ||
| * then remove partition. | ||
| */ | ||
| if (entry->size > FAST_GET_MAX_COPY_SIZE && entry->thread) { | ||
| if (entry->size > FAST_GET_MAX_COPY_SIZE && entry->mdom && mdom) { | ||
| struct k_mem_partition part = { | ||
| .start = (uintptr_t)entry->sram_ptr, | ||
| .start = (uintptr_t)sram_ptr, | ||
| .size = ALIGN_UP(entry->size, CONFIG_MM_DRV_PAGE_SIZE), | ||
| .attr = K_MEM_PARTITION_P_RO_U_RO | XTENSA_MMU_CACHED_WB, | ||
| }; | ||
| struct k_mem_domain *domain = k_current_get()->mem_domain_info.mem_domain; | ||
|
|
||
| LOG_DBG("removing partition %p size %#zx from thread %p", | ||
| (void *)part.start, part.size, k_current_get()); | ||
| int err = k_mem_domain_remove_partition(domain, &part); | ||
| LOG_DBG("removing partition %p size %#zx memory domain %p", | ||
| (void *)part.start, part.size, mdom); | ||
| int err = k_mem_domain_remove_partition(mdom, &part); | ||
|
|
||
| if (err) | ||
| LOG_WRN("partition removal failed: %d", err); | ||
|
|
||
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 userspace proxy already stores a pointer to the memory domain in a different place. Need to distinguishing the behavior for PROXY/APPLICATION.
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.
@softwarecki is this patch breaking anything for the "thread" model? If not, I'd propose to merge it to fix the "application" model which is currently broken because of this fast-get regression. Once it's all fixed we can carefully check what we can improve