Thread (49 messages) 49 messages, 6 authors, 2012-09-19

Re: [PATCH v3 05/20] Input: Send events one packet at a time

flat view

From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Date: 2012-09-13 06:56:20
Also in: lkml

On Sat, Sep 01, 2012 at 09:47:00PM +0200, Henrik Rydberg wrote:
quoted hunk ↗ jump to hunk
On heavy event loads, such as a multitouch driver, the irqsoff latency
can be as high as 250 us.  By accumulating a frame worth of data
before passing it on, the latency can be dramatically reduced.  As a
side effect, the special EV_SYN handling can be removed, since the
frame is now atomic.

This patch adds the events() handler callback and uses it if it
exists. The latency is improved by 50 us even without the callback.

Signed-off-by: Henrik Rydberg <redacted>
---
 drivers/input/input.c | 176 +++++++++++++++++++++++++++++++++++---------------
 include/linux/input.h |  24 ++++++-
 2 files changed, 144 insertions(+), 56 deletions(-)
diff --git a/drivers/input/input.c b/drivers/input/input.c
index a57c4a5..5b66b2f 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -47,6 +47,8 @@ static DEFINE_MUTEX(input_mutex);
 
 static struct input_handler *input_table[8];
 
+static const struct input_value input_value_sync = { EV_SYN, SYN_REPORT, 1 };
+
 static inline int is_event_supported(unsigned int code,
 				     unsigned long *bm, unsigned int max)
 {
@@ -90,46 +92,81 @@ static void input_stop_autorepeat(struct input_dev *dev)
  * filtered out, through all open handles. This function is called with
  * dev->event_lock held and interrupts disabled.
  */
-static void input_pass_event(struct input_dev *dev,
-			     unsigned int type, unsigned int code, int value)
+static unsigned int input_to_handler(struct input_handle *handle,
+			struct input_value *vals, unsigned int count)
 {
-	struct input_handler *handler;
-	struct input_handle *handle;
+	struct input_handler *handler = handle->handler;
+	struct input_value *end = vals;
+	struct input_value *v;
 
-	rcu_read_lock();
+	for (v = vals; v != vals + count; v++) {
+		if (handler->filter &&
+		    handler->filter(handle, v->type, v->code, v->value))
+			continue;
+		if (end != v)
+			*end = *v;
+		end++;
+	}
 
-	handle = rcu_dereference(dev->grab);
-	if (handle)
-		handle->handler->event(handle, type, code, value);
-	else {
-		bool filtered = false;
+	count = end - vals;
+	if (!count)
+		return 0;
 
-		list_for_each_entry_rcu(handle, &dev->h_list, d_node) {
-			if (!handle->open)
-				continue;
+	if (handler->events)
+		handler->events(handle, vals, count);
+	else
+		for (v = vals; v != end; v++)
+			handler->event(handle, v->type, v->code, v->value);
Filter handlers do not typically have ->event() methods, that's the
reason for reported panic.

Thanks.

-- 
Dmitry
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help