Commit 6ccf9984 authored by Edmund Raile's avatar Edmund Raile Committed by Takashi Iwai

Revert "ALSA: firewire-lib: obsolete workqueue for period update"

prepare resolution of AB/BA deadlock competition for substream lock:
restore workqueue previously used for process context:

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

Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/r/kwryofzdmjvzkuw6j3clftsxmoolynljztxqwg76hzeo4simnl@jn3eo7pe642q/Signed-off-by: default avatarEdmund Raile <edmund.raile@protonmail.com>
Reviewed-by: default avatarTakashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Link: https://patch.msgid.link/20240730195318.869840-2-edmund.raile@protonmail.com
parent 3c0b6f92
...@@ -77,6 +77,8 @@ ...@@ -77,6 +77,8 @@
// overrun. Actual device can skip more, then this module stops the packet streaming. // overrun. Actual device can skip more, then this module stops the packet streaming.
#define IR_JUMBO_PAYLOAD_MAX_SKIP_CYCLES 5 #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 * amdtp_stream_init - initialize an AMDTP stream structure
* @s: the AMDTP stream to initialize * @s: the AMDTP stream to initialize
...@@ -105,6 +107,7 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit, ...@@ -105,6 +107,7 @@ int amdtp_stream_init(struct amdtp_stream *s, struct fw_unit *unit,
s->flags = flags; s->flags = flags;
s->context = ERR_PTR(-1); s->context = ERR_PTR(-1);
mutex_init(&s->mutex); mutex_init(&s->mutex);
INIT_WORK(&s->period_work, pcm_period_work);
s->packet_index = 0; s->packet_index = 0;
init_waitqueue_head(&s->ready_wait); init_waitqueue_head(&s->ready_wait);
...@@ -347,6 +350,7 @@ EXPORT_SYMBOL(amdtp_stream_get_max_payload); ...@@ -347,6 +350,7 @@ EXPORT_SYMBOL(amdtp_stream_get_max_payload);
*/ */
void amdtp_stream_pcm_prepare(struct amdtp_stream *s) void amdtp_stream_pcm_prepare(struct amdtp_stream *s)
{ {
cancel_work_sync(&s->period_work);
s->pcm_buffer_pointer = 0; s->pcm_buffer_pointer = 0;
s->pcm_period_pointer = 0; s->pcm_period_pointer = 0;
} }
...@@ -624,6 +628,16 @@ static void update_pcm_pointers(struct amdtp_stream *s, ...@@ -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, static int queue_packet(struct amdtp_stream *s, struct fw_iso_packet *params,
bool sched_irq) bool sched_irq)
{ {
...@@ -1910,6 +1924,7 @@ static void amdtp_stream_stop(struct amdtp_stream *s) ...@@ -1910,6 +1924,7 @@ static void amdtp_stream_stop(struct amdtp_stream *s)
return; return;
} }
cancel_work_sync(&s->period_work);
fw_iso_context_stop(s->context); fw_iso_context_stop(s->context);
fw_iso_context_destroy(s->context); fw_iso_context_destroy(s->context);
s->context = ERR_PTR(-1); s->context = ERR_PTR(-1);
......
...@@ -191,6 +191,7 @@ struct amdtp_stream { ...@@ -191,6 +191,7 @@ struct amdtp_stream {
/* For a PCM substream processing. */ /* For a PCM substream processing. */
struct snd_pcm_substream *pcm; struct snd_pcm_substream *pcm;
struct work_struct period_work;
snd_pcm_uframes_t pcm_buffer_pointer; snd_pcm_uframes_t pcm_buffer_pointer;
unsigned int pcm_period_pointer; unsigned int pcm_period_pointer;
unsigned int pcm_frame_multiplier; unsigned int pcm_frame_multiplier;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment