summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@insightbb.com>2007-06-04 03:29:36 (GMT)
committerDmitry Torokhov <dtor@insightbb.com>2007-06-04 03:50:05 (GMT)
commit1dfa2812404c37d7571622195f907cea3331616c (patch)
tree2533af73ff0e1e4d24603967bd6cdc092973dce9
parent26be5a509af5f80c7012bd4f0478a94746c9c9d9 (diff)
downloadlinux-fsl-qoriq-1dfa2812404c37d7571622195f907cea3331616c.tar.xz
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 <dtor@mail.ru>
-rw-r--r--drivers/input/evdev.c2
-rw-r--r--drivers/input/joydev.c2
-rw-r--r--drivers/input/mousedev.c2
-rw-r--r--drivers/input/tsdev.c2
4 files changed, 4 insertions, 4 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index a4c3729..93b407c 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 9bcc542..c83bfe8 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 7678e98..dc78f62 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 5e5b5c9..af4581d 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);
}