diff options
Diffstat (limited to '0010-ZEN-Input-evdev-use-call_rcu-when-detaching-client.patch')
-rw-r--r-- | 0010-ZEN-Input-evdev-use-call_rcu-when-detaching-client.patch | 107 |
1 files changed, 0 insertions, 107 deletions
diff --git a/0010-ZEN-Input-evdev-use-call_rcu-when-detaching-client.patch b/0010-ZEN-Input-evdev-use-call_rcu-when-detaching-client.patch deleted file mode 100644 index 28a066ead711..000000000000 --- a/0010-ZEN-Input-evdev-use-call_rcu-when-detaching-client.patch +++ /dev/null @@ -1,107 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Kenny Levinsen <kl@kl.wtf> -Date: Sun, 27 Dec 2020 14:43:13 +0000 -Subject: [PATCH] ZEN: Input: evdev - use call_rcu when detaching client - -Significant time was spent on synchronize_rcu in evdev_detach_client -when applications closed evdev devices. Switching VT away from a -graphical environment commonly leads to mass input device closures, -which could lead to noticable delays on systems with many input devices. - -Replace synchronize_rcu with call_rcu, deferring reclaim of the evdev -client struct till after the RCU grace period instead of blocking the -calling application. - -While this does not solve all slow evdev fd closures, it takes care of a -good portion of them, including this simple test: - - #include <fcntl.h> - #include <unistd.h> - - int main(int argc, char *argv[]) - { - int idx, fd; - const char *path = "/dev/input/event0"; - for (idx = 0; idx < 1000; idx++) { - if ((fd = open(path, O_RDWR)) == -1) { - return -1; - } - close(fd); - } - return 0; - } - -Time to completion of above test when run locally: - - Before: 0m27.111s - After: 0m0.018s - -Signed-off-by: Kenny Levinsen <kl@kl.wtf> ---- - drivers/input/evdev.c | 19 +++++++++++-------- - 1 file changed, 11 insertions(+), 8 deletions(-) - -diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c -index 95f90699d2b17b4e42e067bf44b6deac611fdb8b..2b10fe29d2c8d9028a2f8d6c2c8987f01802f471 100644 ---- a/drivers/input/evdev.c -+++ b/drivers/input/evdev.c -@@ -46,6 +46,7 @@ struct evdev_client { - struct fasync_struct *fasync; - struct evdev *evdev; - struct list_head node; -+ struct rcu_head rcu; - enum input_clock_type clk_type; - bool revoked; - unsigned long *evmasks[EV_CNT]; -@@ -377,13 +378,22 @@ static void evdev_attach_client(struct evdev *evdev, - spin_unlock(&evdev->client_lock); - } - -+static void evdev_reclaim_client(struct rcu_head *rp) -+{ -+ struct evdev_client *client = container_of(rp, struct evdev_client, rcu); -+ unsigned int i; -+ for (i = 0; i < EV_CNT; ++i) -+ bitmap_free(client->evmasks[i]); -+ kvfree(client); -+} -+ - static void evdev_detach_client(struct evdev *evdev, - struct evdev_client *client) - { - spin_lock(&evdev->client_lock); - list_del_rcu(&client->node); - spin_unlock(&evdev->client_lock); -- synchronize_rcu(); -+ call_rcu(&client->rcu, evdev_reclaim_client); - } - - static int evdev_open_device(struct evdev *evdev) -@@ -436,7 +446,6 @@ static int evdev_release(struct inode *inode, struct file *file) - { - struct evdev_client *client = file->private_data; - struct evdev *evdev = client->evdev; -- unsigned int i; - - mutex_lock(&evdev->mutex); - -@@ -448,11 +457,6 @@ static int evdev_release(struct inode *inode, struct file *file) - - evdev_detach_client(evdev, client); - -- for (i = 0; i < EV_CNT; ++i) -- bitmap_free(client->evmasks[i]); -- -- kvfree(client); -- - evdev_close_device(evdev); - - return 0; -@@ -495,7 +499,6 @@ static int evdev_open(struct inode *inode, struct file *file) - - err_free_client: - evdev_detach_client(evdev, client); -- kvfree(client); - return error; - } - |