mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
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
This commit is contained in:
parent
d0630a0b80
commit
2acd83beb4
|
|
@ -418,9 +418,7 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
|
|||
if (snd_BUG_ON(!runtime))
|
||||
return -EINVAL;
|
||||
|
||||
if (get_user(sflags, &src->flags) ||
|
||||
get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
|
||||
get_user(scontrol.avail_min, &src->c.control.avail_min))
|
||||
if (snd_pcm_sync_ptr_get_user(sflags, scontrol, src))
|
||||
return -EFAULT;
|
||||
if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
|
||||
err = snd_pcm_hwsync(substream);
|
||||
|
|
@ -450,15 +448,7 @@ static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
|
|||
}
|
||||
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
if (put_user(sstatus.state, &src->s.status.state) ||
|
||||
put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
|
||||
put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
|
||||
put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp_nsec) ||
|
||||
put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
|
||||
put_user(sstatus.audio_tstamp.tv_sec, &src->s.status.audio_tstamp_sec) ||
|
||||
put_user(sstatus.audio_tstamp.tv_nsec, &src->s.status.audio_tstamp_nsec) ||
|
||||
put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
|
||||
put_user(scontrol.avail_min, &src->c.control.avail_min))
|
||||
if (snd_pcm_sync_ptr_put_user(sstatus, scontrol, src))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -3052,6 +3052,34 @@ static inline int snd_pcm_hwsync(struct snd_pcm_substream *substream)
|
|||
return snd_pcm_delay(substream, NULL);
|
||||
}
|
||||
|
||||
#define snd_pcm_sync_ptr_get_user(__f, __c, __ptr) ({ \
|
||||
int __err = 0; \
|
||||
typeof(*(__ptr)) __user *__src = (__ptr); \
|
||||
\
|
||||
if (get_user(__f, &src->flags) || \
|
||||
get_user(__c.appl_ptr, &__src->c.control.appl_ptr) || \
|
||||
get_user(__c.avail_min, &__src->c.control.avail_min)) \
|
||||
__err = -EFAULT; \
|
||||
__err; \
|
||||
})
|
||||
|
||||
#define snd_pcm_sync_ptr_put_user(__s, __c, __ptr) ({ \
|
||||
int __err = 0; \
|
||||
typeof(*(__ptr)) __user *__src = (__ptr); \
|
||||
\
|
||||
if (put_user(__s.state, &__src->s.status.state) || \
|
||||
put_user(__s.hw_ptr, &__src->s.status.hw_ptr) || \
|
||||
put_user(__s.tstamp.tv_sec, &__src->s.status.tstamp_sec) || \
|
||||
put_user(__s.tstamp.tv_nsec, &__src->s.status.tstamp_nsec) || \
|
||||
put_user(__s.suspended_state, &__src->s.status.suspended_state) || \
|
||||
put_user(__s.audio_tstamp.tv_sec, &__src->s.status.audio_tstamp_sec) || \
|
||||
put_user(__s.audio_tstamp.tv_nsec, &__src->s.status.audio_tstamp_nsec) || \
|
||||
put_user(__c.appl_ptr, &__src->c.control.appl_ptr) || \
|
||||
put_user(__c.avail_min, &__src->c.control.avail_min)) \
|
||||
__err = -EFAULT; \
|
||||
__err; \
|
||||
})
|
||||
|
||||
static int snd_pcm_sync_ptr(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_sync_ptr __user *_sync_ptr)
|
||||
{
|
||||
|
|
@ -3165,9 +3193,7 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
|
|||
if (snd_BUG_ON(!runtime))
|
||||
return -EINVAL;
|
||||
|
||||
if (get_user(sflags, &src->flags) ||
|
||||
get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
|
||||
get_user(scontrol.avail_min, &src->c.control.avail_min))
|
||||
if (snd_pcm_sync_ptr_get_user(sflags, scontrol, src))
|
||||
return -EFAULT;
|
||||
if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
|
||||
err = snd_pcm_hwsync(substream);
|
||||
|
|
@ -3200,15 +3226,7 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
|
|||
}
|
||||
if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
|
||||
snd_pcm_dma_buffer_sync(substream, SNDRV_DMA_SYNC_DEVICE);
|
||||
if (put_user(sstatus.state, &src->s.status.state) ||
|
||||
put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
|
||||
put_user(sstatus.tstamp.tv_sec, &src->s.status.tstamp_sec) ||
|
||||
put_user(sstatus.tstamp.tv_nsec, &src->s.status.tstamp_nsec) ||
|
||||
put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
|
||||
put_user(sstatus.audio_tstamp.tv_sec, &src->s.status.audio_tstamp_sec) ||
|
||||
put_user(sstatus.audio_tstamp.tv_nsec, &src->s.status.audio_tstamp_nsec) ||
|
||||
put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
|
||||
put_user(scontrol.avail_min, &src->c.control.avail_min))
|
||||
if (snd_pcm_sync_ptr_put_user(sstatus, scontrol, src))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user