From 1dfa2812404c37d7571622195f907cea3331616c Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 3 Jun 2007 23:29:36 -0400 Subject: [PATCH] Input: reduce raciness when input handlers disconnect There is a race between input handler's release() and disconnect() methods: when input handler disconnects it wakes up all regular users and then process to walk user list to wake up async. users. While disconnect() walks the list release() removes elements of the same list causing oopses. While this is not a substibute for proper locking we can reduce odds of getting an oops if we wake up normal readers after walking the list. Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 2 +- drivers/input/joydev.c | 2 +- drivers/input/mousedev.c | 2 +- drivers/input/tsdev.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index a4c3729d3960..93b407cd4600 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -700,9 +700,9 @@ static void evdev_disconnect(struct input_handle *handle) if (evdev->open) { input_flush_device(handle, NULL); input_close_device(handle); - wake_up_interruptible(&evdev->wait); list_for_each_entry(client, &evdev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); + wake_up_interruptible(&evdev->wait); } else evdev_free(evdev); } diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c index 9bcc5425049b..c83bfe8914ac 100644 --- a/drivers/input/joydev.c +++ b/drivers/input/joydev.c @@ -595,9 +595,9 @@ static void joydev_disconnect(struct input_handle *handle) if (joydev->open) { input_close_device(handle); - wake_up_interruptible(&joydev->wait); list_for_each_entry(client, &joydev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); + wake_up_interruptible(&joydev->wait); } else joydev_free(joydev); } diff --git a/drivers/input/mousedev.c b/drivers/input/mousedev.c index 7678e9876550..dc78f62cbee1 100644 --- a/drivers/input/mousedev.c +++ b/drivers/input/mousedev.c @@ -767,9 +767,9 @@ static void mousedev_disconnect(struct input_handle *handle) if (mousedev->open) { input_close_device(handle); - wake_up_interruptible(&mousedev->wait); list_for_each_entry(client, &mousedev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); + wake_up_interruptible(&mousedev->wait); } else mousedev_free(mousedev); } diff --git a/drivers/input/tsdev.c b/drivers/input/tsdev.c index 5e5b5c91d75b..af4581d00d82 100644 --- a/drivers/input/tsdev.c +++ b/drivers/input/tsdev.c @@ -477,9 +477,9 @@ static void tsdev_disconnect(struct input_handle *handle) if (tsdev->open) { input_close_device(handle); - wake_up_interruptible(&tsdev->wait); list_for_each_entry(client, &tsdev->client_list, node) kill_fasync(&client->fasync, SIGIO, POLL_HUP); + wake_up_interruptible(&tsdev->wait); } else tsdev_free(tsdev); }