From 99921ec67dcdaeb5a5cc503f23ea2b5b6ff380ae Mon Sep 17 00:00:00 2001 From: Takashi Sakamoto Date: Fri, 18 Oct 2019 00:54:23 +0900 Subject: ALSA: firewire-lib: tune the maximum available size of PCM period Linux driver for 1394 OHCI controller voluntarily flushes isoc context when total size of accumulated context header reached PAGE_SIZE. This kicks tasklet for the isoc context. This is inconvenient to process runtime of PCM substream. This commit adds a restriction of the maximum size of PCM period to avoid this behaviour. Signed-off-by: Takashi Sakamoto Link: https://lore.kernel.org/r/20191017155424.885-12-o-takashi@sakamocchi.jp Signed-off-by: Takashi Iwai --- sound/firewire/amdtp-stream.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) (limited to 'sound/firewire') diff --git a/sound/firewire/amdtp-stream.c b/sound/firewire/amdtp-stream.c index fd7c3e4d5374..8a7818130382 100644 --- a/sound/firewire/amdtp-stream.c +++ b/sound/firewire/amdtp-stream.c @@ -176,6 +176,8 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, struct snd_pcm_runtime *runtime) { struct snd_pcm_hardware *hw = &runtime->hw; + unsigned int ctx_header_size; + unsigned int maximum_usec_per_period; int err; hw->info = SNDRV_PCM_INFO_BATCH | @@ -196,19 +198,24 @@ int amdtp_stream_add_pcm_hw_constraints(struct amdtp_stream *s, hw->period_bytes_max = hw->period_bytes_min * 2048; hw->buffer_bytes_max = hw->period_bytes_max * hw->periods_min; - /* - * Currently firewire-lib processes 16 packets in one software - * interrupt callback. This equals to 2msec but actually the - * interval of the interrupts has a jitter. - * Additionally, even if adding a constraint to fit period size to - * 2msec, actual calculated frames per period doesn't equal to 2msec, - * depending on sampling rate. - * Anyway, the interval to call snd_pcm_period_elapsed() cannot 2msec. - * Here let us use 5msec for safe period interrupt. - */ + // Linux driver for 1394 OHCI controller voluntarily flushes isoc + // context when total size of accumulated context header reaches + // PAGE_SIZE. This kicks tasklet for the isoc context and brings + // callback in the middle of scheduled interrupts. + // Although AMDTP streams in the same domain use the same events per + // IRQ, use the largest size of context header between IT/IR contexts. + // Here, use the value of context header in IR context is for both + // contexts. + if (!(s->flags & CIP_NO_HEADER)) + ctx_header_size = IR_CTX_HEADER_SIZE_CIP; + else + ctx_header_size = IR_CTX_HEADER_SIZE_NO_CIP; + maximum_usec_per_period = USEC_PER_SEC * PAGE_SIZE / + CYCLES_PER_SECOND / ctx_header_size; + err = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_PERIOD_TIME, - 5000, UINT_MAX); + 5000, maximum_usec_per_period); if (err < 0) goto end; -- cgit v1.2.3