Commit ef4db239 authored by Takashi Iwai's avatar Takashi Iwai

ALSA: rawmidi: Use kvmalloc() for buffers

The size of in-kernel rawmidi buffers may be big up to 1MB, and it can
be specified freely by user-space; which implies that user-space may
trigger kmalloc() errors frequently.

This patch replaces the buffer allocation via kvmalloc() for dealing
with bigger buffers gracefully.
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent f5beb598
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/mm.h>
#include <sound/rawmidi.h> #include <sound/rawmidi.h>
#include <sound/info.h> #include <sound/info.h>
#include <sound/control.h> #include <sound/control.h>
...@@ -128,7 +129,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream) ...@@ -128,7 +129,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
runtime->avail = 0; runtime->avail = 0;
else else
runtime->avail = runtime->buffer_size; runtime->avail = runtime->buffer_size;
runtime->buffer = kmalloc(runtime->buffer_size, GFP_KERNEL); runtime->buffer = kvmalloc(runtime->buffer_size, GFP_KERNEL);
if (!runtime->buffer) { if (!runtime->buffer) {
kfree(runtime); kfree(runtime);
return -ENOMEM; return -ENOMEM;
...@@ -142,7 +143,7 @@ static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream) ...@@ -142,7 +143,7 @@ static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream)
{ {
struct snd_rawmidi_runtime *runtime = substream->runtime; struct snd_rawmidi_runtime *runtime = substream->runtime;
kfree(runtime->buffer); kvfree(runtime->buffer);
kfree(runtime); kfree(runtime);
substream->runtime = NULL; substream->runtime = NULL;
return 0; return 0;
...@@ -654,7 +655,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime, ...@@ -654,7 +655,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime,
if (params->avail_min < 1 || params->avail_min > params->buffer_size) if (params->avail_min < 1 || params->avail_min > params->buffer_size)
return -EINVAL; return -EINVAL;
if (params->buffer_size != runtime->buffer_size) { if (params->buffer_size != runtime->buffer_size) {
newbuf = kmalloc(params->buffer_size, GFP_KERNEL); newbuf = kvmalloc(params->buffer_size, GFP_KERNEL);
if (!newbuf) if (!newbuf)
return -ENOMEM; return -ENOMEM;
spin_lock_irq(&runtime->lock); spin_lock_irq(&runtime->lock);
...@@ -663,7 +664,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime, ...@@ -663,7 +664,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime,
runtime->buffer_size = params->buffer_size; runtime->buffer_size = params->buffer_size;
__reset_runtime_ptrs(runtime, is_input); __reset_runtime_ptrs(runtime, is_input);
spin_unlock_irq(&runtime->lock); spin_unlock_irq(&runtime->lock);
kfree(oldbuf); kvfree(oldbuf);
} }
runtime->avail_min = params->avail_min; runtime->avail_min = params->avail_min;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment