-
Notifications
You must be signed in to change notification settings - Fork 325
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
DRAM: more cold functions #9850
base: main
Are you sure you want to change the base?
Conversation
Move several initialisation functions to run from DRAM directly. Signed-off-by: Guennadi Liakhovetski <[email protected]>
Mark all IPC functions as "cold" to run them directly in DRAM. Signed-off-by: Guennadi Liakhovetski <[email protected]>
I understand why init functions should go to DRAM, but why IPC? |
@marcinszkudlinski the idea is that only audio protocols are "hot" - only schedulers and audio processing threads. Everything else can be "cold" and IPC processing is one of such large code areas. But if you have concerns that this can break something, let's discuss, maybe we're overlooking some use-cases? |
@lyakh not really I think - as long as we do have enough HPSRAM, use it. |
IPC part looks really suspicious, do you have any data what is the profit and perf drop? Especially when main CPU is under high load and we will lag more with DRAM access |
HPSRAM is precious, agree need to be really careful what we put in DRAM it should only be parts of IPC that are not time critical. i.e. trigger is time critical, but load module is not time critical. We need to find this balance, Linux only really cares about prepare()/trigger() driver ops and any associated IPCs. Don't know about Windows ? |
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.
Some functions are really obvious pipeline construction/free APIs, but some utility APIs could be used in the stream triggering flow. Best to check.
@@ -197,7 +198,7 @@ int comp_buffer_connect(struct comp_dev *comp, uint32_t comp_core, | |||
return pipeline_connect(comp, buffer, dir); | |||
} | |||
|
|||
int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id) | |||
__cold int ipc_pipeline_complete(struct ipc *ipc, uint32_t comp_id) |
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.
Can you check this, not sure if done in prepare() ? maybe for IPC3 only ?
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.
@lgirdwood this is only called from
ipc4_pipeline_complete()
ipc4_pipeline_prepare()
ipc4_set_pipeline_state() idc_ppl_state()
ipc4_process_glb_message() idc_cmd()
ipc_cmd() idc_handler()
ipc_platform_do_cmd() idc_ipc() P4WQ
ipc_do_cmd() idc_cmd()
EDF scheduler idc_handler()
P4WQ
so, it's only called from the EDF scheduler or from IDC P4WQ, both of which use the EDF_ZEPHYR_PRIORITY
priority (currently 1)
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.
ok, so are you confirming its not called as part of a LL or DP process() ? I assume its only used in EDF for non process() usage.
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.
@lgirdwood correct, as it stands there don't seem to be any paths leading to this function being called from audio processing context
@lgirdwood @marcinszkudlinski @abonislawski as far as I understand the worst would be cases when we're running close to 100% performance capacity and at that moment the user is issuing some IPCs - maybe to start an additional light stream. In principle we still have a couple of free DSP cycles to run an additional stream, but while preparing it, IPC processing adds significant DSP load. So, if we process IPCs in DRAM, that processing becomes slower. As long as we don't disable interrupts during IPC processing for too long, we still shouldn't disturb higher priority audio processing, running in parallel, but IPC response time will become longer. Is that what we're worried about? Is that important? Replying to @marcinszkudlinski - do we really lose LL cycles because of IPC processing? That shouldn't happen AFAICS? If we have code, locking interrupts, we have to identify and improve it... |
Replying to @marcinszkudlinski - do we really lose LL cycles because of IPC processing? That shouldn't happen AFAICS? If we have code, locking interrupts, we have to identify and improve it... We don't lose LL cycles since LL preempts low priority workloads/threads (even if workload TEXT is in DRAM, stack/heap will be SRAM). @jsarha can you share some data soon. Thanks |
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.
Hmm, @lrgirdwo you mention in comments that " trigger is time critical, but load module is not time critical". The current PR doesn't seem to make any provision to keep trigger related code in hot memory. Not sure how to review this, is this intentional or not?
@@ -404,7 +405,7 @@ int ipc4_pipeline_prepare(struct ipc_comp_dev *ppl_icd, uint32_t cmd) | |||
return ret; | |||
} | |||
|
|||
int ipc4_pipeline_trigger(struct ipc_comp_dev *ppl_icd, uint32_t cmd, bool *delayed) | |||
__cold int ipc4_pipeline_trigger(struct ipc_comp_dev *ppl_icd, uint32_t cmd, bool *delayed) |
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.
Wasn't trigger ops supposed to be kept on the warm path?
@@ -496,15 +497,15 @@ int ipc4_pipeline_trigger(struct ipc_comp_dev *ppl_icd, uint32_t cmd, bool *dela | |||
return ret; | |||
} | |||
|
|||
static void ipc_compound_pre_start(int msg_id) | |||
__cold static void ipc_compound_pre_start(int msg_id) |
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.
Part of the trigger/start/stop set...?
{ | ||
/* ipc thread will wait for all scheduled tasks to be complete | ||
* Use a reference count to check status of these tasks. | ||
*/ | ||
atomic_add(&msg_data.delayed_reply, 1); | ||
} | ||
|
||
static void ipc_compound_post_start(uint32_t msg_id, int ret, bool delayed) | ||
__cold static void ipc_compound_post_start(uint32_t msg_id, int ret, bool delayed) |
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.
Part of the trigger/start/stop set...?
{ | ||
struct ipc4_message_request in; | ||
|
||
in.primary.dat = msg_data.msg_in.pri; | ||
ipc_compound_msg_done(in.primary.r.type, reply->error); | ||
} | ||
|
||
void ipc_cmd(struct ipc_cmd_hdr *_hdr) | ||
__cold void ipc_cmd(struct ipc_cmd_hdr *_hdr) |
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.
If we want to separate trigger/start from less timing critical IPCs, then we need to keep this top-level ipc_cmd as warm.
There is indeed some impact to MCPS at least in 44.1kHz playback trough SRC. SRC playback was chosen because its readily available on nocodec topology and SRC has a lot of __cold tagged functions in its configuration code. In addition to this PR I also merged #9844 on top of it. The test is a 5min 44.1kHz playback using the branch built with xcc using both CONFIG_COLD_STORE_EXECUTE_DRAM=n and y. It was run on LNL RVP using nocodec topology. The original mtrace files are here: |
Thanks @jsarha - there is a 20kcps delta with DRAM=y and this PR on LNL. I think the Peaks are related to L1 exit work, I think the 20kcps is due the the relocatable code used for llext. @lyakh do you concur ? |
Move all of IPC and some initialisation code to DRAM.