ALSA: pcm - Avoid GFP_ATOMIC in snd_pcm_link()
GFP_ATOMIC is used in snd_pcm_link() just because the kmalloc is called inside a lock. Since this function isn't too critical for speed and is rarely called in practice, better to allocate the chunk at first before spinlock and free it in error paths, so that GFP_KERNEL can be used. Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
4af87a939e
commit
1662591b2e
|
@ -1586,12 +1586,18 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
|
|||
struct file *file;
|
||||
struct snd_pcm_file *pcm_file;
|
||||
struct snd_pcm_substream *substream1;
|
||||
struct snd_pcm_group *group;
|
||||
|
||||
file = snd_pcm_file_fd(fd);
|
||||
if (!file)
|
||||
return -EBADFD;
|
||||
pcm_file = file->private_data;
|
||||
substream1 = pcm_file->substream;
|
||||
group = kmalloc(sizeof(*group), GFP_KERNEL);
|
||||
if (!group) {
|
||||
res = -ENOMEM;
|
||||
goto _nolock;
|
||||
}
|
||||
down_write(&snd_pcm_link_rwsem);
|
||||
write_lock_irq(&snd_pcm_link_rwlock);
|
||||
if (substream->runtime->status->state == SNDRV_PCM_STATE_OPEN ||
|
||||
|
@ -1604,11 +1610,7 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
|
|||
goto _end;
|
||||
}
|
||||
if (!snd_pcm_stream_linked(substream)) {
|
||||
substream->group = kmalloc(sizeof(struct snd_pcm_group), GFP_ATOMIC);
|
||||
if (substream->group == NULL) {
|
||||
res = -ENOMEM;
|
||||
goto _end;
|
||||
}
|
||||
substream->group = group;
|
||||
spin_lock_init(&substream->group->lock);
|
||||
INIT_LIST_HEAD(&substream->group->substreams);
|
||||
list_add_tail(&substream->link_list, &substream->group->substreams);
|
||||
|
@ -1620,7 +1622,10 @@ static int snd_pcm_link(struct snd_pcm_substream *substream, int fd)
|
|||
_end:
|
||||
write_unlock_irq(&snd_pcm_link_rwlock);
|
||||
up_write(&snd_pcm_link_rwsem);
|
||||
_nolock:
|
||||
fput(file);
|
||||
if (res < 0)
|
||||
kfree(group);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue