}
/*
- * 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)
event.code = code;
event.value = value;
+ rcu_read_lock();
+
client = rcu_dereference(evdev->grab);
if (client)
evdev_pass_event(client, &event);
list_for_each_entry_rcu(client, &evdev->client_list, node)
evdev_pass_event(client, &event);
+ rcu_read_unlock();
+
wake_up_interruptible(&evdev->wait);
}
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;
}
return -EINVAL;
rcu_assign_pointer(evdev->grab, NULL);
- synchronize_sched();
+ synchronize_rcu();
input_release_device(&evdev->handle);
return 0;
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,
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)
/*
* Pass event through all open handles. This function is called with
- * dev->event_lock held and interrupts disabled. Because of that we
- * do not need to use rcu_read_lock() here although we are using RCU
- * to access handle list. Note that because of that write-side uses
- * synchronize_sched() instead of synchronize_ru().
+ * dev->event_lock held and interrupts disabled.
*/
static void input_pass_event(struct input_dev *dev,
unsigned int type, unsigned int code, int value)
{
- struct input_handle *handle = rcu_dereference(dev->grab);
+ struct input_handle *handle;
+
+ rcu_read_lock();
+ handle = rcu_dereference(dev->grab);
if (handle)
handle->handler->event(handle, type, code, value);
else
if (handle->open)
handle->handler->event(handle,
type, code, value);
+ rcu_read_unlock();
}
/*
if (is_event_supported(type, dev->evbit, EV_MAX)) {
spin_lock_irqsave(&dev->event_lock, flags);
+ rcu_read_lock();
grab = rcu_dereference(dev->grab);
if (!grab || grab == handle)
input_handle_event(dev, type, code, value);
+ rcu_read_unlock();
spin_unlock_irqrestore(&dev->event_lock, flags);
}
}
rcu_assign_pointer(dev->grab, handle);
- /*
- * Not using synchronize_rcu() because read-side is protected
- * by a spinlock with interrupts off instead of rcu_read_lock().
- */
- synchronize_sched();
+ synchronize_rcu();
out:
mutex_unlock(&dev->mutex);
if (dev->grab == handle) {
rcu_assign_pointer(dev->grab, NULL);
/* Make sure input_pass_event() notices that grab is gone */
- synchronize_sched();
+ synchronize_rcu();
list_for_each_entry(handle, &dev->h_list, d_node)
if (handle->open && handle->handler->start)
* Make sure we are not delivering any more events
* through this handle
*/
- synchronize_sched();
+ synchronize_rcu();
}
}
if (!--handle->open) {
/*
- * synchronize_sched() makes sure that input_pass_event()
+ * synchronize_rcu() makes sure that input_pass_event()
* completed and that no more input events are delivered
* through this handle
*/
- synchronize_sched();
+ synchronize_rcu();
}
mutex_unlock(&dev->mutex);
return error;
list_add_tail_rcu(&handle->d_node, &dev->h_list);
mutex_unlock(&dev->mutex);
- /*
- * We don't use synchronize_rcu() here because we rely
- * on dev->event_lock to protect read-side critical
- * section in input_pass_event().
- */
- synchronize_sched();
+ synchronize_rcu();
/*
* Since we are supposed to be called from ->connect()
mutex_lock(&dev->mutex);
list_del_rcu(&handle->d_node);
mutex_unlock(&dev->mutex);
- synchronize_sched();
+ synchronize_rcu();
}
EXPORT_SYMBOL(input_unregister_handle);
event.time = jiffies_to_msecs(jiffies);
+ rcu_read_lock();
list_for_each_entry_rcu(client, &joydev->client_list, node)
joydev_pass_event(client, &event);
+ rcu_read_unlock();
wake_up_interruptible(&joydev->wait);
}
spin_lock(&joydev->client_lock);
list_add_tail_rcu(&client->node, &joydev->client_list);
spin_unlock(&joydev->client_lock);
- /*
- * We don't use synchronize_rcu() here because read-side
- * critical section is protected by a spinlock (dev->event_lock)
- * instead of rcu_read_lock().
- */
- synchronize_sched();
+ synchronize_rcu();
}
static void joydev_detach_client(struct joydev *joydev,
spin_lock(&joydev->client_lock);
list_del_rcu(&client->node);
spin_unlock(&joydev->client_lock);
- synchronize_sched();
+ synchronize_rcu();
}
static int joydev_open_device(struct joydev *joydev)
unsigned int new_head;
int wake_readers = 0;
+ rcu_read_lock();
list_for_each_entry_rcu(client, &mousedev->client_list, node) {
/* Just acquire the lock, interrupts already disabled */
wake_readers = 1;
}
}
+ rcu_read_unlock();
if (wake_readers)
wake_up_interruptible(&mousedev->wait);
spin_lock(&mousedev->client_lock);
list_add_tail_rcu(&client->node, &mousedev->client_list);
spin_unlock(&mousedev->client_lock);
- /*
- * We don't use synchronize_rcu() here because read-side
- * critical section is protected by a spinlock (dev->event_lock)
- * instead of rcu_read_lock().
- */
- synchronize_sched();
+ synchronize_rcu();
}
static void mousedev_detach_client(struct mousedev *mousedev,
spin_lock(&mousedev->client_lock);
list_del_rcu(&client->node);
spin_unlock(&mousedev->client_lock);
- synchronize_sched();
+ synchronize_rcu();
}
static int mousedev_release(struct inode *inode, struct file *file)