]> www.infradead.org Git - nvme.git/commitdiff
Revert "ALSA: firewire-lib: obsolete workqueue for period update"
authorEdmund Raile <edmund.raile@protonmail.com>
Tue, 30 Jul 2024 19:53:26 +0000 (19:53 +0000)
committerTakashi Iwai <tiwai@suse.de>
Wed, 31 Jul 2024 09:28:13 +0000 (11:28 +0200)
prepare resolution of AB/BA deadlock competition for substream lock:
restore workqueue previously used for process context:

revert commit b5b519965c4c ("ALSA: firewire-lib: obsolete workqueue
for period update")

Cc: stable@vger.kernel.org
Link: 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-2-edmund.raile@protonmail.com
sound/firewire/amdtp-stream.c
sound/firewire/amdtp-stream.h

index d35d0a420ee088ade28cbe3212c0e9d6d3199594..31201d506a218f6e177a32da33754af32e1d5a2b 100644 (file)
@@ -77,6 +77,8 @@
 // overrun. Actual device can skip more, then this module stops the packet streaming.
 #define IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES       5
 
+static void pcm_period_work(struct work_struct *work);
+
 /**
  * amdtp_stream_init - initialize an AMDTP stream structure
  * @s: the AMDTP stream to initialize
@@ -105,6 +107,7 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
        s->flags = flags;
        s->context = ERR_PTR(-1);
        mutex_init(&s->mutex);
+       INIT_WORK(&s->period_work, pcm_period_work);
        s->packet_index = 0;
 
        init_waitqueue_head(&s->ready_wait);
@@ -347,6 +350,7 @@ EXPORT_SYMBOL(amdtp_stream_get_max_payload);
  */
 void amdtp_stream_pcm_prepare(struct amdtp_stream *s)
 {
+       cancel_work_sync(&s->period_work);
        s->pcm_buffer_pointer = 0;
        s->pcm_period_pointer = 0;
 }
@@ -624,6 +628,16 @@ static void update_pcm_pointers(struct amdtp_stream *s,
        }
 }
 
+static void pcm_period_work(struct work_struct *work)
+{
+       struct amdtp_stream *s = container_of(work, struct amdtp_stream,
+                                             period_work);
+       struct snd_pcm_substream *pcm = READ_ONCE(s->pcm);
+
+       if (pcm)
+               snd_pcm_period_elapsed(pcm);
+}
+
 static int queue_packet(struct amdtp_stream *s, struct fw_iso_packet *params,
                        bool sched_irq)
 {
@@ -1910,6 +1924,7 @@ static void amdtp_stream_stop(struct amdtp_stream *s)
                return;
        }
 
+       cancel_work_sync(&s->period_work);
        fw_iso_context_stop(s->context);
        fw_iso_context_destroy(s->context);
        s->context = ERR_PTR(-1);
index a1ed2e80f91a7cc07fecf55288a20a240d0900da..775db3fc4959f57d006a247d5f5d6d74586a110c 100644 (file)
@@ -191,6 +191,7 @@ struct amdtp_stream {
 
        /* For a PCM substream processing. */
        struct snd_pcm_substream *pcm;
+       struct work_struct period_work;
        snd_pcm_uframes_t pcm_buffer_pointer;
        unsigned int pcm_period_pointer;
        unsigned int pcm_frame_multiplier;