[alsa-devel] [PATCH 3/3] ALSA: pcm: conditionally avoid mmap of control data
Takashi Sakamoto
o-takashi at sakamocchi.jp
Tue May 16 12:55:09 CEST 2017
On May 16 2017 16:02, Takashi Iwai wrote:
> On Tue, 16 May 2017 08:54:17 +0200,
> Takashi Sakamoto wrote:
>>
>> On May 16 2017 15:34, Takashi Iwai wrote:
>>>>> IIRC, the problem isn't about the forward / rewind but about the
>>>>> normal data transfer. In mmap mode, we transfer data on the mmap
>>>>> buffer, and update appl_ptr via mmap control. Both are done without
>>>>> notification to the driver (which is intentional for avoiding the
>>>>> context switching).
>>>>>
>>>>> So we want to disable this optimization and always notify to the
>>>>> driver. Disabling mmap status/control is the straight hack as it
>>>>> falls back to ioctl and then the driver can know the change.
>>>>
>>>> There's SNDRV_PCM_IOCTL_HW_SYNC command. In kernel land
>>>> implementation, this command is handled with a call of 'struct
>>>> snd_pcm_ops.pointer'.
>>>>
>>>> In alsa-lib, this command is often executed in most cases to handle
>>>> PCM frames.
>>>
>>> The HWSYNC or SYNC_PTR ioctls are used only as the fallback when mmap
>>> failed. It's the exact goal of this patch :)
>>
>> Although SYNC_PTR is in the fallback mechanism of alsa-lib, HWSYNC is
>> not in.
>>
>> (alsa-lib)
>> ioctl(SNDRV_PCM_IOCTL_HWSYNC)
>> <-snd_pcm_hw_hw_sync()
>> = struct snd_pcm_fast_ops.hwsync
>> <-__snd_pcm_hw_hwsync()
>> <-snd_pcm_hwsync()
>> <-snd_pcm_avail()
>> <-snd_pcm_read_areas()
>> <-snd_pcm_mmap_readi()
>> <-snd_pcm_mmap_readn()
>> <-snd_pcm_avail_delay()
>> <-snd_pcm_write_areas()
>> <-snd_pcm_mmap_writei()
>> <-snd_pcm_mmap_writen()
>>
>> For a case that applications execute ioctl(2) with
>> SNDRV_PCM_IOCTL_READN/READI/WRITEN/WRITEI, in kernel land
>> snd_pcm_lib_read1()/snd_pcm_lib_write1() should have calls of 'struct
>> snd_pcm_ops.pointer', I think.
>
> It's about the less-optimized code path with snd_pcm_mmap_read/write.
> For the code path calling snd_pcm_mmap_begin() /
> snd_pcm_mmap_commit(), there is no hwsync ioctl call.
Indeed. I recalled it from my memory just after posting the previous
message. In a case of the fallback, ioctl(2) with SYNC_PTR is surely
executed:
ioctl(SNDRV_PCM_IOCTL_SYNC_PTR)
<-snd_pcm_hw_hw_mmap_commit)
= struct snd_pcm_fast_ops.mmap_commit()
<-__snd_pcm_mmap_commit()
<-snd_pcm_mmap_commit()
Now I agreed with the aim of this patch. In alsa-lib, 0 is passed as a
'flags' option to ioctl(2) with SYNC_PTR in the call of
snd_pcm_mmap_commit(). In kernel land, overhead to handle the ioctl is
lighter than HWSYNC because hwptr is not synchronized.
However, in my opinion, disabling mmap the status and control data is
exaggerated to the aim. SYNC_PTR ioctl is still available when page
frame of these data is mapped. I can assume an idea to take alsa-lib to
execute this command in snd_pcm_mmap_commit() when the NO_REWIND flag is
enabled. Here, I assume that the flag and SYNC_PTR are tight coupling.
(but we should concern about backward compatibility of relevant stuffs...)
By the way, at present, I think that this patchset may also be
convenient to IEC 611883-1/6 engine and drivers in ALSA firewire stack.
The engine is programmed to execute packetization in both of irq context
of OHCI1394 isochronous context and process context of HWSYNC, to reduce
packetization delay for PCM data substream. However, to the process
context, this design expects applications to call ioctl(2) periodically
with some commands; e.g. HWSYNC. As Iwai-san said, this ioctl command is
not executed in snd_pcm_mmap_begin()/snd_pcm_mmap_commit() loop and I
had concerns about it. (For example, PulseAudio is programmed to execute
snd_pcm_avail() in the loop, but jackd isn't.) But I forgot it, oops :p
Thanks
Takashi Sakamoto
More information about the Alsa-devel
mailing list