[alsa-devel] [PATCH 1/1] ALSA: pcm: introduce ACK_APPLPTR flag and bump up interface version to 2.0.14
Takashi Sakamoto
o-takashi at sakamocchi.jp
Mon Jun 19 14:26:32 CEST 2017
On Jun 19 2017 02:15, Takashi Iwai wrote:
> On Sun, 18 Jun 2017 18:49:19 +0200,
> Takashi Sakamoto wrote:
>>
>> In a development period for v4.13, it's clear that there's a type of
>> devices which demand userspace applications to change their behaviour.
>> These devices can take care of application-side pointer on PCM buffer
>> for their data transmission. As a result, these devices achieve some
>> advantages. For these devices, drivers need to get feedback about
>> current position of the pointer from applications when they
>> queue/dequeue PCM frames on the buffer.
>>
>> When applications operates with SNDRV_PCM_IOCTL_[READ|WRITE][N|I] command
>> for ioctl(2) to transmit/receive PCM frames, the above is achieved with
>> an assist of ALSA PCM core. On the other hand, when applications run with
>> mmap operations, the above is not achieved. In this case, they should call
>> ioctl(2) with SNDRV_PCM_IOCTL_SYNC_PTR after operating any PCM frames on
>> the buffer. But existent applications are not programmed to do it.
>
> ... they are programmed to behave so, when the PCM status mmap fails.
As I said, the solution to disable mmap for status/control data has
different scope from this issue.
>> This commit adds a new flag; SNDRV_PCM_INFO_ACK_APPLPTR. When
>> applications find this flag on 'struct snd_pcm_hw_params.info', they're
>> expected to perform as the above. When programmed so, they should set
>> SNDRV_PCM_HW_PARAMS_ACK_APPLPTR flag to the structure in advance. Else,
>> they're not allowed to do mmap operation. This is for backward
>> compatibility because existent stuffs in user land don't perform like
>> the above.
>>
>> As of this type of device, digital signal processor (DSP) integrated
>> to Intel's processor is reported. The DSP can prefetch the PCM frames on
>> the buffer and go to a deep sleep mode till next awakening. The awakening
>> is done by drivers. When applications deliver information about the number
>> of handled PCM frames to a corresponding driver in kernel land, then the
>> driver calculates according to the number, then awakens the DSP from the
>> sleep.
>>
>> Additionally, there's two types of devices which potentially receive
>> advantages from this change. One is packet-oriented drivers, and another
>> is drivers with ALSA indirect layer. The former may process packets
>> immediately in process context when handling the feedback. This results
>> in reduction of audio latency. The latter may copy PCM frames in process
>> context. This results in reduction CPU time on any interrupt context.
>>
>> Anyway, this flag requires userspace applications to change their
>> behaviour. This commit bumps up interface version to v2.0.14.
>>
>> Signed-off-by: Takashi Sakamoto <o-takashi at sakamocchi.jp>
>> ---
>> include/uapi/sound/asound.h | 11 ++++++++++-
>> sound/core/pcm_native.c | 25 +++++++++++++++++++++++++
>> 2 files changed, 35 insertions(+), 1 deletion(-)
>>
>> diff --git a/include/uapi/sound/asound.h b/include/uapi/sound/asound.h
>> index fd41697cb4d3..ff7bb89e65a6 100644
>> --- a/include/uapi/sound/asound.h
>> +++ b/include/uapi/sound/asound.h
>> @@ -152,7 +152,7 @@ struct snd_hwdep_dsp_image {
>> * *
>> *****************************************************************************/
>>
>> -#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 13)
>> +#define SNDRV_PCM_VERSION SNDRV_PROTOCOL_VERSION(2, 0, 14)
>>
>> typedef unsigned long snd_pcm_uframes_t;
>> typedef signed long snd_pcm_sframes_t;
>> @@ -268,6 +268,8 @@ typedef int __bitwise snd_pcm_subformat_t;
>> #define SNDRV_PCM_INFO_MMAP_VALID 0x00000002 /* period data are valid during transfer */
>> #define SNDRV_PCM_INFO_DOUBLE 0x00000004 /* Double buffering needed for PCM start/stop */
>> #define SNDRV_PCM_INFO_BATCH 0x00000010 /* double buffering */
>> +/* Driver/hardware acknowledge current appl_ptr for specific purposes. */
>> +#define SNDRV_PCM_INFO_ACK_APPLPTR 0x00000012
>> #define SNDRV_PCM_INFO_INTERLEAVED 0x00000100 /* channels are interleaved */
>> #define SNDRV_PCM_INFO_NONINTERLEAVED 0x00000200 /* channels are not interleaved */
>> #define SNDRV_PCM_INFO_COMPLEX 0x00000400 /* complex frame organization (mmap only) */
>> @@ -365,6 +367,13 @@ typedef int snd_pcm_hw_param_t;
>> #define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */
>> #define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) /* export buffer */
>> #define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) /* disable period wakeups */
>> +/*
>> + * When applications are programmed to execute ioctl(2) with
>> + * SNDRV_PCM_IOCTL_SYNC_PTR for notification of current appl_ptr after handling
>> + * any frames on mapped PCM buffer for driver/hardware with
>> + * SNDRV_PCM_INFO_ACK_APPLPTR, this should be set.
>> + */
>> +#define SNDRV_PCM_HW_PARAMS_ACK_APPLPTR (1<<3)
>>
>> struct snd_interval {
>> unsigned int min, max;
>> diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
>> index 7e8f3656b695..48772a2bd027 100644
>> --- a/sound/core/pcm_native.c
>> +++ b/sound/core/pcm_native.c
>> @@ -249,6 +249,27 @@ static bool hw_support_mmap(struct snd_pcm_substream *substream)
>> return true;
>> }
>>
>> +static int constrain_params_with_precondition(struct snd_pcm_substream *substream,
>> + struct snd_pcm_hw_params *params)
>> +{
>> + struct snd_mask *mask;
>> +
>> + /*
>> + * When drivers require applications' cooperation to report current
>> + * appl_ptr and the applications voluntarily perform it, mmap operation
>> + * is allowed. Else, read/write operations are allowed.
>> + */
>> + if ((substream->runtime->hw.info & SNDRV_PCM_INFO_ACK_APPLPTR) &&
>> + !(params->flags & SNDRV_PCM_HW_PARAMS_ACK_APPLPTR)) {
>> + mask = hw_param_mask(params, SNDRV_PCM_HW_PARAM_ACCESS);
>> + snd_mask_reset(mask, SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
>> + snd_mask_reset(mask, SNDRV_PCM_ACCESS_MMAP_NONINTERLEAVED);
>> + snd_mask_reset(mask, SNDRV_PCM_ACCESS_MMAP_COMPLEX);
>
> Well, it's only the lack of sync_ptr, and the mmap of the ring buffer
> itself is fine. Disabling the ring-buffer mmap is a much bigger
> hammer and the significant performance penalty than disabling PCM
> control/status mmap.
No. Old stuffs don't satisfy requirements of the new devices/drivers.
Constraint to read/write operation is fair enough and not penalty
because programs are written so that they cannot assist the new
devices/drivers.
Well-programmed applications can handle a case in which mmap operation
is not allowed. This patchset is enough reasonable.
Regards
Takashi Sakamoto
More information about the Alsa-devel
mailing list