Skip to content

Commit f5043e6

Browse files
recallmenotgregkh
authored andcommitted
Revert "ALSA: firewire-lib: operate for period elapse event in process context"
commit 3dab73a upstream. Commit 7ba5ca3 ("ALSA: firewire-lib: operate for period elapse event in process context") removed the process context workqueue from amdtp_domain_stream_pcm_pointer() and update_pcm_pointers() to remove its overhead. With RME Fireface 800, this lead to a regression since Kernels 5.14.0, causing an AB/BA deadlock competition for the substream lock with eventual system freeze under ALSA operation: thread 0: * (lock A) acquire substream lock by snd_pcm_stream_lock_irq() in snd_pcm_status64() * (lock B) wait for tasklet to finish by calling tasklet_unlock_spin_wait() in tasklet_disable_in_atomic() in ohci_flush_iso_completions() of ohci.c thread 1: * (lock B) enter tasklet * (lock A) attempt to acquire substream lock, waiting for it to be released: snd_pcm_stream_lock_irqsave() in snd_pcm_period_elapsed() in update_pcm_pointers() in process_ctx_payloads() in process_rx_packets() of amdtp-stream.c ? tasklet_unlock_spin_wait </NMI> <TASK> ohci_flush_iso_completions firewire_ohci amdtp_domain_stream_pcm_pointer snd_firewire_lib snd_pcm_update_hw_ptr0 snd_pcm snd_pcm_status64 snd_pcm ? native_queued_spin_lock_slowpath </NMI> <IRQ> _raw_spin_lock_irqsave snd_pcm_period_elapsed snd_pcm process_rx_packets snd_firewire_lib irq_target_callback snd_firewire_lib handle_it_packet firewire_ohci context_tasklet firewire_ohci Restore the process context work queue to prevent deadlock AB/BA deadlock competition for ALSA substream lock of snd_pcm_stream_lock_irq() in snd_pcm_status64() and snd_pcm_stream_lock_irqsave() in snd_pcm_period_elapsed(). revert commit 7ba5ca3 ("ALSA: firewire-lib: operate for period elapse event in process context") Replace inline description to prevent future deadlock. Cc: stable@vger.kernel.org Fixes: 7ba5ca3 ("ALSA: firewire-lib: operate for period elapse event in process context") Reported-by: edmund.raile <edmund.raile@proton.me> Closes: https://lore.kernel.org/r/kwryofzdmjvzkuw6j3clftsxmoolynljztxqwg76hzeo4simnl@jn3eo7pe642q/ Signed-off-by: Edmund Raile <edmund.raile@protonmail.com> Reviewed-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/20240730195318.869840-3-edmund.raile@protonmail.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
1 parent 5f8a5a1 commit f5043e6

File tree

1 file changed

+9
-14
lines changed

1 file changed

+9
-14
lines changed

sound/firewire/amdtp-stream.c

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -615,16 +615,8 @@ static void update_pcm_pointers(struct amdtp_stream *s,
615615
// The program in user process should periodically check the status of intermediate
616616
// buffer associated to PCM substream to process PCM frames in the buffer, instead
617617
// of receiving notification of period elapsed by poll wait.
618-
if (!pcm->runtime->no_period_wakeup) {
619-
if (in_softirq()) {
620-
// In software IRQ context for 1394 OHCI.
621-
snd_pcm_period_elapsed(pcm);
622-
} else {
623-
// In process context of ALSA PCM application under acquired lock of
624-
// PCM substream.
625-
snd_pcm_period_elapsed_under_stream_lock(pcm);
626-
}
627-
}
618+
if (!pcm->runtime->no_period_wakeup)
619+
queue_work(system_highpri_wq, &s->period_work);
628620
}
629621
}
630622

@@ -1866,11 +1858,14 @@ unsigned long amdtp_domain_stream_pcm_pointer(struct amdtp_domain *d,
18661858
{
18671859
struct amdtp_stream *irq_target = d->irq_target;
18681860

1869-
// Process isochronous packets queued till recent isochronous cycle to handle PCM frames.
18701861
if (irq_target && amdtp_stream_running(irq_target)) {
1871-
// In software IRQ context, the call causes dead-lock to disable the tasklet
1872-
// synchronously.
1873-
if (!in_softirq())
1862+
// use wq to prevent AB/BA deadlock competition for
1863+
// substream lock:
1864+
// fw_iso_context_flush_completions() acquires
1865+
// lock by ohci_flush_iso_completions(),
1866+
// amdtp-stream process_rx_packets() attempts to
1867+
// acquire same lock by snd_pcm_elapsed()
1868+
if (current_work() != &s->period_work)
18741869
fw_iso_context_flush_completions(irq_target->context);
18751870
}
18761871

0 commit comments

Comments
 (0)