]> Pileus Git - ~andy/linux/blobdiff - drivers/input/evdev.c
Input: evdev - fall back to vmalloc for client event buffer
[~andy/linux] / drivers / input / evdev.c
index b6ded17b3be3adda86ca93bf582f679f837442aa..a06e12552886fa57ffbe1731eb744762666cd787 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/poll.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/mm.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/input/mt.h>
@@ -369,7 +371,11 @@ static int evdev_release(struct inode *inode, struct file *file)
        mutex_unlock(&evdev->mutex);
 
        evdev_detach_client(evdev, client);
-       kfree(client);
+
+       if (is_vmalloc_addr(client))
+               vfree(client);
+       else
+               kfree(client);
 
        evdev_close_device(evdev);
 
@@ -389,12 +395,14 @@ static int evdev_open(struct inode *inode, struct file *file)
 {
        struct evdev *evdev = container_of(inode->i_cdev, struct evdev, cdev);
        unsigned int bufsize = evdev_compute_buffer_size(evdev->handle.dev);
+       unsigned int size = sizeof(struct evdev_client) +
+                                       bufsize * sizeof(struct input_event);
        struct evdev_client *client;
        int error;
 
-       client = kzalloc(sizeof(struct evdev_client) +
-                               bufsize * sizeof(struct input_event),
-                        GFP_KERNEL);
+       client = kzalloc(size, GFP_KERNEL | __GFP_NOWARN);
+       if (!client)
+               client = vzalloc(size);
        if (!client)
                return -ENOMEM;