Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 0 additions & 23 deletions posix/include/rtos/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,29 +97,6 @@ static inline void *rballoc(uint32_t flags, size_t bytes)
return rballoc_align(flags, bytes, PLATFORM_DCACHE_ALIGN);
}

/**
* Changes size of the memory block allocated.
* @param ptr Address of the block to resize.
* @param flags Flags, see SOF_MEM_FLAG_...
* @param bytes New size in bytes.
* @param old_bytes Old size in bytes.
* @param alignment Alignment in bytes.
* @return Pointer to the resized memory of NULL if failed.
*/
void *rbrealloc_align(void *ptr, uint32_t flags, size_t bytes,
size_t old_bytes, uint32_t alignment);

/**
* Similar to rballoc_align(), returns resized buffer aligned to
* PLATFORM_DCACHE_ALIGN.
*/
static inline void *rbrealloc(void *ptr, uint32_t flags,
size_t bytes, size_t old_bytes)
{
return rbrealloc_align(ptr, flags, bytes, old_bytes,
PLATFORM_DCACHE_ALIGN);
}

/**
* Frees the memory block.
* @param ptr Pointer to the memory block.
Expand Down
121 changes: 93 additions & 28 deletions src/audio/buffers/comp_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,16 @@ static void comp_buffer_free(struct sof_audio_buffer *audio_buffer)

struct mod_alloc_ctx *alloc = buffer->audio_buffer.alloc;

#ifdef CONFIG_SOF_USERSPACE_LL
assert(alloc);
if (alloc->vreg)
vregion_free(alloc->vreg, buffer->stream.addr);
else
sof_heap_free(alloc->heap, buffer->stream.addr);
#else
rfree(buffer->stream.addr);
#endif

if (alloc && alloc->vreg) {
vregion_free(alloc->vreg, buffer);
if (!vregion_put(alloc->vreg))
Expand Down Expand Up @@ -254,7 +263,15 @@ struct comp_buffer *buffer_alloc(struct mod_alloc_ctx *alloc, size_t size, uint3
return NULL;
}

#ifdef CONFIG_SOF_USERSPACE_LL
assert(alloc);
if (alloc->vreg)
stream_addr = vregion_alloc_align(alloc->vreg, VREGION_MEM_TYPE_INTERIM, size, align);
else
stream_addr = sof_heap_alloc(alloc->heap, flags, size, align);
#else
stream_addr = rballoc_align(flags, size, align);
#endif
if (!stream_addr) {
tr_err(&buffer_tr, "could not alloc size = %zu bytes of flags = 0x%x",
size, flags);
Expand All @@ -264,7 +281,15 @@ struct comp_buffer *buffer_alloc(struct mod_alloc_ctx *alloc, size_t size, uint3
buffer = buffer_alloc_struct(alloc, stream_addr, size, flags, is_shared);
if (!buffer) {
tr_err(&buffer_tr, "could not alloc buffer structure");
#ifdef CONFIG_SOF_USERSPACE_LL
assert(alloc);
if (alloc->vreg)
vregion_free(alloc->vreg, stream_addr);
else
sof_heap_free(alloc->heap, stream_addr);
#else
rfree(stream_addr);
#endif
}

return buffer;
Expand Down Expand Up @@ -292,7 +317,15 @@ struct comp_buffer *buffer_alloc_range(struct mod_alloc_ctx *alloc, size_t prefe
preferred_size += minimum_size - preferred_size % minimum_size;

for (size = preferred_size; size >= minimum_size; size -= minimum_size) {
#ifdef CONFIG_SOF_USERSPACE_LL
assert(alloc);
if (alloc->vreg)
stream_addr = vregion_alloc_align(alloc->vreg, VREGION_MEM_TYPE_INTERIM, size, align);
else
stream_addr = sof_heap_alloc(alloc->heap, flags, size, align);
#else
stream_addr = rballoc_align(flags, size, align);
#endif
if (stream_addr)
break;
}
Expand All @@ -308,7 +341,15 @@ struct comp_buffer *buffer_alloc_range(struct mod_alloc_ctx *alloc, size_t prefe
buffer = buffer_alloc_struct(alloc, stream_addr, size, flags, is_shared);
if (!buffer) {
tr_err(&buffer_tr, "could not alloc buffer structure");
#ifdef CONFIG_SOF_USERSPACE_LL
assert(alloc);
if (alloc->vreg)
vregion_free(alloc->vreg, stream_addr);
else
sof_heap_free(alloc->heap, stream_addr);
#else
rfree(stream_addr);
#endif
}

return buffer;
Expand All @@ -329,6 +370,9 @@ void buffer_zero(struct comp_buffer *buffer)
int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignment)
{
void *new_ptr = NULL;
#ifdef CONFIG_SOF_USERSPACE_LL
struct mod_alloc_ctx *alloc = buffer->audio_buffer.alloc;
#endif

CORE_CHECK_STRUCT(&buffer->audio_buffer);

Expand All @@ -341,14 +385,16 @@ int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignmen
if (size == audio_stream_get_size(&buffer->stream))
return 0;

Copy link

Copilot AI Apr 23, 2026

Choose a reason for hiding this comment

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

In buffer_set_size(), when callers pass alignment==0 (e.g. module_adapter.c and copier_ipcgtw.c do), this now forwards 0 to sof_heap_alloc(). Previously the alignment==0 path used rbrealloc() which implicitly aligned to PLATFORM_DCACHE_ALIGN. To preserve behavior and avoid potentially invalid/insufficient alignment from the underlying heap, map alignment==0 to PLATFORM_DCACHE_ALIGN (or to audio_stream_get_align()/existing stream alignment) before calling sof_heap_alloc().

Suggested change
if (!alignment)
alignment = PLATFORM_DCACHE_ALIGN;

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

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.

if (!alignment)
new_ptr = rbrealloc(audio_stream_get_addr(&buffer->stream),
buffer->flags | SOF_MEM_FLAG_NO_COPY,
size, audio_stream_get_size(&buffer->stream));
#ifdef CONFIG_SOF_USERSPACE_LL
assert(alloc);
if (alloc->vreg)
new_ptr = vregion_alloc_align(alloc->vreg, VREGION_MEM_TYPE_INTERIM, size, alignment);
else
new_ptr = rbrealloc_align(audio_stream_get_addr(&buffer->stream),
buffer->flags | SOF_MEM_FLAG_NO_COPY, size,
audio_stream_get_size(&buffer->stream), alignment);
new_ptr = sof_heap_alloc(alloc->heap, buffer->flags, size, alignment);
#else
new_ptr = rballoc_align(buffer->flags, size, alignment);
#endif

/* we couldn't allocate bigger chunk */
if (!new_ptr && size > audio_stream_get_size(&buffer->stream)) {
buf_err(buffer, "resize can't alloc %u bytes of flags 0x%x",
Expand All @@ -357,8 +403,18 @@ int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignmen
}

/* use bigger chunk, else just use the old chunk but set smaller */
if (new_ptr)
buffer->stream.addr = new_ptr;
if (new_ptr) {
#ifdef CONFIG_SOF_USERSPACE_LL
assert(alloc);
if (alloc->vreg)
vregion_free(alloc->vreg, audio_stream_get_addr(&buffer->stream));
else
sof_heap_free(alloc->heap, audio_stream_get_addr(&buffer->stream));
#else
rfree(audio_stream_get_addr(&buffer->stream));
#endif
audio_stream_set_addr(&buffer->stream, new_ptr);
}

buffer_init_stream(buffer, size);

Expand All @@ -368,10 +424,12 @@ int buffer_set_size(struct comp_buffer *buffer, uint32_t size, uint32_t alignmen
int buffer_set_size_range(struct comp_buffer *buffer, size_t preferred_size, size_t minimum_size,
uint32_t alignment)
{
void *ptr = audio_stream_get_addr(&buffer->stream);
const size_t actual_size = audio_stream_get_size(&buffer->stream);
void *new_ptr = NULL;
size_t new_size;
#ifdef CONFIG_SOF_USERSPACE_LL
struct mod_alloc_ctx *alloc = buffer->audio_buffer.alloc;
#endif

CORE_CHECK_STRUCT(&buffer->audio_buffer);

Expand All @@ -389,22 +447,19 @@ int buffer_set_size_range(struct comp_buffer *buffer, size_t preferred_size, siz
if (preferred_size == actual_size)
return 0;

if (!alignment) {
for (new_size = preferred_size; new_size >= minimum_size;
new_size -= minimum_size) {
new_ptr = rbrealloc(ptr, buffer->flags | SOF_MEM_FLAG_NO_COPY,
new_size, actual_size);
if (new_ptr)
break;
}
} else {
for (new_size = preferred_size; new_size >= minimum_size;
new_size -= minimum_size) {
new_ptr = rbrealloc_align(ptr, buffer->flags | SOF_MEM_FLAG_NO_COPY,
new_size, actual_size, alignment);
if (new_ptr)
break;
}
for (new_size = preferred_size; new_size >= minimum_size;
new_size -= minimum_size) {
#ifdef CONFIG_SOF_USERSPACE_LL
assert(alloc);
if (alloc->vreg)
new_ptr = vregion_alloc_align(alloc->vreg, VREGION_MEM_TYPE_INTERIM, new_size, alignment);
else
new_ptr = sof_heap_alloc(alloc->heap, buffer->flags, new_size, alignment);
#else
new_ptr = rballoc_align(buffer->flags, new_size, alignment);
#endif
if (new_ptr)
break;
}
Comment on lines +450 to 463
Copy link

Copilot AI Apr 23, 2026

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).

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Fixed in V2.


/* we couldn't allocate bigger chunk */
Expand All @@ -415,8 +470,18 @@ int buffer_set_size_range(struct comp_buffer *buffer, size_t preferred_size, siz
}

/* use bigger chunk, else just use the old chunk but set smaller */
if (new_ptr)
buffer->stream.addr = new_ptr;
if (new_ptr) {
#ifdef CONFIG_SOF_USERSPACE_LL
assert(alloc);
if (alloc->vreg)
vregion_free(alloc->vreg, audio_stream_get_addr(&buffer->stream));
else
sof_heap_free(alloc->heap, audio_stream_get_addr(&buffer->stream));
#else
rfree(audio_stream_get_addr(&buffer->stream));
#endif
audio_stream_set_addr(&buffer->stream, new_ptr);
}

buffer_init_stream(buffer, new_size);

Expand Down
12 changes: 0 additions & 12 deletions src/lib/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,6 @@ void rfree(void *ptr)
free(ptr);
}

void *rbrealloc_align(void *ptr, uint32_t flags, size_t bytes,
size_t old_bytes, uint32_t alignment)
{
void *newptr = aligned_alloc(alignment, bytes);

if (!newptr)
return NULL;
memcpy(newptr, ptr, bytes > old_bytes ? old_bytes : bytes);
free(ptr);
return newptr;
}

/* TODO: all mm_pm_...() routines to be implemented for IMR storage */
uint32_t mm_pm_context_size(void)
{
Expand Down
6 changes: 0 additions & 6 deletions src/platform/library/lib/alloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,6 @@ void *rballoc_align(uint32_t flags, size_t bytes,
return malloc(bytes);
}

void *rbrealloc_align(void *ptr, uint32_t flags, size_t bytes,
size_t old_bytes, uint32_t alignment)
{
return realloc(ptr, bytes);
}

void *sof_heap_alloc(struct k_heap *heap, uint32_t flags, size_t bytes,
size_t alignment)
{
Expand Down
10 changes: 0 additions & 10 deletions test/cmocka/src/common_mocks.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,6 @@ void WEAK *rzalloc(uint32_t flags,
return calloc(bytes, 1);
}

void WEAK *rbrealloc_align(void *ptr, uint32_t flags,
size_t bytes, size_t old_bytes, uint32_t alignment)
{
(void)flags;
(void)old_bytes;
(void)alignment;

return realloc(ptr, bytes);
}

void WEAK *rmalloc_align(uint32_t flags, size_t bytes, uint32_t alignment)
{
(void)flags;
Expand Down
23 changes: 0 additions & 23 deletions zephyr/include/rtos/alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,29 +88,6 @@ static inline void *rballoc(uint32_t flags, size_t bytes)
return rballoc_align(flags, bytes, PLATFORM_DCACHE_ALIGN);
}

/**
* Changes size of the memory block allocated.
* @param ptr Address of the block to resize.
* @param flags Flags, see SOF_MEM_FLAG_...
* @param bytes New size in bytes.
* @param old_bytes Old size in bytes.
* @param alignment Alignment in bytes.
* @return Pointer to the resized memory of NULL if failed.
*/
void *rbrealloc_align(void *ptr, uint32_t flags, size_t bytes,
size_t old_bytes, uint32_t alignment);

/**
* Similar to rballoc_align(), returns resized buffer aligned to
* PLATFORM_DCACHE_ALIGN.
*/
static inline void *rbrealloc(void *ptr, uint32_t flags,
size_t bytes, size_t old_bytes)
{
return rbrealloc_align(ptr, flags, bytes, old_bytes,
PLATFORM_DCACHE_ALIGN);
}

/**
* Frees the memory block.
* @param ptr Pointer to the memory block.
Expand Down
Loading