Skip to content

Commit 2acd83b

Browse files
chleroytiwai
authored andcommitted
ALSA: pcm: refactor copy from/to user in SNDRV_PCM_IOCTL_SYNC_PTR
In an effort of optimising SNDRV_PCM_IOCTL_SYNC_PTR ioctl which is a hot path, lets first refactor the copy from and to user with macros. This is done with macros and not static inline fonctions because types differs between the different versions of snd_pcm_sync_ptr() like functions. First step is to refactor only snd_pcm_ioctl_sync_ptr_compat() and snd_pcm_ioctl_sync_ptr_x32() as it would be a performance regression for snd_pcm_sync_ptr() and snd_pcm_ioctl_sync_ptr_buggy() for now. They may be refactored after next patch. Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Signed-off-by: Takashi Iwai <tiwai@suse.de> Link: https://patch.msgid.link/f8b77932bb9ce96148ae5c3953e7ee44fa2359f8.1749883041.git.christophe.leroy@csgroup.eu
1 parent d0630a0 commit 2acd83b

2 files changed

Lines changed: 32 additions & 24 deletions

File tree

sound/core/pcm_compat.c

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -418,9 +418,7 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
418418
if (snd_BUG_ON(!runtime))
419419
return -EINVAL;
420420

421-
if (get_user(sflags, &src->flags) ||
422-
get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
423-
get_user(scontrol.avail_min, &src->c.control.avail_min))
421+
if (snd_pcm_sync_ptr_get_user(sflags, scontrol, src))
424422
return -EFAULT;
425423
if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
426424
err = snd_pcm_hwsync(substream);
@@ -450,15 +448,7 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
450448
}
451449
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
452450
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
453-
if (put_user(sstatus.state, &src->s.status.state) ||
454-
put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
455-
put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
456-
put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp_nsec) ||
457-
put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
458-
put_user(sstatus.audio_tstamp.tv_sec, &src->s.status.audio_tstamp_sec) ||
459-
put_user(sstatus.audio_tstamp.tv_nsec, &src->s.status.audio_tstamp_nsec) ||
460-
put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
461-
put_user(scontrol.avail_min, &src->c.control.avail_min))
451+
if (snd_pcm_sync_ptr_put_user(sstatus, scontrol, src))
462452
return -EFAULT;
463453

464454
return 0;

sound/core/pcm_native.c

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3052,6 +3052,34 @@ static inline int snd_pcm_hwsync(struct snd_pcm_substream *substream)
30523052
return snd_pcm_delay(substream, NULL);
30533053
}
30543054

3055+
#define snd_pcm_sync_ptr_get_user(__f, __c, __ptr) ({ \
3056+
int __err = 0; \
3057+
typeof(*(__ptr)) __user *__src = (__ptr); \
3058+
\
3059+
if (get_user(__f, &src->flags) || \
3060+
get_user(__c.appl_ptr, &__src->c.control.appl_ptr) || \
3061+
get_user(__c.avail_min, &__src->c.control.avail_min)) \
3062+
__err = -EFAULT; \
3063+
__err; \
3064+
})
3065+
3066+
#define snd_pcm_sync_ptr_put_user(__s, __c, __ptr) ({ \
3067+
int __err = 0; \
3068+
typeof(*(__ptr)) __user *__src = (__ptr); \
3069+
\
3070+
if (put_user(__s.state, &__src->s.status.state) || \
3071+
put_user(__s.hw_ptr, &__src->s.status.hw_ptr) || \
3072+
put_user(__s.tstamp.tv_sec, &__src->s.status.tstamp_sec) || \
3073+
put_user(__s.tstamp.tv_nsec, &__src->s.status.tstamp_nsec) || \
3074+
put_user(__s.suspended_state, &__src->s.status.suspended_state) || \
3075+
put_user(__s.audio_tstamp.tv_sec, &__src->s.status.audio_tstamp_sec) || \
3076+
put_user(__s.audio_tstamp.tv_nsec, &__src->s.status.audio_tstamp_nsec) || \
3077+
put_user(__c.appl_ptr, &__src->c.control.appl_ptr) || \
3078+
put_user(__c.avail_min, &__src->c.control.avail_min)) \
3079+
__err = -EFAULT; \
3080+
__err; \
3081+
})
3082+
30553083
static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
30563084
struct snd_pcm_sync_ptr __user *_sync_ptr)
30573085
{
@@ -3165,9 +3193,7 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
31653193
if (snd_BUG_ON(!runtime))
31663194
return -EINVAL;
31673195

3168-
if (get_user(sflags, &src->flags) ||
3169-
get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
3170-
get_user(scontrol.avail_min, &src->c.control.avail_min))
3196+
if (snd_pcm_sync_ptr_get_user(sflags, scontrol, src))
31713197
return -EFAULT;
31723198
if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
31733199
err = snd_pcm_hwsync(substream);
@@ -3200,15 +3226,7 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
32003226
}
32013227
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
32023228
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
3203-
if (put_user(sstatus.state, &src->s.status.state) ||
3204-
put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
3205-
put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
3206-
put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp_nsec) ||
3207-
put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
3208-
put_user(sstatus.audio_tstamp.tv_sec, &src->s.status.audio_tstamp_sec) ||
3209-
put_user(sstatus.audio_tstamp.tv_nsec, &src->s.status.audio_tstamp_nsec) ||
3210-
put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
3211-
put_user(scontrol.avail_min, &src->c.control.avail_min))
3229+
if (snd_pcm_sync_ptr_put_user(sstatus, scontrol, src))
32123230
return -EFAULT;
32133231

32143232
return 0;

0 commit comments

Comments
 (0)