diff options
author | millerliang <millerliang@google.com> | 2023-06-06 15:05:24 +0800 |
---|---|---|
committer | Miller Liang <millerliang@google.com> | 2023-06-08 04:50:45 +0000 |
commit | 4beb16aca994bea699e98f9e6309965486898b54 (patch) | |
tree | 92c8d84b43d2ac6a26131868efd528ed9b1d9e75 | |
parent | a6d92518e59f1b02b5238fa5a3a5c3df434d00ff (diff) | |
download | aoc-4beb16aca994bea699e98f9e6309965486898b54.tar.gz |
aoc/alsa: do not queue a work if cancel_work_sync is in progressandroid-u-beta-4_r0.7android-u-beta-4_r0.5android-u-beta-4_r0.1android-gs-tangorpro-5.10-u-beta4android-gs-raviole-5.10-u-beta4android-gs-bluejay-5.10-u-beta4
Do not queue a work if the cancel_work_sync is in progress.
Bug: 284055134
Change-Id: I7e2a5b12ccd6cc28b23f15ea65fe4d66fe379b25
Signed-off-by: millerliang <millerliang@google.com>
-rw-r--r-- | alsa/aoc_alsa.h | 1 | ||||
-rw-r--r-- | alsa/aoc_alsa_incall.c | 20 | ||||
-rw-r--r-- | alsa/aoc_alsa_pcm.c | 17 | ||||
-rw-r--r-- | alsa/aoc_alsa_voip.c | 19 |
4 files changed, 51 insertions, 6 deletions
diff --git a/alsa/aoc_alsa.h b/alsa/aoc_alsa.h index 9c3e6cb..9ebd338 100644 --- a/alsa/aoc_alsa.h +++ b/alsa/aoc_alsa.h @@ -294,6 +294,7 @@ struct aoc_alsa_stream { int entry_point_idx; /* Index of entry point, same as idx in playback */ int stream_type; /* Normal pcm, incall, mmap, hifi, compr */ int isr_type; /* timer, interrupt */ + atomic_t cancel_work_active; int channels; /* Number of channels in audio */ int params_rate; /* Sampling rate */ diff --git a/alsa/aoc_alsa_incall.c b/alsa/aoc_alsa_incall.c index 4c64ab7..72a2636 100644 --- a/alsa/aoc_alsa_incall.c +++ b/alsa/aoc_alsa_incall.c @@ -86,7 +86,20 @@ static enum hrtimer_restart aoc_incall_hifi_irq_process(struct aoc_alsa_stream * alsa_stream->pos = (consumed - alsa_stream->hw_ptr_base) % alsa_stream->buffer_size; } - schedule_work(&alsa_stream->pcm_period_work); + /* Do not queue a work if the cancel_work is active */ + if (atomic_read(&alsa_stream->cancel_work_active) > 0) + return HRTIMER_RESTART; + + if (!queue_work(system_highpri_wq, &alsa_stream->pcm_period_work)) { + wake_up(&alsa_stream->substream->runtime->sleep); + wake_up(&alsa_stream->substream->runtime->tsleep); + alsa_stream->wq_busy_count++; + + if (!(alsa_stream->wq_busy_count % 5)) + pr_warn("incall/hifi period work busy count = %d\n", + alsa_stream->wq_busy_count); + } else + alsa_stream->wq_busy_count = 0; return HRTIMER_RESTART; } @@ -183,6 +196,9 @@ static int snd_aoc_pcm_open(struct snd_soc_component *component, alsa_stream->dev = dev; alsa_stream->idx = idx; alsa_stream->stream_type = aoc_pcm_device_to_stream_type(idx); + alsa_stream->wq_busy_count = 0; + atomic_set(&alsa_stream->cancel_work_active, 0); + INIT_WORK(&alsa_stream->pcm_period_work, aoc_pcm_period_work_handler); /* Ring buffer will be flushed at prepare() before playback/capture */ @@ -244,8 +260,10 @@ static int snd_aoc_pcm_close(struct snd_soc_component *component, dev_dbg(component->dev, "name %s substream %pK", rtd->dai_link->name, substream); aoc_timer_stop_sync(alsa_stream); + atomic_set(&alsa_stream->cancel_work_active, 1); audio_free_isr(alsa_stream->dev); cancel_work_sync(&alsa_stream->pcm_period_work); + atomic_set(&alsa_stream->cancel_work_active, 0); if (mutex_lock_interruptible(&chip->audio_mutex)) { dev_err(component->dev, "ERR: interrupted while waiting for lock\n"); diff --git a/alsa/aoc_alsa_pcm.c b/alsa/aoc_alsa_pcm.c index ff2df69..2734651 100644 --- a/alsa/aoc_alsa_pcm.c +++ b/alsa/aoc_alsa_pcm.c @@ -33,8 +33,10 @@ static void free_aoc_service_work_handler(struct work_struct *work) return; aoc_timer_stop_sync(alsa_stream); + atomic_set(&alsa_stream->cancel_work_active, 1); audio_free_isr(alsa_stream->dev); cancel_work_sync(&alsa_stream->pcm_period_work); + atomic_set(&alsa_stream->cancel_work_active, 0); if (mutex_lock_interruptible(&chip->audio_mutex)) { pr_err("ERR: interrupted while waiting for lock\n"); @@ -201,15 +203,19 @@ static enum hrtimer_restart aoc_pcm_irq_process(struct aoc_alsa_stream *alsa_str alsa_stream->pos = (consumed - alsa_stream->hw_ptr_base) % alsa_stream->buffer_size; } + /* Do not queue a work if the cancel_work is active */ + if (atomic_read(&alsa_stream->cancel_work_active) > 0) + return HRTIMER_RESTART; + if (!queue_work(system_highpri_wq, &alsa_stream->pcm_period_work)) { wake_up(&alsa_stream->substream->runtime->sleep); wake_up(&alsa_stream->substream->runtime->tsleep); - alsa_stream->wq_busy_count ++; - } else { - if (alsa_stream->wq_busy_count > 5) + alsa_stream->wq_busy_count++; + + if (!(alsa_stream->wq_busy_count % 5)) pr_warn("period work busy count = %d\n", alsa_stream->wq_busy_count); + } else alsa_stream->wq_busy_count = 0; - } return HRTIMER_RESTART; } @@ -304,6 +310,7 @@ static int snd_aoc_pcm_open(struct snd_soc_component *component, alsa_stream->idx = idx; alsa_stream->stream_type = aoc_pcm_device_to_stream_type(idx); alsa_stream->wq_busy_count = 0; + atomic_set(&alsa_stream->cancel_work_active, 0); INIT_WORK(&alsa_stream->free_aoc_service_work, free_aoc_service_work_handler); INIT_WORK(&alsa_stream->pcm_period_work, aoc_pcm_period_work_handler); @@ -384,8 +391,10 @@ static int snd_aoc_pcm_close(struct snd_soc_component *component, pr_debug("%s: name %s substream %p", __func__, rtd->dai_link->name, substream); aoc_timer_stop_sync(alsa_stream); + atomic_set(&alsa_stream->cancel_work_active, 1); audio_free_isr(alsa_stream->dev); cancel_work_sync(&alsa_stream->pcm_period_work); + atomic_set(&alsa_stream->cancel_work_active, 0); if (mutex_lock_interruptible(&chip->audio_mutex)) { pr_err("ERR: interrupted while waiting for lock\n"); diff --git a/alsa/aoc_alsa_voip.c b/alsa/aoc_alsa_voip.c index a719bb6..cf98d16 100644 --- a/alsa/aoc_alsa_voip.c +++ b/alsa/aoc_alsa_voip.c @@ -85,7 +85,19 @@ static enum hrtimer_restart aoc_voip_irq_process(struct aoc_alsa_stream *alsa_st alsa_stream->pos = (consumed - alsa_stream->hw_ptr_base) % alsa_stream->buffer_size; } - schedule_work(&alsa_stream->pcm_period_work); + /* Do not queue a work if the cancel_work is active */ + if (atomic_read(&alsa_stream->cancel_work_active) > 0) + return HRTIMER_RESTART; + + if (!queue_work(system_highpri_wq, &alsa_stream->pcm_period_work)) { + wake_up(&alsa_stream->substream->runtime->sleep); + wake_up(&alsa_stream->substream->runtime->tsleep); + alsa_stream->wq_busy_count++; + + if (!(alsa_stream->wq_busy_count % 5)) + pr_warn("voip period work busy count = %d\n", alsa_stream->wq_busy_count); + } else + alsa_stream->wq_busy_count = 0; return HRTIMER_RESTART; } @@ -182,6 +194,9 @@ static int snd_aoc_pcm_open(struct snd_soc_component *component, alsa_stream->cstream = NULL; alsa_stream->dev = dev; alsa_stream->idx = idx; + alsa_stream->wq_busy_count = 0; + atomic_set(&alsa_stream->cancel_work_active, 0); + INIT_WORK(&alsa_stream->pcm_period_work, aoc_pcm_period_work_handler); /* Ring buffer will be flushed at prepare() before playback/capture */ @@ -243,8 +258,10 @@ static int snd_aoc_pcm_close(struct snd_soc_component *component, dev_dbg(component->dev, "name %s substream %pK", rtd->dai_link->name, substream); aoc_timer_stop_sync(alsa_stream); + atomic_set(&alsa_stream->cancel_work_active, 1); audio_free_isr(alsa_stream->dev); cancel_work_sync(&alsa_stream->pcm_period_work); + atomic_set(&alsa_stream->cancel_work_active, 0); if (mutex_lock_interruptible(&chip->audio_mutex)) { dev_err(component->dev, "ERR: interrupted while waiting for lock\n"); |