Skip to content

Commit 48f30a3

Browse files
author
Yu-Hsuan Hsu
committed
ASoC: SOF: Use high-priority workqueue for PCM period elapsed
The snd_sof_pcm_period_elapsed function currently schedules work on the system-wide workqueue. This can lead to potential delays or jitter in audio processing if the system workqueue is busy with other tasks. To improve real-time performance and ensure timely processing of PCM periods, create a dedicated high-priority, unbound workqueue ("sof_pcm_wq") specifically for this purpose. Update the period elapsed handling to queue work onto this new workqueue, while maintaining a fallback to the system workqueue if the dedicated one is not initialized. Signed-off-by: Yu-Hsuan Hsu <yuhsuan@google.com>
1 parent 58baae7 commit 48f30a3

3 files changed

Lines changed: 21 additions & 1 deletion

File tree

sound/soc/sof/core.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -696,6 +696,12 @@ int snd_sof_device_probe(struct device *dev, struct snd_sof_pdata *plat_data)
696696
mutex_init(&sdev->client_event_handler_mutex);
697697
mutex_init(&sdev->dsp_fw_boot_mutex);
698698

699+
/* Create high-priority workqueue for PCM period elapsed work */
700+
sdev->pcm_period_wq = alloc_workqueue("sof_pcm_wq", WQ_HIGHPRI | WQ_UNBOUND, 0);
701+
if (!sdev->pcm_period_wq) {
702+
dev_err(dev, "error: failed to create sof_pcm_wq\n");
703+
}
704+
699705
/* set default timeouts if none provided */
700706
if (plat_data->desc->ipc_timeout == 0)
701707
sdev->ipc_timeout = TIMEOUT_DEFAULT_IPC_MS;
@@ -797,6 +803,12 @@ int snd_sof_device_remove(struct device *dev)
797803
/* release firmware */
798804
snd_sof_fw_unload(sdev);
799805

806+
/* Destroy the PCM workqueue */
807+
if (sdev->pcm_period_wq) {
808+
destroy_workqueue(sdev->pcm_period_wq);
809+
sdev->pcm_period_wq = NULL;
810+
}
811+
800812
return 0;
801813
}
802814
EXPORT_SYMBOL(snd_sof_device_remove);

sound/soc/sof/pcm.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream)
4545
struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream);
4646
struct snd_soc_component *component =
4747
snd_soc_rtdcom_lookup(rtd, SOF_AUDIO_PCM_DRV_NAME);
48+
struct snd_sof_dev *sdev = snd_soc_component_get_drvdata(component);
4849
struct snd_sof_pcm *spcm;
4950

5051
spcm = snd_sof_find_spcm_dai(component, rtd);
@@ -62,7 +63,12 @@ void snd_sof_pcm_period_elapsed(struct snd_pcm_substream *substream)
6263
* To avoid sending IPC before the previous IPC is handled, we
6364
* schedule delayed work here to call the snd_pcm_period_elapsed().
6465
*/
65-
schedule_work(&spcm->stream[substream->stream].period_elapsed_work);
66+
if (sdev->pcm_period_wq) {
67+
queue_work(sdev->pcm_period_wq, &spcm->stream[substream->stream].period_elapsed_work);
68+
} else {
69+
// Fallback to system workqueue
70+
schedule_work(&spcm->stream[substream->stream].period_elapsed_work);
71+
}
6672
}
6773
EXPORT_SYMBOL(snd_sof_pcm_period_elapsed);
6874

sound/soc/sof/sof-priv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -701,6 +701,8 @@ struct snd_sof_dev {
701701
/* used to store the FW filename and path passed from userspace for DSP ops testing */
702702
struct sof_loadable_file_profile test_profile;
703703

704+
struct workqueue_struct *pcm_period_wq; /* WQ for PCM period elapsed */
705+
704706
void *private; /* core does not touch this */
705707
};
706708

0 commit comments

Comments
 (0)