All of lore.kernel.org
 help / color / mirror / Atom feed
From: Takashi Sakamoto <o-takashi@sakamocchi.jp>
To: tiwai@suse.de
Cc: alsa-devel@alsa-project.org, clemens@ladisch.de
Subject: [PATCH] ALSA: firewire-lib: support NO_PERIOD_WAKEUP in ALSA PCM runtime
Date: Thu, 27 May 2021 21:32:53 +0900	[thread overview]
Message-ID: <20210527123253.174315-1-o-takashi@sakamocchi.jp> (raw)

Drivers of ALSA firewire stack can process packets for IT/IR context in
process context when the process operates ALSA PCM character device by
calling ioctl(2) with some requests. The ioctl requests are:

 * SNDRV_PCM_IOCTL_HWSYNC
 * SNDRV_PCM_IOCTL_SYNC_PTR
 * SNDRV_PCM_IOCTL_REWIND
 * SNDRV_PCM_IOCTL_FORWARD
 * SNDRV_PCM_IOCTL_WRITEI_FRAMES
 * SNDRV_PCM_IOCTL_READI_FRAMES
 * SNDRV_PCM_IOCTL_WRITEN_FRAMES
 * SNDRV_PCM_IOCTL_READN_FRAMES

This means that general application can process PCM frames apart from
hardware IRQ invocation, even if they are programmed by either IRQ-based
scheduling model or Timer-based scheduling model.

This commit add support for Timer-based scheduling model by allowing
PCM runtime to suppress both process wakeup per period and scheduling
hardware IRQ.

SNDRV_PCM_INFO_BATCH is obsoleted since ALSA IEC 61883-1/6 packet streaming
engine can report the number of transferred PCM frames within PCM period
boundary. The granularity equals to SYT_INTERVAL in blocking transmission.
In non-blocking transmission, it doesn't equal to SYT_INTERVAL but doesn't
exceed.

This patch is tested with PulseAudio, and --sched-model option of axfer
with fix against the issue reported at:

 * https://lore.kernel.org/alsa-devel/687f9871-7484-1370-04d1-9c968e86f72b@linux.intel.com/#r

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
---
 sound/firewire/amdtp-stream.c | 27 +++++++++++++++++++++------
 1 file changed, 21 insertions(+), 6 deletions(-)

diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c
index 68ffbc33f692..8e72e7f4c082 100644
--- a/sound/firewire/amdtp-stream.c
+++ b/sound/firewire/amdtp-stream.c
@@ -191,14 +191,13 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s,
 	unsigned int maximum_usec_per_period;
 	int err;
 
-	hw->info = SNDRV_PCM_INFO_BATCH |
-		   SNDRV_PCM_INFO_BLOCK_TRANSFER |
+	hw->info = SNDRV_PCM_INFO_BLOCK_TRANSFER |
 		   SNDRV_PCM_INFO_INTERLEAVED |
 		   SNDRV_PCM_INFO_JOINT_DUPLEX |
 		   SNDRV_PCM_INFO_MMAP |
-		   SNDRV_PCM_INFO_MMAP_VALID;
+		   SNDRV_PCM_INFO_MMAP_VALID |
+		   SNDRV_PCM_INFO_NO_PERIOD_WAKEUP;
 
-	/* SNDRV_PCM_INFO_BATCH */
 	hw->periods_min = 2;
 	hw->periods_max = UINT_MAX;
 
@@ -503,7 +502,12 @@ static void update_pcm_pointers(struct amdtp_stream *s,
 	s->pcm_period_pointer += frames;
 	if (s->pcm_period_pointer >= pcm->runtime->period_size) {
 		s->pcm_period_pointer -= pcm->runtime->period_size;
-		queue_work(system_highpri_wq, &s->period_work);
+
+		// The program in user process should periodically check the status of intermediate
+		// buffer associated to PCM substream to process PCM frames in the buffer, instead
+		// of receiving notification of period elapsed by poll wait.
+		if (!pcm->runtime->no_period_wakeup)
+			queue_work(system_highpri_wq, &s->period_work);
 	}
 }
 
@@ -949,6 +953,7 @@ static void process_rx_packets(struct fw_iso_context *context, u32 tstamp, size_
 	unsigned int event_count = s->ctx_data.rx.event_count;
 	unsigned int pkt_header_length;
 	unsigned int packets;
+	bool need_hw_irq;
 	int i;
 
 	if (s->packet_index < 0)
@@ -968,6 +973,16 @@ static void process_rx_packets(struct fw_iso_context *context, u32 tstamp, size_
 	else
 		pkt_header_length = 0;
 
+	if (s == d->irq_target) {
+		// At NO_PERIOD_WAKEUP mode, the packets for all IT/IR contexts are processed by
+		// the tasks of user process operating ALSA PCM character device by calling ioctl(2)
+		// with some requests, instead of scheduled hardware IRQ of an IT context.
+		struct snd_pcm_substream *pcm = READ_ONCE(s->pcm);
+		need_hw_irq = !pcm || !pcm->runtime->no_period_wakeup;
+	} else {
+		need_hw_irq = false;
+	}
+
 	for (i = 0; i < packets; ++i) {
 		const struct pkt_desc *desc = s->pkt_descs + i;
 		struct {
@@ -984,7 +999,7 @@ static void process_rx_packets(struct fw_iso_context *context, u32 tstamp, size_
 			event_count += desc->data_blocks;
 			if (event_count >= events_per_period) {
 				event_count -= events_per_period;
-				sched_irq = true;
+				sched_irq = need_hw_irq;
 			}
 		}
 
-- 
2.27.0


             reply	other threads:[~2021-05-27 12:34 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-05-27 12:32 Takashi Sakamoto [this message]
2021-05-28  9:07 ` [PATCH] ALSA: firewire-lib: support NO_PERIOD_WAKEUP in ALSA PCM runtime Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210527123253.174315-1-o-takashi@sakamocchi.jp \
    --to=o-takashi@sakamocchi.jp \
    --cc=alsa-devel@alsa-project.org \
    --cc=clemens@ladisch.de \
    --cc=tiwai@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.