OSDN Git Service

ALSA: rawmidi: Use kvmalloc() for buffers
authorTakashi Iwai <tiwai@suse.de>
Tue, 17 Jul 2018 21:12:33 +0000 (23:12 +0200)
committerTakashi Iwai <tiwai@suse.de>
Wed, 18 Jul 2018 05:47:57 +0000 (07:47 +0200)
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: Takashi Iwai <tiwai@suse.de>
sound/core/rawmidi.c

index cc944a3..69517e1 100644 (file)
@@ -29,6 +29,7 @@
 #include <linux/mutex.h>
 #include <linux/module.h>
 #include <linux/delay.h>
+#include <linux/mm.h>
 #include <sound/rawmidi.h>
 #include <sound/info.h>
 #include <sound/control.h>
@@ -128,7 +129,7 @@ static int snd_rawmidi_runtime_create(struct snd_rawmidi_substream *substream)
                runtime->avail = 0;
        else
                runtime->avail = runtime->buffer_size;
-       runtime->buffer = kmalloc(runtime->buffer_size, GFP_KERNEL);
+       runtime->buffer = kvmalloc(runtime->buffer_size, GFP_KERNEL);
        if (!runtime->buffer) {
                kfree(runtime);
                return -ENOMEM;
@@ -142,7 +143,7 @@ static int snd_rawmidi_runtime_free(struct snd_rawmidi_substream *substream)
 {
        struct snd_rawmidi_runtime *runtime = substream->runtime;
 
-       kfree(runtime->buffer);
+       kvfree(runtime->buffer);
        kfree(runtime);
        substream->runtime = NULL;
        return 0;
@@ -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)
                return -EINVAL;
        if (params->buffer_size != runtime->buffer_size) {
-               newbuf = kmalloc(params->buffer_size, GFP_KERNEL);
+               newbuf = kvmalloc(params->buffer_size, GFP_KERNEL);
                if (!newbuf)
                        return -ENOMEM;
                spin_lock_irq(&runtime->lock);
@@ -663,7 +664,7 @@ static int resize_runtime_buffer(struct snd_rawmidi_runtime *runtime,
                runtime->buffer_size = params->buffer_size;
                __reset_runtime_ptrs(runtime, is_input);
                spin_unlock_irq(&runtime->lock);
-               kfree(oldbuf);
+               kvfree(oldbuf);
        }
        runtime->avail_min = params->avail_min;
        return 0;