Skip to content

Commit

Permalink
ipc4: Add preeption guard to bind/unbind
Browse files Browse the repository at this point in the history
This is a workaround to protect bind/unbind operations to be preempted
by LL scheduler but still enabling IDC interrupt.

Signed-off-by: Serhiy Katsyuba <[email protected]>
  • Loading branch information
serhiy-katsyuba-intel authored and marcinszkudlinski committed Sep 15, 2023
1 parent e4f2396 commit 0a8d12b
Showing 1 changed file with 19 additions and 8 deletions.
27 changes: 19 additions & 8 deletions src/ipc/ipc4/helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,15 @@ static struct comp_buffer *ipc4_create_buffer(struct comp_dev *src, struct comp_
return buffer_new(&ipc_buf);
}

/* FIXME: avoid Zephyr internal platform specific defines */
#ifdef CONFIG_SOC_SERIES_INTEL_ACE
#define lock_ll_sched(flags) irq_disable(ACE_IRQ_TO_ZEPHYR(ACE_INTL_TTS))
#define unlock_ll_sched(flags) irq_enable(ACE_IRQ_TO_ZEPHYR(ACE_INTL_TTS))
#else
#define lock_ll_sched(flags) irq_local_disable(flags)
#define unlock_ll_sched(flags) irq_local_enable(flags)
#endif

int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
{
struct ipc4_module_bind_unbind *bu;
Expand All @@ -347,6 +356,8 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
int src_id, sink_id;
int ret;

ARG_UNUSED(flags);

bu = (struct ipc4_module_bind_unbind *)_connect;
src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id);
sink_id = IPC4_COMP_ID(bu->extension.r.dst_module_id, bu->extension.r.dst_instance_id);
Expand Down Expand Up @@ -389,7 +400,7 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
source_set_ibs(audio_stream_get_source(&buffer->stream), source_src_cfg.obs);
sink_set_obs(audio_stream_get_sink(&buffer->stream), sink_src_cfg.ibs);

irq_local_disable(flags);
lock_ll_sched(flags);

ret = comp_buffer_connect(source, source->ipc_config.core, buffer,
PPL_CONN_DIR_COMP_TO_BUFFER);
Expand All @@ -407,8 +418,6 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
}

/* comp_bind() may call comp_bind_remote() and so IDC interrupt should be enabled */
irq_local_enable(flags);

ret = comp_bind(source, bu);
if (ret < 0)
goto e_src_bind;
Expand All @@ -429,17 +438,18 @@ int ipc_comp_connect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
source->direction_set = true;
}

unlock_ll_sched(flags);

return IPC4_SUCCESS;

e_sink_bind:
comp_unbind(source, bu);
e_src_bind:
irq_local_disable(flags);
pipeline_disconnect(sink, buffer, PPL_CONN_DIR_BUFFER_TO_COMP);
e_sink_connect:
pipeline_disconnect(source, buffer, PPL_CONN_DIR_COMP_TO_BUFFER);
free:
irq_local_enable(flags);
unlock_ll_sched(flags);
buffer_free(buffer);
return IPC4_INVALID_RESOURCE_STATE;
}
Expand All @@ -459,6 +469,8 @@ int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
uint32_t flags;
int ret, ret1;

ARG_UNUSED(flags);

bu = (struct ipc4_module_bind_unbind *)_connect;
src_id = IPC4_COMP_ID(bu->primary.r.module_id, bu->primary.r.instance_id);
sink_id = IPC4_COMP_ID(bu->extension.r.dst_module_id, bu->extension.r.dst_instance_id);
Expand Down Expand Up @@ -495,14 +507,13 @@ int ipc_comp_disconnect(struct ipc *ipc, ipc_pipe_comp_connect *_connect)
if (!buffer)
return IPC4_INVALID_RESOURCE_ID;

irq_local_disable(flags);
lock_ll_sched(flags);
pipeline_disconnect(src, buffer, PPL_CONN_DIR_COMP_TO_BUFFER);
pipeline_disconnect(sink, buffer, PPL_CONN_DIR_BUFFER_TO_COMP);
irq_local_enable(flags);

/* comp_unbind() may call comp_unbind_remote() and so IDC interrupt should be enabled */
ret = comp_unbind(src, bu);
ret1 = comp_unbind(sink, bu);
unlock_ll_sched(flags);

buffer_free(buffer);

Expand Down

0 comments on commit 0a8d12b

Please sign in to comment.