[alsa-devel] [PATCH 3/3] ALSA: pcm: Limit the appl_ptr sync workaround only for old user-space

Takashi Iwai tiwai at suse.de
Tue Jun 20 17:33:52 CEST 2017


Now that user-space (typically alsa-lib) can specify which protocol
version it supports, we can optimize the kernel code depending on the
reported protocol version.

In this patch, we change the previous hack for enforcing the appl_ptr
sync by disabling status/control mmap.  Instead of forcibly disabling,
we disable the status/control mmap selectively only when the
user-space does *not* understand the protocol.  That is, when the
user-space reports it supporting the new protocol version including
the sync appl_ptr feature, we allow the mmap like the normal case.
Then user-space is supposed to do the sync in addition to the mmap.

Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
 sound/core/pcm_native.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index df3e0303409f..3f91d5c4ed76 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -3336,6 +3336,7 @@ static const struct vm_operations_struct snd_pcm_vm_ops_status =
 static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file *file,
 			       struct vm_area_struct *area)
 {
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	long size;
 
 	/* Disallow the status/control mmap when SYNC_APPLPTR flag is set;
@@ -3344,8 +3345,12 @@ static int snd_pcm_mmap_status(struct snd_pcm_substream *substream, struct file
 	 * In theory, it should be enough to disallow only PCM control mmap,
 	 * but since the current alsa-lib implementation requires both status
 	 * and control mmaps always paired, we have to disable both of them.
+	 *
+	 * If user_pversion is 2.0.14 or greater, it implies that user-space
+	 * supports the explicit appl_ptr sync, so we still allow the mmap.
 	 */
-	if (substream->runtime->hw.info & SNDRV_PCM_INFO_SYNC_APPLPTR)
+	if (runtime->user_pversion < SNDRV_PROTOCOL_VERSION(2, 0, 14) &&
+	    (runtime->hw.info & SNDRV_PCM_INFO_SYNC_APPLPTR))
 		return -ENXIO;
 	if (!(area->vm_flags & VM_READ))
 		return -EINVAL;
@@ -3382,10 +3387,12 @@ static const struct vm_operations_struct snd_pcm_vm_ops_control =
 static int snd_pcm_mmap_control(struct snd_pcm_substream *substream, struct file *file,
 				struct vm_area_struct *area)
 {
+	struct snd_pcm_runtime *runtime = substream->runtime;
 	long size;
 
 	/* see the comment in snd_pcm_mmap_status() */
-	if (substream->runtime->hw.info & SNDRV_PCM_INFO_SYNC_APPLPTR)
+	if (runtime->user_pversion < SNDRV_PROTOCOL_VERSION(2, 0, 14) &&
+	    (runtime->hw.info & SNDRV_PCM_INFO_SYNC_APPLPTR))
 		return -ENXIO;
 	if (!(area->vm_flags & VM_READ))
 		return -EINVAL;
-- 
2.13.1



More information about the Alsa-devel mailing list