mirror of https://github.com/thesofproject/sof.git
ipc: fix buffer cache handling during freeing
Both IPC3 and IPC4 stream termination paths use uncached buffer addresses, which can contain stale data with core-local buffers. Fix both to use cached buffer aliases. Signed-off-by: Guennadi Liakhovetski <guennadi.liakhovetski@linux.intel.com>
This commit is contained in:
parent
9ead82e1b8
commit
566415e642
|
@ -472,6 +472,7 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id)
|
|||
unsigned int core;
|
||||
bool sink_active = false;
|
||||
bool source_active = false;
|
||||
struct comp_buffer __sparse_cache *buffer_c;
|
||||
|
||||
/* check whether buffer exists */
|
||||
ibd = ipc_get_comp_by_id(ipc, buffer_id);
|
||||
|
@ -489,6 +490,8 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id)
|
|||
if (!cpu_is_me(ibd->core))
|
||||
return ipc_process_on_core(ibd->core, false);
|
||||
|
||||
buffer_c = buffer_acquire(ibd->cb);
|
||||
|
||||
/* try to find sink/source components to check if they still exists */
|
||||
list_for_item(clist, &ipc->comp_list) {
|
||||
icd = container_of(clist, struct ipc_comp_dev, list);
|
||||
|
@ -496,19 +499,21 @@ int ipc_buffer_free(struct ipc *ipc, uint32_t buffer_id)
|
|||
continue;
|
||||
|
||||
/* check comp state if sink and source are valid */
|
||||
if (ibd->cb->sink == icd->cd &&
|
||||
ibd->cb->sink->state != COMP_STATE_READY) {
|
||||
sink = ibd->cb->sink;
|
||||
if (buffer_c->sink == icd->cd &&
|
||||
buffer_c->sink->state != COMP_STATE_READY) {
|
||||
sink = buffer_c->sink;
|
||||
sink_active = true;
|
||||
}
|
||||
|
||||
if (ibd->cb->source == icd->cd &&
|
||||
ibd->cb->source->state != COMP_STATE_READY) {
|
||||
source = ibd->cb->source;
|
||||
if (buffer_c->source == icd->cd &&
|
||||
buffer_c->source->state != COMP_STATE_READY) {
|
||||
source = buffer_c->source;
|
||||
source_active = true;
|
||||
}
|
||||
}
|
||||
|
||||
buffer_release(buffer_c);
|
||||
|
||||
/*
|
||||
* A buffer could be connected to 2 different pipelines. When one pipeline is freed, the
|
||||
* buffer comp that belongs in this pipeline will need to be freed even when the other
|
||||
|
|
|
@ -349,10 +349,13 @@ int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
|
|||
|
||||
buffer_id = IPC4_COMP_ID(bu->extension.r.src_queue, bu->extension.r.dst_queue);
|
||||
list_for_item(sink_list, &src->bsink_list) {
|
||||
struct comp_buffer *buf;
|
||||
struct comp_buffer *buf = container_of(sink_list, struct comp_buffer, source_list);
|
||||
struct comp_buffer __sparse_cache *buf_c = buffer_acquire(buf);
|
||||
bool found = buf_c->id == buffer_id;
|
||||
|
||||
buf = container_of(sink_list, struct comp_buffer, source_list);
|
||||
if (buf->id == buffer_id) {
|
||||
buffer_release(buf_c);
|
||||
|
||||
if (found) {
|
||||
buffer = buf;
|
||||
break;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue