From 82ba56c273911f7eda79849cfa0fc2d2e5a3b75b Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sat, 13 Oct 2007 15:46:55 -0400 Subject: Input: use full RCU API RT guys alerted me to the fact that in their tree spinlocks are preemptible and it is better to use full RCU API (rcu_read_lock()/rcu_read_unlock()) to be safe. Signed-off-by: Dmitry Torokhov --- drivers/input/evdev.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) (limited to 'drivers/input/evdev.c') diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 27026f7d3c0..1d62c8b88e1 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -63,10 +63,7 @@ static void evdev_pass_event(struct evdev_client *client, } /* - * Pass incoming event to all connected clients. Note that we are - * caleld under a spinlock with interrupts off so we don't need - * to use rcu_read_lock() here. Writers will be using syncronize_sched() - * instead of synchrnoize_rcu(). + * Pass incoming event to all connected clients. */ static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) @@ -80,6 +77,8 @@ static void evdev_event(struct input_handle *handle, event.code = code; event.value = value; + rcu_read_lock(); + client = rcu_dereference(evdev->grab); if (client) evdev_pass_event(client, &event); @@ -87,6 +86,8 @@ static void evdev_event(struct input_handle *handle, list_for_each_entry_rcu(client, &evdev->client_list, node) evdev_pass_event(client, &event); + rcu_read_unlock(); + wake_up_interruptible(&evdev->wait); } @@ -142,12 +143,7 @@ static int evdev_grab(struct evdev *evdev, struct evdev_client *client) return error; rcu_assign_pointer(evdev->grab, client); - /* - * We don't use synchronize_rcu() here because read-side - * critical section is protected by a spinlock instead - * of rcu_read_lock(). - */ - synchronize_sched(); + synchronize_rcu(); return 0; } @@ -158,7 +154,7 @@ static int evdev_ungrab(struct evdev *evdev, struct evdev_client *client) return -EINVAL; rcu_assign_pointer(evdev->grab, NULL); - synchronize_sched(); + synchronize_rcu(); input_release_device(&evdev->handle); return 0; @@ -170,7 +166,7 @@ static void evdev_attach_client(struct evdev *evdev, spin_lock(&evdev->client_lock); list_add_tail_rcu(&client->node, &evdev->client_list); spin_unlock(&evdev->client_lock); - synchronize_sched(); + synchronize_rcu(); } static void evdev_detach_client(struct evdev *evdev, @@ -179,7 +175,7 @@ static void evdev_detach_client(struct evdev *evdev, spin_lock(&evdev->client_lock); list_del_rcu(&client->node); spin_unlock(&evdev->client_lock); - synchronize_sched(); + synchronize_rcu(); } static int evdev_open_device(struct evdev *evdev) -- cgit v1.2.3