-
Notifications
You must be signed in to change notification settings - Fork 350
buffer: extend ability to allocate on specific heap to all functions #10719
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 | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -161,7 +161,7 @@ static void comp_buffer_free(struct sof_audio_buffer *audio_buffer) | |||||||||
|
|
||||||||||
| struct k_heap *heap = buffer->audio_buffer.heap; | ||||||||||
|
|
||||||||||
| rfree(buffer->stream.addr); | ||||||||||
| sof_heap_free(heap, buffer->stream.addr); | ||||||||||
| sof_heap_free(heap, buffer); | ||||||||||
| if (heap) { | ||||||||||
| struct dp_heap_user *mod_heap_user = container_of(heap, struct dp_heap_user, heap); | ||||||||||
|
|
@@ -254,7 +254,7 @@ struct comp_buffer *buffer_alloc(struct k_heap *heap, size_t size, uint32_t flag | |||||||||
| return NULL; | ||||||||||
| } | ||||||||||
|
|
||||||||||
| stream_addr = rballoc_align(flags, size, align); | ||||||||||
| stream_addr = sof_heap_alloc(heap, flags, size, align); | ||||||||||
| if (!stream_addr) { | ||||||||||
| tr_err(&buffer_tr, "could not alloc size = %zu bytes of flags = 0x%x", | ||||||||||
| size, flags); | ||||||||||
|
|
@@ -264,7 +264,7 @@ struct comp_buffer *buffer_alloc(struct k_heap *heap, size_t size, uint32_t flag | |||||||||
| buffer = buffer_alloc_struct(heap, stream_addr, size, flags, is_shared); | ||||||||||
| if (!buffer) { | ||||||||||
| tr_err(&buffer_tr, "could not alloc buffer structure"); | ||||||||||
| rfree(stream_addr); | ||||||||||
| sof_heap_free(heap, stream_addr); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| return buffer; | ||||||||||
|
|
@@ -292,7 +292,7 @@ struct comp_buffer *buffer_alloc_range(struct k_heap *heap, size_t preferred_siz | |||||||||
| preferred_size += minimum_size - preferred_size % minimum_size; | ||||||||||
|
|
||||||||||
| for (size = preferred_size; size >= minimum_size; size -= minimum_size) { | ||||||||||
| stream_addr = rballoc_align(flags, size, align); | ||||||||||
| stream_addr = sof_heap_alloc(heap, flags, size, align); | ||||||||||
| if (stream_addr) | ||||||||||
| break; | ||||||||||
| } | ||||||||||
|
|
@@ -308,7 +308,7 @@ struct comp_buffer *buffer_alloc_range(struct k_heap *heap, size_t preferred_siz | |||||||||
| buffer = buffer_alloc_struct(heap, stream_addr, size, flags, is_shared); | ||||||||||
| if (!buffer) { | ||||||||||
| tr_err(&buffer_tr, "could not alloc buffer structure"); | ||||||||||
| rfree(stream_addr); | ||||||||||
| sof_heap_free(heap, stream_addr); | ||||||||||
| } | ||||||||||
|
|
||||||||||
| return buffer; | ||||||||||
|
|
@@ -341,14 +341,8 @@ int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignmen | |||||||||
| if (size == audio_stream_get_size(&buffer->stream)) | ||||||||||
| return 0; | ||||||||||
|
|
||||||||||
|
||||||||||
| if (!alignment) | |
| alignment = PLATFORM_DCACHE_ALIGN; |
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 same semantics are now implemented by sof_heap_alloc() so 0 can be passed forward to it.
Copilot
AI
Apr 23, 2026
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.
In buffer_set_size_range(), alignment is forwarded directly to sof_heap_alloc(). When alignment==0, earlier code used rbrealloc() (i.e., PLATFORM_DCACHE_ALIGN via the rbrealloc wrapper). To avoid potentially allocating buffers with weaker-than-expected alignment, consider normalizing alignment==0 to PLATFORM_DCACHE_ALIGN (or the stream’s current alignment) before the allocation loop.
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.
sof_heap_alloc() implements these semantics for alignment==0, so no need to add a special case for PLATFORM_DCACHE_ALIGN here.
Copilot
AI
Apr 23, 2026
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.
buffer_set_size_range(): the resize loop decrements new_size until it drops below minimum_size. If all allocations fail, new_ptr stays NULL and new_size will end up < minimum_size (often 0), but the function later calls buffer_init_stream(buffer, new_size). That can set an invalid size despite the earlier validation. Consider handling the “no allocation succeeded” case explicitly: for grow requests return -ENOMEM without changing the stream; for shrink requests skip allocating a new block and just set the stream size to the chosen target (>= minimum_size).
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.
Fixed in V2.
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.
Why is this step needed? Is it for the extra alignment as the comment in 380 line says?
/* Align preferred size to a multiple of the minimum size */
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.
Right, I was struggling with this one as well. As far as I understand the old code, this was a bug in the old code. If the allocation fails (so new_ptr==NULL), but the old allocation is still bigger than the last allocation attempted, the old implementation would set the buffer size to a value that is smaller than what the user asked, but also smaller than what is actually allocated.
This seems wrong, so I'm setting new size to the minimum user asked.
Other alternative would be to set the size of the actual size (allocated).
Not sure which is best (and/or least confusing).
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.
but for the alternative you probably would need to adjust the actual size to meet the mentioned "extra alignment"... and still this is only fallback for the initial allocation failure so I would't bother... better option would be to have a proper realloc function.
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.
it seems to me that instead of "adding an ability to specify a heap" this commit moves the actual data buffer allocations to the common module heap (when used) instead of using VMH? Wouldn't it be better to directly move this allocation to vregions? Potentially after #10702 is merged?
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.
@lyakh True, although it's arguably less confusing to use the heap one passes to buffer_alloc(). But I'm ok to sequencing options and can wait for vregions.